实现test_mql PNL0002管路动态
This commit is contained in:
1 parent
7569917924
commit
a071896834
6 files changed
+492
No files matched your search
@@ -477,6 +477,199 @@ class AmesimPnl0003Pipe(_DarcyPipeResistanceMixin, DynamicComponent):
|
||||
)
|
||||
|
||||
|
||||
class AmesimPnl0002Pipe(_DarcyPipeResistanceMixin, DynamicComponent):
|
||||
"""First-pass AMESim ``PNL0002`` (R-C-R) pipe.
|
||||
|
||||
The center compliance owns the gas state. Positive connection mass flows
|
||||
enter that center storage from each external port.
|
||||
"""
|
||||
|
||||
state_size = 2
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
*,
|
||||
diameter_mm: float,
|
||||
length_m: float,
|
||||
relative_roughness: float,
|
||||
polytropic_constant: float = 1.35,
|
||||
heat_transfer_coefficient: float = 0.0,
|
||||
external_temperature_k: float = 293.15,
|
||||
gas: AmesimPneumaticGas = HELIUM_PNEUMATIC_GAS,
|
||||
pctr_0: float = 101_325.0,
|
||||
Tctr_0: float = 293.15,
|
||||
) -> None:
|
||||
if diameter_mm <= 0.0:
|
||||
raise ValueError("diameter_mm must be positive")
|
||||
if length_m <= 0.0:
|
||||
raise ValueError("length_m must be positive")
|
||||
if relative_roughness < 0.0:
|
||||
raise ValueError("relative_roughness must be non-negative")
|
||||
if polytropic_constant <= 0.0:
|
||||
raise ValueError("polytropic_constant must be positive")
|
||||
if heat_transfer_coefficient < 0.0:
|
||||
raise ValueError("heat_transfer_coefficient must be non-negative")
|
||||
if external_temperature_k <= 0.0:
|
||||
raise ValueError("external_temperature_k must be positive")
|
||||
|
||||
super().__init__(name=name)
|
||||
self.diameter = diameter_mm * 1.0e-3
|
||||
self.length = length_m
|
||||
self.relative_roughness = relative_roughness
|
||||
self.polytropic_constant = polytropic_constant
|
||||
self.heat_transfer_coefficient = heat_transfer_coefficient
|
||||
self.external_temperature = external_temperature_k
|
||||
self.gas = gas
|
||||
self.area = diameter_mm_to_area_m2(diameter_mm)
|
||||
self.volume = self.area * self.length
|
||||
self.heat_transfer_area = pi * self.diameter * self.length
|
||||
self._resistance_length = self.length / 2.0
|
||||
|
||||
rho0 = gas.density(pctr_0, Tctr_0)
|
||||
mass0 = rho0 * self.volume
|
||||
self.state = VolumeState(
|
||||
m=mass0,
|
||||
U=mass0 * gas.specific_internal_energy(Tctr_0),
|
||||
)
|
||||
self.port_1 = PortState()
|
||||
self.port_2 = PortState()
|
||||
|
||||
def get_state_vector(self) -> list[float]:
|
||||
return self.state.as_vector()
|
||||
|
||||
def set_state_vector(self, values: list[float]) -> None:
|
||||
self.state = VolumeState.from_vector(values)
|
||||
|
||||
def properties(self) -> ThermodynamicProperties:
|
||||
if self.state.m <= 0.0:
|
||||
raise ValueError("pipe mass must stay positive")
|
||||
temperature = self.gas.temperature_from_internal_energy(
|
||||
self.state.U / self.state.m
|
||||
)
|
||||
density = self.state.m / self.volume
|
||||
pressure = self.gas.pressure(density, temperature)
|
||||
properties = ThermodynamicProperties(
|
||||
p=pressure,
|
||||
T=temperature,
|
||||
rho=density,
|
||||
u=self.state.U / self.state.m,
|
||||
h=self.gas.specific_enthalpy(temperature),
|
||||
)
|
||||
self.port_1.p = pressure
|
||||
self.port_1.h_outflow = properties.h
|
||||
self.port_2.p = pressure
|
||||
self.port_2.h_outflow = properties.h
|
||||
return properties
|
||||
|
||||
def gas_mass_g(self) -> float:
|
||||
return self.state.m * 1.0e3
|
||||
|
||||
def port_mass_flow(
|
||||
self,
|
||||
*,
|
||||
port_pressure_pa: float,
|
||||
port_temperature_k: float,
|
||||
) -> float:
|
||||
"""Return mass flow from an external port into the center storage."""
|
||||
if port_pressure_pa <= 0.0:
|
||||
raise ValueError("port_pressure_pa must be positive")
|
||||
if port_temperature_k <= 0.0:
|
||||
raise ValueError("port_temperature_k must be positive")
|
||||
|
||||
center = self.properties()
|
||||
pressure_difference = port_pressure_pa - center.p
|
||||
if pressure_difference == 0.0:
|
||||
return 0.0
|
||||
upstream_pressure = max(port_pressure_pa, center.p)
|
||||
upstream_temperature = (
|
||||
port_temperature_k if pressure_difference > 0.0 else center.T
|
||||
)
|
||||
density = self.gas.density(upstream_pressure, upstream_temperature)
|
||||
magnitude = self._mass_flow_for_resistance_pressure_drop(
|
||||
abs(pressure_difference),
|
||||
density=density,
|
||||
temperature=upstream_temperature,
|
||||
)
|
||||
return magnitude if pressure_difference > 0.0 else -magnitude
|
||||
|
||||
def _mass_flow_for_resistance_pressure_drop(
|
||||
self,
|
||||
pressure_drop_pa: float,
|
||||
*,
|
||||
density: float,
|
||||
temperature: float,
|
||||
) -> float:
|
||||
original_length = self.length
|
||||
self.length = self._resistance_length
|
||||
try:
|
||||
return self._mass_flow_for_pressure_drop(
|
||||
pressure_drop_pa,
|
||||
density=density,
|
||||
temperature=temperature,
|
||||
)
|
||||
finally:
|
||||
self.length = original_length
|
||||
|
||||
def diagnostics(
|
||||
self,
|
||||
*,
|
||||
mass_flow_kg_s: float,
|
||||
temperature_k: float | None = None,
|
||||
) -> AmesimPnl0001Diagnostics:
|
||||
properties = self.properties()
|
||||
temperature = temperature_k or properties.T
|
||||
reynolds = self._reynolds_number(mass_flow_kg_s, temperature)
|
||||
friction_factor = self._friction_factor(reynolds)
|
||||
velocity = mass_flow_kg_s / (properties.rho * self.area)
|
||||
original_length = self.length
|
||||
self.length = self._resistance_length
|
||||
try:
|
||||
pressure_drop = self._darcy_pressure_drop(
|
||||
mass_flow_kg_s,
|
||||
density=properties.rho,
|
||||
temperature=temperature,
|
||||
)
|
||||
finally:
|
||||
self.length = original_length
|
||||
return AmesimPnl0001Diagnostics(
|
||||
mass_flow_kg_s=mass_flow_kg_s,
|
||||
reynolds_number=reynolds,
|
||||
gas_velocity_m_s=velocity,
|
||||
friction_factor=friction_factor,
|
||||
pressure_drop_pa=pressure_drop,
|
||||
)
|
||||
|
||||
def derivatives_from_connections(
|
||||
self,
|
||||
*,
|
||||
port_1_m_flow: float,
|
||||
connected_h_1: float,
|
||||
port_2_m_flow: float,
|
||||
connected_h_2: float,
|
||||
) -> VolumeState:
|
||||
center = self.properties()
|
||||
inlet_h_1 = self.connection_inlet_enthalpy(
|
||||
port_m_flow=port_1_m_flow,
|
||||
connected_h=connected_h_1,
|
||||
internal_h=center.h,
|
||||
)
|
||||
inlet_h_2 = self.connection_inlet_enthalpy(
|
||||
port_m_flow=port_2_m_flow,
|
||||
connected_h=connected_h_2,
|
||||
internal_h=center.h,
|
||||
)
|
||||
heat_flow = (
|
||||
self.heat_transfer_coefficient
|
||||
* self.heat_transfer_area
|
||||
* (self.external_temperature - center.T)
|
||||
)
|
||||
return VolumeState(
|
||||
m=port_1_m_flow + port_2_m_flow,
|
||||
U=port_1_m_flow * inlet_h_1 + port_2_m_flow * inlet_h_2 + heat_flow,
|
||||
)
|
||||
|
||||
|
||||
class AmesimPnl00rPipe(_DarcyPipeResistanceMixin, AlgebraicComponent):
|
||||
"""First-pass AMESim ``PNL00R`` (R) pipe resistance."""
|
||||
|
||||
|
||||
Reference in new issue
Block a user