完善 PNL00R 摩擦模型与八路回归
This commit is contained in:
1 parent
684d28752a
commit
f725f038b6
10 files changed
+498
-98
No files matched your search
@@ -54,6 +54,22 @@ class Pnl0001DerivativeLinearization:
|
||||
|
||||
_MAX_REPORTED_FRICTION_FACTOR = 64_000_000.0
|
||||
|
||||
# ``pn2pipefr`` blends the laminar and turbulent friction branches over a
|
||||
# much wider Reynolds range than the former hard 2300..4000 interpolation.
|
||||
# These constants are a uniform-Re least-squares fit to the unchanged
|
||||
# Simcenter Amesim 2404 test_mql result for PNL00R/PNL0001/PNL0003 at both
|
||||
# rr=0.045/14 and rr=0.045/20. The shifted Hill exponent is greater than 2,
|
||||
# so its zero-valued join to the laminar branch is C2 continuous.
|
||||
_PN2PIPEFR_TRANSITION_START_REYNOLDS = 89.96829989
|
||||
_PN2PIPEFR_TRANSITION_SCALE_REYNOLDS = 2741.96700831
|
||||
_PN2PIPEFR_TRANSITION_SHARPNESS = 8.37293695
|
||||
|
||||
# PNL00R keeps the exact closed-form laminar solve where the fitted
|
||||
# transition contribution is below four parts per million. Extending this
|
||||
# shortcut to Re=2300 bypassed the real AMESim transition and introduced a
|
||||
# solver-visible branch point.
|
||||
_PN2PIPEFR_ANALYTIC_LAMINAR_MAX_REYNOLDS = 1000.0
|
||||
|
||||
|
||||
def _reported_friction_factor(value: float) -> float:
|
||||
return min(float(value), _MAX_REPORTED_FRICTION_FACTOR)
|
||||
@@ -75,8 +91,8 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
"""AMESim PNL00R pneumatic pipe friction resistance.
|
||||
|
||||
The public model exposes the AMESim PNL00R catalog/XML contract and uses
|
||||
an auditable Darcy-Weisbach resistance with Reynolds/roughness-dependent
|
||||
friction. Exact `pn2pipefr_` parity is left for the later model tuning pass.
|
||||
the `pn2pipefr` compressible gas relation with a Reynolds/roughness-
|
||||
dependent equivalent flow coefficient.
|
||||
"""
|
||||
|
||||
MODEL_TYPE = "amesim_pnl00r"
|
||||
@@ -244,7 +260,7 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
if reynolds_number <= 0.0:
|
||||
return 64_000_000.0
|
||||
laminar = 64.0 / reynolds_number
|
||||
if reynolds_number <= 2300.0:
|
||||
if reynolds_number <= _PN2PIPEFR_TRANSITION_START_REYNOLDS:
|
||||
return laminar
|
||||
|
||||
# pn2pipefr does not apply the fully rough correction at every
|
||||
@@ -274,10 +290,13 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
turbulent = smooth_turbulent + roughness_weight * (
|
||||
fully_rough - smooth_turbulent
|
||||
)
|
||||
if reynolds_number >= 4000.0:
|
||||
return turbulent
|
||||
fraction = (reynolds_number - 2300.0) / 1700.0
|
||||
return laminar + fraction**0.58 * (turbulent - laminar)
|
||||
transition_coordinate = (
|
||||
(reynolds_number - _PN2PIPEFR_TRANSITION_START_REYNOLDS)
|
||||
/ _PN2PIPEFR_TRANSITION_SCALE_REYNOLDS
|
||||
)
|
||||
transition_power = transition_coordinate**_PN2PIPEFR_TRANSITION_SHARPNESS
|
||||
transition_weight = transition_power / (1.0 + transition_power)
|
||||
return laminar + transition_weight * (turbulent - laminar)
|
||||
|
||||
def darcy_pressure_drop(
|
||||
self,
|
||||
@@ -329,13 +348,17 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
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)
|
||||
upstream_temperature = self._port_temperature("port_1" if pressure_difference > 0.0 else "port_2")
|
||||
density = max(self.medium.density(upstream_pressure, upstream_temperature), 1.0e-12)
|
||||
magnitude = self._mass_flow_for_pressure_drop(
|
||||
abs(pressure_difference),
|
||||
density=density,
|
||||
temperature=upstream_temperature,
|
||||
upstream_temperature = self._port_temperature(
|
||||
"port_1" if pressure_difference > 0.0 else "port_2"
|
||||
)
|
||||
magnitude = AmesimPnl0001._one_way_pn2pipefr_mass_flow(
|
||||
self,
|
||||
upstream_pressure=max(p_1, p_2),
|
||||
downstream_pressure=min(p_1, p_2),
|
||||
upstream_temperature=upstream_temperature,
|
||||
resistance_length=self.le,
|
||||
max_iterations=64,
|
||||
analytic_laminar=True,
|
||||
)
|
||||
return magnitude if pressure_difference > 0.0 else -magnitude
|
||||
|
||||
@@ -347,17 +370,19 @@ class AmesimPnl00r(AlgebraicComponent):
|
||||
)
|
||||
density = max(self.medium.density(upstream_pressure, upstream_temperature), 1.0e-12)
|
||||
reynolds = self.reynolds_number(m_flow, upstream_temperature)
|
||||
friction = self.friction_factor(reynolds)
|
||||
flow_coefficient = sqrt(self.diam / (self.le * friction))
|
||||
velocity = m_flow / (density * self.area)
|
||||
cm = (
|
||||
abs(m_flow)
|
||||
* sqrt(upstream_temperature)
|
||||
/ max(self.area * upstream_pressure, 1.0e-18)
|
||||
/ max(flow_coefficient * self.area * upstream_pressure, 1.0e-18)
|
||||
)
|
||||
return {
|
||||
"re": reynolds,
|
||||
"cm": cm,
|
||||
"v": velocity,
|
||||
"ff": _reported_friction_factor(self.friction_factor(reynolds)),
|
||||
"ff": _reported_friction_factor(friction),
|
||||
}
|
||||
|
||||
def pressure_flow_equation_values(self) -> tuple[float, ...]:
|
||||
@@ -754,6 +779,8 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
downstream_pressure: float,
|
||||
upstream_temperature: float,
|
||||
resistance_length: float,
|
||||
max_iterations: int = 16,
|
||||
analytic_laminar: bool = False,
|
||||
) -> float:
|
||||
"""AMESim pn2pipefr-style compressible friction flow."""
|
||||
|
||||
@@ -824,6 +851,18 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
value *= tanh(max(smoothing_argument, 0.0))
|
||||
return value
|
||||
|
||||
if analytic_laminar:
|
||||
flow_parameter = mass_flow_parameter(pressure_ratio)
|
||||
viscosity = self._dynamic_viscosity(T_up)
|
||||
laminar_mass_flow = (
|
||||
self.area * p_up * flow_parameter
|
||||
) ** 2 / (16.0 * pi * viscosity * resistance_length * T_up)
|
||||
if (
|
||||
self.reynolds_number(laminar_mass_flow, T_up)
|
||||
<= _PN2PIPEFR_ANALYTIC_LAMINAR_MAX_REYNOLDS
|
||||
):
|
||||
return laminar_mass_flow
|
||||
|
||||
def target_flow(mass_flow: float) -> float:
|
||||
reynolds = self.reynolds_number(mass_flow, T_up)
|
||||
friction = self.friction_factor(reynolds)
|
||||
@@ -846,7 +885,7 @@ class AmesimPnl0001(ThermodynamicVolumeComponent):
|
||||
* mass_flow_parameter(pressure_ratio)
|
||||
/ sqrt(T_up)
|
||||
)
|
||||
for _iteration in range(16):
|
||||
for _iteration in range(max_iterations):
|
||||
next_magnitude = target_flow(magnitude)
|
||||
if abs(next_magnitude - magnitude) <= max(
|
||||
1.0e-12,
|
||||
|
||||
Reference in new issue
Block a user