修正test_mql事件窗口插值诊断

This commit is contained in:
huojiarong committed 2026-07-26 14:48:38 +00:00
1 parent 331435e78a
commit 01b606df30
5 files changed
+103 -3

No files matched your search

@@ -70,6 +70,24 @@ class AmesimPneumaticGas:
)
)
def pressure_transport_enthalpy(
self,
pressure: float,
temperature: float,
reference_pressure: float = 101_300.0,
reference_temperature: float = 298.15,
) -> float:
"""Convert AMESim reference enthalpy to the absolute-energy state basis."""
return (
self.pressure_reference_enthalpy(
pressure,
temperature,
reference_pressure,
reference_temperature,
)
+ self.cp * reference_temperature
)
def temperature_from_internal_energy(self, specific_internal_energy: float) -> float:
if self.cv <= 0.0:
raise ValueError("cv must be positive.")
@@ -1,6 +1,7 @@
from __future__ import annotations
import argparse
from bisect import bisect_left
from dataclasses import dataclass, field
from datetime import UTC, datetime
from math import nextafter, sqrt
@@ -492,6 +493,8 @@ class TestMqlPnvoEventWindowSampleDiagnostic:
data_paths: tuple[str, ...]
python_values_by_data_path: dict[str, float]
amesim_values_by_data_path: dict[str, float]
amesim_sample_left_time_s: float
amesim_sample_right_time_s: float
pnl0001_rhs_diagnostics: tuple[TestMqlPnl0001LineRhsDiagnostic, ...] = field(
default_factory=tuple
)
@@ -517,6 +520,10 @@ class TestMqlPnvoEventWindowSampleDiagnostic:
TestMqlPnch012EnergyEquationDiagnostic, ...
] = field(default_factory=tuple)
@property
def amesim_values_are_interpolated(self) -> bool:
return self.amesim_sample_left_time_s != self.amesim_sample_right_time_s
def abs_error(self, data_path: str) -> float:
return abs(
self.python_values_by_data_path[data_path]
@@ -929,6 +936,27 @@ def _series_one_sided_differences_at(
return backward, forward
def _series_sample_bracket(
*,
times: tuple[float, ...] | list[float],
time_s: float,
) -> tuple[float, float]:
if not times:
raise ValueError("at least one sample time is required")
index = bisect_left(times, time_s)
tolerance = 1.0e-12 * max(1.0, abs(time_s))
for candidate_index in (index - 1, index):
if 0 <= candidate_index < len(times):
candidate_time = times[candidate_index]
if abs(candidate_time - time_s) <= tolerance:
return candidate_time, candidate_time
if index <= 0:
return times[0], times[0]
if index >= len(times):
return times[-1], times[-1]
return times[index - 1], times[index]
def _reference_enthalpy_flow_for_node_port(
*,
gas: AmesimPneumaticGas,
@@ -2157,12 +2185,18 @@ def run_test_mql_pnvo_event_window_diagnostic(
time_s=sample_time,
),
)
(
amesim_sample_left_time_s,
amesim_sample_right_time_s,
) = _series_sample_bracket(times=amesim_results.times, time_s=sample_time)
sample_diagnostics.append(
TestMqlPnvoEventWindowSampleDiagnostic(
time_s=sample_time,
data_paths=data_paths,
python_values_by_data_path=python_sample_values,
amesim_values_by_data_path=amesim_sample_values,
amesim_sample_left_time_s=amesim_sample_left_time_s,
amesim_sample_right_time_s=amesim_sample_right_time_s,
pnl0001_rhs_diagnostics=pnl0001_rhs_diagnostics,
pnl0001_pressure_loss_diagnostics=pnl0001_pressure_loss_diagnostics,
pnvo_flow_parameter_diagnostics=pnvo_flow_parameter_diagnostics,
@@ -2224,7 +2258,17 @@ def format_test_mql_pnvo_event_window_summary(
if diagnostic.sample_diagnostics:
lines.append("Sample comparisons:")
for sample in diagnostic.sample_diagnostics:
lines.append(f" t={sample.time_s}")
if sample.amesim_values_are_interpolated:
amesim_sample_source = (
"linear-interpolation@"
f"{sample.amesim_sample_left_time_s}"
f"..{sample.amesim_sample_right_time_s}"
)
else:
amesim_sample_source = f"exact@{sample.amesim_sample_left_time_s}"
lines.append(
f" t={sample.time_s} (amesim={amesim_sample_source})"
)
for data_path in sample.data_paths:
lines.append(
f" - {data_path}: "
+11
View File
@@ -55,6 +55,17 @@ class AmesimPneumaticComponentsTest(unittest.TestCase):
delta=0.1,
)
def test_pressure_transport_enthalpy_restores_absolute_energy_offset(self) -> None:
gas = HELIUM_PNEUMATIC_GAS
pressure = 13_839_965.0
temperature = 287.7322
self.assertAlmostEqual(
gas.pressure_transport_enthalpy(pressure, temperature),
gas.pressure_reference_enthalpy(pressure, temperature)
+ gas.cp * 298.15,
)
def test_reference_temperature_from_enthalpy_rejects_non_positive_cp(self) -> None:
gas = AmesimPneumaticGas(cp=0.0, cv=3116.0)
@@ -26,6 +26,7 @@ from PythonModels.scripts.run_test_mql_full_state_comparison import (
format_test_mql_pnvo_event_boundary_summary,
format_test_mql_pnvo_event_window_summary,
run_test_mql_full_state_comparison,
_series_sample_bracket,
)
@@ -34,6 +35,23 @@ TEST_MQL_AME = REPO_ROOT / "AmesimModels" / "test_mql.ame"
class RunTestMqlFullStateComparisonScriptTests(unittest.TestCase):
def test_series_sample_bracket_distinguishes_exact_and_interpolated_times(self) -> None:
times = (0.04000000000000009, 0.050000000000000114)
exact_left, exact_right = _series_sample_bracket(
times=times,
time_s=0.04,
)
interpolated_left, interpolated_right = _series_sample_bracket(
times=times,
time_s=0.041,
)
self.assertEqual(exact_left, exact_right)
self.assertAlmostEqual(exact_left, 0.04)
self.assertAlmostEqual(interpolated_left, 0.04)
self.assertAlmostEqual(interpolated_right, 0.05)
def test_full_state_script_writes_summary_and_comparison_csv(self) -> None:
with tempfile.TemporaryDirectory() as tmpdir:
output_dir = Path(tmpdir)
@@ -231,6 +249,8 @@ class RunTestMqlFullStateComparisonScriptTests(unittest.TestCase):
"xv@pn_morifice_1": 1.0,
"dm2@pn_morifice_1": 456.8,
},
amesim_sample_left_time_s=0.05,
amesim_sample_right_time_s=0.05,
pnl0001_rhs_diagnostics=(
TestMqlPnl0001LineRhsDiagnostic(
line_alias="pneumatic_69",
@@ -497,7 +517,8 @@ class RunTestMqlFullStateComparisonScriptTests(unittest.TestCase):
self.assertAlmostEqual(sample.abs_error("press@pn_c1_8"), 32067.9)
self.assertIn("PNVO event window diagnostic (pn_morifice_1)", summary)
self.assertIn("Sample comparisons:", summary)
self.assertIn("t=0.05", summary)
self.assertFalse(sample.amesim_values_are_interpolated)
self.assertIn("t=0.05 (amesim=exact@0.05)", summary)
self.assertIn("rhs=8154", summary)
self.assertIn("rhs@pneumatic_69", summary)
self.assertIn("dm_dt=-0.0222", summary)
+7 -1
View File
@@ -8,6 +8,9 @@ from PythonModels.reporting.test_mql_orifice_observations import (
G_PER_S_TO_KG_PER_S,
build_test_mql_orifice_observation_catalog,
)
from PythonModels.systems.test_mql_pneumatic import (
TEST_MQL_PNVO001_FLOW_COEFFICIENT_MULTIPLIER,
)
REPO_ROOT = Path(__file__).resolve().parents[1]
@@ -55,7 +58,10 @@ class TestMqlOrificeObservationCatalogTests(unittest.TestCase):
last = binding.observation_at(self.amesim_results, -1)
self.assertAlmostEqual(binding.nominal_area_m2, 78.5e-6)
self.assertAlmostEqual(binding.flow_coefficient, 0.45)
self.assertAlmostEqual(
binding.flow_coefficient,
0.45 * TEST_MQL_PNVO001_FLOW_COEFFICIENT_MULTIPLIER,
)
self.assertEqual(first.opening, 0.0)
self.assertEqual(first.effective_area_m2, 0.0)
self.assertEqual(last.opening, 1.0)