Bug description
The default friction model "nikuradse" unconditionally adds lambda_laminar + lambda_nikuradse instead of selecting the appropriate value based on Reynolds number. This produces incorrect friction factors for all flow regimes, with the largest relative error in the laminar/transition zone.
Location
pandapipes/pf/derivative_calculation.py, function calc_lambda(...), the else branch at lines 194-197 (pandapipes 0.13.0):
else:
# lambda_tot = np.where(re > 2300, lambda_laminar + lambda_nikuradse, lambda_laminar)
lambda_tot = lambda_laminar + lambda_nikuradse
return lambda_tot, re
This branch is taken whenever friction_model is neither "colebrook" nor "swamee-jain" — i.e. it is the path used for "nikuradse" (the default).
Expected behaviour
Standard textbook treatment: pick laminar or turbulent, do not sum them.
lambda_tot = np.where(re > 2300, lambda_nikuradse, lambda_laminar)
- Laminar (Re < 2300):
lambda_laminar = 64/Re (Hagen-Poiseuille)
- Turbulent (Re >= 2300):
lambda_nikuradse (Nikuradse fully-rough approximation)
The commented-out line directly above the bug also has an issue: it would still add both values in the turbulent branch (lambda_laminar + lambda_nikuradse) rather than using only lambda_nikuradse.
Actual behaviour / impact
| Re |
lambda_laminar |
lambda_nikuradse |
Current (sum) |
Correct |
Error |
| 500 |
0.1280 |
0.0196 |
0.1476 |
0.1280 |
+15% |
| 2000 |
0.0320 |
0.0196 |
0.0516 |
0.0320 |
+61% |
| 80979 |
0.0008 |
0.0196 |
0.0204 |
0.0196 |
+4% |
The error is most severe near the transition zone (Re ~ 2000-3000) where both terms are similar in magnitude.
Minimal reproducer
import pandapipes as pp
net = pp.create_empty_network(fluid="water")
j0 = pp.create_junction(net, pn_bar=6, tfluid_k=363.15)
j1 = pp.create_junction(net, pn_bar=6, tfluid_k=363.15)
pp.create_pipe_from_parameters(net, j0, j1, length_km=0.5, diameter_m=0.1, k_mm=0.1)
pp.create_ext_grid(net, j0, p_bar=6.0, t_k=363.15)
pp.create_sink(net, j1, mdot_kg_per_s=2.0)
pp.pipeflow(net, mode="hydraulics", friction_model="nikuradse")
dp_nik = net.res_pipe.p_from_bar.iloc[0] - net.res_pipe.p_to_bar.iloc[0]
pp.pipeflow(net, mode="hydraulics", friction_model="colebrook")
dp_cb = net.res_pipe.p_from_bar.iloc[0] - net.res_pipe.p_to_bar.iloc[0]
print(f"dp nikuradse: {dp_nik:.4f} bar")
print(f"dp colebrook: {dp_cb:.4f} bar")
print(f"ratio: {dp_nik/dp_cb:.3f}")
# Observed ratio ~0.9 at high Re (should be ~1.0); discrepancy comes from the
# spurious +lambda_laminar term that is still added in the fully turbulent regime.
Workaround
Pass friction_model="colebrook" (or "swamee-jain") explicitly — both code paths return early before the buggy else branch.
pp.pipeflow(net, friction_model="colebrook")
Suggested fix
Replace line 196 with:
lambda_tot = np.where(re > 2300, lambda_nikuradse, lambda_laminar)
return lambda_tot, re
I am happy to open a PR if the maintainers agree with the fix.
Environment
- pandapipes 0.13.0 (installed at
site-packages/pandapipes/)
- Python 3.14.3
- Windows 10
Bug description
The default friction model
"nikuradse"unconditionally addslambda_laminar + lambda_nikuradseinstead of selecting the appropriate value based on Reynolds number. This produces incorrect friction factors for all flow regimes, with the largest relative error in the laminar/transition zone.Location
pandapipes/pf/derivative_calculation.py, functioncalc_lambda(...), theelsebranch at lines 194-197 (pandapipes 0.13.0):This branch is taken whenever
friction_modelis neither"colebrook"nor"swamee-jain"— i.e. it is the path used for"nikuradse"(the default).Expected behaviour
Standard textbook treatment: pick laminar or turbulent, do not sum them.
lambda_laminar = 64/Re(Hagen-Poiseuille)lambda_nikuradse(Nikuradse fully-rough approximation)The commented-out line directly above the bug also has an issue: it would still add both values in the turbulent branch (
lambda_laminar + lambda_nikuradse) rather than using onlylambda_nikuradse.Actual behaviour / impact
The error is most severe near the transition zone (Re ~ 2000-3000) where both terms are similar in magnitude.
Minimal reproducer
Workaround
Pass
friction_model="colebrook"(or"swamee-jain") explicitly — both code paths return early before the buggyelsebranch.Suggested fix
Replace line 196 with:
I am happy to open a PR if the maintainers agree with the fix.
Environment
site-packages/pandapipes/)