整合求解器活动监控与步长回归证据

同步远端 PNL0003 诊断和大采样网格能力,语义合并活动感知的 60 秒真停滞判定与旧后端 15 分钟兼容兜底。

纳管热路径优化、15 单元运行证据、浏览器与 API 报告,并补充北京时间更新日志和遗留问题。
This commit is contained in:
lujingze committed 2026-08-19 16:24:31 +00:00
1 parent c19cf77aee
commit e18399c022
46 files changed
+181589 -170

No files matched your search

+135
View File
@@ -10,6 +10,7 @@ from app.main import (
compile_system_xml_network,
run_system_xml_simulation,
)
from app.simulation.solvers.solver import SolveIVPConfig
from app.simulation.systems.generic import GenericFluidSystem
from app.system_xml import validate_system_xml_document
from tests.test_amesim_pnvo001_signal_xml import signal_edge, signal_port
@@ -302,6 +303,140 @@ class AmesimMechanicalXmlTests(unittest.TestCase):
self.assertEqual(tolerances, [1.0e-12, 1.0e-12])
self.assertEqual(len(tolerances), len(system.initial_state_vector()))
def test_self_loop_contact_does_not_relax_mass_velocity(self) -> None:
contact_parameters = {**LSTP00A_DEFAULTS, "rcont": 1.0e11}
project = ReactFlowProjectPayload(
projectSchemaVersion=1,
name="amesim-mechanical-self-contact",
nodes=[
component_node(
"mass_1",
"amesim_mecmas21",
[
mechanical_port("port_1", "left"),
mechanical_port("port_2", "right"),
],
MECMAS21_DEFAULTS,
),
component_node(
"contact_1",
"amesim_lstp00a",
[
mechanical_port("port_1", "left"),
mechanical_port("port_2", "right"),
],
contact_parameters,
),
],
edges=[
physical_edge(
"edge-1",
"mass_1",
"port_1",
"contact_1",
"port_1",
),
physical_edge(
"edge-2",
"mass_1",
"port_2",
"contact_1",
"port_2",
),
],
simulation={
"t_start": 0.0,
"t_stop": 0.02,
"step": 0.01,
"max_step": 0.005,
"method": "BDF",
},
)
system = GenericFluidSystem(compile_reactflow_network(project))
plan = system.mechanical_state_reducer.absolute_tolerance_plan(
1.0e-8,
mode="contact-aware-v1",
)
self.assertEqual(plan.values, (1.0e-12, 1.0e-12))
self.assertEqual(plan.groups[0].contacts, ())
self.assertFalse(plan.groups[0].eligible)
self.assertEqual(plan.groups[0].reason, "noFlexibleContact")
def test_weak_contact_damping_does_not_relax_velocity(self) -> None:
project = elastic_contact_project()
project.nodes[2].data.parameters["rcont"] = 1.0e-300
system = GenericFluidSystem(compile_reactflow_network(project))
plan = system.mechanical_state_reducer.absolute_tolerance_plan(
1.0e-8,
mode="contact-aware-v1",
)
self.assertTrue(plan.groups)
self.assertTrue(all(not group.eligible for group in plan.groups))
self.assertTrue(
all(group.reason == "weakContactDamping" for group in plan.groups)
)
self.assertTrue(
all(
group.velocity_atol == 1.0e-12
and group.position_atol == 1.0e-12
for group in plan.groups
)
)
def test_legacy_tolerance_ignores_extreme_contact_scales(self) -> None:
project = elastic_contact_project()
project.nodes[2].data.parameters.update(
{"kcont": 5.0e-324, "Pdis": 5.0e-324, "rcont": 1.0}
)
system = GenericFluidSystem(compile_reactflow_network(project))
legacy = system.mechanical_state_reducer.absolute_tolerance_plan(
1.0e-8,
mode="legacy",
)
contact_aware = (
system.mechanical_state_reducer.absolute_tolerance_plan(
1.0e-8,
mode="contact-aware-v1",
)
)
self.assertTrue(all(value == 1.0e-12 for value in legacy.values))
self.assertTrue(
all(group.reason == "legacyMode" for group in legacy.groups)
)
self.assertTrue(
all(
group.reason == "invalidContactScale"
for group in contact_aware.groups
)
)
def test_contact_aware_tolerance_is_limited_to_bdf(self) -> None:
system = GenericFluidSystem(
compile_reactflow_network(zero_force_mass_project())
)
result = system.simulate(
SolveIVPConfig(
t_start=0.0,
t_stop=0.001,
method="RK45",
max_step=0.001,
),
sample_step=0.001,
)
self.assertTrue(result.success)
tolerance = result.diagnostics["integration"][
"mechanicalAbsoluteTolerance"
]
self.assertEqual(tolerance["mode"], "legacy")
def test_sparse_reactflow_mecmas_parameters_use_registered_defaults(self) -> None:
project = mecmas_project(1.0, 1.0)