对齐AMESim管阻孔口与储气耦合

This commit is contained in:
huojiarong committed 2026-08-10 13:07:03 +00:00
1 parent 7671418582
commit 6abcc220de
14 files changed
+817 -65

No files matched your search

+123 -13
View File
@@ -1,7 +1,7 @@
from __future__ import annotations
from collections.abc import Mapping
from math import isclose, log10, pi, sqrt
from math import isclose, log, log10, pi, sqrt, tanh
from app.simulation.components.amesim.gases import (
AMESIM_GAS_INDEX_PARAMETER,
@@ -246,7 +246,7 @@ class AmesimPnl00r(AlgebraicComponent):
while self.darcy_pressure_drop(upper, density=density, temperature=temperature) < pressure_drop:
upper *= 10.0
if upper > 1.0e3:
raise ValueError("unable to bracket PNL00R resistance flow")
return 1.0e3
lower = 0.0
for _ in range(48):
middle = 0.5 * (lower + upper)
@@ -257,7 +257,7 @@ class AmesimPnl00r(AlgebraicComponent):
return 0.5 * (lower + upper)
def mass_flow(self, p_1: float, p_2: float) -> float:
if p_1 == p_2:
if isclose(p_1, p_2, rel_tol=1.0e-7, abs_tol=1.0e-9):
return 0.0
pressure_difference = p_1 - p_2
upstream_pressure = max(p_1, p_2, 1.0)
@@ -645,7 +645,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
) < pressure_drop:
upper *= 10.0
if upper > 1.0e3:
raise ValueError("unable to bracket PNL0001 resistance flow")
return 1.0e3
lower = 0.0
for _ in range(48):
middle = 0.5 * (lower + upper)
@@ -659,16 +659,126 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
upper = middle
return 0.5 * (lower + upper)
def _one_way_pn2pipefr_mass_flow(
self,
*,
upstream_pressure: float,
downstream_pressure: float,
upstream_temperature: float,
resistance_length: float,
) -> float:
"""AMESim pn2pipefr-style compressible friction flow."""
p_up = max(float(upstream_pressure), 1.0)
p_down = max(min(float(downstream_pressure), p_up), 0.0)
T_up = max(float(upstream_temperature), 1.0)
if resistance_length <= 0.0:
raise ValueError("Pipe resistance length must be positive.")
gamma_s = self.medium.isentropic_density_pressure_factor(
p_up,
T_up,
p_down,
)
gamma_s = min(max(gamma_s, 1.0e-9), 1.0 - 1.0e-9)
density = max(self.medium.density(p_up, T_up), 1.0e-12)
pressure_ratio = max(p_down / p_up, 0.0)
critical_ratio = (2.0 * gamma_s / (gamma_s + 1.0)) ** (
1.0 / (1.0 - gamma_s)
)
def mass_flow_parameter(ratio: float) -> float:
if ratio <= critical_ratio:
value = (
sqrt(2.0 / (1.0 + gamma_s) * density * T_up / p_up)
* (2.0 * gamma_s / (gamma_s + 1.0))
** (gamma_s / (1.0 - gamma_s))
)
effective_ratio = critical_ratio
else:
expansion = ratio ** (2.0 * gamma_s) - ratio ** (1.0 + gamma_s)
value = sqrt(
max(
2.0
/ (1.0 - gamma_s)
* density
* T_up
/ p_up
* expansion,
0.0,
)
)
effective_ratio = ratio
accuracy = 0.9999
reference_expansion = (
accuracy ** (2.0 * gamma_s)
- accuracy ** (1.0 + gamma_s)
)
reference = sqrt(
max(
2.0
/ (1.0 - gamma_s)
* density
* T_up
/ p_up
* reference_expansion,
0.0,
)
)
if value > 0.0 and reference > 0.0:
smoothing_argument = (
12.0
* abs(value / reference)
* log(effective_ratio)
/ log(accuracy)
)
value *= tanh(max(smoothing_argument, 0.0))
return value
def target_flow(mass_flow: float) -> float:
reynolds = self.reynolds_number(mass_flow, T_up)
friction = self.friction_factor(reynolds)
flow_coefficient = sqrt(
self.diam / (resistance_length * friction)
)
return (
flow_coefficient
* self.area
* p_up
* mass_flow_parameter(pressure_ratio)
/ sqrt(T_up)
)
flow_coefficient = sqrt(self.diam / (resistance_length * 0.02))
magnitude = (
flow_coefficient
* self.area
* p_up
* mass_flow_parameter(pressure_ratio)
/ sqrt(T_up)
)
for _iteration in range(16):
next_magnitude = target_flow(magnitude)
if abs(next_magnitude - magnitude) <= max(
1.0e-12,
abs(magnitude) * 1.0e-9,
):
return next_magnitude
magnitude = 0.5 * (magnitude + next_magnitude)
return magnitude
def mass_flow(self, p_1: float, p_2: float, temperature: float) -> float:
if p_1 == p_2:
if isclose(p_1, p_2, rel_tol=0.0, abs_tol=1.0e-8):
return 0.0
pressure_difference = p_1 - p_2
upstream_pressure = max(p_1, p_2, 1.0)
density = max(self.medium.density(upstream_pressure, temperature), 1.0e-12)
magnitude = self._mass_flow_for_pressure_drop(
abs(pressure_difference),
density=density,
temperature=temperature,
upstream_temperature = max(float(temperature), 1.0)
resistance_length = getattr(self, "resistance_length", self.le)
magnitude = self._one_way_pn2pipefr_mass_flow(
upstream_pressure=max(p_1, p_2),
downstream_pressure=min(p_1, p_2),
upstream_temperature=upstream_temperature,
resistance_length=resistance_length,
)
return magnitude if pressure_difference > 0.0 else -magnitude
@@ -1115,7 +1225,7 @@ class AmesimPnl0003(DynamicComponent):
while self.darcy_pressure_drop(upper, density=density, temperature=temperature) < pressure_drop:
upper *= 10.0
if upper > 1.0e3:
raise ValueError("unable to bracket PNL0003 resistance flow")
return 1.0e3
lower = 0.0
for _ in range(48):
middle = 0.5 * (lower + upper)
@@ -1129,7 +1239,7 @@ class AmesimPnl0003(DynamicComponent):
port_1 = self._properties(self.state_1)
port_2 = self._properties(self.state_2)
pressure_difference = port_1.p - port_2.p
if pressure_difference == 0.0:
if isclose(port_1.p, port_2.p, rel_tol=1.0e-7, abs_tol=1.0e-9):
return 0.0
upstream = port_1 if pressure_difference > 0.0 else port_2
magnitude = self._mass_flow_for_pressure_drop(