对齐Amesim氦气PR物性与PNVO流量

This commit is contained in:
huojiarong committed 2026-08-03 15:34:33 +00:00
1 parent 18d9802f03
commit 046aa49814
13 files changed
+730 -73

No files matched your search

+65 -9
View File
@@ -18,7 +18,7 @@ from tests.test_system_xml_protocol import physical_port
class AmesimHeliumPengRobinsonMediumTests(unittest.TestCase):
def test_uses_shared_peng_robinson_eos_and_committed_caloric_constants(
def test_uses_amesim_2404_peng_robinson_and_nasa_constants(
self,
) -> None:
medium = AmesimHeliumPengRobinsonMedium()
@@ -32,11 +32,11 @@ class AmesimHeliumPengRobinsonMediumTests(unittest.TestCase):
self.assertEqual(medium.SUBSTANCE_ID, "helium")
self.assertEqual(medium.PROPERTY_METHOD_ID, "peng_robinson")
self.assertAlmostEqual(medium.R_gas, HELIUM_PR.specific_gas_constant)
self.assertEqual(medium.cp_ref, 5193.0)
self.assertEqual(medium.cv, 3116.0)
self.assertEqual(medium.cp_at_temperature(400.0), 5193.0)
self.assertEqual(medium.cv_at_temperature(400.0), 3116.0)
self.assertAlmostEqual(medium.gamma, 5193.0 / 3116.0)
self.assertEqual(medium.cp_ref, 2.5 * medium.R_gas)
self.assertEqual(medium.cv, 1.5 * medium.R_gas)
self.assertEqual(medium.cp_at_temperature(400.0), 2.5 * medium.R_gas)
self.assertEqual(medium.cv_at_temperature(400.0), 1.5 * medium.R_gas)
self.assertAlmostEqual(medium.gamma, 5.0 / 3.0)
self.assertAlmostEqual(density, HELIUM_PR.density(pressure, temperature))
self.assertAlmostEqual(
medium.pressure(density * volume, temperature, volume),
@@ -44,7 +44,7 @@ class AmesimHeliumPengRobinsonMediumTests(unittest.TestCase):
delta=pressure * 1.0e-12,
)
def test_constant_caloric_model_and_sutherland_viscosity_complete_contract(
def test_nasa_caloric_reference_and_sutherland_viscosity_complete_contract(
self,
) -> None:
medium = AmesimHeliumPengRobinsonMedium()
@@ -53,8 +53,14 @@ class AmesimHeliumPengRobinsonMediumTests(unittest.TestCase):
internal_energy = medium.specific_internal_energy(temperature)
enthalpy = medium.specific_enthalpy(temperature)
self.assertEqual(internal_energy, 3116.0 * temperature)
self.assertEqual(enthalpy, 5193.0 * temperature)
self.assertEqual(
internal_energy,
medium.R_gas * (1.5 * temperature - 745.375),
)
self.assertEqual(
enthalpy,
medium.R_gas * (2.5 * temperature - 745.375),
)
self.assertEqual(
medium.temperature_from_internal_energy(internal_energy),
temperature,
@@ -66,6 +72,56 @@ class AmesimHeliumPengRobinsonMediumTests(unittest.TestCase):
self.assertAlmostEqual(medium.dynamic_viscosity(293.15), 1.96e-5)
self.assertEqual(medium.sutherland_constant, 79.4)
def test_pressure_transport_enthalpy_includes_peng_robinson_departure(
self,
) -> None:
medium = AmesimHeliumPengRobinsonMedium()
pressure = 13_839_965.0
temperature = 287.7322
ideal_enthalpy = medium.specific_enthalpy(temperature)
transport_enthalpy = medium.specific_enthalpy_at_pressure(pressure, temperature)
self.assertGreater(
transport_enthalpy,
ideal_enthalpy,
)
self.assertAlmostEqual(
medium.temperature_from_pressure_enthalpy(pressure, transport_enthalpy),
temperature,
delta=1.0e-8,
)
density = medium.density(pressure, temperature)
volume = 0.01
properties = medium.properties_from_mU(
density * volume,
density
* volume
* medium.specific_internal_energy_at_pressure(pressure, temperature),
volume,
)
self.assertAlmostEqual(properties.p, pressure, delta=pressure * 1.0e-10)
self.assertAlmostEqual(properties.T, temperature, delta=1.0e-8)
self.assertAlmostEqual(
properties.h,
transport_enthalpy,
delta=2.0e-8,
)
def test_amesim_2404_real_gas_isentropic_factor_reference(self) -> None:
medium = AmesimHeliumPengRobinsonMedium()
self.assertAlmostEqual(
medium.isentropic_density_pressure_factor(
15_201_996.778497815,
292.3997890954483,
405_072.8123335606,
),
0.5807873871273339,
delta=1.0e-12,
)
def test_definition_maps_local_selector_to_amesim_fluid_and_eos_codes(
self,
) -> None:
+2 -2
View File
@@ -51,8 +51,8 @@ class AmesimPneumaticComponentsTest(unittest.TestCase):
self.assertAlmostEqual(ideal_reference_h, -54099.6354, delta=0.001)
self.assertAlmostEqual(
pressure_reference_h - ideal_reference_h,
11936.1,
delta=0.1,
12762.690087540526,
delta=1.0e-4,
)
def test_pressure_transport_enthalpy_restores_absolute_energy_offset(self) -> None:
+5 -1
View File
@@ -23,7 +23,11 @@ class AmesimPnl0001PipeTests(unittest.TestCase):
self.assertEqual(len(self.pipe.get_state_vector()), 2)
self.assertAlmostEqual(properties.p, 15.3e6, delta=1.0e-5)
self.assertAlmostEqual(properties.T, 293.15)
self.assertAlmostEqual(self.pipe.gas_mass_g(), 3.716965219188, places=10)
self.assertAlmostEqual(
self.pipe.gas_mass_g(),
self.pipe.gas.density(15.3e6, 293.15) * self.pipe.volume * 1000.0,
places=10,
)
def test_resistance_flow_follows_pressure_gradient(self) -> None:
forward = self.pipe.resistance_mass_flow(
@@ -3,6 +3,9 @@ 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
@@ -61,6 +64,86 @@ class AmesimPnvo001FixedOpeningComponentTests(unittest.TestCase):
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,
)
if __name__ == "__main__":
unittest.main()
+34 -3
View File
@@ -19,6 +19,11 @@ class PengRobinsonTest(unittest.TestCase):
density = HELIUM_PR.density(pressure, temperature)
self.assertGreater(HELIUM_PR.compressibility_factor(pressure, temperature), 1.0)
self.assertAlmostEqual(
density,
24.114225444477153,
delta=1.0e-12,
)
self.assertAlmostEqual(
HELIUM_PR.pressure_from_density(temperature, density),
pressure,
@@ -28,17 +33,43 @@ class PengRobinsonTest(unittest.TestCase):
def test_helium_residual_enthalpy_is_small_at_atmosphere(self) -> None:
self.assertAlmostEqual(
HELIUM_PR.residual_specific_enthalpy(101_300.0, 298.15),
17.834,
25.3556466754,
delta=0.01,
)
def test_helium_residual_enthalpy_captures_high_pressure_departure(self) -> None:
self.assertAlmostEqual(
HELIUM_PR.residual_specific_enthalpy(13_839_965.0, 287.7322),
11953.9,
12788.0457342,
delta=0.1,
)
def test_residual_isochoric_heat_capacity_is_internal_energy_derivative(
self,
) -> None:
temperature = 292.3997890954483
density = 24.02697515640726
temperature_step = 1.0e-3
numerical_derivative = (
HELIUM_PR.residual_specific_internal_energy_at_density(
temperature + temperature_step,
density,
)
- HELIUM_PR.residual_specific_internal_energy_at_density(
temperature - temperature_step,
density,
)
) / (2.0 * temperature_step)
self.assertAlmostEqual(
HELIUM_PR.residual_isochoric_heat_capacity_at_density(
temperature,
density,
),
numerical_derivative,
delta=1.0e-6,
)
def test_air_reference_remains_available_for_other_models(self) -> None:
z = AIR_PR.compressibility_factor(101_325.0, 300.0)
density = AIR_PR.density(101_325.0, 300.0)
@@ -60,7 +91,7 @@ class PengRobinsonTest(unittest.TestCase):
molar_mass=0.004002602,
critical_temperature=5.1953,
critical_pressure=227_460.0,
acentric_factor=-0.385,
acentric_factor=-0.382,
)
self.assertAlmostEqual(fluid.specific_gas_constant, 2077.3, delta=0.5)
@@ -16,6 +16,7 @@ from app.simulation.components.experimental.storage.tank import Tank
from app.simulation.core.medium import IdealGasMedium
from app.simulation.core.state import VolumeState
from app.simulation.solvers.algebraic import AlgebraicSolveError, PressureFlowSolver
from app.simulation.systems.generic import GenericFluidSystem
from app.simulation.systems.network import SimulationNetwork
@@ -59,10 +60,40 @@ class PressureFlowSolverInitializationTests(unittest.TestCase):
mass = medium.density(pressure, temperature) * component.V
component.state = VolumeState(
m=mass,
U=mass * medium.specific_internal_energy(temperature),
U=mass
* medium.specific_internal_energy_at_pressure(
pressure,
temperature,
),
)
component.refresh_thermodynamic_ports()
def test_stream_enthalpy_refreshes_explicit_orifice_flow(self) -> None:
network, medium, high, low, valve = self._near_equal_pressure_network()
self._set_pressure_temperature(
high,
medium,
15_201_996.778497815,
292.3997890954483,
)
self._set_pressure_temperature(
low,
medium,
405_072.8123335606,
393.46713105173205,
)
system = GenericFluidSystem(network)
system.consistent_initial_state_vector()
self.assertLess(valve._connected_h["port_2"], 0.0)
self.assertAlmostEqual(
valve.port_2.m_flow,
valve.mass_flow(valve.port_2.p, valve.port_3.p),
places=12,
)
self.assertAlmostEqual(valve.port_3.m_flow, -valve.port_2.m_flow, places=12)
def test_current_storage_pressure_reseeds_stale_orifice_ports_and_flow(self) -> None:
network, medium, high, low, valve = self._near_equal_pressure_network()
solver = PressureFlowSolver(network, max_evaluations=10)