对齐Amesim氦气PR物性与PNVO流量
This commit is contained in:
1 parent
18d9802f03
commit
046aa49814
13 files changed
+730
-73
No files matched your search
@@ -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