from __future__ import annotations import unittest from pathlib import Path from PythonModels.reporting.amesim_results import load_test_mql_amesim_results from PythonModels.systems.test_mql import TestMqlSystem from PythonModels.systems.test_mql_nodes import ( build_test_mql_node3_assembly, build_test_mql_node4_assembly, ) REPO_ROOT = Path(__file__).resolve().parents[1] TEST_MQL_AME = REPO_ROOT / "AmesimModels" / "test_mql.ame" class TestMqlPneumaticNode3Tests(unittest.TestCase): @classmethod def setUpClass(cls) -> None: cls.nodes = build_test_mql_node3_assembly() cls.results = load_test_mql_amesim_results(TEST_MQL_AME) def test_builds_all_eight_pn3node2_instances(self) -> None: self.assertEqual(len(self.nodes), 8) self.assertIn("pn_node3_9", self.nodes) system = TestMqlSystem() self.assertEqual(system.typed_node3_count, 8) self.assertEqual(system.node3_assembly["pn_node3_9"].alias, "pn_node3_9") def test_port_two_flow_is_exact_sum_of_ports_one_and_three(self) -> None: balance = self.nodes["pn_node3_9"].balance( port_2_temperature_k=281.0, port_2_pressure_pa=4.4e6, port_1_enthalpy_flow_w=2.0, port_1_mass_flow_g_s=3.0, port_3_enthalpy_flow_w=-0.5, port_3_mass_flow_g_s=-1.0, port_1_volume_derivative_l_min=4.0, port_1_volume_cm3=5.0, port_3_volume_derivative_l_min=-1.0, port_3_volume_cm3=6.0, ) self.assertEqual(balance.temperature_k, 281.0) self.assertEqual(balance.pressure_pa, 4.4e6) self.assertEqual(balance.port_2_enthalpy_flow_w, 1.5) self.assertEqual(balance.port_2_mass_flow_g_s, 2.0) self.assertEqual(balance.port_2_volume_derivative_l_min, 3.0) self.assertEqual(balance.port_2_volume_cm3, 11.0) def test_pn_node3_9_baseline_matches_adjacent_line_flow_sum(self) -> None: index = 500 balance = self.nodes["pn_node3_9"].balance( port_2_temperature_k=self.results.series("t1@pneumatic_88")[index], port_2_pressure_pa=( self.results.series("p1@pneumatic_88")[index] + 101_300.0 ), port_1_enthalpy_flow_w=self.results.series("dh1@pneumatic_100")[index], port_1_mass_flow_g_s=self.results.series("dm1@pneumatic_100")[index], port_3_enthalpy_flow_w=self.results.series("dh1@pneumatic_97")[index], port_3_mass_flow_g_s=self.results.series("dm1@pneumatic_97")[index], ) self.assertAlmostEqual( balance.port_2_mass_flow_g_s, self.results.series("dm2@pn_node3_9")[index], ) self.assertAlmostEqual( balance.port_2_enthalpy_flow_w, self.results.series("dh2@pn_node3_9")[index], ) self.assertEqual(self.results.series("vol2@pn_node3_9")[index], 0.0) self.assertEqual(self.results.series("dvol2@pn_node3_9")[index], 0.0) def test_rejects_nonphysical_primary_pressure_or_temperature(self) -> None: node = self.nodes["pn_node3_9"] with self.assertRaises(ValueError): node.balance( port_2_temperature_k=0.0, port_2_pressure_pa=1.0e5, port_1_enthalpy_flow_w=0.0, port_1_mass_flow_g_s=0.0, port_3_enthalpy_flow_w=0.0, port_3_mass_flow_g_s=0.0, ) class TestMqlPneumaticNode4Tests(unittest.TestCase): @classmethod def setUpClass(cls) -> None: cls.nodes = build_test_mql_node4_assembly() cls.results = load_test_mql_amesim_results(TEST_MQL_AME) def test_builds_all_eight_p4node2_instances(self) -> None: self.assertEqual(len(self.nodes), 8) self.assertIn("pnnode4_17", self.nodes) system = TestMqlSystem() self.assertEqual(system.typed_node4_count, 8) self.assertEqual(system.node4_assembly["pnnode4_17"].alias, "pnnode4_17") def test_pnnode4_17_neighborhood_maps_adjacent_p4_nodes(self) -> None: system = TestMqlSystem() neighborhood = system.p4_node_neighborhood("pnnode4_17") self.assertEqual(neighborhood.node_alias, "pnnode4_17") self.assertEqual(neighborhood.primary.line_alias, "pneumatic_68") self.assertEqual(neighborhood.primary.chamber_alias, "pn_c1_9") self.assertEqual(neighborhood.port_1.line_alias, "pneumatic_86") self.assertEqual(neighborhood.port_1.remote_node_alias, "pnnode4_18") self.assertEqual(neighborhood.port_1.remote_port, "port_3") self.assertEqual(neighborhood.port_3.line_alias, "pneumatic_83") self.assertEqual(neighborhood.port_3.remote_node_alias, "pnnode4_16") self.assertEqual(neighborhood.port_3.remote_port, "port_1") self.assertEqual(neighborhood.port_4.orifice_alias, "pn_morifice_9") self.assertEqual(neighborhood.port_4.direct_line_alias, "pneumatic_90") def test_adjacent_p4_node_primary_pressures_match_their_pnl0001_states(self) -> None: index = 500 self.assertAlmostEqual( self.results.series("press1@pnnode4_18")[index], self.results.series("p2@pneumatic_66")[index], ) self.assertAlmostEqual( self.results.series("press1@pnnode4_16")[index], self.results.series("p2@pneumatic_69")[index], ) def test_adjacent_p4_node_baselines_match_adjacent_flow_sums(self) -> None: index = 500 pnnode4_18 = self.nodes["pnnode4_18"].balance( port_2_temperature_k=self.results.series("temp1@pnnode4_18")[index], port_2_pressure_pa=( self.results.series("press1@pnnode4_18")[index] + 101_300.0 ), port_1_enthalpy_flow_w=self.results.series("dh1@pneumatic_80")[index], port_1_mass_flow_g_s=self.results.series("dm1@pneumatic_80")[index], port_3_enthalpy_flow_w=self.results.series("dh2@pneumatic_86")[index], port_3_mass_flow_g_s=self.results.series("dm2@pneumatic_86")[index], port_4_enthalpy_flow_w=self.results.series("dh2@pn_morifice_10")[index], port_4_mass_flow_g_s=self.results.series("dm2@pn_morifice_10")[index], ) pnnode4_16 = self.nodes["pnnode4_16"].balance( port_2_temperature_k=self.results.series("temp1@pnnode4_16")[index], port_2_pressure_pa=( self.results.series("press1@pnnode4_16")[index] + 101_300.0 ), port_1_enthalpy_flow_w=self.results.series("dh1@pneumatic_83")[index], port_1_mass_flow_g_s=self.results.series("dm1@pneumatic_83")[index], port_3_enthalpy_flow_w=self.results.series("dh2@pneumatic_95")[index], port_3_mass_flow_g_s=self.results.series("dm2@pneumatic_95")[index], port_4_enthalpy_flow_w=self.results.series("dh2@pn_morifice_1")[index], port_4_mass_flow_g_s=self.results.series("dm2@pn_morifice_1")[index], ) self.assertAlmostEqual( pnnode4_18.port_2_mass_flow_g_s, self.results.series("dm2@pnnode4_18")[index], ) self.assertAlmostEqual( pnnode4_18.port_2_enthalpy_flow_w, self.results.series("dh2@pnnode4_18")[index], ) self.assertAlmostEqual( pnnode4_16.port_2_mass_flow_g_s, self.results.series("dm2@pnnode4_16")[index], ) self.assertAlmostEqual( pnnode4_16.port_2_enthalpy_flow_w, self.results.series("dh2@pnnode4_16")[index], ) def test_port_two_flow_is_exact_sum_of_ports_one_three_and_four(self) -> None: balance = self.nodes["pnnode4_17"].balance( port_2_temperature_k=281.0, port_2_pressure_pa=4.4e6, port_1_enthalpy_flow_w=2.0, port_1_mass_flow_g_s=3.0, port_3_enthalpy_flow_w=-0.5, port_3_mass_flow_g_s=-1.0, port_4_enthalpy_flow_w=4.0, port_4_mass_flow_g_s=5.0, port_1_volume_derivative_l_min=4.0, port_1_volume_cm3=5.0, port_3_volume_derivative_l_min=-1.0, port_3_volume_cm3=6.0, port_4_volume_derivative_l_min=2.0, port_4_volume_cm3=7.0, ) self.assertEqual(balance.temperature_k, 281.0) self.assertEqual(balance.pressure_pa, 4.4e6) self.assertEqual(balance.port_2_enthalpy_flow_w, 5.5) self.assertEqual(balance.port_2_mass_flow_g_s, 7.0) self.assertEqual(balance.port_2_volume_derivative_l_min, 5.0) self.assertEqual(balance.port_2_volume_cm3, 18.0) def test_pnnode4_17_baseline_matches_adjacent_flow_sum(self) -> None: index = 500 balance = self.nodes["pnnode4_17"].balance( port_2_temperature_k=self.results.series("temp1@pnnode4_17")[index], port_2_pressure_pa=( self.results.series("press1@pnnode4_17")[index] + 101_300.0 ), port_1_enthalpy_flow_w=self.results.series("dh1@pneumatic_86")[index], port_1_mass_flow_g_s=self.results.series("dm1@pneumatic_86")[index], port_3_enthalpy_flow_w=self.results.series("dh2@pneumatic_83")[index], port_3_mass_flow_g_s=self.results.series("dm2@pneumatic_83")[index], port_4_enthalpy_flow_w=self.results.series("dh2@pn_morifice_9")[index], port_4_mass_flow_g_s=self.results.series("dm2@pn_morifice_9")[index], ) self.assertAlmostEqual( balance.port_2_mass_flow_g_s, self.results.series("dm2@pnnode4_17")[index], ) self.assertAlmostEqual( balance.port_2_enthalpy_flow_w, self.results.series("dh2@pnnode4_17")[index], ) self.assertEqual(self.results.series("vol2@pnnode4_17")[index], 0.0) self.assertEqual(self.results.series("dvol2@pnnode4_17")[index], 0.0) self.assertAlmostEqual( self.results.series("press1@pnnode4_17")[index], self.results.series("p2@pneumatic_68")[index], ) def test_rejects_nonphysical_primary_pressure_or_temperature(self) -> None: node = self.nodes["pnnode4_17"] with self.assertRaises(ValueError): node.balance( port_2_temperature_k=0.0, port_2_pressure_pa=1.0e5, port_1_enthalpy_flow_w=0.0, port_1_mass_flow_g_s=0.0, port_3_enthalpy_flow_w=0.0, port_3_mass_flow_g_s=0.0, port_4_enthalpy_flow_w=0.0, port_4_mass_flow_g_s=0.0, ) if __name__ == "__main__": unittest.main()