110 lines
3.2 KiB
Python
110 lines
3.2 KiB
Python
from __future__ import annotations
|
||
|
||
from collections.abc import Callable
|
||
from dataclasses import dataclass
|
||
from typing import ClassVar
|
||
|
||
from app.simulation.core.medium import GasMedium, IdealGasMedium
|
||
from app.simulation.core.peng_robinson import HELIUM_PR, PengRobinsonFluid
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class AmesimIdealAirMedium(IdealGasMedium):
|
||
"""AMESim air properties evaluated with the ideal-gas method.
|
||
|
||
Substance identity and property method are part of the concrete Python
|
||
type. A future air correlation or helium Peng-Robinson implementation can
|
||
therefore coexist as a sibling type without turning ``gi`` into a fluid
|
||
enumeration.
|
||
"""
|
||
|
||
SUBSTANCE_ID: ClassVar[str] = "air"
|
||
PROPERTY_METHOD_ID: ClassVar[str] = "ideal_gas"
|
||
|
||
name: str = "AMESimAirIdealGas"
|
||
R_gas: float = 287.0
|
||
cp_ref: float = 1005.0
|
||
T_ref: float = 300.0
|
||
cp_slope: float = 0.0
|
||
viscosity_ref: float = 1.82e-5
|
||
viscosity_T_ref: float = 293.15
|
||
sutherland_constant: float = 110.4
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class AmesimHeliumPengRobinsonMedium(IdealGasMedium):
|
||
"""AMESim helium with a Peng-Robinson mechanical equation of state.
|
||
|
||
The pressure-density-temperature relation is evaluated by the shared
|
||
``HELIUM_PR`` fluid. The first public AMESim port keeps the committed
|
||
constant-heat-capacity caloric model so it can be consumed through the
|
||
same :class:`GasMedium` contract as ideal-gas air.
|
||
"""
|
||
|
||
SUBSTANCE_ID: ClassVar[str] = "helium"
|
||
PROPERTY_METHOD_ID: ClassVar[str] = "peng_robinson"
|
||
fluid: ClassVar[PengRobinsonFluid] = HELIUM_PR
|
||
|
||
name: str = "AMESimHeliumPengRobinson"
|
||
R_gas: float = HELIUM_PR.specific_gas_constant
|
||
cp_ref: float = 5193.0
|
||
T_ref: float = 293.15
|
||
cp_slope: float = 0.0
|
||
viscosity_ref: float = 1.96e-5
|
||
viscosity_T_ref: float = 293.15
|
||
sutherland_constant: float = 79.4
|
||
|
||
@property
|
||
def cv(self) -> float:
|
||
return 3116.0
|
||
|
||
def cv_at_temperature(self, T: float) -> float:
|
||
del T
|
||
return self.cv
|
||
|
||
def density(self, p: float, T: float) -> float:
|
||
return self.fluid.density(p, T)
|
||
|
||
def pressure(self, m: float, T: float, V: float) -> float:
|
||
if V <= 0.0:
|
||
raise ValueError("Volume must stay positive.")
|
||
return self.fluid.pressure_from_density(T, m / V)
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class AmesimGasPropertyModelSpec:
|
||
"""A selectable calculation method for one AMESim gas substance."""
|
||
|
||
value: int
|
||
label: str
|
||
method_id: str
|
||
factory: Callable[[], GasMedium]
|
||
eos_type: int
|
||
|
||
def build_medium(self) -> GasMedium:
|
||
return self.factory()
|
||
|
||
|
||
AMESIM_AIR_IDEAL_GAS_PROPERTY_MODEL = 0
|
||
AMESIM_AIR_PROPERTY_MODELS = (
|
||
AmesimGasPropertyModelSpec(
|
||
value=AMESIM_AIR_IDEAL_GAS_PROPERTY_MODEL,
|
||
label="理想气体",
|
||
method_id=AmesimIdealAirMedium.PROPERTY_METHOD_ID,
|
||
factory=AmesimIdealAirMedium,
|
||
eos_type=1,
|
||
),
|
||
)
|
||
|
||
|
||
AMESIM_HELIUM_PENG_ROBINSON_PROPERTY_MODEL = 0
|
||
AMESIM_HELIUM_PROPERTY_MODELS = (
|
||
AmesimGasPropertyModelSpec(
|
||
value=AMESIM_HELIUM_PENG_ROBINSON_PROPERTY_MODEL,
|
||
label="Peng–Robinson",
|
||
method_id=AmesimHeliumPengRobinsonMedium.PROPERTY_METHOD_ID,
|
||
factory=AmesimHeliumPengRobinsonMedium,
|
||
eos_type=6,
|
||
),
|
||
)
|