211 lines
7.6 KiB
Python
211 lines
7.6 KiB
Python
from __future__ import annotations
|
||
|
||
import unittest
|
||
|
||
from app.main import ReactFlowProjectPayload, compile_reactflow_network
|
||
from app.simulation.components.amesim.library import LIBRARY
|
||
from app.simulation.components.amesim.media.mediums import (
|
||
AMESIM_AIR_PROPERTY_MODELS,
|
||
AMESIM_HELIUM_PENG_ROBINSON_PROPERTY_MODEL,
|
||
AMESIM_HELIUM_PROPERTY_MODELS,
|
||
AmesimHeliumPengRobinsonMedium,
|
||
)
|
||
from app.simulation.core.medium import IdealGasMedium
|
||
from app.simulation.core.peng_robinson import HELIUM_PR
|
||
from app.simulation.registry import COMPONENT_MODEL_REGISTRY
|
||
from tests.test_generic_system_xml_simulation import component_node
|
||
from tests.test_system_xml_protocol import physical_port
|
||
|
||
|
||
class AmesimHeliumPengRobinsonMediumTests(unittest.TestCase):
|
||
def test_uses_amesim_2404_peng_robinson_and_nasa_constants(
|
||
self,
|
||
) -> None:
|
||
medium = AmesimHeliumPengRobinsonMedium()
|
||
pressure = 15.3e6
|
||
temperature = 293.15
|
||
|
||
density = medium.density(pressure, temperature)
|
||
volume = 0.02
|
||
|
||
self.assertIs(medium.fluid, HELIUM_PR)
|
||
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, 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),
|
||
pressure,
|
||
delta=pressure * 1.0e-12,
|
||
)
|
||
|
||
def test_nasa_caloric_reference_and_sutherland_viscosity_complete_contract(
|
||
self,
|
||
) -> None:
|
||
medium = AmesimHeliumPengRobinsonMedium()
|
||
temperature = 340.0
|
||
|
||
internal_energy = medium.specific_internal_energy(temperature)
|
||
enthalpy = medium.specific_enthalpy(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,
|
||
)
|
||
self.assertEqual(
|
||
medium.temperature_from_enthalpy(enthalpy),
|
||
temperature,
|
||
)
|
||
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:
|
||
self.assertEqual(LIBRARY.version, "0.3.0")
|
||
self.assertEqual(AMESIM_HELIUM_PENG_ROBINSON_PROPERTY_MODEL, 0)
|
||
self.assertEqual(AMESIM_HELIUM_PROPERTY_MODELS[0].value, 0)
|
||
self.assertEqual(AMESIM_HELIUM_PROPERTY_MODELS[0].eos_type, 6)
|
||
self.assertEqual(AMESIM_AIR_PROPERTY_MODELS[0].eos_type, 1)
|
||
|
||
spec = COMPONENT_MODEL_REGISTRY["amesim_helium_medium"]
|
||
property_model = spec.parameter_by_name["property_model"]
|
||
|
||
self.assertEqual(spec.display.category_id, "media")
|
||
self.assertEqual(spec.display.role, "amesimGasMediumDefinition")
|
||
self.assertEqual(spec.display.label, "氦气介质定义")
|
||
self.assertEqual(spec.model_version, "0.1.0")
|
||
self.assertEqual(spec.ports, ())
|
||
self.assertEqual(property_model.default, 0.0)
|
||
self.assertEqual(property_model.editor, "amesimGasPropertyModel")
|
||
self.assertEqual(
|
||
[(option.value, option.label) for option in property_model.options],
|
||
[(0, "Peng–Robinson")],
|
||
)
|
||
|
||
component = spec.create(
|
||
"helium_properties",
|
||
IdealGasMedium(),
|
||
{"gi": 2.0, "property_model": 0.0},
|
||
)
|
||
definition = component.gas_definition()
|
||
|
||
self.assertEqual(component.parameter_values, {"gi": 2.0, "property_model": 0.0})
|
||
self.assertEqual(definition.label, "氦气(Peng–Robinson)")
|
||
self.assertEqual(definition.fluid_type, 12)
|
||
self.assertEqual(definition.eos_type, 6)
|
||
self.assertIsInstance(definition.medium, AmesimHeliumPengRobinsonMedium)
|
||
|
||
def test_project_compile_injects_helium_before_dynamic_state_initialization(
|
||
self,
|
||
) -> None:
|
||
pressure = 13_839_965.0
|
||
temperature = 287.7322
|
||
volume = 0.01
|
||
project = ReactFlowProjectPayload(
|
||
name="helium-peng-robinson-compile",
|
||
nodes=[
|
||
component_node(
|
||
"helium_properties",
|
||
"amesim_helium_medium",
|
||
[],
|
||
{"gi": 2.0, "property_model": 0.0},
|
||
),
|
||
component_node(
|
||
"chamber_1",
|
||
"amesim_pnch023",
|
||
[
|
||
physical_port("port_1", "bidirectional", "left"),
|
||
physical_port("port_2", "bidirectional", "right"),
|
||
],
|
||
{
|
||
"gi": 2.0,
|
||
"cvol": volume,
|
||
"kth": 0.0,
|
||
"sth": 0.1,
|
||
"extemp": 293.15,
|
||
"p0": pressure,
|
||
"T0": temperature,
|
||
},
|
||
),
|
||
],
|
||
)
|
||
|
||
network = compile_reactflow_network(project)
|
||
chamber = network.components["chamber_1"]
|
||
|
||
self.assertNotIn("helium_properties", network.components)
|
||
self.assertIsInstance(chamber.medium, AmesimHeliumPengRobinsonMedium)
|
||
self.assertAlmostEqual(
|
||
chamber.state.m,
|
||
HELIUM_PR.density(pressure, temperature) * volume,
|
||
delta=1.0e-12,
|
||
)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|