180 lines
5.6 KiB
Python
180 lines
5.6 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from PythonModels.components.amesim_pneumatic import (
|
|
HELIUM_PNEUMATIC_GAS,
|
|
AmesimPneumaticGas,
|
|
AmesimPneumaticOrifice,
|
|
AmesimPneumaticVolume,
|
|
AmesimVariablePneumaticVolume,
|
|
)
|
|
from PythonModels.systems.test_mql_config import TestMqlConfig, TestMqlResolvedComponent
|
|
|
|
|
|
AMESIM_REFERENCE_PRESSURE_PA = 101_300.0
|
|
BAR_TO_PA = 1.0e5
|
|
DEFAULT_TEST_MQL_TEMPERATURE_K = 293.15
|
|
DEFAULT_VARIABLE_CHAMBER_PRESSURE_BAR = 1.0
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class TestMqlPneumaticAssembly:
|
|
fixed_chambers: dict[str, AmesimPneumaticVolume]
|
|
variable_chambers: dict[str, AmesimVariablePneumaticVolume]
|
|
fixed_orifices: dict[str, AmesimPneumaticOrifice]
|
|
variable_orifices: dict[str, AmesimPneumaticOrifice]
|
|
fixed_initial_absolute_pressure_pa: float
|
|
variable_initial_absolute_pressure_pa: float
|
|
|
|
@property
|
|
def initial_pressure_pa(self) -> float:
|
|
return pressure_to_amesim_gauge_pa(self.fixed_initial_absolute_pressure_pa)
|
|
|
|
@property
|
|
def fixed_initial_gauge_pressure_pa(self) -> float:
|
|
return pressure_to_amesim_gauge_pa(self.fixed_initial_absolute_pressure_pa)
|
|
|
|
@property
|
|
def variable_initial_gauge_pressure_pa(self) -> float:
|
|
return pressure_to_amesim_gauge_pa(self.variable_initial_absolute_pressure_pa)
|
|
|
|
@property
|
|
def chamber_count(self) -> int:
|
|
return len(self.fixed_chambers) + len(self.variable_chambers)
|
|
|
|
@property
|
|
def orifice_count(self) -> int:
|
|
return len(self.fixed_orifices) + len(self.variable_orifices)
|
|
|
|
@property
|
|
def component_count(self) -> int:
|
|
return self.chamber_count + self.orifice_count
|
|
|
|
@property
|
|
def aliases(self) -> tuple[str, ...]:
|
|
return tuple(
|
|
[
|
|
*self.fixed_chambers,
|
|
*self.variable_chambers,
|
|
*self.fixed_orifices,
|
|
*self.variable_orifices,
|
|
]
|
|
)
|
|
|
|
|
|
def build_test_mql_pneumatic_assembly(
|
|
config: TestMqlConfig | None = None,
|
|
gas: AmesimPneumaticGas = HELIUM_PNEUMATIC_GAS,
|
|
) -> TestMqlPneumaticAssembly:
|
|
config = config or TestMqlConfig.from_amesim_specs()
|
|
fixed_initial_absolute_pressure_pa = absolute_pressure_from_amesim_bar_parameter(
|
|
config.global_parameters["P0"]
|
|
)
|
|
variable_initial_absolute_pressure_pa = absolute_pressure_from_amesim_bar_parameter(
|
|
DEFAULT_VARIABLE_CHAMBER_PRESSURE_BAR
|
|
)
|
|
fixed_chambers = {
|
|
component.alias: _build_chamber(
|
|
component,
|
|
volume_parameter="cvol",
|
|
gas=gas,
|
|
initial_pressure_pa=fixed_initial_absolute_pressure_pa,
|
|
)
|
|
for component in config.components_by_submodel("PNCH023")
|
|
}
|
|
variable_chambers = {
|
|
component.alias: _build_chamber(
|
|
component,
|
|
volume_parameter="cvol0",
|
|
gas=gas,
|
|
initial_pressure_pa=variable_initial_absolute_pressure_pa,
|
|
)
|
|
for component in config.components_by_submodel("PNCH012")
|
|
}
|
|
fixed_orifices = {
|
|
component.alias: _build_orifice(
|
|
component,
|
|
area_parameter="area",
|
|
gas=gas,
|
|
opening=1.0,
|
|
)
|
|
for component in config.components_by_submodel("PNOR001")
|
|
}
|
|
variable_orifices = {
|
|
component.alias: _build_orifice(
|
|
component,
|
|
area_parameter="area0",
|
|
gas=gas,
|
|
opening=1.0,
|
|
)
|
|
for component in config.components_by_submodel("PNVO001")
|
|
}
|
|
return TestMqlPneumaticAssembly(
|
|
fixed_chambers=fixed_chambers,
|
|
variable_chambers=variable_chambers,
|
|
fixed_orifices=fixed_orifices,
|
|
variable_orifices=variable_orifices,
|
|
fixed_initial_absolute_pressure_pa=fixed_initial_absolute_pressure_pa,
|
|
variable_initial_absolute_pressure_pa=variable_initial_absolute_pressure_pa,
|
|
)
|
|
|
|
|
|
def absolute_pressure_from_amesim_bar_parameter(pressure_bar: float) -> float:
|
|
return pressure_bar * BAR_TO_PA
|
|
|
|
|
|
def pressure_to_amesim_gauge_pa(absolute_pressure_pa: float) -> float:
|
|
return absolute_pressure_pa - AMESIM_REFERENCE_PRESSURE_PA
|
|
|
|
|
|
def pressure_from_amesim_bar_parameter(pressure_bar: float) -> float:
|
|
return pressure_to_amesim_gauge_pa(absolute_pressure_from_amesim_bar_parameter(pressure_bar))
|
|
|
|
|
|
def _build_chamber(
|
|
component: TestMqlResolvedComponent,
|
|
*,
|
|
volume_parameter: str,
|
|
gas: AmesimPneumaticGas,
|
|
initial_pressure_pa: float,
|
|
) -> AmesimPneumaticVolume:
|
|
if volume_parameter == "cvol0":
|
|
return AmesimVariablePneumaticVolume.from_liters(
|
|
name=component.alias,
|
|
dead_volume_liters=component.parameter_value(volume_parameter),
|
|
gas=gas,
|
|
p0=initial_pressure_pa,
|
|
T0=_component_temperature(component),
|
|
)
|
|
return AmesimPneumaticVolume.from_liters(
|
|
name=component.alias,
|
|
volume_liters=component.parameter_value(volume_parameter),
|
|
gas=gas,
|
|
p0=initial_pressure_pa,
|
|
T0=_component_temperature(component),
|
|
)
|
|
|
|
|
|
def _build_orifice(
|
|
component: TestMqlResolvedComponent,
|
|
*,
|
|
area_parameter: str,
|
|
gas: AmesimPneumaticGas,
|
|
opening: float,
|
|
) -> AmesimPneumaticOrifice:
|
|
return AmesimPneumaticOrifice.from_mm2(
|
|
name=component.alias,
|
|
area_mm2=component.parameter_value(area_parameter),
|
|
flow_coefficient=component.parameter_value("cq"),
|
|
gas=gas,
|
|
opening=opening,
|
|
)
|
|
|
|
|
|
def _component_temperature(component: TestMqlResolvedComponent) -> float:
|
|
parameter = component.parameters.get("extemp")
|
|
if parameter is None or parameter.value is None:
|
|
return DEFAULT_TEST_MQL_TEMPERATURE_K
|
|
return parameter.value
|