Files
SystemSimulationApp/tests/test_amesim_pnvo001_fixed_component.py
T

240 lines
7.8 KiB
Python

from __future__ import annotations
import unittest
from app.simulation.components.amesim.flow.orifices import AmesimPnvo001FixedOpening
from app.simulation.components.amesim.media.mediums import (
AmesimHeliumPengRobinsonMedium,
)
from app.simulation.core.medium import IdealGasMedium
from app.simulation.registry import COMPONENT_MODEL_REGISTRY
class AmesimPnvo001FixedOpeningComponentTests(unittest.TestCase):
def setUp(self) -> None:
self.medium = IdealGasMedium()
def test_default_create_preserves_fixed_opening_contract(self) -> None:
valve = COMPONENT_MODEL_REGISTRY["amesim_pnvo001_fixed"].create(
"valve_1",
self.medium,
{},
)
self.assertIsInstance(valve, AmesimPnvo001FixedOpening)
self.assertEqual(set(valve.ports), {"port_2", "port_3"})
self.assertEqual(
set(valve.parameter_values),
{"cq", "area0", "Cv", "Kv", "gi", "flowset", "opening"},
)
self.assertEqual(valve.opening, 1.0)
def test_rejects_fractional_flowset(self) -> None:
with self.assertRaisesRegex(ValueError, "must be one of"):
COMPONENT_MODEL_REGISTRY["amesim_pnvo001_fixed"].create(
"valve_1",
self.medium,
{"flowset": 1.5},
)
def test_opening_scales_effective_area(self) -> None:
valve = AmesimPnvo001FixedOpening(
"valve_1",
self.medium,
area0=2.0e-6,
opening=0.25,
)
self.assertAlmostEqual(valve.maximum_area, 2.0e-6)
self.assertAlmostEqual(valve.effective_area, 0.5e-6)
self.assertEqual(valve.component_result_values()["xv"], 0.25)
def test_zero_opening_blocks_flow(self) -> None:
valve = AmesimPnvo001FixedOpening("valve_1", self.medium, opening=0.0)
self.assertEqual(valve.mass_flow(500000.0, 100000.0), 0.0)
def test_mass_flow_is_bidirectional_by_pressure_order(self) -> None:
valve = AmesimPnvo001FixedOpening("valve_1", self.medium, opening=0.5)
forward = valve.mass_flow(500000.0, 100000.0)
reverse = valve.mass_flow(100000.0, 500000.0)
self.assertGreater(forward, 0.0)
self.assertLess(reverse, 0.0)
self.assertAlmostEqual(forward, -reverse)
def test_mass_flow_uses_connected_enthalpy_from_the_upstream_side(self) -> None:
valve = AmesimPnvo001FixedOpening("valve_1", self.medium, opening=0.5)
hot_h = self.medium.specific_enthalpy(600.0)
cold_h = self.medium.specific_enthalpy(200.0)
valve.update_stream_outflows({"port_2": hot_h, "port_3": cold_h})
self.assertEqual(valve.port_2.h_outflow, cold_h)
self.assertEqual(valve.port_3.h_outflow, hot_h)
self.assertAlmostEqual(
valve.mass_flow(500000.0, 100000.0),
valve._one_way_mass_flow(
upstream_pressure=500000.0,
downstream_pressure=100000.0,
upstream_temperature=600.0,
),
)
self.assertAlmostEqual(
valve.mass_flow(100000.0, 500000.0),
-valve._one_way_mass_flow(
upstream_pressure=500000.0,
downstream_pressure=100000.0,
upstream_temperature=200.0,
),
)
def test_helium_flow_uses_pressure_enthalpy_and_real_gas_factor(self) -> None:
medium = AmesimHeliumPengRobinsonMedium()
valve = AmesimPnvo001FixedOpening(
"valve_1",
medium,
cq=0.45,
area0=78.5e-6,
opening=1.0,
)
upstream_pressure = 15_201_996.778497815
downstream_pressure = 405_072.8123335606
upstream_temperature = 292.3997890954483
valve.port_2.p = upstream_pressure
valve.port_3.p = downstream_pressure
upstream_enthalpy = medium.specific_enthalpy_at_pressure(
upstream_pressure,
upstream_temperature,
)
valve.update_stream_outflows(
{
"port_2": upstream_enthalpy,
"port_3": medium.specific_enthalpy_at_pressure(
downstream_pressure,
393.46713105173205,
),
}
)
self.assertLess(upstream_enthalpy, 0.0)
self.assertAlmostEqual(
valve._upstream_temperature("port_2"),
upstream_temperature,
delta=1.0e-8,
)
self.assertAlmostEqual(
valve.mass_flow(upstream_pressure, downstream_pressure),
0.49551308906777447,
delta=1.0e-9,
)
results = valve.component_result_values()
self.assertAlmostEqual(
results["cm"],
0.015778323343746598,
delta=1.0e-11,
)
self.assertAlmostEqual(
results["gasvel"],
894.7011595213406,
delta=1.0e-8,
)
def test_helium_laminar_transition_matches_amesim_baseline(self) -> None:
medium = AmesimHeliumPengRobinsonMedium()
valve = AmesimPnvo001FixedOpening(
"valve_1",
medium,
cq=0.45,
area0=78.5e-6,
opening=1.0,
)
cases = (
# p_up [PaA], p_down [PaA], T_up [K], dm [g/s], Cm, velocity [m/s]
(
10_837_357.913884956,
10_835_428.362241976,
255.45507181057303,
9.770711291393273,
4.07922685863417e-4,
13.951480313568323,
),
(
10_735_827.842429036,
10_735_543.135671863,
254.49635939397584,
3.4711877823059916,
1.4601624857015259e-4,
4.982778680076626,
),
(
10_703_773.135050302,
10_703_621.857082237,
254.1925398502598,
1.53560321377487,
6.475023461883112e-5,
2.208065833961227,
),
(
10_682_359.261700785,
10_682_301.022976216,
253.98926908210996,
0.25626141624058846,
1.0822847918204546e-5,
0.36890236539556787,
),
(
10_678_100.351449525,
10_678_093.704329137,
253.94881208705195,
0.0033658306146710985,
1.421965896377586e-7,
0.004846389527047451,
),
)
for (
p_up,
p_down,
T_up,
expected_dm,
expected_cm,
expected_velocity,
) in cases:
with self.subTest(pressure_difference=p_up - p_down):
mass_flow_parameter, gas_velocity = (
valve._one_way_flow_characteristics(
upstream_pressure=p_up,
downstream_pressure=p_down,
upstream_temperature=T_up,
)
)
mass_flow_g_s = (
valve._one_way_mass_flow(
upstream_pressure=p_up,
downstream_pressure=p_down,
upstream_temperature=T_up,
)
* 1.0e3
)
self.assertAlmostEqual(mass_flow_g_s, expected_dm, delta=1.0e-11)
self.assertAlmostEqual(
mass_flow_parameter,
expected_cm,
delta=1.0e-15,
)
self.assertAlmostEqual(
gas_velocity,
expected_velocity,
delta=5.0e-10,
)
if __name__ == "__main__":
unittest.main()