The Reynolds number¶
How much a flow's inertia outweighs its viscosity past a body, Re = rho |u| L / mu, with rho the fluid's density, |u| the body's speed through it, L the body's length (a sphere's diameter) and mu the fluid's dynamic viscosity (a substance's, lusine.materials).
It says which drag law holds: below about 1 Stokes's (lusine.laws.drag), from about 10^3 to a sphere's drag crisis near 2 x 10^5 the wake's (lusine.laws.quadratic_drag, C_d nearly constant). Source: Kundu & Cohen, Fluid Mechanics, 6th ed., 10.11 (Reynolds number; drag on a sphere). Checked against a reference in numpy, which has its own tests.
- Source
- Kundu & Cohen, Fluid Mechanics, 6th ed., 10.11.
- Proof
- reference.
reynolds_number.trait
namespace lusine.properties;
float reynolds_number(float<kg/m3> density, float<m/s> speed, float<m> length, float<Pa*s> viscosity)
{
return ((density * speed) * length) / viscosity;
}
A flow's inertia over its viscosity past a body, rho |u| L / mu, which says which drag law holds: Stokes's (lusine.laws.drag) below about 1, the wake's (lusine.laws.quadratic_drag) from about 10^3 to a sphere's drag crisis near 2 x 10^5.
import os, sys
root = os.getcwd()
while not os.path.isfile(os.path.join(root, 'docsite.json')):
root = os.path.dirname(root)
sys.path.insert(0, os.path.join(root, 'tools'))
import numpy as np
import matplotlib.pyplot as plt
from lusine import trait_run
F32 = np.float32
U = float(np.finfo(F32).eps) / 2 # binary32's unit roundoff, 2^-24
rng = np.random.default_rng(2026)
The kernel¶
The law as the library states it.
print(trait_run.source('properties/reynolds_number.trait'))
// lusine.properties.reynolds_number: how much a flow's inertia outweighs its viscosity past a body, Re = rho |u| L /
// mu, with rho the fluid's density, |u| the body's speed through it, L the body's length (a sphere's diameter) and mu
// the fluid's dynamic viscosity (a substance's, lusine.materials). It says which drag law holds: below about 1
// Stokes's (lusine.laws.drag), from about 10^3 to a sphere's drag crisis near 2 x 10^5 the wake's
// (lusine.laws.quadratic_drag, C_d nearly constant).
// Source: Kundu & Cohen, Fluid Mechanics, 6th ed., 10.11 (Reynolds number; drag on a sphere).
// Checked against a reference in numpy, which has its own tests.
namespace lusine.properties;
float reynolds_number(float<kg/m3> density, float<m/s> speed, float<m> length, float<Pa*s> viscosity)
{
return ((density * speed) * length) / viscosity;
}
The program¶
Each section below runs the kernel over a lattice of items, one a case: the host sets every parameter, and main() binds the kernel over the items.
print(trait_run.law_program('properties/reynolds_number.trait', 'reynolds_number'))
namespace probe;
lusine.version version = { { number = 1 } };
struct item {
host float<kg/m3> density;
host float<m/s> speed;
host float<m> length;
host float<Pa*s> viscosity;
float result_0;
};
lattice<item, 1> items(spacing = 1 m, boundary = wall);
void main() { items.result_0 = lusine.properties.reynolds_number(items.density, items.speed, items.length, items.viscosity); }
from lusine.kernels.properties.reynolds_number import reynolds_number as reference
Reference: a boule, a jack and a grain¶
Air at 20 C (rho 1.204 kg/m^3, mu 1.81 x 10^-5 Pa s): a boule (D 74 mm) and a jack (D 30 mm) at 7 m/s are in the wake's drag; a 0.1 mm grain settling at 1 mm/s in water is in Stokes's.
re = trait_run.law('properties/reynolds_number.trait', 'reynolds_number', density=np.array([1.204, 1.204, 1000.0]),
speed=np.array([7.0, 7.0, 1e-3]), length=np.array([0.074, 0.030, 1e-4]),
viscosity=np.array([1.81e-5, 1.81e-5, 1e-3]))
want = reference(np.array([1.204, 1.204, 1000.0]), np.array([7.0, 7.0, 1e-3]), np.array([0.074, 0.030, 1e-4]),
np.array([1.81e-5, 1.81e-5, 1e-3]))
assert np.max(np.abs(re - want) / want) <= 1e-6
assert 1e3 < re[1] < re[0] < 2e5 and re[2] < 1
print(f'a boule {re[0]:.3g}, a jack {re[1]:.3g}: the wake\'s drag; a grain {re[2]:.2g}: Stokes\'s')
a boule 3.45e+04, a jack 1.4e+04: the wake's drag; a grain 0.1: Stokes's