Files
pipe-system-simulation-test/src/friction.py
T
2026-06-03 15:41:04 +08:00

75 lines
2.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# src/friction.py
"""
Darcy-Weisbach friction factor calculation.
Supports:
- Laminar: f = 64 / Re (Re < 2300)
- Turbulent: Colebrook-White implicit equation (Re > 4000)
- Transition: linear blend between laminar & turbulent (2300 <= Re <= 4000)
"""
import numpy as np
def _colebrook_white(Re, eps_D, n_iter=10):
"""
Solve the Colebrook-White equation for Darcy friction factor f:
1/sqrt(f) = -2 log10( eps_D/3.7 + 2.51/(Re*sqrt(f)) )
Uses fixed-point iteration seeded with the Swamee-Jain approximation.
"""
# Swamee-Jain initial guess (explicit approximation)
A = eps_D / 3.7
B = 2.51 / Re
f = 0.25 / (np.log10(A + B / np.sqrt(0.02))) ** 2
for _ in range(n_iter):
f = 0.25 / (np.log10(A + B / np.sqrt(f))) ** 2
return f
def darcy_friction_factor(Re, eps_D):
"""
Compute Darcy-Weisbach friction factor for a given Reynolds number
and relative roughness eps/D.
Parameters
----------
Re : float or ndarray
Reynolds number (ρ|u|D/μ). Values <= 0 return 0 (no flow).
eps_D : float
Relative roughness ε/D (dimensionless).
Returns
-------
f : same shape as Re
Darcy friction factor.
"""
Re = np.asarray(Re, dtype=float)
scalar = Re.ndim == 0
Re = np.atleast_1d(Re)
f = np.zeros_like(Re)
lam = Re < 2300
turb = Re > 4000
trans = ~lam & ~turb # 2300 <= Re <= 4000
# Laminar: f = 64/Re (avoid division by zero for Re~0)
Re_lam = np.where(Re > 1e-12, Re, 1e-12)
f[lam] = 64.0 / Re_lam[lam]
# Turbulent: Colebrook-White
if np.any(turb):
f[turb] = _colebrook_white(Re[turb], eps_D)
# Transition: linear blend
if np.any(trans):
f_lam = 64.0 / Re_lam[trans]
f_turb = _colebrook_white(Re[trans], eps_D)
alpha = (Re[trans] - 2300.0) / 1700.0 # 0 at Re=2300, 1 at Re=4000
f[trans] = (1.0 - alpha) * f_lam + alpha * f_turb
return float(f[0]) if scalar else f