对齐Amesim氦气PR物性与PNVO流量
This commit is contained in:
1 parent
18d9802f03
commit
046aa49814
13 files changed
+730
-73
No files matched your search
@@ -38,16 +38,29 @@ class GasMedium(Protocol):
|
||||
|
||||
def density(self, p: float, T: float) -> float: ...
|
||||
|
||||
def isentropic_density_pressure_factor(
|
||||
self,
|
||||
p: float,
|
||||
T: float,
|
||||
downstream_pressure: float | None = None,
|
||||
) -> float: ...
|
||||
|
||||
def dynamic_viscosity(self, T: float) -> float: ...
|
||||
|
||||
def specific_internal_energy(self, T: float) -> float: ...
|
||||
|
||||
def specific_internal_energy_at_pressure(self, p: float, T: float) -> float: ...
|
||||
|
||||
def specific_enthalpy(self, T: float) -> float: ...
|
||||
|
||||
def specific_enthalpy_at_pressure(self, p: float, T: float) -> float: ...
|
||||
|
||||
def temperature_from_internal_energy(self, u: float) -> float: ...
|
||||
|
||||
def temperature_from_enthalpy(self, h: float) -> float: ...
|
||||
|
||||
def temperature_from_pressure_enthalpy(self, p: float, h: float) -> float: ...
|
||||
|
||||
def temperature_from_mass_internal_energy(self, m: float, U: float) -> float: ...
|
||||
|
||||
def pressure(self, m: float, T: float, V: float) -> float: ...
|
||||
@@ -96,6 +109,18 @@ class IdealGasMedium:
|
||||
def density(self, p: float, T: float) -> float:
|
||||
return p / (self.R_gas * T)
|
||||
|
||||
def isentropic_density_pressure_factor(
|
||||
self,
|
||||
p: float,
|
||||
T: float,
|
||||
downstream_pressure: float | None = None,
|
||||
) -> float:
|
||||
del p
|
||||
del downstream_pressure
|
||||
cp = self.cp_at_temperature(T)
|
||||
cv = self.cv_at_temperature(T)
|
||||
return cv / cp
|
||||
|
||||
def dynamic_viscosity(self, T: float) -> float:
|
||||
"""Return dynamic viscosity using the default air Sutherland law."""
|
||||
|
||||
@@ -116,6 +141,10 @@ class IdealGasMedium:
|
||||
+ 0.5 * self.cp_slope * delta_T * delta_T
|
||||
)
|
||||
|
||||
def specific_internal_energy_at_pressure(self, p: float, T: float) -> float:
|
||||
del p
|
||||
return self.specific_internal_energy(T)
|
||||
|
||||
def specific_enthalpy(self, T: float) -> float:
|
||||
delta_T = T - self.T_ref
|
||||
return (
|
||||
@@ -124,6 +153,10 @@ class IdealGasMedium:
|
||||
+ 0.5 * self.cp_slope * delta_T * delta_T
|
||||
)
|
||||
|
||||
def specific_enthalpy_at_pressure(self, p: float, T: float) -> float:
|
||||
del p
|
||||
return self.specific_enthalpy(T)
|
||||
|
||||
def temperature_from_internal_energy(self, u: float) -> float:
|
||||
reference_internal_energy = self.cv * self.T_ref
|
||||
delta_u = u - reference_internal_energy
|
||||
@@ -156,6 +189,10 @@ class IdealGasMedium:
|
||||
delta_T = positive_root if abs(positive_root) <= abs(negative_root) else negative_root
|
||||
return self.T_ref + delta_T
|
||||
|
||||
def temperature_from_pressure_enthalpy(self, p: float, h: float) -> float:
|
||||
del p
|
||||
return self.temperature_from_enthalpy(h)
|
||||
|
||||
def temperature_from_mass_internal_energy(self, m: float, U: float) -> float:
|
||||
if m <= 0.0:
|
||||
raise ValueError("Mass must stay positive when recovering temperature.")
|
||||
|
||||
@@ -6,6 +6,10 @@ from dataclasses import dataclass
|
||||
from math import acos, cos, isfinite, log, pi, sqrt
|
||||
|
||||
UNIVERSAL_GAS_CONSTANT = 8.31446261815324
|
||||
# Simcenter Amesim 2404 ``sag_reinit_eos_`` keeps more digits than the
|
||||
# commonly printed Peng-Robinson constants 0.45724 and 0.07780.
|
||||
PENG_ROBINSON_A_COEFFICIENT = 0.457235583
|
||||
PENG_ROBINSON_B_COEFFICIENT = 0.07779607
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -29,7 +33,7 @@ class PengRobinsonFluid:
|
||||
@property
|
||||
def a_parameter(self) -> float:
|
||||
return (
|
||||
0.45724
|
||||
PENG_ROBINSON_A_COEFFICIENT
|
||||
* UNIVERSAL_GAS_CONSTANT
|
||||
* UNIVERSAL_GAS_CONSTANT
|
||||
* self.critical_temperature
|
||||
@@ -39,7 +43,12 @@ class PengRobinsonFluid:
|
||||
|
||||
@property
|
||||
def b_parameter(self) -> float:
|
||||
return 0.07780 * UNIVERSAL_GAS_CONSTANT * self.critical_temperature / self.critical_pressure
|
||||
return (
|
||||
PENG_ROBINSON_B_COEFFICIENT
|
||||
* UNIVERSAL_GAS_CONSTANT
|
||||
* self.critical_temperature
|
||||
/ self.critical_pressure
|
||||
)
|
||||
|
||||
@property
|
||||
def kappa(self) -> float:
|
||||
@@ -62,12 +71,32 @@ class PengRobinsonFluid:
|
||||
/ (self.critical_temperature * sqrt_reduced_temperature)
|
||||
)
|
||||
|
||||
def alpha_temperature_second_derivative(self, temperature: float) -> float:
|
||||
self._validate_temperature(temperature)
|
||||
reduced_temperature = temperature / self.critical_temperature
|
||||
sqrt_reduced_temperature = sqrt(reduced_temperature)
|
||||
alpha_base = 1.0 + self.kappa * (1.0 - sqrt_reduced_temperature)
|
||||
return (
|
||||
self.kappa
|
||||
/ (2.0 * self.critical_temperature * self.critical_temperature)
|
||||
* (
|
||||
self.kappa / reduced_temperature
|
||||
+ alpha_base / (reduced_temperature * sqrt_reduced_temperature)
|
||||
)
|
||||
)
|
||||
|
||||
def attractive_parameter(self, temperature: float) -> float:
|
||||
return self.a_parameter * self.alpha(temperature)
|
||||
|
||||
def attractive_parameter_temperature_derivative(self, temperature: float) -> float:
|
||||
return self.a_parameter * self.alpha_temperature_derivative(temperature)
|
||||
|
||||
def attractive_parameter_temperature_second_derivative(
|
||||
self,
|
||||
temperature: float,
|
||||
) -> float:
|
||||
return self.a_parameter * self.alpha_temperature_second_derivative(temperature)
|
||||
|
||||
def pressure_from_molar_volume(self, temperature: float, molar_volume: float) -> float:
|
||||
self._validate_temperature(temperature)
|
||||
if molar_volume <= self.b_parameter:
|
||||
@@ -83,6 +112,51 @@ class PengRobinsonFluid:
|
||||
raise ValueError("Density must be positive.")
|
||||
return self.pressure_from_molar_volume(temperature, self.molar_mass / density)
|
||||
|
||||
def pressure_temperature_derivative_at_density(
|
||||
self,
|
||||
temperature: float,
|
||||
density: float,
|
||||
) -> float:
|
||||
self._validate_temperature(temperature)
|
||||
if density <= 0.0:
|
||||
raise ValueError("Density must be positive.")
|
||||
molar_volume = self.molar_mass / density
|
||||
if molar_volume <= self.b_parameter:
|
||||
raise RecoverableTrialStateError(
|
||||
"Molar volume must be larger than Peng-Robinson b parameter."
|
||||
)
|
||||
b = self.b_parameter
|
||||
denominator = molar_volume * (molar_volume + b) + b * (molar_volume - b)
|
||||
return (
|
||||
UNIVERSAL_GAS_CONSTANT / (molar_volume - b)
|
||||
- self.attractive_parameter_temperature_derivative(temperature) / denominator
|
||||
)
|
||||
|
||||
def pressure_density_derivative_at_temperature(
|
||||
self,
|
||||
temperature: float,
|
||||
density: float,
|
||||
) -> float:
|
||||
self._validate_temperature(temperature)
|
||||
if density <= 0.0:
|
||||
raise ValueError("Density must be positive.")
|
||||
molar_volume = self.molar_mass / density
|
||||
if molar_volume <= self.b_parameter:
|
||||
raise RecoverableTrialStateError(
|
||||
"Molar volume must be larger than Peng-Robinson b parameter."
|
||||
)
|
||||
b = self.b_parameter
|
||||
denominator = molar_volume * (molar_volume + b) + b * (molar_volume - b)
|
||||
pressure_molar_volume_derivative = (
|
||||
-UNIVERSAL_GAS_CONSTANT * temperature / (molar_volume - b) ** 2
|
||||
+ self.attractive_parameter(temperature)
|
||||
* 2.0
|
||||
* (molar_volume + b)
|
||||
/ denominator**2
|
||||
)
|
||||
molar_volume_density_derivative = -self.molar_mass / (density * density)
|
||||
return pressure_molar_volume_derivative * molar_volume_density_derivative
|
||||
|
||||
def reduced_parameters(self, pressure: float, temperature: float) -> tuple[float, float]:
|
||||
self._validate_pressure_temperature(pressure, temperature)
|
||||
a_alpha = self.attractive_parameter(temperature)
|
||||
@@ -165,6 +239,63 @@ class PengRobinsonFluid:
|
||||
)
|
||||
return residual_molar_enthalpy / self.molar_mass
|
||||
|
||||
def residual_specific_internal_energy_at_density(
|
||||
self,
|
||||
temperature: float,
|
||||
density: float,
|
||||
) -> float:
|
||||
"""Return Peng-Robinson internal-energy departure, J/kg."""
|
||||
self._validate_temperature(temperature)
|
||||
if density <= 0.0:
|
||||
raise ValueError("Density must be positive.")
|
||||
molar_volume = self.molar_mass / density
|
||||
b = self.b_parameter
|
||||
if molar_volume <= b:
|
||||
raise RecoverableTrialStateError(
|
||||
"Molar volume must be larger than Peng-Robinson b parameter."
|
||||
)
|
||||
attractive = self.attractive_parameter(temperature)
|
||||
d_attractive_d_temperature = (
|
||||
self.attractive_parameter_temperature_derivative(temperature)
|
||||
)
|
||||
log_argument = (
|
||||
molar_volume + (1.0 + sqrt(2.0)) * b
|
||||
) / (
|
||||
molar_volume + (1.0 - sqrt(2.0)) * b
|
||||
)
|
||||
residual_molar_internal_energy = (
|
||||
temperature * d_attractive_d_temperature - attractive
|
||||
) * log(log_argument) / (2.0 * sqrt(2.0) * b)
|
||||
return residual_molar_internal_energy / self.molar_mass
|
||||
|
||||
def residual_isochoric_heat_capacity_at_density(
|
||||
self,
|
||||
temperature: float,
|
||||
density: float,
|
||||
) -> float:
|
||||
"""Return the constant-volume heat-capacity departure, J/kg/K."""
|
||||
self._validate_temperature(temperature)
|
||||
if density <= 0.0:
|
||||
raise ValueError("Density must be positive.")
|
||||
molar_volume = self.molar_mass / density
|
||||
b = self.b_parameter
|
||||
if molar_volume <= b:
|
||||
raise RecoverableTrialStateError(
|
||||
"Molar volume must be larger than Peng-Robinson b parameter."
|
||||
)
|
||||
log_argument = (
|
||||
molar_volume + (1.0 + sqrt(2.0)) * b
|
||||
) / (
|
||||
molar_volume + (1.0 - sqrt(2.0)) * b
|
||||
)
|
||||
residual_molar_cv = (
|
||||
temperature
|
||||
* self.attractive_parameter_temperature_second_derivative(temperature)
|
||||
* log(log_argument)
|
||||
/ (2.0 * sqrt(2.0) * b)
|
||||
)
|
||||
return residual_molar_cv / self.molar_mass
|
||||
|
||||
@staticmethod
|
||||
def _validate_temperature(temperature: float) -> None:
|
||||
if temperature <= 0.0:
|
||||
@@ -181,7 +312,8 @@ HELIUM_PR = PengRobinsonFluid(
|
||||
molar_mass=0.004002602,
|
||||
critical_temperature=5.1953,
|
||||
critical_pressure=227_460.0,
|
||||
acentric_factor=-0.385,
|
||||
# Simcenter Amesim 2404 helium_eos.data.
|
||||
acentric_factor=-0.382,
|
||||
)
|
||||
|
||||
NITROGEN_PR = PengRobinsonFluid(
|
||||
|
||||
Reference in new issue
Block a user