接入AMESim help文档与PNVO流量诊断
This commit is contained in:
1 parent
f0f8f40c7a
commit
84d1675292
17 files changed
+450
-7
No files matched your search
@@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
import argparse
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import UTC, datetime
|
||||
from math import nextafter
|
||||
from math import nextafter, sqrt
|
||||
from pathlib import Path
|
||||
|
||||
from PythonModels.core.solver import SolveIVPConfig, integrate_ode
|
||||
@@ -27,6 +27,7 @@ from PythonModels.systems.test_mql import (
|
||||
TestMqlSimulationResult,
|
||||
TestMqlSystem,
|
||||
)
|
||||
from PythonModels.systems.test_mql_pneumatic import AMESIM_REFERENCE_PRESSURE_PA
|
||||
|
||||
|
||||
DEFAULT_FULL_STATE_COMPARISON_DATA_PATHS = (
|
||||
@@ -265,6 +266,45 @@ class TestMqlPnvoEventWindowSegmentDiagnostic:
|
||||
message: str
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TestMqlPnl0001PressureLossCalibrationDiagnostic:
|
||||
line_alias: str
|
||||
chamber_alias: str
|
||||
time_s: float
|
||||
amesim_cm: float
|
||||
amesim_dm1_g_s: float
|
||||
amesim_mass_flow_magnitude_kg_s: float
|
||||
amesim_line_gauge_pressure_pa: float
|
||||
amesim_chamber_gauge_pressure_pa: float
|
||||
amesim_line_temperature_k: float
|
||||
amesim_pressure_drop_pa: float
|
||||
current_darcy_pressure_drop_pa: float
|
||||
pressure_drop_multiplier: float
|
||||
amesim_linear_conductance_kg_s_sqrt_k_per_pa: float
|
||||
python_linear_conductance_kg_s_sqrt_k_per_pa: float
|
||||
python_to_amesim_linear_conductance_ratio: float
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TestMqlPnvoFlowParameterDiagnostic:
|
||||
orifice_alias: str
|
||||
time_s: float
|
||||
amesim_cm: float
|
||||
amesim_dm2_g_s: float
|
||||
amesim_opening: float
|
||||
amesim_gas_velocity_m_s: float
|
||||
python_opening: float
|
||||
python_flow_coefficient: float
|
||||
python_effective_area_m2: float
|
||||
python_line_pressure_pa: float
|
||||
python_boundary_pressure_pa: float
|
||||
python_upstream_pressure_pa: float
|
||||
python_upstream_temperature_k: float
|
||||
python_mass_flow_kg_s: float
|
||||
python_cm: float
|
||||
python_to_amesim_cm_ratio: float
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TestMqlPnvoEventWindowSampleDiagnostic:
|
||||
time_s: float
|
||||
@@ -274,6 +314,12 @@ class TestMqlPnvoEventWindowSampleDiagnostic:
|
||||
pnl0001_rhs_diagnostics: tuple[TestMqlPnl0001LineRhsDiagnostic, ...] = field(
|
||||
default_factory=tuple
|
||||
)
|
||||
pnl0001_pressure_loss_diagnostics: tuple[
|
||||
TestMqlPnl0001PressureLossCalibrationDiagnostic, ...
|
||||
] = field(default_factory=tuple)
|
||||
pnvo_flow_parameter_diagnostics: tuple[
|
||||
TestMqlPnvoFlowParameterDiagnostic, ...
|
||||
] = field(default_factory=tuple)
|
||||
|
||||
def abs_error(self, data_path: str) -> float:
|
||||
return abs(
|
||||
@@ -509,6 +555,166 @@ def format_test_mql_pnvo_event_boundary_summary(
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def _pnl0001_pressure_loss_calibration_diagnostic(
|
||||
*,
|
||||
closure: object,
|
||||
amesim_results: AmesimResults,
|
||||
python_values_by_data_path: dict[str, float],
|
||||
line_alias: str,
|
||||
chamber_alias: str,
|
||||
time_s: float,
|
||||
) -> TestMqlPnl0001PressureLossCalibrationDiagnostic:
|
||||
if line_alias != "pneumatic_69" or chamber_alias != "pn_c1_8":
|
||||
raise KeyError(f"Unsupported PNL0001 pressure-loss diagnostic: {line_alias}")
|
||||
line = closure.pneumatic_closure.components.p4_port3_remote_primary_line
|
||||
|
||||
def amesim_value(data_path: str) -> float:
|
||||
return interpolate_series_value(
|
||||
amesim_results.times,
|
||||
amesim_results.series(data_path),
|
||||
time_s,
|
||||
)
|
||||
|
||||
amesim_cm = amesim_value(f"cm@{line_alias}")
|
||||
amesim_dm1_g_s = amesim_value(f"dm1@{line_alias}")
|
||||
amesim_line_gauge_pressure_pa = amesim_value(f"p2@{line_alias}")
|
||||
amesim_chamber_gauge_pressure_pa = amesim_value(f"press@{chamber_alias}")
|
||||
amesim_line_temperature_k = amesim_value(f"t2@{line_alias}")
|
||||
mass_flow_magnitude_kg_s = abs(amesim_dm1_g_s) * 1.0e-3
|
||||
amesim_pressure_drop_pa = abs(
|
||||
amesim_line_gauge_pressure_pa - amesim_chamber_gauge_pressure_pa
|
||||
)
|
||||
current_darcy_pressure_drop_pa = abs(
|
||||
line.darcy_pressure_drop_for_state(
|
||||
mass_flow_kg_s=mass_flow_magnitude_kg_s,
|
||||
pressure_pa=(
|
||||
amesim_line_gauge_pressure_pa + AMESIM_REFERENCE_PRESSURE_PA
|
||||
),
|
||||
temperature_k=amesim_line_temperature_k,
|
||||
)
|
||||
)
|
||||
if current_darcy_pressure_drop_pa > 0.0:
|
||||
pressure_drop_multiplier = (
|
||||
amesim_pressure_drop_pa / current_darcy_pressure_drop_pa
|
||||
)
|
||||
else:
|
||||
pressure_drop_multiplier = (
|
||||
float("inf") if amesim_pressure_drop_pa > 0.0 else 1.0
|
||||
)
|
||||
amesim_linear_conductance = _pnl0001_linear_conductance(
|
||||
dm1_g_s=amesim_dm1_g_s,
|
||||
temperature_k=amesim_line_temperature_k,
|
||||
pressure_drop_pa=amesim_pressure_drop_pa,
|
||||
)
|
||||
python_pressure_drop_pa = abs(
|
||||
python_values_by_data_path[f"p2@{line_alias}"]
|
||||
- python_values_by_data_path[f"press@{chamber_alias}"]
|
||||
)
|
||||
python_linear_conductance = _pnl0001_linear_conductance(
|
||||
dm1_g_s=python_values_by_data_path[f"dm1@{line_alias}"],
|
||||
temperature_k=python_values_by_data_path[f"t2@{line_alias}"],
|
||||
pressure_drop_pa=python_pressure_drop_pa,
|
||||
)
|
||||
if amesim_linear_conductance > 0.0:
|
||||
conductance_ratio = python_linear_conductance / amesim_linear_conductance
|
||||
else:
|
||||
conductance_ratio = (
|
||||
float("inf") if python_linear_conductance > 0.0 else 1.0
|
||||
)
|
||||
return TestMqlPnl0001PressureLossCalibrationDiagnostic(
|
||||
line_alias=line_alias,
|
||||
chamber_alias=chamber_alias,
|
||||
time_s=time_s,
|
||||
amesim_cm=amesim_cm,
|
||||
amesim_dm1_g_s=amesim_dm1_g_s,
|
||||
amesim_mass_flow_magnitude_kg_s=mass_flow_magnitude_kg_s,
|
||||
amesim_line_gauge_pressure_pa=amesim_line_gauge_pressure_pa,
|
||||
amesim_chamber_gauge_pressure_pa=amesim_chamber_gauge_pressure_pa,
|
||||
amesim_line_temperature_k=amesim_line_temperature_k,
|
||||
amesim_pressure_drop_pa=amesim_pressure_drop_pa,
|
||||
current_darcy_pressure_drop_pa=current_darcy_pressure_drop_pa,
|
||||
pressure_drop_multiplier=pressure_drop_multiplier,
|
||||
amesim_linear_conductance_kg_s_sqrt_k_per_pa=(
|
||||
amesim_linear_conductance
|
||||
),
|
||||
python_linear_conductance_kg_s_sqrt_k_per_pa=(
|
||||
python_linear_conductance
|
||||
),
|
||||
python_to_amesim_linear_conductance_ratio=conductance_ratio,
|
||||
)
|
||||
|
||||
|
||||
def _pnl0001_linear_conductance(
|
||||
*,
|
||||
dm1_g_s: float,
|
||||
temperature_k: float,
|
||||
pressure_drop_pa: float,
|
||||
) -> float:
|
||||
if temperature_k <= 0.0:
|
||||
raise ValueError("temperature_k must be positive")
|
||||
if pressure_drop_pa <= 0.0:
|
||||
return 0.0
|
||||
return abs(dm1_g_s) * 1.0e-3 * sqrt(temperature_k) / pressure_drop_pa
|
||||
|
||||
|
||||
def _pnvo_flow_parameter_diagnostic(
|
||||
*,
|
||||
closure: object,
|
||||
amesim_results: AmesimResults,
|
||||
state_vector: list[float],
|
||||
orifice_alias: str,
|
||||
time_s: float,
|
||||
) -> TestMqlPnvoFlowParameterDiagnostic:
|
||||
if orifice_alias != "pn_morifice_1":
|
||||
raise KeyError(f"Unsupported PNVO flow parameter diagnostic: {orifice_alias}")
|
||||
snapshot = closure.snapshot_at(time_s, state_vector).pneumatic
|
||||
orifice = closure.pneumatic_closure.components.p4_port3_remote_orifice
|
||||
if orifice.name != orifice_alias:
|
||||
raise KeyError(f"Unexpected PNVO diagnostic orifice: {orifice.name}")
|
||||
line_properties = snapshot.p4_port3_remote_orifice_line_port_2
|
||||
boundary_properties = snapshot.p4_port3_remote_primary_line
|
||||
upstream_properties = (
|
||||
line_properties if line_properties.p >= boundary_properties.p else boundary_properties
|
||||
)
|
||||
python_mass_flow_kg_s = snapshot.p4_port3_remote_orifice_to_node_flow
|
||||
denominator = (
|
||||
orifice.flow_coefficient * orifice.effective_area * upstream_properties.p
|
||||
)
|
||||
python_cm = (
|
||||
abs(python_mass_flow_kg_s) * sqrt(upstream_properties.T) / denominator
|
||||
if denominator > 0.0 and upstream_properties.T > 0.0
|
||||
else 0.0
|
||||
)
|
||||
|
||||
def amesim_value(data_path: str) -> float:
|
||||
return interpolate_series_value(
|
||||
amesim_results.times,
|
||||
amesim_results.series(data_path),
|
||||
time_s,
|
||||
)
|
||||
|
||||
amesim_cm = amesim_value(f"cm@{orifice_alias}")
|
||||
cm_ratio = python_cm / amesim_cm if amesim_cm != 0.0 else 0.0
|
||||
return TestMqlPnvoFlowParameterDiagnostic(
|
||||
orifice_alias=orifice_alias,
|
||||
time_s=time_s,
|
||||
amesim_cm=amesim_cm,
|
||||
amesim_dm2_g_s=amesim_value(f"dm2@{orifice_alias}"),
|
||||
amesim_opening=amesim_value(f"xv@{orifice_alias}"),
|
||||
amesim_gas_velocity_m_s=amesim_value(f"gasvel@{orifice_alias}"),
|
||||
python_opening=orifice.opening,
|
||||
python_flow_coefficient=orifice.flow_coefficient,
|
||||
python_effective_area_m2=orifice.effective_area,
|
||||
python_line_pressure_pa=line_properties.p,
|
||||
python_boundary_pressure_pa=boundary_properties.p,
|
||||
python_upstream_pressure_pa=upstream_properties.p,
|
||||
python_upstream_temperature_k=upstream_properties.T,
|
||||
python_mass_flow_kg_s=python_mass_flow_kg_s,
|
||||
python_cm=python_cm,
|
||||
python_to_amesim_cm_ratio=cm_ratio,
|
||||
)
|
||||
|
||||
|
||||
def run_test_mql_pnvo_event_window_diagnostic(
|
||||
config: TestMqlFullStateComparisonScriptConfig | None = None,
|
||||
*,
|
||||
@@ -679,6 +885,25 @@ def run_test_mql_pnvo_event_window_diagnostic(
|
||||
time_s=sample_time,
|
||||
),
|
||||
)
|
||||
pnl0001_pressure_loss_diagnostics = (
|
||||
_pnl0001_pressure_loss_calibration_diagnostic(
|
||||
closure=closure,
|
||||
amesim_results=amesim_results,
|
||||
python_values_by_data_path=python_sample_values,
|
||||
line_alias="pneumatic_69",
|
||||
chamber_alias="pn_c1_8",
|
||||
time_s=sample_time,
|
||||
),
|
||||
)
|
||||
pnvo_flow_parameter_diagnostics = (
|
||||
_pnvo_flow_parameter_diagnostic(
|
||||
closure=closure,
|
||||
amesim_results=amesim_results,
|
||||
state_vector=state_vector_by_sample_time[sample_time],
|
||||
orifice_alias=orifice_alias,
|
||||
time_s=sample_time,
|
||||
),
|
||||
)
|
||||
sample_diagnostics.append(
|
||||
TestMqlPnvoEventWindowSampleDiagnostic(
|
||||
time_s=sample_time,
|
||||
@@ -686,6 +911,8 @@ def run_test_mql_pnvo_event_window_diagnostic(
|
||||
python_values_by_data_path=python_sample_values,
|
||||
amesim_values_by_data_path=amesim_sample_values,
|
||||
pnl0001_rhs_diagnostics=pnl0001_rhs_diagnostics,
|
||||
pnl0001_pressure_loss_diagnostics=pnl0001_pressure_loss_diagnostics,
|
||||
pnvo_flow_parameter_diagnostics=pnvo_flow_parameter_diagnostics,
|
||||
)
|
||||
)
|
||||
python_values = closure.data_path_values(
|
||||
@@ -749,6 +976,35 @@ def format_test_mql_pnvo_event_window_summary(
|
||||
f"dm_dt={rhs.mass_derivative_kg_s}, "
|
||||
f"dU_dt={rhs.energy_derivative_w}"
|
||||
)
|
||||
for pressure_loss in sample.pnl0001_pressure_loss_diagnostics:
|
||||
lines.append(
|
||||
f" - pressure_loss@{pressure_loss.line_alias}: "
|
||||
f"cm={pressure_loss.amesim_cm}, "
|
||||
f"amesim_dm1={pressure_loss.amesim_dm1_g_s}, "
|
||||
f"amesim_dp={pressure_loss.amesim_pressure_drop_pa}, "
|
||||
f"darcy_dp={pressure_loss.current_darcy_pressure_drop_pa}, "
|
||||
f"dp_multiplier={pressure_loss.pressure_drop_multiplier}, "
|
||||
f"amesim_linear_k="
|
||||
f"{pressure_loss.amesim_linear_conductance_kg_s_sqrt_k_per_pa}, "
|
||||
f"python_linear_k="
|
||||
f"{pressure_loss.python_linear_conductance_kg_s_sqrt_k_per_pa}, "
|
||||
f"linear_k_ratio="
|
||||
f"{pressure_loss.python_to_amesim_linear_conductance_ratio}"
|
||||
)
|
||||
for flow_parameter in sample.pnvo_flow_parameter_diagnostics:
|
||||
lines.append(
|
||||
f" - flow_parameter@{flow_parameter.orifice_alias}: "
|
||||
f"amesim_cm={flow_parameter.amesim_cm}, "
|
||||
f"python_cm={flow_parameter.python_cm}, "
|
||||
f"cm_ratio={flow_parameter.python_to_amesim_cm_ratio}, "
|
||||
f"amesim_dm2={flow_parameter.amesim_dm2_g_s}, "
|
||||
f"python_m={flow_parameter.python_mass_flow_kg_s}, "
|
||||
f"opening={flow_parameter.python_opening}, "
|
||||
f"effective_area={flow_parameter.python_effective_area_m2}, "
|
||||
f"upstream_p={flow_parameter.python_upstream_pressure_pa}, "
|
||||
f"upstream_t={flow_parameter.python_upstream_temperature_k}, "
|
||||
f"amesim_gasvel={flow_parameter.amesim_gas_velocity_m_s}"
|
||||
)
|
||||
lines.append("Final comparison:")
|
||||
for data_path in diagnostic.data_paths:
|
||||
lines.append(
|
||||
|
||||
Reference in new issue
Block a user