127 lines
4.2 KiB
Python
127 lines
4.2 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from app.simulation.components.amesim.flow.pipes import AmesimPnl00r
|
|
from app.simulation.core.medium import IdealGasMedium
|
|
from app.simulation.registry import COMPONENT_MODEL_REGISTRY
|
|
|
|
|
|
class AmesimPnl00rComponentTests(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.medium = IdealGasMedium()
|
|
|
|
def test_default_create_preserves_amesim_parameter_contract(self) -> None:
|
|
pipe = COMPONENT_MODEL_REGISTRY["amesim_pnl00r"].create(
|
|
"pnl_1",
|
|
self.medium,
|
|
{},
|
|
)
|
|
|
|
self.assertIsInstance(pipe, AmesimPnl00r)
|
|
self.assertEqual(set(pipe.ports), {"port_1", "port_2"})
|
|
self.assertEqual(set(pipe.parameter_values), {"diam", "le", "rr", "gi"})
|
|
self.assertEqual(pipe.parameter_values["diam"], 0.01)
|
|
self.assertEqual(pipe.gi, 0)
|
|
|
|
def test_rejects_fractional_gas_index(self) -> None:
|
|
with self.assertRaisesRegex(ValueError, "gi must be an integer"):
|
|
COMPONENT_MODEL_REGISTRY["amesim_pnl00r"].create(
|
|
"pnl_1",
|
|
self.medium,
|
|
{"gi": 1.5},
|
|
)
|
|
|
|
def test_zero_pressure_drop_has_zero_flow_and_finite_results(self) -> None:
|
|
pipe = AmesimPnl00r("pnl_1", self.medium)
|
|
pipe.port_1.p = 100000.0
|
|
pipe.port_2.p = 100000.0
|
|
pipe.port_1.m_flow = 0.0
|
|
pipe.port_2.m_flow = 0.0
|
|
|
|
residuals = {
|
|
residual.id.rsplit(":", 1)[1]: residual
|
|
for residual in pipe.pressure_flow_equation_residuals()
|
|
}
|
|
|
|
self.assertEqual(pipe.mass_flow(100000.0, 100000.0), 0.0)
|
|
self.assertEqual(residuals["mass_flow_balance"].value, 0.0)
|
|
self.assertEqual(residuals["pressure_flow_relation"].value, 0.0)
|
|
self.assertEqual(set(pipe.component_result_values()), {"re", "cm", "v", "ff"})
|
|
|
|
def test_mass_flow_is_bidirectional_by_pressure_order(self) -> None:
|
|
pipe = AmesimPnl00r("pnl_1", self.medium, diam=0.014, le=1.0, rr=0.045 / 14.0)
|
|
|
|
forward = pipe.mass_flow(501000.0, 500000.0)
|
|
reverse = pipe.mass_flow(500000.0, 501000.0)
|
|
|
|
self.assertGreater(forward, 0.0)
|
|
self.assertLess(reverse, 0.0)
|
|
self.assertAlmostEqual(forward, -reverse, delta=abs(forward) * 0.02)
|
|
|
|
def test_friction_factor_transitions_from_laminar_to_turbulent(self) -> None:
|
|
pipe = AmesimPnl00r("pnl_1", self.medium, rr=1e-5)
|
|
|
|
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_friction_factor_matches_amesim_smooth_to_rough_transition(self) -> None:
|
|
pipe_20mm = AmesimPnl00r(
|
|
"pnl_20mm",
|
|
self.medium,
|
|
diam=0.02,
|
|
rr=0.045 / 20.0,
|
|
)
|
|
pipe_14mm = AmesimPnl00r(
|
|
"pnl_14mm",
|
|
self.medium,
|
|
diam=0.014,
|
|
rr=0.045 / 14.0,
|
|
)
|
|
|
|
self.assertAlmostEqual(
|
|
pipe_20mm.friction_factor(56_887.5547),
|
|
0.0215740061043,
|
|
delta=1.0e-4,
|
|
)
|
|
self.assertAlmostEqual(
|
|
pipe_20mm.friction_factor(700_686.41),
|
|
0.02400535718,
|
|
delta=8.0e-5,
|
|
)
|
|
self.assertAlmostEqual(
|
|
pipe_14mm.friction_factor(726_799.66),
|
|
0.02658268645,
|
|
delta=8.0e-5,
|
|
)
|
|
|
|
def test_friction_factor_matches_amesim_transition_regime(self) -> None:
|
|
pipe = AmesimPnl00r(
|
|
"pnl_20mm",
|
|
self.medium,
|
|
diam=0.02,
|
|
rr=0.045 / 20.0,
|
|
)
|
|
|
|
self.assertAlmostEqual(
|
|
pipe.friction_factor(3_699.80236),
|
|
0.0391257647759,
|
|
delta=4.0e-4,
|
|
)
|
|
|
|
def test_darcy_pressure_drop_uses_flow_sign(self) -> None:
|
|
pipe = AmesimPnl00r("pnl_1", self.medium)
|
|
density = self.medium.density(500000.0, 300.0)
|
|
|
|
forward = pipe.darcy_pressure_drop(0.01, density=density, temperature=300.0)
|
|
reverse = pipe.darcy_pressure_drop(-0.01, density=density, temperature=300.0)
|
|
|
|
self.assertGreater(forward, 0.0)
|
|
self.assertLess(reverse, 0.0)
|
|
self.assertAlmostEqual(forward, -reverse)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|