接入PNL0001事件窗口RHS诊断

This commit is contained in:
huojiarong committed 2026-07-22 04:21:38 +00:00
1 parent 2120901909
commit f0f8f40c7a
4 files changed
+597 -11

No files matched your search

@@ -5,13 +5,19 @@ import unittest
from pathlib import Path
from PythonModels.core.solver import SolveIVPConfig
from PythonModels.systems.test_mql import TestMqlPnl0001LineRhsDiagnostic
from PythonModels.scripts.run_test_mql_full_state_comparison import (
TestMqlFullStateComparisonExecutionConfig,
TestMqlFullStateComparisonPathConfig,
TestMqlFullStateComparisonScriptConfig,
TestMqlPnvoEventBoundaryDiagnostic,
TestMqlPnvoEventWindowDiagnostic,
TestMqlPnvoEventWindowSampleDiagnostic,
TestMqlPnvoEventWindowSegmentDiagnostic,
format_test_mql_full_state_comparison_summary,
format_test_mql_pnvo_event_boundary_summary,
format_test_mql_pnvo_event_window_summary,
run_test_mql_full_state_comparison,
)
@@ -169,6 +175,109 @@ class RunTestMqlFullStateComparisonScriptTests(unittest.TestCase):
self.assertIn("Observation side: right-continuous STEP0 opening", summary)
self.assertTrue(summary.endswith("\n"))
def test_formats_pnvo_event_window_diagnostic_with_samples(self) -> None:
data_paths = (
"press@pn_c1_8",
"temp@pn_c1_8",
"vol@pn_c1_8",
"mgas1@pn_c1_8",
"p2@pneumatic_69",
"t2@pneumatic_69",
"mgas@pneumatic_69",
"re@pneumatic_69",
"v@pneumatic_69",
"ff@pneumatic_69",
"dm1@pneumatic_69",
"xv@pn_morifice_1",
"dm2@pn_morifice_1",
)
sample = TestMqlPnvoEventWindowSampleDiagnostic(
time_s=0.05,
data_paths=data_paths,
python_values_by_data_path={
"press@pn_c1_8": 219127.9,
"temp@pn_c1_8": 372.3,
"vol@pn_c1_8": 15000.0,
"mgas1@pn_c1_8": 5.46,
"p2@pneumatic_69": 93250.0,
"t2@pneumatic_69": 293.15,
"mgas@pneumatic_69": 0.53,
"re@pneumatic_69": 1.41e6,
"v@pneumatic_69": 832.0,
"ff@pneumatic_69": 0.0243,
"dm1@pneumatic_69": 443.2,
"xv@pn_morifice_1": 1.0,
"dm2@pn_morifice_1": 463.7,
},
amesim_values_by_data_path={
"press@pn_c1_8": 187060.0,
"temp@pn_c1_8": 296.1,
"vol@pn_c1_8": 15000.0,
"mgas1@pn_c1_8": 5.47,
"p2@pneumatic_69": 1484689.6,
"t2@pneumatic_69": 296.1,
"mgas@pneumatic_69": 0.81,
"re@pneumatic_69": 1.35e6,
"v@pneumatic_69": 519.8,
"ff@pneumatic_69": 0.0241,
"dm1@pneumatic_69": 419.9,
"xv@pn_morifice_1": 1.0,
"dm2@pn_morifice_1": 456.8,
},
pnl0001_rhs_diagnostics=(
TestMqlPnl0001LineRhsDiagnostic(
line_alias="pneumatic_69",
chamber_alias="pn_c1_8",
line_pressure_pa=1034250.0,
line_temperature_k=293.15,
chamber_pressure_pa=320427.9,
chamber_temperature_k=379.9,
chamber_to_line_flow_kg_s=-0.4432,
node_to_line_flow_kg_s=0.4210,
mass_derivative_kg_s=-0.0222,
port_1_energy_flow_w=-404000.0,
port_2_energy_flow_w=384000.0,
thermal_energy_flow_w=0.0,
energy_derivative_w=-20000.0,
),
),
)
diagnostic = TestMqlPnvoEventWindowDiagnostic(
orifice_alias="pn_morifice_1",
event_time_s=0.04,
final_time_s=0.05,
data_paths=data_paths,
segment_diagnostics=(
TestMqlPnvoEventWindowSegmentDiagnostic(
t_start=0.048,
t_stop=0.05,
method="BDF",
rtol=1.0e-5,
atol=1.0e-8,
max_step=1.0e-5,
rhs_evaluations=8154,
success=True,
message="success",
),
),
sample_diagnostics=(sample,),
python_values_by_data_path=sample.python_values_by_data_path,
amesim_values_by_data_path=sample.amesim_values_by_data_path,
)
summary = format_test_mql_pnvo_event_window_summary(diagnostic)
self.assertAlmostEqual(diagnostic.abs_error("dm2@pn_morifice_1"), 6.9)
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.assertIn("rhs=8154", summary)
self.assertIn("rhs@pneumatic_69", summary)
self.assertIn("dm_dt=-0.0222", summary)
self.assertIn("Final comparison:", summary)
self.assertTrue(summary.endswith("\n"))
def test_full_state_script_can_skip_artifact_files(self) -> None:
with tempfile.TemporaryDirectory() as tmpdir:
output_dir = Path(tmpdir)
+53
View File
@@ -713,6 +713,37 @@ class TestMqlPn3P4NodeChamberSegmentTests(unittest.TestCase):
+ diagnostic.thermal_energy_flow_w,
)
def test_full_state_closure_diagnoses_pnl0001_line_rhs_terms(self) -> None:
closure = self.system.full_state_closure_from_spec(
self.spec,
inlet_node_pressure_pa=15.31e6,
resistance_boundary_pressure_pa=15.29e6,
)
state = closure.initial_state_vector()
diagnostic = closure.pnl0001_line_rhs_diagnostic(
line_alias="pneumatic_69",
state_vector=state,
time_s=0.04,
)
rhs = closure.rhs_at(0.04, state)
self.assertEqual(diagnostic.chamber_alias, "pn_c1_8")
self.assertGreater(diagnostic.node_to_line_flow_kg_s, 0.0)
self.assertAlmostEqual(
diagnostic.mass_derivative_kg_s,
diagnostic.chamber_to_line_flow_kg_s
+ diagnostic.node_to_line_flow_kg_s,
)
self.assertAlmostEqual(diagnostic.mass_derivative_kg_s, rhs[44])
self.assertAlmostEqual(diagnostic.energy_derivative_w, rhs[45])
self.assertAlmostEqual(
diagnostic.energy_derivative_w,
diagnostic.port_1_energy_flow_w
+ diagnostic.port_2_energy_flow_w
+ diagnostic.thermal_energy_flow_w,
)
def test_full_state_closure_applies_step_controls_to_variable_orifices(self) -> None:
closure = self.system.full_state_closure_from_spec(
self.spec,
@@ -771,6 +802,7 @@ class TestMqlPn3P4NodeChamberSegmentTests(unittest.TestCase):
data_paths = (
"press@pn_c1_8",
"vol@pn_c1_8",
"mgas1@pn_c1_8",
"vol1@pn_brp2_8",
"vvol1@pn_brp2_8",
"x1@mass_friction_endstops_10",
@@ -779,6 +811,12 @@ class TestMqlPn3P4NodeChamberSegmentTests(unittest.TestCase):
"x1@mass_friction_endstops_18",
"v1@mass_friction_endstops_18",
"acc1@mass_friction_endstops_18",
"p2@pneumatic_69",
"t2@pneumatic_69",
"mgas@pneumatic_69",
"re@pneumatic_69",
"v@pneumatic_69",
"ff@pneumatic_69",
"dm1@pneumatic_69",
"xv@pn_morifice_1",
"dm2@pn_morifice_1",
@@ -804,6 +842,11 @@ class TestMqlPn3P4NodeChamberSegmentTests(unittest.TestCase):
self.assertEqual(len(comparison.metrics), len(data_paths))
self.assertAlmostEqual(result.series["press@pn_c1_8"][0], -1300.0)
self.assertAlmostEqual(result.series["vol@pn_c1_8"][0], 15000.0)
self.assertAlmostEqual(
result.series["mgas1@pn_c1_8"][0],
self.amesim_results.series("mgas1@pn_c1_8")[0],
delta=1.0e-4,
)
self.assertAlmostEqual(result.series["vol1@pn_brp2_8"][0], 0.0)
self.assertAlmostEqual(result.series["vvol1@pn_brp2_8"][0], 0.0)
self.assertAlmostEqual(result.series["x1@mass_friction_endstops_10"][0], 0.0)
@@ -813,6 +856,16 @@ class TestMqlPn3P4NodeChamberSegmentTests(unittest.TestCase):
-0.8167936695810917,
)
self.assertAlmostEqual(result.series["acc1@mass_friction_endstops_18"][0], 0.0)
self.assertAlmostEqual(result.series["p2@pneumatic_69"][0], -1300.0)
self.assertAlmostEqual(result.series["t2@pneumatic_69"][0], 293.15)
self.assertAlmostEqual(
result.series["mgas@pneumatic_69"][0],
self.amesim_results.series("mgas@pneumatic_69")[0],
delta=1.0e-5,
)
self.assertAlmostEqual(result.series["re@pneumatic_69"][0], 0.0)
self.assertAlmostEqual(result.series["v@pneumatic_69"][0], 0.0)
self.assertGreater(result.series["ff@pneumatic_69"][0], 0.0)
self.assertAlmostEqual(result.series["dm1@pneumatic_69"][0], 0.0)
self.assertAlmostEqual(result.series["xv@pn_morifice_1"][0], 0.0)
self.assertAlmostEqual(result.series["dm2@pn_morifice_1"][0], 0.0)