feat: integrate AMESim media models and editor UI
This commit is contained in:
1 parent
3e4f466114
commit
e7177ab03e
181 files changed
+7042
-25270
No files matched your search
@@ -3,6 +3,10 @@ from __future__ import annotations
|
||||
from collections.abc import Mapping
|
||||
from math import isclose, log10, pi, sqrt
|
||||
|
||||
from app.simulation.components.amesim.gases import (
|
||||
AMESIM_GAS_INDEX_PARAMETER,
|
||||
normalize_amesim_gas_index,
|
||||
)
|
||||
from app.simulation.core.base import AlgebraicComponent, DynamicComponent, ThermodynamicVolumeComponent
|
||||
from app.simulation.core.catalog import ComponentDisplaySpec, PortDisplaySpec
|
||||
from app.simulation.core.equations import EquationResidual
|
||||
@@ -11,7 +15,7 @@ from app.simulation.core.metadata import (
|
||||
ResultVariableDefinition,
|
||||
THERMODYNAMIC_VOLUME_RESULT_VARIABLES,
|
||||
)
|
||||
from app.simulation.core.medium import IdealGasMedium, ThermodynamicProperties
|
||||
from app.simulation.core.medium import GasMedium, ThermodynamicProperties
|
||||
from app.simulation.core.ports import PortDefinition
|
||||
from app.simulation.core.state import VolumeState
|
||||
|
||||
@@ -31,6 +35,7 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
PortDefinition.pneumatic("port_2", nominal_role="bidirectional"),
|
||||
)
|
||||
PARAMETERS = (
|
||||
AMESIM_GAS_INDEX_PARAMETER,
|
||||
ParameterDefinition(
|
||||
"diam",
|
||||
0.01,
|
||||
@@ -39,6 +44,7 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
unit="m",
|
||||
minimum=0.0,
|
||||
minimum_exclusive=True,
|
||||
description="管路的有效内径,用于计算流通面积和摩擦压降。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"le",
|
||||
@@ -48,6 +54,7 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
unit="m",
|
||||
minimum=0.0,
|
||||
minimum_exclusive=True,
|
||||
description="参与摩擦压降计算的管路有效长度。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"rr",
|
||||
@@ -57,15 +64,7 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
unit="",
|
||||
minimum=0.0,
|
||||
maximum=0.1,
|
||||
),
|
||||
ParameterDefinition(
|
||||
"gi",
|
||||
1.0,
|
||||
label="气体类型索引",
|
||||
quantity="dimensionless",
|
||||
unit="",
|
||||
minimum=1.0,
|
||||
maximum=99.0,
|
||||
description="管壁绝对粗糙度与管径之比,用于计算 Darcy 摩擦因子。",
|
||||
),
|
||||
)
|
||||
RESULT_VARIABLES = (
|
||||
@@ -117,7 +116,7 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
medium: IdealGasMedium,
|
||||
medium: GasMedium,
|
||||
*,
|
||||
diam: float = 0.01,
|
||||
le: float = 1.0,
|
||||
@@ -130,7 +129,7 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
self.diam = float(diam)
|
||||
self.le = float(le)
|
||||
self.rr = float(rr)
|
||||
self.gi = self._integer_parameter("gi", gi)
|
||||
self.gi = normalize_amesim_gas_index(gi)
|
||||
self.area = pi * self.diam * self.diam / 4.0
|
||||
|
||||
initial_h = medium.specific_enthalpy(medium.T_ref)
|
||||
@@ -151,7 +150,7 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
cls,
|
||||
*,
|
||||
name: str,
|
||||
medium: IdealGasMedium,
|
||||
medium: GasMedium,
|
||||
parameters: Mapping[str, float],
|
||||
) -> AmesimPnl00r:
|
||||
return cls(
|
||||
@@ -166,22 +165,11 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
def _port_temperature(self, port_name: str) -> float:
|
||||
port = self.get_port(port_name)
|
||||
if port.h_outflow > 0.0:
|
||||
return max(port.h_outflow / self.medium.cp_ref, 1.0)
|
||||
return max(self.medium.temperature_from_enthalpy(port.h_outflow), 1.0)
|
||||
return self.medium.T_ref
|
||||
|
||||
@staticmethod
|
||||
def _dynamic_viscosity(temperature_k: float) -> float:
|
||||
if temperature_k <= 0.0:
|
||||
raise ValueError("temperature_k must be positive")
|
||||
reference_temperature = 293.15
|
||||
reference_viscosity = 1.82e-5
|
||||
sutherland_constant = 110.4
|
||||
return (
|
||||
reference_viscosity
|
||||
* (temperature_k / reference_temperature) ** 1.5
|
||||
* (reference_temperature + sutherland_constant)
|
||||
/ (temperature_k + sutherland_constant)
|
||||
)
|
||||
def _dynamic_viscosity(self, temperature_k: float) -> float:
|
||||
return self.medium.dynamic_viscosity(temperature_k)
|
||||
|
||||
def reynolds_number(self, mass_flow: float, temperature: float) -> float:
|
||||
viscosity = self._dynamic_viscosity(temperature)
|
||||
@@ -322,6 +310,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
PortDefinition.pneumatic("port_2", nominal_role="bidirectional"),
|
||||
)
|
||||
PARAMETERS = (
|
||||
AMESIM_GAS_INDEX_PARAMETER,
|
||||
ParameterDefinition(
|
||||
"diam",
|
||||
0.01,
|
||||
@@ -330,6 +319,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
unit="m",
|
||||
minimum=0.0,
|
||||
minimum_exclusive=True,
|
||||
description="管路的有效内径,用于计算流通面积、储气容积和摩擦压降。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"le",
|
||||
@@ -339,6 +329,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
unit="m",
|
||||
minimum=0.0,
|
||||
minimum_exclusive=True,
|
||||
description="管路的有效长度,用于计算储气容积、换热面积和摩擦压降。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"rr",
|
||||
@@ -348,6 +339,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
unit="",
|
||||
minimum=0.0,
|
||||
maximum=0.1,
|
||||
description="管壁绝对粗糙度与管径之比,用于计算 Darcy 摩擦因子。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"k",
|
||||
@@ -358,6 +350,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
minimum=0.0,
|
||||
minimum_exclusive=True,
|
||||
maximum=2.0,
|
||||
description="AMESim 管路热力学配置使用的多方指数。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"kth",
|
||||
@@ -366,6 +359,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
quantity="heat_transfer_coefficient",
|
||||
unit="W/(m2*K)",
|
||||
minimum=0.0,
|
||||
description="管内气体与外部环境之间的对流换热系数。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"extemp",
|
||||
@@ -375,15 +369,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
unit="K",
|
||||
minimum=0.0,
|
||||
minimum_exclusive=True,
|
||||
),
|
||||
ParameterDefinition(
|
||||
"gi",
|
||||
1.0,
|
||||
label="气体类型索引",
|
||||
quantity="dimensionless",
|
||||
unit="",
|
||||
minimum=1.0,
|
||||
maximum=99.0,
|
||||
description="管路外部环境的绝对温度,用于计算换热功率。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"mode",
|
||||
@@ -393,6 +379,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
unit="",
|
||||
minimum=1.0,
|
||||
maximum=2.0,
|
||||
description="热模型选择:1 为绝热,2 为按换热系数计算环境换热。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"p0",
|
||||
@@ -402,6 +389,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
unit="Pa",
|
||||
minimum=0.0,
|
||||
minimum_exclusive=True,
|
||||
description="仿真开始时管内气体的绝对压力。",
|
||||
),
|
||||
ParameterDefinition(
|
||||
"T0",
|
||||
@@ -411,6 +399,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
unit="K",
|
||||
minimum=0.0,
|
||||
minimum_exclusive=True,
|
||||
description="仿真开始时管内气体的绝对温度。",
|
||||
),
|
||||
)
|
||||
RESULT_VARIABLES = THERMODYNAMIC_VOLUME_RESULT_VARIABLES + (
|
||||
@@ -462,7 +451,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
medium: IdealGasMedium,
|
||||
medium: GasMedium,
|
||||
*,
|
||||
diam: float = 0.01,
|
||||
le: float = 1.0,
|
||||
@@ -497,14 +486,14 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
self.k = float(k)
|
||||
self.kth = float(kth)
|
||||
self.extemp = float(extemp)
|
||||
self.gi = self._integer_parameter("gi", gi)
|
||||
self.gi = normalize_amesim_gas_index(gi)
|
||||
self.mode = self._integer_parameter("mode", mode)
|
||||
self.p0 = float(p0)
|
||||
self.T0 = float(T0)
|
||||
self.area = pi * self.diam * self.diam / 4.0
|
||||
self.volume = self.area * self.le
|
||||
self.exchange_area = pi * self.diam * self.le
|
||||
m0 = self.p0 * self.volume / (medium.R_gas * self.T0)
|
||||
m0 = medium.density(self.p0, self.T0) * self.volume
|
||||
U0 = m0 * medium.specific_internal_energy(self.T0)
|
||||
self.state = VolumeState(m=m0, U=U0)
|
||||
initial_h = medium.specific_enthalpy(self.T0)
|
||||
@@ -527,7 +516,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
cls,
|
||||
*,
|
||||
name: str,
|
||||
medium: IdealGasMedium,
|
||||
medium: GasMedium,
|
||||
parameters: Mapping[str, float],
|
||||
) -> "AmesimPnl0001":
|
||||
return cls(
|
||||
@@ -566,9 +555,8 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
return 0.0
|
||||
return self.kth * self.exchange_area * (self.extemp - temperature)
|
||||
|
||||
@staticmethod
|
||||
def _dynamic_viscosity(temperature_k: float) -> float:
|
||||
return AmesimPnl00r._dynamic_viscosity(temperature_k)
|
||||
def _dynamic_viscosity(self, temperature_k: float) -> float:
|
||||
return self.medium.dynamic_viscosity(temperature_k)
|
||||
|
||||
def reynolds_number(self, mass_flow: float, temperature: float) -> float:
|
||||
viscosity = self._dynamic_viscosity(temperature)
|
||||
@@ -745,7 +733,7 @@ class AmesimPnl0002(AmesimPnl0001):
|
||||
cls,
|
||||
*,
|
||||
name: str,
|
||||
medium: IdealGasMedium,
|
||||
medium: GasMedium,
|
||||
parameters: Mapping[str, float],
|
||||
) -> "AmesimPnl0002":
|
||||
return cls(
|
||||
@@ -943,7 +931,7 @@ class AmesimPnl0003(DynamicComponent):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
medium: IdealGasMedium,
|
||||
medium: GasMedium,
|
||||
*,
|
||||
diam: float = 0.01,
|
||||
le: float = 1.0,
|
||||
@@ -982,7 +970,7 @@ class AmesimPnl0003(DynamicComponent):
|
||||
self.k = float(k)
|
||||
self.kth = float(kth)
|
||||
self.extemp = float(extemp)
|
||||
self.gi = AmesimPnl0001._integer_parameter("gi", gi)
|
||||
self.gi = normalize_amesim_gas_index(gi)
|
||||
self.mode = AmesimPnl0001._integer_parameter("mode", mode)
|
||||
self.area = pi * self.diam * self.diam / 4.0
|
||||
self.volume = self.area * self.le
|
||||
@@ -1004,13 +992,13 @@ class AmesimPnl0003(DynamicComponent):
|
||||
cls,
|
||||
*,
|
||||
name: str,
|
||||
medium: IdealGasMedium,
|
||||
medium: GasMedium,
|
||||
parameters: Mapping[str, float],
|
||||
) -> "AmesimPnl0003":
|
||||
return cls(name=name, medium=medium, **dict(parameters))
|
||||
|
||||
def _initial_state(self, pressure: float, temperature: float) -> VolumeState:
|
||||
mass = pressure * self.compliance_volume / (self.medium.R_gas * temperature)
|
||||
mass = self.medium.density(pressure, temperature) * self.compliance_volume
|
||||
return VolumeState(m=mass, U=mass * self.medium.specific_internal_energy(temperature))
|
||||
|
||||
def get_state_vector(self) -> list[float]:
|
||||
@@ -1040,9 +1028,8 @@ class AmesimPnl0003(DynamicComponent):
|
||||
def refresh_thermodynamic_ports(self) -> tuple[ThermodynamicProperties, ThermodynamicProperties]:
|
||||
return self.properties_1(), self.properties_2()
|
||||
|
||||
@staticmethod
|
||||
def _dynamic_viscosity(temperature_k: float) -> float:
|
||||
return AmesimPnl00r._dynamic_viscosity(temperature_k)
|
||||
def _dynamic_viscosity(self, temperature_k: float) -> float:
|
||||
return self.medium.dynamic_viscosity(temperature_k)
|
||||
|
||||
def reynolds_number(self, mass_flow: float, temperature: float) -> float:
|
||||
viscosity = self._dynamic_viscosity(temperature)
|
||||
|
||||
Reference in new issue
Block a user