From a63fda313b2d523532dd0ae2764d8d90d3f4cbfc Mon Sep 17 00:00:00 2001 From: huojiarong Date: Wed, 15 Jul 2026 10:08:53 +0000 Subject: [PATCH] =?UTF-8?q?=E6=A0=A1=E9=AA=8Ctest=5Fmql=E6=9C=BA=E6=A2=B0?= =?UTF-8?q?=E8=A7=82=E6=B5=8B=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AmesimModels/test_mql/README.md | 6 ++-- PythonModels/systems/test_mql_mechanical.py | 15 ++++++++ tests/test_test_mql_mechanical.py | 39 +++++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/AmesimModels/test_mql/README.md b/AmesimModels/test_mql/README.md index 0ee0adc..ebf1a0b 100644 --- a/AmesimModels/test_mql/README.md +++ b/AmesimModels/test_mql/README.md @@ -92,12 +92,12 @@ - 保留 AMESim alias 和对应 `Data_Path`,并把直径、刚度、阻尼、穿透距离等参数换算到 SI 单位。 - `tests/test_test_mql_mechanical.py` - - 保护机械组件数量、活塞面积、质量端止动参数、载荷质量行程限制、弹性端止动参数、机械节点端口数和单位换算。 + - 保护机械组件数量、活塞面积、质量端止动参数、载荷质量行程限制、弹性端止动参数、机械节点端口数、单位换算,以及 8 个活塞/8 个弹性端止动的 AMESim 末端样本对齐。 - `PythonModels/components/amesim_mechanical.py` - 提供 AMESim 机械侧小原语,当前覆盖 `PNRP17` 活塞腔几何和 `LSTP00A` 弹性端止动接触力。 - - 活塞腔长度、体积、体积变化率已用 `length@pn_brp2_8`、`vol1@pn_brp2_8`、`vvol1@pn_brp2_8` 的 AMESim 样本校验。 - - 端止动接触力已按 `gap@elasticendstop_8`、`f1@elasticendstop_8` 和阻尼速度样本校验。 + - 活塞腔长度、体积、体积变化率已用 `length@pn_brp2_*`、`vol1@pn_brp2_*`、`vvol1@pn_brp2_*` 的 AMESim 样本校验。 + - 端止动接触力已按 `gap@elasticendstop_*`、`f1@elasticendstop_*` 和阻尼速度样本校验。 - `tests/test_amesim_mechanical_components.py` - 保护机械原语单位换算、活塞几何、活塞体积变化率和弹性端止动接触力。 diff --git a/PythonModels/systems/test_mql_mechanical.py b/PythonModels/systems/test_mql_mechanical.py index b1dbf93..5d054bb 100644 --- a/PythonModels/systems/test_mql_mechanical.py +++ b/PythonModels/systems/test_mql_mechanical.py @@ -3,6 +3,7 @@ from __future__ import annotations from dataclasses import dataclass from PythonModels.components.amesim_mechanical import ( + AmesimElasticEndstop, AmesimPistonGeometry, circular_area, mm_to_m, @@ -31,6 +32,13 @@ class TestMqlPistonSpec: annulus_area_m2: float data_paths: tuple[str, ...] + def geometry(self) -> AmesimPistonGeometry: + return AmesimPistonGeometry( + piston_diameter_m=self.piston_diameter_m, + rod_diameter_m=self.rod_diameter_m, + zero_length_m=self.zero_displacement_m, + ) + @dataclass(frozen=True) class TestMqlMassEndstopSpec: @@ -58,6 +66,13 @@ class TestMqlElasticEndstopSpec: wire_diameter_m: float data_paths: tuple[str, ...] + def endstop(self) -> AmesimElasticEndstop: + return AmesimElasticEndstop( + contact_stiffness_n_per_m=self.contact_stiffness_n_per_m, + contact_damping_n_per_m_per_s=self.contact_damping_n_per_m_per_s, + gap0_m=self.gap_m, + ) + @dataclass(frozen=True) class TestMqlMechanicalNodeSpec: diff --git a/tests/test_test_mql_mechanical.py b/tests/test_test_mql_mechanical.py index ec52ec8..54ed555 100644 --- a/tests/test_test_mql_mechanical.py +++ b/tests/test_test_mql_mechanical.py @@ -92,6 +92,45 @@ class TestMqlMechanicalAssemblyTests(unittest.TestCase): self.assertEqual(node.sum_mode, 1) self.assertIn("dynamic_mechanical_node_alternative_2", self.assembly.aliases) + + def test_all_piston_geometry_observables_match_amesim_final_sample(self) -> None: + for alias, piston in self.assembly.pistons.items(): + with self.subTest(alias=alias): + geometry = piston.geometry() + x4 = self.amesim_results.series(f"x4@{alias}")[-1] + x5 = self.amesim_results.series(f"x5@{alias}")[-1] + v4 = self.amesim_results.series(f"v4@{alias}")[-1] + v5 = self.amesim_results.series(f"v5@{alias}")[-1] + + self.assertAlmostEqual( + geometry.chamber_length_mm(x4, x5), + self.amesim_results.series(f"length@{alias}")[-1], + ) + self.assertAlmostEqual( + geometry.chamber_volume_cm3(x4, x5), + self.amesim_results.series(f"vol1@{alias}")[-1], + delta=1.0e-6, + ) + self.assertAlmostEqual( + geometry.chamber_volume_rate_l_min(v4, v5), + self.amesim_results.series(f"vvol1@{alias}")[-1], + delta=1.0e-8, + ) + + def test_all_elastic_endstop_forces_match_amesim_final_sample(self) -> None: + for endstop_alias, endstop_spec in self.assembly.elastic_endstops.items(): + piston_alias = endstop_alias.replace("elasticendstop", "pn_brp2") + with self.subTest(alias=endstop_alias): + endstop = endstop_spec.endstop() + gap_mm = self.amesim_results.series(f"gap@{endstop_alias}")[-1] + penetration_velocity_m_s = self.amesim_results.series(f"v5@{piston_alias}")[-1] + + self.assertAlmostEqual( + endstop.contact_force(gap_mm, penetration_velocity_m_s), + self.amesim_results.series(f"f1@{endstop_alias}")[-1], + delta=1.0e-3, + ) + def test_unit_helpers(self) -> None: self.assertAlmostEqual(mm_to_m(20.0), 0.02) self.assertAlmostEqual(n_per_mm_to_n_per_m(1.0e6), 1.0e9)