merge/model-development-into-main #2
No files matched your search
@@ -3858,8 +3858,13 @@ class TestMqlSystem:
|
|||||||
def __init__(self, archive_path: Path | None = None) -> None:
|
def __init__(self, archive_path: Path | None = None) -> None:
|
||||||
self.archive_path = archive_path or Path(__file__).resolve().parents[2] / AMESIM_ARCHIVE_RELATIVE_PATH
|
self.archive_path = archive_path or Path(__file__).resolve().parents[2] / AMESIM_ARCHIVE_RELATIVE_PATH
|
||||||
self.network = SimulationNetwork(name=MODEL_NAME)
|
self.network = SimulationNetwork(name=MODEL_NAME)
|
||||||
|
self.pneumatic_assembly = self._build_pneumatic_assembly()
|
||||||
|
pneumatic_components = self._pneumatic_components_by_alias()
|
||||||
for spec in COMPONENT_SPECS:
|
for spec in COMPONENT_SPECS:
|
||||||
self.network.add_component(AmesimStructuralComponent(spec))
|
alias = str(spec["alias"])
|
||||||
|
self.network.add_component(
|
||||||
|
pneumatic_components.get(alias, AmesimStructuralComponent(spec))
|
||||||
|
)
|
||||||
for spec in CONNECTION_SPECS:
|
for spec in CONNECTION_SPECS:
|
||||||
self.network.connect(
|
self.network.connect(
|
||||||
str(spec["source_component"]),
|
str(spec["source_component"]),
|
||||||
@@ -3868,6 +3873,78 @@ class TestMqlSystem:
|
|||||||
str(spec["target_port"]),
|
str(spec["target_port"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _build_pneumatic_assembly():
|
||||||
|
# Local import avoids a module cycle: test_mql_config reads constants from this module.
|
||||||
|
from PythonModels.systems.test_mql_pneumatic import build_test_mql_pneumatic_assembly
|
||||||
|
|
||||||
|
return build_test_mql_pneumatic_assembly()
|
||||||
|
|
||||||
|
def _pneumatic_components_by_alias(self) -> dict[str, Component]:
|
||||||
|
return {
|
||||||
|
**self.pneumatic_assembly.fixed_chambers,
|
||||||
|
**self.pneumatic_assembly.variable_chambers,
|
||||||
|
**self.pneumatic_assembly.fixed_orifices,
|
||||||
|
**self.pneumatic_assembly.variable_orifices,
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def typed_pneumatic_component_count(self) -> int:
|
||||||
|
return len(self._pneumatic_components_by_alias())
|
||||||
|
|
||||||
|
def pneumatic_state_vector(self) -> list[float]:
|
||||||
|
return self.network.initial_state_vector()
|
||||||
|
|
||||||
|
def pneumatic_branch_closure(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
name: str,
|
||||||
|
upstream_volume_alias: str,
|
||||||
|
orifice_alias: str,
|
||||||
|
downstream_volume_alias: str,
|
||||||
|
):
|
||||||
|
from PythonModels.components.amesim_pneumatic import (
|
||||||
|
AmesimPneumaticOrifice,
|
||||||
|
AmesimPneumaticVolume,
|
||||||
|
)
|
||||||
|
from PythonModels.systems.test_mql_closure import (
|
||||||
|
TestMqlPneumaticBranchComponents,
|
||||||
|
TestMqlPneumaticClosure,
|
||||||
|
)
|
||||||
|
|
||||||
|
upstream_volume = self.network.components[upstream_volume_alias]
|
||||||
|
orifice = self.network.components[orifice_alias]
|
||||||
|
downstream_volume = self.network.components[downstream_volume_alias]
|
||||||
|
if not isinstance(upstream_volume, AmesimPneumaticVolume):
|
||||||
|
raise TypeError(f"{upstream_volume_alias} is not an AMESim pneumatic volume")
|
||||||
|
if not isinstance(downstream_volume, AmesimPneumaticVolume):
|
||||||
|
raise TypeError(f"{downstream_volume_alias} is not an AMESim pneumatic volume")
|
||||||
|
if not isinstance(orifice, AmesimPneumaticOrifice):
|
||||||
|
raise TypeError(f"{orifice_alias} is not an AMESim pneumatic orifice")
|
||||||
|
|
||||||
|
def initial_state_vector() -> list[float]:
|
||||||
|
return [
|
||||||
|
*upstream_volume.get_state_vector(),
|
||||||
|
*downstream_volume.get_state_vector(),
|
||||||
|
]
|
||||||
|
|
||||||
|
def apply_state_vector(values: list[float]) -> None:
|
||||||
|
if len(values) != 4:
|
||||||
|
raise ValueError("two-volume pneumatic branch state vector requires four values")
|
||||||
|
upstream_volume.set_state_vector(values[:2])
|
||||||
|
downstream_volume.set_state_vector(values[2:])
|
||||||
|
|
||||||
|
return TestMqlPneumaticClosure(
|
||||||
|
components=TestMqlPneumaticBranchComponents(
|
||||||
|
name=name,
|
||||||
|
upstream_volume=upstream_volume,
|
||||||
|
orifice=orifice,
|
||||||
|
downstream_volume=downstream_volume,
|
||||||
|
),
|
||||||
|
initial_state_vector=initial_state_vector,
|
||||||
|
apply_state_vector=apply_state_vector,
|
||||||
|
)
|
||||||
|
|
||||||
def snapshot(self) -> TestMqlSnapshot:
|
def snapshot(self) -> TestMqlSnapshot:
|
||||||
return TestMqlSnapshot(
|
return TestMqlSnapshot(
|
||||||
model_name=MODEL_NAME,
|
model_name=MODEL_NAME,
|
||||||
|
|||||||
@@ -2,6 +2,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
from PythonModels.components.amesim_pneumatic import (
|
||||||
|
AmesimPneumaticOrifice,
|
||||||
|
AmesimPneumaticVolume,
|
||||||
|
AmesimVariablePneumaticVolume,
|
||||||
|
)
|
||||||
from PythonModels.systems.test_mql import GLOBAL_PARAMETERS, SUBMODEL_COUNTS, TestMqlSystem
|
from PythonModels.systems.test_mql import GLOBAL_PARAMETERS, SUBMODEL_COUNTS, TestMqlSystem
|
||||||
|
|
||||||
|
|
||||||
@@ -25,6 +30,72 @@ class TestMqlStructuralTest(unittest.TestCase):
|
|||||||
self.assertIn("pn_brp2_8", system.network.components)
|
self.assertIn("pn_brp2_8", system.network.components)
|
||||||
self.assertIn("pn_gas_data", system.network.components)
|
self.assertIn("pn_gas_data", system.network.components)
|
||||||
|
|
||||||
|
def test_network_uses_typed_pneumatic_components_where_available(self) -> None:
|
||||||
|
system = TestMqlSystem()
|
||||||
|
|
||||||
|
self.assertEqual(system.typed_pneumatic_component_count, 28)
|
||||||
|
self.assertIsInstance(
|
||||||
|
system.network.components["pn_general_chamber"],
|
||||||
|
AmesimPneumaticVolume,
|
||||||
|
)
|
||||||
|
self.assertIsInstance(
|
||||||
|
system.network.components["pn_c1_8"],
|
||||||
|
AmesimVariablePneumaticVolume,
|
||||||
|
)
|
||||||
|
self.assertIsInstance(
|
||||||
|
system.network.components["pn_orifice_18"],
|
||||||
|
AmesimPneumaticOrifice,
|
||||||
|
)
|
||||||
|
self.assertIsInstance(
|
||||||
|
system.network.components["pn_morifice_11"],
|
||||||
|
AmesimPneumaticOrifice,
|
||||||
|
)
|
||||||
|
self.assertEqual(len(system.pneumatic_state_vector()), 24)
|
||||||
|
|
||||||
|
def test_can_build_pneumatic_branch_closure_from_typed_components(self) -> None:
|
||||||
|
system = TestMqlSystem()
|
||||||
|
|
||||||
|
closure = system.pneumatic_branch_closure(
|
||||||
|
name="typed_branch",
|
||||||
|
upstream_volume_alias="pn_general_chamber",
|
||||||
|
orifice_alias="pn_orifice_18",
|
||||||
|
downstream_volume_alias="pn_c1_8",
|
||||||
|
)
|
||||||
|
snapshot = closure.snapshot()
|
||||||
|
|
||||||
|
self.assertGreater(snapshot.flow, 0.0)
|
||||||
|
self.assertIs(
|
||||||
|
closure.components.upstream_volume,
|
||||||
|
system.network.components["pn_general_chamber"],
|
||||||
|
)
|
||||||
|
self.assertIs(
|
||||||
|
closure.components.orifice,
|
||||||
|
system.network.components["pn_orifice_18"],
|
||||||
|
)
|
||||||
|
self.assertIs(
|
||||||
|
closure.components.downstream_volume,
|
||||||
|
system.network.components["pn_c1_8"],
|
||||||
|
)
|
||||||
|
self.assertAlmostEqual(
|
||||||
|
closure.components.upstream_volume.port_a.m_flow,
|
||||||
|
-snapshot.flow,
|
||||||
|
)
|
||||||
|
self.assertAlmostEqual(
|
||||||
|
closure.components.downstream_volume.port_a.m_flow,
|
||||||
|
snapshot.flow,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_pneumatic_branch_closure_rejects_structural_components(self) -> None:
|
||||||
|
system = TestMqlSystem()
|
||||||
|
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
system.pneumatic_branch_closure(
|
||||||
|
name="invalid_branch",
|
||||||
|
upstream_volume_alias="pn_brp2_8",
|
||||||
|
orifice_alias="pn_orifice_18",
|
||||||
|
downstream_volume_alias="pn_c1_8",
|
||||||
|
)
|
||||||
|
|
||||||
def test_submodel_counts_keep_key_amesim_families(self) -> None:
|
def test_submodel_counts_keep_key_amesim_families(self) -> None:
|
||||||
self.assertEqual(SUBMODEL_COUNTS["PNRP17"], 8)
|
self.assertEqual(SUBMODEL_COUNTS["PNRP17"], 8)
|
||||||
self.assertEqual(SUBMODEL_COUNTS["PNCH012"], 8)
|
self.assertEqual(SUBMODEL_COUNTS["PNCH012"], 8)
|
||||||
|
|||||||
Reference in new issue
Block a user