Fix pneumatic node zero-flow reversal

This commit is contained in:
huojiarong committed 2026-08-17 09:24:35 +00:00
1 parent 16a7eb2d6c
commit 0fa166c8e5
3 files changed
+159 -3

No files matched your search

@@ -9,6 +9,24 @@ from app.simulation.core.medium import IdealGasMedium
from app.simulation.core.ports import PortDefinition, PortState
_REFERENCE_OUTFLOW_REGULARIZATION_RATIO = 0.05
def _regularized_inverse_outflow(flow: float, transition_flow: float) -> float:
"""Return a C1 inverse that tends to zero as a negative flow vanishes."""
if flow >= 0.0:
return 0.0
transition_flow = max(float(transition_flow), 1.0e-12)
if -flow >= transition_flow:
return 1.0 / flow
return (
flow
* (2.0 * transition_flow * transition_flow - flow * flow)
/ transition_flow**4
)
class _AmesimPneumaticNode(AlgebraicComponent):
"""Shared implementation for AMESim pneumatic junction submodels.
@@ -102,7 +120,7 @@ class _AmesimPneumaticNode(AlgebraicComponent):
else self.temperature_reference_h
)
if reference_port.m_flow < -1e-12:
if reference_port.m_flow < 0.0:
energy_without_reference = sum(
port.m_flow
* (
@@ -113,8 +131,29 @@ class _AmesimPneumaticNode(AlgebraicComponent):
for name, port in self.ports.items()
if name != self.REFERENCE_PORT
)
non_reference_flow_scale = sum(
abs(port.m_flow)
for name, port in self.ports.items()
if name != self.REFERENCE_PORT
)
transition_flow = (
_REFERENCE_OUTFLOW_REGULARIZATION_RATIO
* non_reference_flow_scale
)
# Port 2 carries AMESim's residual-energy causality. Exact
# division is singular when its outflow reverses through zero, so
# use a C1 band that matches the exact balance at its boundary and
# tends to the mixed enthalpy at zero flow.
inverse_flow = _regularized_inverse_outflow(
reference_port.m_flow,
transition_flow,
)
energy_residual_at_mixed_h = (
energy_without_reference
+ reference_port.m_flow * mixed_h
)
reference_port.h_outflow = (
-energy_without_reference / reference_port.m_flow
mixed_h - energy_residual_at_mixed_h * inverse_flow
)