from __future__ import annotations import unittest from PythonModels.components.amesim_pneumatic import ( HELIUM_PNEUMATIC_GAS, AmesimPneumaticOrifice, AmesimPneumaticVolume, AmesimVariablePneumaticVolume, cm3_to_m3, compressible_orifice_mass_flow, diameter_mm_to_area_m2, kg_to_g, liters_to_m3, m3_to_cm3, mm2_to_m2, ) class AmesimPneumaticComponentsTest(unittest.TestCase): def test_unit_conversions(self) -> None: self.assertAlmostEqual(liters_to_m3(15.0), 0.015) self.assertAlmostEqual(m3_to_cm3(0.015), 15000.0) self.assertAlmostEqual(cm3_to_m3(15000.0), 0.015) self.assertAlmostEqual(kg_to_g(1.25), 1250.0) self.assertAlmostEqual(mm2_to_m2(78.5), 78.5e-6) self.assertAlmostEqual(diameter_mm_to_area_m2(10.0), 7.853981633974483e-5) def test_volume_initial_state_matches_requested_pressure_temperature(self) -> None: volume = AmesimPneumaticVolume.from_liters( name="pn_general_chamber", volume_liters=57.0, p0=15.3e6, T0=293.15, ) props = volume.properties() self.assertAlmostEqual(props.p, 15.3e6, delta=15.3e6 * 1.0e-12) self.assertAlmostEqual(props.T, 293.15) self.assertGreater(props.rho, 20.0) self.assertLess(props.rho, 30.0) def test_volume_reports_amesim_style_observables(self) -> None: volume = AmesimPneumaticVolume.from_liters( name="pn_general_chamber", volume_liters=57.0, p0=15.3e6, T0=293.15, ) self.assertAlmostEqual(volume.volume_cm3(), 57000.0) self.assertAlmostEqual( volume.pressure_gauge_pa(reference_pressure_pa=101_300.0), 15198700.0, ) self.assertGreater(volume.gas_mass_g(), 1300.0) def test_volume_balances_two_connections_with_stream_enthalpy(self) -> None: volume = AmesimPneumaticVolume.from_liters( name="pn_general_chamber", volume_liters=57.0, p0=15.3e6, T0=293.15, ) internal_h = volume.properties().h derivative = volume.derivatives_from_two_connections( port_a_m_flow=0.2, connected_h_a=internal_h + 1000.0, port_b_m_flow=-0.1, connected_h_b=internal_h - 1000.0, internal_h=internal_h, ) self.assertAlmostEqual(derivative.m, 0.1) self.assertAlmostEqual( derivative.U, 0.2 * (internal_h + 1000.0) - 0.1 * internal_h, ) self.assertAlmostEqual(volume.port_a.p, volume.port_b.p) def test_variable_volume_tracks_external_volume(self) -> None: volume = AmesimVariablePneumaticVolume.from_liters( name="pn_c1_8", dead_volume_liters=15.0, p0=100000.0, T0=293.15, ) self.assertAlmostEqual(volume.volume_cm3(), 15000.0) volume.set_external_volume_m3(cm3_to_m3(34242.54636512914)) self.assertAlmostEqual(volume.volume_cm3(), 49242.54636512914) def test_orifice_returns_signed_mass_flow(self) -> None: orifice = AmesimPneumaticOrifice.from_mm2( name="pn_orifice_18", area_mm2=78.5, flow_coefficient=0.9, ) forward = orifice.mass_flow(15.3e6, 1.0e6, 293.15) reverse = orifice.mass_flow(1.0e6, 15.3e6, 293.15) self.assertGreater(forward, 0.0) self.assertAlmostEqual(reverse, -forward) self.assertEqual(orifice.mass_flow(1.0e6, 1.0e6, 293.15), 0.0) def test_choked_flow_is_independent_of_lower_downstream_pressure(self) -> None: base = compressible_orifice_mass_flow( upstream_pressure=15.3e6, downstream_pressure=1.0e6, upstream_temperature=293.15, area=78.5e-6, flow_coefficient=0.9, gas=HELIUM_PNEUMATIC_GAS, ) lower_back_pressure = compressible_orifice_mass_flow( upstream_pressure=15.3e6, downstream_pressure=0.1e6, upstream_temperature=293.15, area=78.5e-6, flow_coefficient=0.9, gas=HELIUM_PNEUMATIC_GAS, ) self.assertGreater(base, 0.0) self.assertAlmostEqual(lower_back_pressure, base) def test_subcritical_flow_decreases_as_back_pressure_rises(self) -> None: low_back_pressure = compressible_orifice_mass_flow( upstream_pressure=1.0e6, downstream_pressure=0.6e6, upstream_temperature=293.15, area=78.5e-6, flow_coefficient=0.9, ) high_back_pressure = compressible_orifice_mass_flow( upstream_pressure=1.0e6, downstream_pressure=0.9e6, upstream_temperature=293.15, area=78.5e-6, flow_coefficient=0.9, ) self.assertGreater(low_back_pressure, high_back_pressure) self.assertGreater(high_back_pressure, 0.0) if __name__ == "__main__": unittest.main()