diff --git a/app/simulation/components/amesim/flow/pipes.py b/app/simulation/components/amesim/flow/pipes.py index c9c1b88..ceefc07 100644 --- a/app/simulation/components/amesim/flow/pipes.py +++ b/app/simulation/components/amesim/flow/pipes.py @@ -27,6 +27,13 @@ from app.simulation.core.ports import PortDefinition from app.simulation.core.state import VolumeState +_MAX_REPORTED_FRICTION_FACTOR = 64_000_000.0 + + +def _reported_friction_factor(value: float) -> float: + return min(float(value), _MAX_REPORTED_FRICTION_FACTOR) + + _DYNAMIC_PIPE_POLYTROPIC_MODE = ParameterCondition("mode", (1.0,)) _DYNAMIC_PIPE_HEAT_EXCHANGE_MODE = ParameterCondition("mode", (2.0,)) _DYNAMIC_PIPE_PARAMETER_GROUPS = ( @@ -315,7 +322,7 @@ class AmesimPnl00r(AlgebraicComponent): "re": reynolds, "cm": cm, "v": velocity, - "ff": self.friction_factor(reynolds), + "ff": _reported_friction_factor(self.friction_factor(reynolds)), } def pressure_flow_equation_values(self) -> tuple[float, ...]: @@ -842,7 +849,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent): / max(self.area * upstream_pressure, 1.0e-18) ), "v": flow / (density * self.area), - "ff": self.friction_factor(reynolds), + "ff": _reported_friction_factor(self.friction_factor(reynolds)), } def pressure_flow_equation_values(self) -> tuple[float, ...]: @@ -1092,7 +1099,7 @@ class AmesimPnl0002(AmesimPnl0001): "re": reynolds, "cm": cm, "v": velocity, - "ff": friction, + "ff": _reported_friction_factor(friction), } def pressure_flow_equation_values(self) -> tuple[float, ...]: @@ -1442,7 +1449,7 @@ class AmesimPnl0003(DynamicComponent): / max(self.area * max(port_1.p, port_2.p, 1.0), 1.0e-18) ), "v": center_flow / (max(upstream.rho, 1.0e-12) * self.area), - "ff": self.friction_factor(reynolds), + "ff": _reported_friction_factor(self.friction_factor(reynolds)), } def pressure_flow_equation_values(self) -> tuple[float, ...]: diff --git a/tests/test_amesim_pnl00r_component.py b/tests/test_amesim_pnl00r_component.py index ac5040f..b530207 100644 --- a/tests/test_amesim_pnl00r_component.py +++ b/tests/test_amesim_pnl00r_component.py @@ -76,29 +76,21 @@ class AmesimPnl00rComponentTests(unittest.TestCase): self.assertEqual(pipe.mass_flow(base_pressure, base_pressure), 0.0) self.assertGreater(pipe.mass_flow(15.3e6 + 0.1, 15.3e6), 0.0) - def test_mass_flow_is_continuous_across_former_relative_deadband(self) -> None: - pipe = AmesimPnl00r("pnl_1", self.medium, diam=0.014, le=1.0, rr=0.045 / 14.0) - base_pressure = 8.0e6 - former_threshold = base_pressure * 1.0e-7 - - below = pipe.mass_flow(base_pressure + 0.99 * former_threshold, base_pressure) - above = pipe.mass_flow(base_pressure + 1.01 * former_threshold, base_pressure) - reverse = pipe.mass_flow(base_pressure, base_pressure + 0.99 * former_threshold) - - self.assertGreater(below, 0.0) - self.assertGreater(above, below) - self.assertLess(reverse, 0.0) - self.assertAlmostEqual(below, -reverse, delta=abs(below) * 1.0e-9) - self.assertLess(abs(above - below), abs(above) * 0.05) - self.assertEqual(pipe.mass_flow(base_pressure, base_pressure), 0.0) def test_friction_factor_transitions_from_laminar_to_turbulent(self) -> None: pipe = AmesimPnl00r("pnl_1", self.medium, rr=1e-5) + self.assertGreater(pipe.friction_factor(1.0e-12), 64_000_000.0) self.assertAlmostEqual(pipe.friction_factor(100.0), 64.0 / 100.0) self.assertGreater(pipe.friction_factor(100000.0), 0.0) self.assertLess(pipe.friction_factor(100000.0), 0.1) + def test_reported_friction_factor_is_bounded_at_tiny_flow(self) -> None: + pipe = AmesimPnl00r("pnl_1", self.medium) + pipe.mass_flow = lambda _p_1, _p_2: 1.0e-30 + + self.assertEqual(pipe.component_result_values()["ff"], 64_000_000.0) + def test_friction_factor_matches_amesim_smooth_to_rough_transition(self) -> None: pipe_20mm = AmesimPnl00r( "pnl_20mm",