test "hydrostatic pressure" {
// Water depth 10m, water density 1000 kg/m³
// p = p0 + ρgh = 101325 + 1000*9.80665*10 = 199391.5 Pa
let p = hydrostatic_pressure_std(ATMOSPHERIC_PRESSURE, RHO_WATER, 10.0)
assert_eq(approx_equal(p, 199391.5, 50.0), true)
// Buoyant force
let fb = buoyant_force_std(RHO_WATER, 1.0) // 1 m³ water
assert_eq(approx_equal(fb, 9806.65, 1.0), true)
}test "continuity equation" {
// Volume flow rate
let q = volume_flow_rate(0.1, 2.0) // 0.1 m² * 2 m/s
assert_eq(q, 0.2)
// Velocity calculation from flow rate
let v = velocity_from_flow_rate(0.2, 0.1)
assert_eq(v, 2.0)
// Mass flow rate
let mdot = mass_flow_rate(RHO_WATER, 0.2)
assert_eq(mdot, 200.0)
}test "bernoulli equation" {
// Total head: z=5, p/(ρg)=10.19, v²/(2g)=0.459
let h = bernoulli_total_head_std(5.0, 100000.0, RHO_WATER, 3.0)
assert_eq(approx_equal(h, 15.65, 0.5), true)
// Velocity head
let hv = velocity_head(5.0, G)
assert_eq(approx_equal(hv, 1.274, 0.01), true)
}test "reynolds number" {
// Re = ρvD/μ
// Water: ρ=1000, v=1 m/s, D=0.1 m, μ=0.001002
// Re = 1000*1*0.1/0.001002 ≈ 99800
let re = reynolds_number(RHO_WATER, 1.0, 0.1, MU_WATER_20C)
assert_eq(approx_equal(re, 99800.0, 500.0), true)
// Determine flow regime
assert_eq(is_turbulent_pipe(5000.0), true)
assert_eq(is_turbulent_pipe(1000.0), false)
}test "laminar flow" {
// Laminar flow rate: Q = πΔpR⁴/(8μL)
// Δp=1000 Pa, μ=0.001, L=10 m, R=0.05 m
// Q = π*1000*0.05⁴/(8*0.001*10) = π*1000*0.00000625/0.08 = 0.245 m³/s
let q = laminar_flow_rate(1000.0, MU_WATER_20C, 10.0, 0.05)
assert_eq(approx_equal(q, 0.245, 0.01), true)
// Laminar friction factor
let f = laminar_friction_factor(1000.0)
assert_eq(f, 0.064)
}test "darcy weisbach" {
// Friction head loss
// f=0.02, L=100 m, D=0.2 m, v=2 m/s
// hf = 0.02*(100/0.2)*(4/(2*9.81)) = 0.02*500*0.204 = 2.04 m
let hf = darcy_weisbach_head_loss_std(0.02, 100.0, 0.2, 2.0)
assert_eq(approx_equal(hf, 2.04, 0.1), true)
}test "local losses" {
// Local head loss
let hl = local_head_loss_std(0.5, 3.0)
assert_eq(approx_equal(hl, 0.229, 0.01), true)
// Sudden expansion loss coefficient
let k_exp = sudden_expansion_loss_coefficient(0.1, 0.2)
assert_eq(approx_equal(k_exp, 0.25, 0.01), true)
}test "manning formula" {
// Rectangular open channel: b=2m, h=1m, n=0.013, S=0.001
// A = 2*1 = 2 m², P = 2+2*1 = 4 m, R = 2/4 = 0.5 m
// Q = (1/0.013)*2*0.5^(2/3)*0.001^(1/2)
let r = hydraulic_radius_rect(2.0, 1.0)
assert_eq(approx_equal(r, 0.5, 0.01), true)
let q = manning_flow_rate(0.013, 2.0, 0.5, 0.001)
assert_eq(q > 0.0, true)
}test "froude number" {
// Fr = v/sqrt(gh)
// v=2 m/s, h=1 m
// Fr = 2/sqrt(9.81*1) = 0.639
let fr = froude_number(2.0, G, 1.0)
assert_eq(approx_equal(fr, 0.639, 0.01), true)
// Flow regime classification
assert_eq(flow_regime(0.5), "subcritical")
assert_eq(flow_regime(1.0), "critical")
assert_eq(flow_regime(2.0), "supercritical")
}test "drag and lift" {
// Drag force: F_D = 0.5*ρ*v²*A*C_D
// ρ=1.204, v=10 m/s, A=1 m², C_D=0.5
// F_D = 0.5*1.204*100*1*0.5 = 30.1 N
let fd = drag_force(RHO_AIR, 10.0, 1.0, 0.5)
assert_eq(approx_equal(fd, 30.1, 0.1), true)
// Lift force: F_L = 0.5*ρ*v²*A*C_L = 0.5*1.204*100*1*0.8 = 48.16 N
let fl = lift_force(RHO_AIR, 10.0, 1.0, 0.8)
assert_eq(approx_equal(fl, 48.16, 0.1), true)
}test "dimensionless numbers" {
// Weber number
let we = weber_number(RHO_WATER, 5.0, 0.1, SIGMA_WATER)
assert_eq(we > 0.0, true)
// Mach number
let ma = mach_number(340.0, 340.0)
assert_eq(ma, 1.0)
// Euler number: Eu = Δp/(ρv²) = 1000/(1000*25) = 0.04
let eu = euler_number(1000.0, RHO_WATER, 5.0)
assert_eq(approx_equal(eu, 0.04, 0.01), true)
}test "tools functions" {
// Square and cube
assert_eq(square(3.0), 9.0)
assert_eq(cube(2.0), 8.0)
// Cube root
assert_eq(approx_equal(cbrt(27.0), 3.0, 0.0001), true)
assert_eq(approx_equal(cbrt(8.0), 2.0, 0.0001), true)
// Logarithm (approximate, with larger tolerance)
assert_eq(approx_equal(log10_approx(100.0), 2.0, 0.3), true)
}moon testfn area_from_flow_rate(flow_rate : Double, velocity : Double) -> Doublefn bernoulli_pressure_drop(v1 : Double, v2 : Double, z1 : Double, z2 : Double, rho : Double, g : Double) -> Doublefn bernoulli_total_head(z : Double, p : Double, rho : Double, g : Double, v : Double) -> Doublefn bernoulli_total_head_std(z : Double, p : Double, rho : Double, v : Double) -> Doublefn bisection(f : (Double) -> Double, a : Double, b : Double, tolerance : Double) -> Doublefn blasius_friction_factor(re : Double) -> Doublefn boundary_layer_thickness_laminar(x : Double, re_x : Double) -> Doublefn boundary_layer_thickness_turbulent(x : Double, re_x : Double) -> Doublefn buoyant_force(rho : Double, g : Double, volume : Double) -> Doublefn colebrook_friction_factor_estimate(re : Double, epsilon : Double, d : Double) -> Doublefn critical_depth_rect(q : Double, g : Double) -> Doublefn cylinder_drag_coefficient(re : Double) -> Doublefn darcy_weisbach_head_loss(f : Double, l : Double, d : Double, v : Double, g : Double) -> Doublefn darcy_weisbach_head_loss_std(f : Double, l : Double, d : Double, v : Double) -> Doublefn darcy_weisbach_pressure_drop(f : Double, l : Double, d : Double, rho : Double, v : Double) -> Doublefn drag_force(rho : Double, v : Double, area : Double, cd : Double) -> Doublefn euler_number(dp : Double, rho : Double, v : Double) -> Doublefn flat_plate_friction_coefficient_laminar(re_x : Double) -> Doublefn flat_plate_friction_coefficient_turbulent(re_x : Double) -> Doublefn flow_regime(fr : Double) -> Stringfn froude_dimensionless(v : Double, g : Double, l : Double) -> Doublefn froude_number(v : Double, g : Double, h : Double) -> Doublefn froude_similarity(fr_model : Double, fr_prototype : Double) -> Boolfn fully_rough_friction_factor(epsilon : Double, d : Double) -> Doublefn hydraulic_diameter(area : Double, perimeter : Double) -> Doublefn hydraulic_radius(area : Double, perimeter : Double) -> Doublefn hydraulic_radius_trapezoid(b : Double, h : Double, m : Double) -> Doublefn hydrostatic_pressure(p0 : Double, rho : Double, g : Double, h : Double) -> Doublefn hydrostatic_pressure_std(p0 : Double, rho : Double, h : Double) -> Doublefn is_turbulent(re : Double, re_critical : Double) -> Boolfn jet_force(rho : Double, area : Double, velocity : Double) -> Doublefn jet_force_angled(rho : Double, area : Double, velocity : Double, angle_rad : Double) -> Doublefn laminar_flow_rate(dp : Double, mu : Double, l : Double, r : Double) -> Doublefn laminar_max_velocity(dp : Double, mu : Double, l : Double, r : Double) -> Doublefn laminar_mean_velocity(dp : Double, mu : Double, l : Double, r : Double) -> Doublefn laminar_pressure_drop(mu : Double, l : Double, v : Double, d : Double) -> Doublefn laminar_velocity_profile(dp : Double, mu : Double, l : Double, r : Double, r_pipe : Double) -> Doublefn lift_force(rho : Double, v : Double, area : Double, cl : Double) -> Doublefn local_head_loss(k : Double, v : Double, g : Double) -> Doublefn mach_number(v : Double, c : Double) -> Doublefn manning_flow_rate(n : Double, area : Double, r : Double, s : Double) -> Doublefn manning_velocity(n : Double, r : Double, s : Double) -> Doublefn mass_flow_rate_av(rho : Double, area : Double, velocity : Double) -> Doublefn momentum_force(rho : Double, q : Double, v1 : Double, v2 : Double) -> Doublefn newton_method(f : (Double) -> Double, df : (Double) -> Double, x0 : Double, tolerance : Double) -> Doublefn orifice_flow_rate(c : Double, a0 : Double, dh : Double, g : Double) -> Doublefn pressure_center_depth(y_c : Double, i_c : Double, area : Double) -> Doublefn pressure_center_rect(h_c : Double, b : Double, h : Double) -> Doublefn pressure_head(p : Double, rho : Double, g : Double) -> Doublefn reynolds_dimensionless(rho : Double, v : Double, l : Double, mu : Double) -> Doublefn reynolds_number(rho : Double, v : Double, d : Double, mu : Double) -> Doublefn reynolds_number_hydraulic_diameter(rho : Double, v : Double, d_h : Double, mu : Double) -> Doublefn reynolds_number_kinematic(v : Double, d : Double, nu : Double) -> Doublefn reynolds_similarity(re_model : Double, re_prototype : Double) -> Boolfn sphere_drag_coefficient_stokes(re : Double) -> Doublefn sphere_drag_stokes(mu : Double, d : Double, v : Double) -> Doublefn sudden_contraction_loss_coefficient(a1 : Double, a2 : Double) -> Doublefn sudden_expansion_loss_coefficient(a1 : Double, a2 : Double) -> Doublefn total_head_loss(h_friction : Double, h_local : Double) -> Doublefn total_pressure_plane(rho : Double, g : Double, h_c : Double, area : Double) -> Doublefn total_pressure_plane_std(rho : Double, h_c : Double, area : Double) -> Doublefn velocity_from_flow_rate(flow_rate : Double, area : Double) -> Doublefn venturi_flow_rate(c : Double, a1 : Double, a2 : Double, dh : Double, g : Double) -> Doublefn volume_flow_rate(area : Double, velocity : Double) -> Doublefn weber_number(rho : Double, v : Double, l : Double, sigma : Double) -> Doublefn weir_rectangular_flow(c : Double, b : Double, h : Double) -> Doublefn weir_triangular_flow(c : Double, theta_deg : Double, h : Double) -> DoubleInstall
Download zip