修复循环信号与事件采样并接入 LSTP 接触定位,补充八路验证及复用实验
相较上一版 Jacobian 确定性复用更新,本次补齐事件边界一致性、结果两侧采样及接触事件定位;保留已有物性复用和组件力学公式。 - 统一 UD00 信号求值与下一事件查询的绝对时间边界,修复循环边界浮点舍入导致的阶段错位、重复或漏报,并覆盖零时长、多阶段及长周期场景。 - 引入原生输出语义 v2:保留规则网格真实时间,补充内部时间事件和状态事件的左邻及事件后采样,按保存时间、状态和离散模式重放结果。 - 两条代码生成路径均发出 LSTP 接触描述,默认定位间隙过零及非负力模式的力截断;仅在接受事件时更新防重复记录,增加 contactEvents 诊断计数。 - 补充 MASS/LSTP 独立事件实验、八路全曲线与驱动阶段配对评估,以及 Amesim 不连续点输出对照和力差定位报告;MASS 新增释放机制仍保留为独立实验。 - 保存局部 probe、context 访问与回退、shadow replay、R288 real skip/typed replay 及阀门数值尾部诊断工具和报告;未证明净收益的实验不启用为生产默认优化。 - 更新原生运行说明和元件建模规范,补充信号边界、输出语义、接触事件和实验依赖回归测试。 验证:五组专项回归共 34 项全部通过;37 个待提交 Python 文件语法检查通过;git diff --cached --check 通过。
This commit is contained in:
1 parent
1aac220084
commit
7611f13208
85 files changed
+11358
-33
No files matched your search
@@ -0,0 +1,151 @@
|
||||
# LSTP 主路接入与八路力差定位
|
||||
|
||||
日期:2026-09-17。参照:本机 Amesim 2404、当前循环八路归档及上轮已审计的非循环归档。
|
||||
|
||||
## 1. 结论
|
||||
|
||||
**LSTP 事件已接入平台默认原生求解流程。循环、非循环八路的 238 条比较曲线均与上一轮“仅 LSTP”独立实验逐值相同,生成的原 RHS、雅可比结构和求解计数保持一致。MASS 的新增释放检查未合入。**
|
||||
|
||||
此前循环八路约 **128.55 万 N** 的最大力差,主要来自事件附近的保存时刻差异:平台配对点尚在驱动跳变边界,Amesim 普通输出点已经向前演化约 **2.20 ps**。两边驱动值相同,但连续速度已经不同,`1e11 N/(m/s)` 的阻尼将这个速度差放大。
|
||||
|
||||
在 Amesim 副本中只开启 **Discontinuities printout(不连续点输出)** 后,沿用原有共同网格及同驱动阶段配对,循环八路最大力差降为 **1.312403 N**,力的相对差超过 5% 的样本归零。平台没有再次改变积分结果,Amesim 原有所有样本也逐值不变,只新增了事件保存点。
|
||||
|
||||
另一个约 **−2.084e14 N** 的原始力峰,在 Amesim 的事件输出中同样存在,来自理想硬限位碰撞后的速度重置与大阻尼。这是当前参照工况本身产生的瞬态量级,不能直接当成平台独有的数值误差。
|
||||
|
||||
## 2. 默认流程改动及验证
|
||||
|
||||
- 两条生成路径均发出 `NativeContact` 描述,直接引用两端质量组的速度/位移状态,涵盖数值/几何刚度模式。
|
||||
- 默认定位 LSTP 间隙过零;非负力模式还定位接触区内原始力过零。允许负力的模式不新增力截断事件。
|
||||
- 沿用已测试的接受步密集插值、二分定位及相对速度换向分段检查。接触事件不重置位置或速度,不额外调用整模型 RHS。
|
||||
- 防重复记录只在事件接受时更新,不参与力、雅可比或输出重放。保留已有输出语义 v2;结果增加 `contactEvents` 诊断计数。
|
||||
- 两条生成路径原有间隙表达式的浮点运算顺序分别保留。移除新增常量描述表后,生成的 C 源码 SHA-256 与上轮原模型相同;雅可比仍为 132 状态、27 色和原物性复用方案。
|
||||
|
||||
实现:[事件描述](../../app/simulation/native_codegen/contacts.py)、[公共事件处理](../../native/runtime/common.c)、[接触定位](../../native/runtime/contact_events.h)、[组件接入规范 12.3](../standard/component-model-authoring-spec-v1.md#123-lstp-接触状态事件)。已有 LSTP 实例自动生效,无需工程 JSON 另加事件开关。
|
||||
|
||||
| 主路复测 | 循环 | 非循环 |
|
||||
| --- | ---: | ---: |
|
||||
| 与独立 LSTP 实验的全部比较数组 | 完全相同 | 完全相同 |
|
||||
| 接受步 | 16,934 | 9,980 |
|
||||
| RHS 求值 | 81,067 | 54,412 |
|
||||
| 求解器启动 | 21 | 6 |
|
||||
| 新增 LSTP 接触事件 | 8,同一时刻合并重启一次 | 8,同一时刻合并重启一次 |
|
||||
| 接触力截断事件 | 0 | 0 |
|
||||
| 同阶段配对 | 5,001/5,001 | 5,001/5,001 |
|
||||
|
||||
本轮未重新做五次性能测量,不将单次秒数解释为新性能变化;积分计数与上一轮独立实验一致。上轮性能结论见[MASS/LSTP 独立报告](MASS与LSTP事件独立实验及八路对比-2026-09-17.md)。
|
||||
|
||||
验证覆盖解析碰撞、守恒、两个最大步长、BDF/RK45、几何刚度、指数阻尼、力截断、同号间隙的中间接触/脱离、切触、无事件轨迹不变、事件输出及纯求解一致性,以及原有摩擦、硬限位和雅可比结构。
|
||||
|
||||
8 项 LSTP 专项及相关输出/信号、摩擦/结构回归合计 **27 个不同测试方法通过**。最初 Amesim 参考回路测试误用 2 ms 采样,参考含 1 ms 点,产生插值误差;恢复到参考的 1 ms 采样后原公差通过,没有放宽断言。另保留旧独立实验工具的兼容处理:使用新运行库时关闭主路接触注册,避免与实验事件重复执行。
|
||||
|
||||
测试日志:[LSTP 首批](../../test/lstp-mainline-unit.log)、[参考回路复测及输出/信号回归](../../test/lstp-mainline-regression.log)、[摩擦与结构](../../test/lstp-mainline-friction-structure.log)、[几何刚度](../../test/lstp-mainline-geometry.log)。八路原始结果:[主路汇总](../../test/lstp-mainline-20260917/baseline-summary.json)。
|
||||
|
||||
另有 1 项旧独立实验入口在新运行库上的[兼容回归](../../test/lstp-mainline-experiment-compatibility.log)通过;最终源码/结果隔离核验见[检查记录](../../test/lstp-mainline-20260917/final-verification.json)。
|
||||
|
||||
## 3. 将 32.4 s 的力差拆开
|
||||
|
||||
以第 2 路为例,接触力为:
|
||||
|
||||
`F = K*p + R*(1-exp(-p/Pdis))*(v_branch-v_common)`。
|
||||
|
||||
此时穿透约 4.6866 μm,`Pdis=0.1 μm`,阻尼系数已基本达到 `R=1e11 N/(m/s)`。由两侧保存的间隙和速度分别重建接触力,均与各自输出完全一致。
|
||||
|
||||
| 原普通输出的配对量 | 平台 | Amesim |
|
||||
| --- | ---: | ---: |
|
||||
| 实际时间,s | 32.400000000000006 | 32.40000000000221 |
|
||||
| 公共质量块速度,m/s | 0 | −1.2883209101e-5 |
|
||||
| 第 2 路相对速度,m/s | −3.3024983e-12 | 1.2854894891e-5 |
|
||||
| 弹性力,N | 468,662.995301 | 468,662.655106 |
|
||||
| 阻尼力,N | −0.330250 | 1,285,489.489088 |
|
||||
| 总接触力,N | 468,662.665051 | 1,754,152.144194 |
|
||||
|
||||
**弹性项只差 0.340 N,约 128.55 万 N 的差异几乎全部是阻尼项。** 双方均在接触区,并不存在一边接触、一边脱离的模式错误。
|
||||
|
||||
此刻 UD00 驱动从 0 切换为 1e12 N,经负方向力源作用于公共质量块。质量为 170,000 kg,位于 0.37 m 上限,切换后向允许方向释放,加速度约 −5.882e6 m/s²。经过约 2.2e-12 s,速度变化达到约 1.3e-5 m/s,乘以大阻尼便得到百万牛级力变化。
|
||||
|
||||
本机参考代码中,[UD00](F:/AMESim2404/Amesim/libsig/submodels/UD00.c:593)更新周期阶段并调用时间不连续处理;[MECMAS21](F:/AMESim2404/Amesim/libmec/submodels/MECMAS21.c:547)将理想限位交给 `endst2_`;[LSTP00A](F:/AMESim2404/Amesim/libmec/submodels/LSTP00A.c:296)由穿透及其导数计算接触力。这些代码和本次输出支持上述因果链,但本报告不据此声称两套积分器内部算法完全相同。
|
||||
|
||||
## 4. 三种对照验证取样影响
|
||||
|
||||
### A. 使用相同实际时刻的连续状态
|
||||
|
||||
在独立运行库副本中增加 210 个只读密集输出查询,包括 Amesim 真正保存的时间。查询不改变步长、时间事件或接受状态;完整积分计数与主路运行一致。结果重放仍调用原模型公式。
|
||||
|
||||
| 第 2 路名义时刻 | 原配对绝对力差,N | 同一实际时刻绝对力差,N | 减少 |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| 21.6 s | 387,825.741 | 7,758.635 | 98.00% |
|
||||
| 32.4 s | 1,285,489.479 | 5,025.566 | 99.61% |
|
||||
| 43.2 s | 29,254.603 | 3.685 | 99.99% |
|
||||
|
||||
同一实际时刻仍有小残差,不能据此宣称皮秒瞬态完全一致。32.4 s 附近 binary64 时间间距约 7.105e-15 s;按此刻加速度和阻尼估算,一格时间变化对应约 4,180 N。主路日志在这些驱动边界也记录了积分器成功步未推进外部浮点时间的情况。
|
||||
|
||||
进一步用**同一已保存的边界状态**,在独立程序中将局部时间从 0 开始,只继续到上述 2.20 ps;原力学、热力学公式及驱动阶段不变。rtol=1e-8 和 1e-10 的第 2 路末力均约 **1,761,496.860 N**;默认绝对时间密集输出为 **1,749,126.578 N**,Amesim 普通输出为 **1,754,152.144 N**。该试验表明这一极短瞬态对时间原点和启动处理敏感,单纯再收紧相对容差不能解释或消除全部残差。局部时钟没有合入生产。
|
||||
|
||||
证据:[逐支路力分解与同时间对照](../../test/lstp-mainline-20260917/force-error-analysis.json)、[连续状态取样](../../test/lstp-mainline-20260917/trace/dense-outputs.json)、[局部时钟结果](../../test/lstp-mainline-20260917/rebase/summary.json)。
|
||||
|
||||
### B. 直接比较事件前后保存点
|
||||
|
||||
按本机 [Amesim `ameputsimopt`](F:/AMESim2404/Amesim/scripting/python/amesim.py:1093) 的定义,仅将副本 `.sim` 第二行的 `simOptions[2]` 从 0 改为 1,启用 `printDiscont`。模型、容差、时间区间、普通输出间隔及其他求解选项不变,重新运行 Amesim。
|
||||
|
||||
记录从 5,002 行增至 5,046 行,核验**所有原有时刻、全部原保存变量逐值不变**。32.4 s 第 2 路新增记录为:
|
||||
|
||||
| Amesim 实际时刻,s | 阶段 | 公共质量块速度,m/s | 接触力,N |
|
||||
| --- | --- | ---: | ---: |
|
||||
| 32.400000000000006 | 驱动切换前 | 0 | 468,662.652083 |
|
||||
| 32.40000000000001 | 驱动切换后立即 | 0 | 468,662.652083 |
|
||||
| 32.40000000000221 | 原普通输出,已演化约 2.2 ps | −1.2883209101e-5 | 1,754,152.144194 |
|
||||
|
||||
平台事件后的力为 **468,662.665051 N**。与 Amesim 的事件后立即值比较,差 **0.012968 N**。这直接证明“相同信号阶段”还不足以把事件边界与已经演化的普通输出当成同一个瞬态。
|
||||
|
||||
### C. 保持原比较算法,重新比较整组八路
|
||||
|
||||
平台结果不变;参照换成含事件点的 Amesim 输出,仍用相同名义 10 ms 网格、相同时间候选窗口、完整 10 个驱动信号配对,并让所有曲线共用一对行。没有根据力差选择样本,没有删除事件网格点。
|
||||
|
||||
Amesim 原始事件输出存在一处文件行序倒置:先写 0.8000000000000009 s 普通点,后写 0.8 s 事件点。本次诊断只按原始实际时间稳定排序,保留全部行、值和重复时间,并保存排序到原始行的映射;未改变平台导入器或原始结果文件。
|
||||
|
||||
| 循环八路指标 | 原普通 Amesim 输出 | Amesim 含事件点输出 |
|
||||
| --- | ---: | ---: |
|
||||
| 比较曲线/网格点 | 238 / 5,001 | 238 / 5,001 |
|
||||
| 未配对时刻 | 0 | 0 |
|
||||
| 全网格最大绝对力差,N | 1,285,489.485624 | **1.312403** |
|
||||
| 最大力差时刻 | 32.4 s | 0.01 s |
|
||||
| 力的相对差超过 5% 的曲线样本数 | 24 | **0** |
|
||||
| 所有变量相对差超过 5% 的曲线样本数 | 32 | **6** |
|
||||
| 最大压力差,Pa | 61.105785 | 61.105785 |
|
||||
| 最大温度差,K | 0.389714 | 0.389714 |
|
||||
|
||||
剩余 6 个为质量流量 4、焓流 2;5% 仍只是原有诊断线。32.4 s 八路在事件侧配对后的力差均小于 0.015 N。**1.312403 N 是这组共同网格和事件侧对照的最大差,不能作为网格之间所有极短瞬态误差的上界。**
|
||||
|
||||
证据:[新对照汇总](../../test/lstp-mainline-20260917/event-output-comparison/summary.json)、[全部曲线](../../test/lstp-mainline-20260917/event-output-comparison/comparison.json)、[阶段配对](../../test/lstp-mainline-20260917/event-output-comparison/phase-pairing.json)、[原始行映射](../../test/lstp-mainline-20260917/event-output-comparison/ame-row-order.json)。
|
||||
|
||||
## 5. 约 2.084e14 N 的原始力峰来自哪里
|
||||
|
||||
该峰发生在约 32.4003551 s,即释放后约 0.355 ms,公共质量块从上限运动至下限。碰撞前,两端速度都约 −2083.9 m/s、相对速度较小;理想下限把公共质量块速度重置为 0,支路质量块仍保持约 −2083.9 m/s。因此大阻尼立即产生约 −2.084e14 N 的力。此模型允许负接触力,该值不会被截断。
|
||||
|
||||
| 第 2 路对应的下限碰撞后 | 平台 | Amesim |
|
||||
| --- | ---: | ---: |
|
||||
| 事件时刻,s | 32.40035510065042 | 32.400355100640695 |
|
||||
| 公共质量块位移/速度 | 0 m / 0 m/s | 0 m / 0 m/s |
|
||||
| 支路速度,m/s | −2083.913265366 | −2083.913208006 |
|
||||
| 接触力,N | −2.083913259638e14 | −2.083913202278e14 |
|
||||
|
||||
对应碰撞时间差约 **9.73 ps**,力值相对差约 **2.75e-6%**。单看绝对差仍有约 5.74e6 N,但这是在约 2.084e14 N 的峰值上。两边都出现同一种速度重置和阻尼峰,不能把这个峰本身归因于缺少 LSTP 事件。
|
||||
|
||||
这验证了当前参照模型的实现一致性;是否希望工程模型具有如此大的外力、速度及理想碰撞瞬态,应由工况与接触建模目标决定,不能用调小数值结果来替代模型选择。
|
||||
|
||||
证据:[平台碰撞前后样本](../../test/lstp-mainline-20260917/raw-force-peak.json)、[Amesim 事件输出及碰撞样本](../../test/lstp-mainline-20260917/amesim-event-output/mechanical-events.json)。
|
||||
|
||||
## 6. 后续建议及复现
|
||||
|
||||
初步平台展示与正确性评价,优先使用**开启不连续点输出的 Amesim 结果**作为参照,并保留共同事件侧配对、原时间戳及原普通输出的审计。当前证据不支持为消除原来的 128 万 N 配对差再调整 LSTP 刚度、阻尼,或将昂贵的 MASS 释放实验合入默认路径。
|
||||
|
||||
若下一步要验证皮秒尺度的峰形,再研究按事件相对时间表示/求解短瞬态、保存精度以及硬限位重置后的连续状态;本次只完成了独立局部时钟诊断,没有改生产时间处理。
|
||||
|
||||
[诊断脚本](../../tests/manual/diagnose_mql8_force_events.py)支持分阶段复现,完整执行使用新目录:
|
||||
|
||||
```powershell
|
||||
.\.venv-win\Scripts\python.exe -X utf8 -m unittest tests.test_native_contact_events -v
|
||||
.\.venv-win\Scripts\python.exe -X utf8 tests/manual/diagnose_mql8_force_events.py --output test/lstp-mainline-new-run --stage all
|
||||
```
|
||||
|
||||
该诊断依赖本工作站已对齐的工程、上一轮独立实验数据和 Amesim 2404。源码、测试、规范及本文为可跟踪交付;原始结果在 Git 忽略的 `test/lstp-mainline-20260917/`。Windows 编译器的偶发启动失败由现有重试恢复;诊断和新专项串行构建以减少干扰,生产构建调度未更改。
|
||||
@@ -0,0 +1,171 @@
|
||||
# MASS 与 LSTP 事件独立实验及八路对比
|
||||
|
||||
日期:2026-09-17。环境:Windows、本项目 Python 3.12、原生 C、CVODE BDF;组件专项同时覆盖 RK45。
|
||||
|
||||
## 1. 本次实验回答什么
|
||||
|
||||
以已经完成 UD00 边界修复、事件输出语义修改的当前平台为基线,独立比较 `off`、`mass`、`lstp`、`all` 四种配置。循环和非循环各运行 50 s;每种配置保留完整结果,再做 5 次轮换顺序的纯求解计时。
|
||||
|
||||
**实验实现放在 `tests/manual/`,没有把新事件启用到默认平台。已有信号修复、输出语义、组件公式、雅可比分色及物性复用保留。** 因此本文的“未修改”特指本轮新增机械事件关闭,不是回退到此前有信号边界问题的版本。
|
||||
|
||||
MASS 的新增事件在当前八路工况中没有带来精度改善,纯求解耗时中位数增加 **31%–34%**。LSTP 的非循环最大力差降低 **9.90%**,本次耗时没有明显增加,但循环工况 32.4 s 的主要力差没有改善,部分其他误差反而增大。两类一起开启,精度与只开 LSTP 相同,耗时增加 **22%–23%**。
|
||||
|
||||
## 2. 独立实现与隔离方式
|
||||
|
||||
当前 `native/` 冻结为 `test/mechanical-events-20260917/source-control/native/`。`off` 直接用这个副本;其他配置用另一份副本追加实验运行代码,编译缓存、可执行文件、结果存储均放在本次实验目录。
|
||||
|
||||
[实验程序构建](../../tests/manual/mechanical_event_variant.py)在原生成源码后追加事件描述与释放驱动力求值入口。每次构建均断言原生成源码仍是逐字相同的前缀,状态键、求值调度和雅可比稀疏结构一致。正常 RHS、Jacobian 和物性缓存路径没有替换。八路仍为 132 个状态、1,784 个输出、27 个雅可比颜色。
|
||||
|
||||
生产源码的前后 SHA-256 核验、原模型前缀核验与积分计数用于区分“新增事件改变积分轨迹”和“破坏已有优化”。这些检查不代表新事件本身没有计算成本。
|
||||
|
||||
最终核验:46 个生产源码文件前后哈希相同,控制副本与当前 `native/` 相同;所有配置仍采用 `colored-difference` 和输出语义 v2。两组 `off` 的全部比较数组与上一轮输出语义基线完全一致。见[隔离及结果核验](../../test/mechanical-events-20260917/baselines/evidence-verification.json)与[生产源码哈希](../../test/mechanical-events-20260917/baselines/production-verification.json)。
|
||||
|
||||
### MASS
|
||||
|
||||
- 弹性上下限:分别检查 `xmin - x`、`x - xmax` 过零,定位接触和脱离。
|
||||
- 非负接触力模式:在接触区内额外检查未截断力 `K*p + D(p)*v_relative` 过零。允许负力的模式不添加这个截断事件。
|
||||
- 理想/恢复限位保持后的释放:在已贴限位、速度接近零时,检查不施加限位约束的加速度是否转向允许运动的方向。
|
||||
- 原有碰撞、恢复系数和摩擦事件继续按原逻辑处理。弹性事件不重置速度或位置;保持后的释放从约束位置、零速度继续。
|
||||
|
||||
为隔离已有优化,释放驱动力来自独立整模型求值,没有修改原 RHS 以共享中间量。`releaseRhsCalls` 单独记录这项成本,并计入 `nfev`。这是**本实验实现**的代价,不是所有 MASS 事件实现必然付出的代价。
|
||||
|
||||
### LSTP
|
||||
|
||||
按原公式的同一运算顺序计算 `gap = gap0 + x2 - x1`,检查 `-gap` 的过零。非负力模式再检查接触区内的原始力过零;允许负力时不检查力截断。事件不施加硬碰撞式速度重置。
|
||||
|
||||
### 公共定位与输出
|
||||
|
||||
[实验运行库](../../tests/manual/mechanical_events_runtime.c)在积分接受步的密集插值上二分定位;浮点区间不可再分时停止。同一浮点时刻发生的事件合并提交并重启一次。仅在事件真正接受后更新防重复触发记录;试算、雅可比求值和输出重放不更新物理模式,输出仍由原公式计算。
|
||||
|
||||
相对速度换向时,先按换向点分段找间隙根,以覆盖步首尾间隙同号但中间接触/脱离的情况;孤立切触不制造虚假来回事件。这仍依赖积分步已经解析运动,不能保证捕获一个接受步内任意多次未解析的高频振荡。根的二分精度也不等于积分状态精度。
|
||||
|
||||
沿用上一轮 `outputSemantics.version=2`:记录事件左邻时刻和接受后的事件时刻。没有调整比较点来挑选误差更小的力值。
|
||||
|
||||
## 3. 组件独立验证
|
||||
|
||||
验证包括解析解、物理守恒、现有 Amesim 参考回路和无事件回归,代码见[专项测试](../../tests/test_mechanical_event_experiment.py)。
|
||||
|
||||
| 测试 | 验证依据 |
|
||||
| --- | --- |
|
||||
| MASS 弹性上下限 | 阻尼振子的解析接触持续时间及出界速度;两个最大步长、BDF/RK45 |
|
||||
| MASS 保持后释放 | 连续斜坡驱动,1 s 释放;上下限镜像,最终速度和位置解析值 |
|
||||
| MASS 原有恢复碰撞 | 恢复系数 0.5;与事件关闭版逐样本、最终状态和启动次数对照 |
|
||||
| LSTP 两质量弹性碰撞 | 解析接触/脱离时刻、速度交换、总动量和动能加弹性势能 |
|
||||
| MASS/LSTP 非负力 | 接触区内力截断事件、非负输出、MASS 截断时刻解析值 |
|
||||
| 指数阻尼与两种力模式 | MASS/LSTP、BDF/RK45、extended 生成路径,检查完成且无事件抖振 |
|
||||
| 无接触、初始贴边静止、持续接触 | 无多余重启,原始输出与关闭版完全一致 |
|
||||
| 同号间隙与切触 | 已知二次多项式密集输出:准确找到 0.4/0.6 s 两根,切触不造事件 |
|
||||
| 已有 Amesim 回路 | `friction_ideal`、`friction_elastic`、`joint_mechanical`,按现有参考值核验 |
|
||||
|
||||
弹性接触时刻/速度允许误差 2e-6,连续释放时刻 1e-8 s,解析截断时刻 3e-6 s;守恒断言另设独立公差。Amesim 参考来自现有 `amesim-component-semantics-2404.json`,这里不声称重新测出了 Amesim 的内部根定位算法。八路则使用本轮重新运行的 Amesim 结果。
|
||||
|
||||
**9 个测试方法全部通过**,覆盖 38 种模型/配置/求解器组合,另含 2 个解析密集输出场景。按开发顺序分批执行,力截断条件补全后专门复跑相关测试;日志有重复方法,不能把各批数量直接相加。证据:[首批 6 项](../../test/mechanical-events-20260917/isolated-verified.log)、[截断复测及参考回归 3 项](../../test/mechanical-events-20260917/independent-reference-tests.log)、[恢复碰撞回归 1 项](../../test/mechanical-events-20260917/restitution-regression.log)。
|
||||
|
||||
## 4. 八路比较口径
|
||||
|
||||
循环参照为 `tests/data/test_mql.ame`,非循环参照为已审计的 `test/node-fixes-amesim-20260914/test_mql.ame`。输入用上轮已对齐的工程副本,原 AME 和用户工程不修改。每个工况重新执行一次 Amesim,作为四种配置共同的参考;平台 BDF、0–50 s、输出间隔 0.01 s、误差限数值 1e-8。
|
||||
|
||||
八路包含 10 个 MASS:9 个无限位、1 个理想限位,没有弹性限位 MASS;8 个 LSTP 均允许负力,接触刚度与阻尼均为 1e11,指数阻尼距离约 1e-7 m。因此八路不覆盖全部新增模式,必须结合前面的组件测试判断。
|
||||
|
||||
每个比较点先核验 8 个 STEP 和 2 个 UD00 的完整驱动组合,再让全部 238 条曲线共用同一对真实保存行,不跨信号跳变插值。另检查八个 `gap < 0` 标志。信号阶段匹配不等于两边浮点时间完全相同,也不代表验证了网格之间的全部接触事件。
|
||||
|
||||
全部 8 次准确性运行均正常结束,全部比较输出有限;各自 **5,001/5,001 个时刻成功配对,信号最大差为 0,接触/分离标志不匹配为 0**。没有删除未匹配点来改善指标。
|
||||
|
||||
## 5. 八路准确性结果
|
||||
|
||||
### 汇总
|
||||
|
||||
下表列 `off → lstp`。`mass` 在 238 条已比较曲线上与 `off` 完全一致,`all` 与 `lstp` 完全一致,因此不重复相同列。
|
||||
|
||||
| 指标 | 循环:off → lstp | 非循环:off → lstp |
|
||||
| --- | --- | --- |
|
||||
| 最大接触力绝对差,N | 1,285,489.483041 → 1,285,489.485624 | 1.456532 → **1.312403** |
|
||||
| 上项发生时间,s | 32.4 → 32.4 | 0.01 → 0.01 |
|
||||
| 平静段最大力差,N | 0.275890 → **0.212043** | 0.275890 → **0.154170** |
|
||||
| 最大压力差,Pa | 65.686768 → **61.105785** | 65.686768 → **61.105785** |
|
||||
| 最大温度差,K | 0.395395 → **0.389714** | 0.395395 → **0.389714** |
|
||||
| 最大间隙差,m | 1.293005e-8 → **5.474060e-8,增大** | 1.293005e-8 → **1.581826e-8,增大** |
|
||||
| 最大质量流量差,kg/s | 1.326797e-5 → **2.424649e-5,增大** | 5.663171e-6 → **2.424649e-5,增大** |
|
||||
| 最大焓流差,W | 141.920203 → **18.688805** | 141.920203 → **18.688805** |
|
||||
| 明确非零且相对差超过 5% 的曲线样本数 | 56 → **32** | 30 → **6** |
|
||||
|
||||
“平静段”沿用已有定位统计:t≥0.1 s,避开信号边界前后 0.02 s;它不能替代包含事件点的完整指标。5% 是诊断筛查线,不是工程验收公差。循环的 32 个超线样本仍含接触力 24、速度 2、质量流 4、焓流 2;非循环剩余质量流 4、焓流 2。
|
||||
|
||||
最大压力差降低约 6.97%,温度差降低约 1.44%;循环/非循环平静段最大力差分别降低约 23.14%/44.12%。但间隙和质量流量的最大绝对差增大,因此不能称为所有指标全面改善。新增最大流量差发生在 0.09 s、`amesim_pn3node2_1.reference_mass_flow`;该点参考流量约 0.02098 kg/s,绝对差约为参考值的 0.116%。原有小流量样本的相对差计数减少,与这一绝对误差增大可以同时发生。
|
||||
|
||||
### 八个支路分别看
|
||||
|
||||
以下均为各支路完整 0–50 s 网格的最大绝对力差,单位 N。支路编号对应 `amesim_lstp00a_1…8`。循环均发生在 32.4 s,非循环均发生在 0.01 s。
|
||||
|
||||
| 支路 | 循环 off | 循环 lstp | 非循环 off | 非循环 lstp |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| 1 | 1,285,489.480 | 1,285,489.479 | 1.450464 | 1.306552 |
|
||||
| 2 | 1,285,489.483 | 1,285,489.479 | 1.456532 | 1.312398 |
|
||||
| 3 | 1,285,489.482 | 1,285,489.486 | 1.456530 | 1.312403 |
|
||||
| 4 | 1,285,489.478 | 1,285,489.480 | 1.450460 | 1.306567 |
|
||||
| 5 | 1,285,489.475 | 1,285,489.483 | 1.447450 | 1.299400 |
|
||||
| 6 | 1,285,489.475 | 1,285,489.481 | 1.446239 | 1.298499 |
|
||||
| 7 | 1,285,489.477 | 1,285,489.478 | 1.446238 | 1.298504 |
|
||||
| 8 | 1,285,489.478 | 1,285,489.477 | 1.447445 | 1.299415 |
|
||||
|
||||
非循环八路均改善,循环八路的大力差均基本不变。完整精度数据见[汇总](../../test/mechanical-events-20260917/baselines/effect-summary.json)、[逐支路](../../test/mechanical-events-20260917/baselines/branch-force-summary.json)、[全部物理量分组](../../test/mechanical-events-20260917/baselines/group-summary.json)。
|
||||
|
||||
### 实际新增了哪些事件
|
||||
|
||||
两组工况都只有 8 个新增 LSTP 接触事件,全部发生在 **6.5966840909145208e-9 s**,合并为一次积分重启;之后没有检测到新的 LSTP 接触/脱离。当前采用允许负力模式,因此没有力截断事件。
|
||||
|
||||
两组都没有新增 MASS 弹性接触或连续释放事件。当前模型没有弹性限位 MASS;理想限位的相关驱动跳变已有时间事件负责重新启动,没有额外触发本次连续释放根。不能用“本模型未触发”推断其他驱动下不需要释放事件;连续斜坡测试已验证释放能正确发生。
|
||||
|
||||
循环 32.4 s 仍使用平台实际时刻 `32.400000000000006` 和 Amesim `32.40000000000221`。驱动阶段一致,但约 2.20e-12 s 的实际时间差与高刚度连续状态的影响仍未分离。新增的启动间隙事件不能替代对此的检查。
|
||||
|
||||
额外事件保存点的最大绝对接触力仍约为循环 **2.084e14 N**、非循环 **4.035e11 N**,与 `off` 基本同量级;这些点没有同分辨率 Amesim 参考,未计入上述准确性判断。
|
||||
|
||||
## 6. 求解耗时与成本来源
|
||||
|
||||
每组、每配置运行 **5 次纯求解**,轮换配置顺序。计时排除编译和结果重放/序列化;完整输出准确性运行另存。下表为墙钟中位数,括号为五次最小–最大值,百分比相对本次同工况 `off`,不与上轮不同时间运行的单次秒数混比。
|
||||
|
||||
| 配置 | 循环耗时,s | 相对 off | 非循环耗时,s | 相对 off |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| off | 14.334(14.209–14.664) | — | 9.583(8.978–10.293) | — |
|
||||
| mass | 19.220(18.035–20.428) | **+34.09%** | 12.565(12.190–14.599) | **+31.12%** |
|
||||
| lstp | 13.605(13.369–15.221) | **−5.09%** | 8.871(8.661–9.044) | **−7.43%** |
|
||||
| all | 17.697(17.003–19.600) | **+23.46%** | 11.653(11.246–11.852) | **+21.60%** |
|
||||
|
||||
LSTP 的运行范围与基线有重叠,五次试验不构成普遍提速保证;本次没有明显增加耗时,且积分步数下降。MASS 的范围与基线明显分离,额外开销同时有计算次数支持。各配置五次计时的积分计数完全重复,并与完整输出运行一致。
|
||||
|
||||
| 工况/配置 | 接受步 | 拒步 | RHS 求值 nfev | 求解器启动 | 额外释放驱动力求值 |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: |
|
||||
| 循环 off | 19,606 | 1,552 | 85,570 | 20 | 0 |
|
||||
| 循环 mass | 19,606 | 1,552 | 122,240 | 20 | **36,670** |
|
||||
| 循环 lstp | 16,934 | 1,137 | 81,067 | 21 | 0 |
|
||||
| 循环 all | 16,934 | 1,137 | 112,331 | 21 | 31,264 |
|
||||
| 非循环 off | 11,238 | 885 | 56,299 | 5 | 0 |
|
||||
| 非循环 mass | 11,238 | 885 | 78,561 | 5 | **22,262** |
|
||||
| 非循环 lstp | 9,980 | 742 | 54,412 | 6 | 0 |
|
||||
| 非循环 all | 9,980 | 742 | 74,172 | 6 | 19,760 |
|
||||
|
||||
LSTP 循环/非循环分别执行 135,472/79,840 次元件步检查、2,196/963 次密集插值调用,实际只增加一次事件重启;其检查直接使用状态,不调用整模型 RHS。MASS 单独开启时,轨迹、步数和原有重启次数没变,多出的 nfev 恰好等于释放驱动力整模型求值次数。这解释了为什么“没有新事件发生”仍可能有明显耗时。
|
||||
|
||||
CPU 时间中位数也支持同一方向:循环 off/mass/lstp/all 为 13.891/18.266/13.062/16.984 s,非循环为 9.328/11.969/8.609/11.281 s。全部独立计时见[循环](../../test/mechanical-events-20260917/baselines/full/timings.json)、[非循环](../../test/mechanical-events-20260917/baselines/noncyclic/timings.json)。
|
||||
|
||||
## 7. 结论适用范围与下一步
|
||||
|
||||
1. **当前八路不宜直接把本实验 MASS 释放检查作为默认路径。** 其新增事件在这两组工况中没有触发,结果不变而存在额外计算。对于连续驱动力导致的限位释放,专项解析测试证明事件机制有作用;后续若集成,应优先从已有 RHS 获取释放驱动力,或仅计算必要依赖,再重新计时。
|
||||
2. **LSTP 可以作为后续生产集成候选,但本次仍保留在实验中。** 它补齐了接触边界定位,部分误差降低,间隙和质量流量最大误差也有回退;不能据此声称循环八路的主要力差已解决,也不能把这一模型中的耗时结果推广到频繁接触/脱离的模型。正式集成前应根据展示关注量确认这些取舍。
|
||||
3. **循环力峰仍应检查同一实际时刻的连续状态。** 32.4 s 的信号阶段已经一致,新增间隙事件仍未消除差异。下一步应核对细时间窗中的位移、速度、间隙和力,区分实际保存时刻偏移、高刚度响应及已有硬限位处理的影响。
|
||||
|
||||
纳秒级启动事件的定位时刻是本次平台数值轨迹上的根,没有同分辨率 Amesim 根时刻验证。额外事件保存点的巨大力峰同样保留,没有平滑或删除,也没有把缺少同分辨率参考的峰值当成准确性结论。
|
||||
|
||||
## 8. 复现与证据
|
||||
|
||||
[运行说明](../../tests/manual/mechanical_events_experiment.md)、[八路运行脚本](../../tests/manual/evaluate_mechanical_events.py)、[指标汇总脚本](../../tests/manual/summarize_mechanical_events.py)。
|
||||
|
||||
```powershell
|
||||
.\.venv-win\Scripts\python.exe -X utf8 -m unittest tests.test_mechanical_event_experiment -v
|
||||
.\.venv-win\Scripts\python.exe -X utf8 tests/manual/evaluate_mechanical_events.py --output test/mechanical-events-new-run --repeats 5
|
||||
.\.venv-win\Scripts\python.exe -X utf8 tests/manual/summarize_mechanical_events.py test/mechanical-events-new-run
|
||||
```
|
||||
|
||||
八路脚本依赖本工作站 Amesim 2404 及已有对齐工程;主输出目录必须是新目录。构建阶段出现过 Windows 缓存发布拒绝与 GCC 子进程启动/停滞,保留已完成运行后续跑,最后一次恢复使用 `--resume --serial-build`。串行选项只改变实验构建调度,不改变编译参数、模型、事件实现或求解器设置;构建及其等待均不计入上述纯求解时间。
|
||||
|
||||
本轮完整数据位于 Git 忽略的 `test/mechanical-events-20260917/`;代码、测试和本文可跟踪保存。每个配置目录有 `comparison.json`、`curves.npz`、`phase-pairing.json`、完整原始结果、事件日志及五次计时目录。
|
||||
@@ -0,0 +1,95 @@
|
||||
# 事件输出语义修改与八路基线复测
|
||||
|
||||
日期:2026-09-17。Windows,本项目 Python 3.12、原生 C、CVODE BDF;独立测试同时覆盖 RK45。
|
||||
|
||||
## 1. 结论
|
||||
|
||||
**已完成输出语义修改、专项测试,以及循环/非循环两组 50 s 八路基线重跑。两组各 5,001 个比较时刻均找到同一信号驱动阶段的样本,信号比较误差归零;循环接触力尖峰差仍然存在。**
|
||||
|
||||
本次修改只增加事件两侧的保存样本并明确比较规则,没有补充接触事件。前后对照均使用已经修复 UD00 的内核,避免把此前信号修复与本次输出修改混在一起归因。修改前的原生源码快照保存在 `test/output-semantics-20260917/control-source/native/`。
|
||||
|
||||
## 2. 输出语义怎样改变
|
||||
|
||||
- 规则采样时间仍按实际浮点数解释,不把网格点吸附到事件,不提前切换信号。
|
||||
- 对仿真区间内部的时间事件,保存 `nextafter(boundary, -INFINITY)` 和 `boundary`。前者是旧积分段实际到达的终点;后者保留连续状态,用事件后的信号重放输出。两者是相邻的真实浮点时刻,不是两个重名时间戳。
|
||||
- 对已注册的机械状态事件,在当前积分区间可用时,保存事件左邻时刻的插值状态,然后保存事件后的接受状态。这保留了碰撞前后速度及各自模式。初始即时事件没有新左侧区间,不倒填样本。
|
||||
- 同一实际时间依然以后一次接受状态为准;序列严格递增。结果增加 `outputSemantics.version=2`,已有状态/输出块格式和变量集合保持兼容。
|
||||
- 新增样本同样走既有有界缓冲、存储配额和输出重放流程。纯求解模式不保存这些样本。
|
||||
|
||||
主要实现:[公共事件采样](../../native/runtime/common.c)、[BDF](../../native/runtime/cvode_solver.c)、[RK45](../../native/runtime/rk45.c)、[结果元数据](../../native/runtime/main.c)。注册与重放要求见[组件开发规范 12.2](../standard/component-model-authoring-spec-v1.md#122-事件输出与重放)。
|
||||
|
||||
## 3. 如何保证比较阶段一致
|
||||
|
||||
当前八路有 8 个 STEP 和 2 个 UD00,UD00 各启用阶段均为常值。比较程序先取 Amesim 在名义网格附近实际保存的样本,再在平台保存样本中寻找相同的完整信号组合。
|
||||
|
||||
- 时间候选窗口仍为输出间隔的 `1e-7`,本次即 `1e-9 s`;它只用于匹配保存时间的舍入差,不修改求解时间或事件时间。
|
||||
- 10 个信号必须同时一致;所有 238 条曲线共用同一对样本行,不按接触力、压力或误差大小选择样本。
|
||||
- 不跨跳变插值;缺失对应阶段时明确记录未配对,不把错误配对纳入同阶段指标。旧的纯时间匹配指标另存为 `raw-time-comparison.json`,用于审计。
|
||||
- 本规则针对本次分段常值信号;脚本遇到 UD00 斜坡会明确拒绝,避免把“输出值相近”错误地推广为所有信号的阶段标识。
|
||||
- 额外核验八个接触件的带符号间隙:两组全部已配对点的 `gap<0` 标志一致。但这不是对网格之间所有接触/脱离时刻的验证,也不声称复原了 Amesim 的全部内部离散模式。
|
||||
|
||||
修改前循环工况缺少 4 个时刻的同阶段样本,非循环缺少 1 个;修改后两组均为 **5,001/5,001 配对,未配对 0 个**,没有删除事件点。循环改配时刻为 0.8、10.8、32.4、44 s;非循环为 0.8 s。真实时间、选中的信号值及原始行记录在各组 `phase-pairing.json`。
|
||||
|
||||
## 4. 第一次测试与回归
|
||||
|
||||
首先执行输出/相位配对、循环 UD00、存储专项共 18 项,全部通过;另补非网格时刻阶跃测试 1 项,通过。随后结果传输、HTTP 返回、取消/异常处理、恢复碰撞及摩擦保持回归 11 项通过,共 **30 项**。
|
||||
|
||||
关键验证包括:32.4 s 浮点边界前后分属不同阶段时正确配对;Amesim 保留事件前值时选用平台左侧样本;缺失阶段或任一驱动不同则明确拒绝;BDF/RK45 保存非网格阶跃两侧;碰撞前后速度分别为约 1 和 −0.5 m/s;有/无采样的积分最终状态及计数一致;二进制存储与 JSON 返回一致。
|
||||
|
||||
证据:[18 项首次通过日志](../../test/output-semantics-20260917/verified-first-tests.log)、[非网格阶跃](../../test/output-semantics-20260917/off-grid-test.log)、[11 项附加回归](../../test/output-semantics-20260917/additional-regression.log)。测试过程中一次解析碰撞时间断言过严:原设 1e-9 s,实际偏差约 2.61e-8 s;按该数值积分测试的目的改为 1e-6 s。事件两侧相邻浮点时间及速度断言未放宽。编译器偶发启动失败由既有重试恢复。
|
||||
|
||||
## 5. 八路基线结果
|
||||
|
||||
使用原有 AME 作为参照,在副本中审计并对齐参数、连接和运行设置。两组均重新执行 Amesim 归档中的程序及平台程序,没有用旧曲线代替本次运行。循环采用当前 `tests/data/test_mql.ame`;非循环采用此前已审计的 `test/node-fixes-amesim-20260914/test_mql.ame`。时间 0–50 s,输出间隔 0.01 s,两边误差限数值 1e-8。原始工程文件未修改。
|
||||
|
||||
下表“修改前”是保留了 UD00 修复的本次对照运行,采用旧的纯时间配对;“修改后”使用新增事件样本和同阶段配对。每项均包含事件网格点。
|
||||
|
||||
| 指标 | 循环:修改前 → 修改后 | 非循环:修改前 → 修改后 |
|
||||
| --- | --- | --- |
|
||||
| 信号最大绝对差 | 约 1e17 → **0** | 约 1e17 → **0** |
|
||||
| 接触力最大绝对差 | 1,285,489.483 → **1,285,489.483 N** | 1.456532 → **1.456532 N** |
|
||||
| 压力最大绝对差 | 65.686768 → **65.686768 Pa** | 65.686768 → **65.686768 Pa** |
|
||||
| 温度最大绝对差 | 0.395395 → **0.395395 K** | 0.395395 → **0.395395 K** |
|
||||
| 明确非零且相对差超过 5% 的曲线样本数 | 63 → **56** | 32 → **30** |
|
||||
| 修改后信号阶段不匹配的比较点 | **0** | **0** |
|
||||
| 修改后八路接触/分离标志不匹配的比较点 | **0** | **0** |
|
||||
|
||||
5% 仍是诊断筛查线,不是工程验收公差。循环剩余 56 个超线曲线样本为接触力 24、速度 2、质量流 23、焓流 7;非循环剩余 30 个为质量流 23、焓流 7。事件之外的小流量/焓流差异未因本次修改消失。历史初评中的 61 个不能直接当作本次修改前计数,因为本次对照的 UD00 已修复。
|
||||
|
||||
### 32.4 s 为何仍需继续查
|
||||
|
||||
选中的平台时刻为 `32.400000000000006`,Amesim 为 `32.40000000000221`。两边 UD00 均为事件后的值,第 2 路间隙均为负、处于接触区,但力仍分别为 **468,662.661 N** 与 **1,754,152.144 N**。
|
||||
|
||||
本次证据只排除了“信号前值对信号后值”的误配,不能排除高刚度过程对约 `2.20e-12 s` 实际时间差的敏感性,也不能证明缺少接触事件就是该误差的唯一原因。弹性接触力取决于连续位移/速度;切换信号输出不会直接把这些连续状态改成 Amesim 的值。
|
||||
|
||||
共同 10 ms 网格仍不是原始瞬态的上界:循环额外事件点中约 **2.084e14 N** 的绝对力峰仍存在;非循环原始峰值约 **4.035e11 N**。这些原始峰未被平滑、删除或纳入不具备同分辨率参考的精度结论。循环在 t≥0.1 s 且避开信号边界前后 0.02 s 的定位统计中,最大力差约 **0.276 N**,不能替代完整事件段验收。
|
||||
|
||||
## 6. 是否改变求解与耗时
|
||||
|
||||
对两组修改前后原始结果逐项核验:全部旧样本仍保留原始时间,1,784 条原输出在这些时刻数值完全一致,最终状态和全部下列积分计数也一致。这支持本次为输出/对照语义修改,没有改变八路积分轨迹。
|
||||
|
||||
| 项目 | 循环:修改前 → 修改后 | 非循环:修改前 → 修改后 |
|
||||
| --- | --- | --- |
|
||||
| 实际保存点数 | 5,010 → 5,028 | 5,002 → 5,006 |
|
||||
| 接受步数 | 19,606 → 19,606 | 11,238 → 11,238 |
|
||||
| 拒步计数 | 1,552 → 1,552 | 885 → 885 |
|
||||
| 方程求值 | 85,570 → 85,570 | 56,299 → 56,299 |
|
||||
| 求解器启动次数 | 20 → 20 | 5 → 5 |
|
||||
| 雅可比刷新 | 1,835 → 1,835 | 1,270 → 1,270 |
|
||||
| 线性 setup 次数 | 6,028 → 6,028 | 3,603 → 3,603 |
|
||||
| 求解耗时,单次 | 11.945 → 11.572 s | 7.357 → 7.469 s |
|
||||
| 平台进程耗时,单次 | 18.339 → 17.851 s | 13.638 → 13.869 s |
|
||||
|
||||
这些单次耗时有运行波动,不能据此声称性能提升或给出可靠开销百分比;可以确认没有新增积分重启与 RHS 求值。新增保存和输出重放仍有实际工作量。
|
||||
|
||||
## 7. 后续判断与复现
|
||||
|
||||
输出阶段误配已消除,可将这两组作为接下来修改的基线。继续判断循环接触力峰前,应在同一实际时刻或足够细的共同时间窗口核对位移、速度、间隙和接触力,区分保存时间偏移、动态响应及接触事件定位的影响;现有结果不支持直接把全部力峰差归因于接触事件缺失。
|
||||
|
||||
汇总证据:[前后效果对照](../../test/output-semantics-20260917/effect-summary.json)、[修改后运行汇总](../../test/output-semantics-20260917/after/summary.json)、[循环阶段配对](../../test/output-semantics-20260917/after/full/phase-pairing.json)、[非循环阶段配对](../../test/output-semantics-20260917/after/noncyclic/phase-pairing.json)。
|
||||
|
||||
```powershell
|
||||
.\.venv-win\Scripts\python.exe -X utf8 tests/manual/evaluate_mql8_correctness.py --output test/output-semantics-rerun --ame-home F:/AMESim2404/Amesim --align-cyclic-from-ame --noncyclic-ame test/node-fixes-amesim-20260914/test_mql.ame --noncyclic-project tests/data/test-mql-8-corrected.json --profiles full noncyclic
|
||||
```
|
||||
|
||||
输出目录必须是新目录。`--native-source` 可指定本次冻结源码作修改前对照;`tests/manual/summarize_output_semantics.py` 核验 before/after 两组结果。原始结果位于 Git 忽略的 `test/output-semantics-20260917/`;代码、测试与本报告为可跟踪交付。
|
||||
@@ -0,0 +1,132 @@
|
||||
# 八路曲线剩余差异占比与全程评价
|
||||
|
||||
日期:2026-09-17。
|
||||
|
||||
## 1. 结论与适用范围
|
||||
|
||||
**在目前 0–50 s、10 ms 共同输出网格上,两侧主要运行过程的数值一致性较好,剩余流量和焓流差异对整条曲线的影响很小。这个结论支持当前平台的初步功能展示和基线一致性说明。**
|
||||
|
||||
循环工况的 238 条曲线中,只有 3 条曲线、6 个“曲线×时刻”样本超过原来的 5% 相对差筛查线;它们集中在 0.30、0.31、0.32 s 三个时刻,占 5,001 个共同输出时刻的 **0.0600%**。不过,不能据此说其余时间完全没有问题:参考值接近零时,另有零星绝对差异;把这类点也计入,涉及 **34 / 5,001 个时刻,即 0.6799%**。
|
||||
|
||||
比占比更有说服力的是幅值和累计指标:质量流量各曲线中最差的全程相对 L2 误差为 **0.008566%**,焓流为 **0.007368%**;逐条曲线的累计绝对差与参考累计绝对值之比,最差分别为 **0.013934%** 和 **0.013814%**。这两种指标不会仅因为增加长时间的双方零输出而变小。
|
||||
|
||||
本次只读取已有结果,不修改元件、求解器、配对逻辑或工况,不重新求解。统计不包含共同网格之间所有自适应步或所有机械事件点,因此不构成未采样的极短瞬态误差上界。流量和焓流的差异尚未完成根因定位;本次量化的是影响范围和量级。
|
||||
|
||||
## 2. 数据来源与评价口径
|
||||
|
||||
- 循环:上一轮 LSTP 已接入主路的结果,对比开启不连续点输出的 Amesim 结果;238 条曲线,5,001 个共同网格点,全部成功配对。
|
||||
- 不循环:同一轮主路基线的已有结果,Amesim 参照仍为普通输出,采用原有信号阶段配对;主要用来交叉检查剩余流量和焓流差异是否重复出现。
|
||||
- 每个网格点、所有变量沿用同一对原始记录,不根据误差大小重新选择事件侧,没有平滑、插值或删除异常点。
|
||||
- 原相对差口径为 `100 × |平台−Amesim| / |Amesim|`。质量流量只有在 `|Amesim| > 1e-6 kg/s` 时计算该比值;焓流门槛为 `1 W`。这些是已有报告的诊断门槛,不是工程验收公差。
|
||||
- 接近零的区间单列:`|Amesim| ≤ 门槛` 且 `|平台−Amesim| > 门槛`。避免除以极小数,也避免把这些点直接忽略。
|
||||
- “全程占比”使用曲线样本数或不重复时刻数,分母分别注明。连续标记点折合时间只是 10 ms 网格上的估计,不是已经定位的超差起止时刻。
|
||||
|
||||
令差值为 `e`、参考值为 `r`、梯形积分权重为 `w`:
|
||||
|
||||
- 全程相对 L2 误差:`100 × sqrt(Σw·e² / Σw·r²)`,即相对均方根误差。
|
||||
- 全程相对 L1 误差:`100 × Σw·|e| / Σw·|r|`,避免正负误差相互抵消。
|
||||
- 累计输送量误差:对流量或焓流差值做梯形积分;另保存绝对差积分和任意时刻累计有符号差的最大值。
|
||||
|
||||
积分均为已有 10 ms 网格上的估算。每条节点通道独立计算,不把串联节点的流量相加当成系统总输送量,也不把这些积分当成完整的守恒验证。
|
||||
|
||||
## 3. 超过 5% 的差异有多大占比
|
||||
|
||||
每类流量都有 16 条对照曲线,每条 5,001 个点。
|
||||
|
||||
| 变量类别 | 超过 5% 的曲线数 | 超过 5% 的样本数 | 占该类全部 80,016 个样本 | 占该类高于近零门槛的样本 |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| 质量流量 | 2 | 4 | 0.004999% | 4 / 576 = 0.6944% |
|
||||
| 焓流 | 1 | 2 | 0.002500% | 2 / 426 = 0.4695% |
|
||||
|
||||
下面按单条受影响曲线计算,防止其他无差异曲线稀释占比:
|
||||
|
||||
| 曲线 | 超过 5% 的时刻,s | 占本曲线全部样本 | 占本曲线高于近零门槛的样本 | 最大相对差 |
|
||||
| --- | --- | ---: | ---: | ---: |
|
||||
| `amesim_pn3node2_2.reference_mass_flow` | 0.30 | 0.0200% | 1 / 32 = 3.125% | 11.111% |
|
||||
| `amesim_pn3node2_3.reference_mass_flow` | 0.30、0.31、0.32 | 0.0600% | 3 / 32 = 9.375% | 32.690% |
|
||||
| `amesim_p4node2_4.reference_enthalpy_flow` | 0.31、0.32 | 0.0400% | 2 / 35 = 5.714% | 11.360% |
|
||||
|
||||
所以,单说“占全程很小”不够:最差流量曲线高于近零门槛的样本中,仍有 9.375% 超过相对差筛查线。关键是它们全部位于衰减尾部,实际量值很小:
|
||||
|
||||
- 最大相对流量差位于 0.32 s:Amesim **3.66657 mg/s**,平台 **2.46797 mg/s**,差 **1.19860 mg/s**;该曲线参考峰值约 **249,299 mg/s**。
|
||||
- 最大相对焓流差位于 0.31 s:Amesim **−3.08080 W**,平台 **−2.73081 W**,差 **0.34999 W**;该曲线参考绝对峰值约 **522,749 W**。
|
||||
- 0.30–0.32 s 并非本基线登记的 STEP/UD00 信号切换时刻。当前不能把这些剩余差异直接归因为之前的事件侧配对问题。
|
||||
|
||||
若仅查看参考幅值超过各自峰值 1% 的主要幅值区间,并同时要求高于近零门槛,质量流量最大逐点相对差为 **0.11559%**,焓流为 **0.10395%**。1% 峰值是用于区分主要幅值和衰减尾部的辅助口径,不替代上面的全样本统计。
|
||||
|
||||
门槛敏感性也支持差异集中于小量区间:近零门槛缩小到原来的 0.1 倍,超过 5% 的样本增至流量 79、焓流 29;扩大到 10 倍,两类都为 0。本报告保留原门槛,未靠改门槛消除差异。
|
||||
|
||||
## 4. 接近零的区间没有被忽略
|
||||
|
||||
| 类别 | 接近零但绝对差超过门槛的样本 | 占该类全部样本 | 这些点上的最大绝对差 |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| 质量流量 | 44 | 0.054989% | 7.24440 mg/s |
|
||||
| 焓流 | 2 | 0.002500% | 8.01591 W |
|
||||
|
||||
这些异常涉及 31 个不重复时刻,网格折合约 0.31 s,占全程约 0.62%。多数是零散点,最长连续标记段为 45.80–45.84 s 的 5 个样本,网格折合约 0.05 s。焓流两个点分别在 1.41 s 和 46.18 s,并与流量异常时刻重合。
|
||||
|
||||
连同相对差超过 5% 的三个时刻,共涉及 34 个时刻,网格折合约 0.34 s、约 0.68%。**99.32% 的共同网格时刻未触发上述任一筛查条件**,但这不表示误差严格为零。
|
||||
|
||||
按运行阶段分组,流量/焓流的主要绝对差仍在初始阶段;后续循环中没有再次出现高于原近零门槛且相对差超过 5% 的点:
|
||||
|
||||
| 时间区间,s | 最大流量绝对差,mg/s | 最大焓流绝对差,W | 流量近零异常样本 | 焓流近零异常样本 |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| [0, 1) | 24.2465 | 18.6888 | 2 | 0 |
|
||||
| [1, 10.8) | 6.5727 | 8.0159 | 9 | 1 |
|
||||
| [10.8, 21.6) | 0.2172 | 0.02551 | 0 | 0 |
|
||||
| [21.6, 32.4) | 7.2444 | 0.26117 | 5 | 0 |
|
||||
| [32.4, 43.2) | 4.5750 | 0.17762 | 8 | 0 |
|
||||
| [43.2, 50] | 6.3927 | 5.08374 | 20 | 1 |
|
||||
|
||||
## 5. 全程幅值与累计影响
|
||||
|
||||
以下每一列均独立取该类曲线中的最差值,因此同一行不同列可能来自不同曲线。
|
||||
|
||||
| 变量类别 | 最大全程相对 L2 误差 | 最大全程相对 L1 误差 | 最大逐点绝对差 |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| 接触力,8 条 | 0.000008651% | 0.000004595% | 1.31240 N |
|
||||
| 质量流量,16 条 | 0.008566% | 0.013934% | 24.2465 mg/s |
|
||||
| 焓流,16 条 | 0.007368% | 0.013814% | 18.6888 W |
|
||||
| 压力,56 条 | 0.00001109% | 0.000004617% | 61.1058 Pa |
|
||||
| 温度,56 条 | 0.002601% | 0.002407% | 0.389714 K |
|
||||
| 接触间隙,8 条 | 0.133016% | 0.045482% | 54.7406 nm |
|
||||
|
||||
接触间隙的最大逐点相对差为 1.16799%,但对应约 55 nm 的绝对差;因此除近零流量/焓流外,也不应宣称所有变量逐点都小于 1%。其余类别的完整逐曲线结果保存在统计 JSON 中。
|
||||
|
||||
质量流量的绝对差积分最大为 **7.82056e−7 kg = 0.782056 mg**;同一条曲线的参考绝对流量积分为 **5.61262 g**,比值 **0.013934%**。所有流量曲线中,任意时刻累计有符号差的最大绝对值为 **0.364845 mg**。
|
||||
|
||||
焓流的绝对差积分最大为 **0.491310 J**;该通道参考绝对焓流积分约 **12,521.9 J**。逐条比较误差积分与各自参考积分,最差比例为 **0.013814%**,来自另一条较小幅值通道。所有焓流曲线中,任意时刻累计有符号差的最大绝对值为 **0.307860 J**。
|
||||
|
||||
这些结果表明,在已保存输出的尺度上,剩余差异没有表现为显著的累计质量输送或能量输送偏差。
|
||||
|
||||
模型中另有异常量级的机械位移/容积输出,例如某位移参考值达到约 1.12e17 m;其绝对差虽大,相对差很小。本报告评价两套实现的一致性,不把这类模型本身的异常物理量级解释为工程工况合理,也不笼统宣称所有量的绝对差都小。
|
||||
|
||||
## 6. 不循环工况交叉检查
|
||||
|
||||
不循环工况仍然是相同三个时刻、相同三条曲线、相同六个相对差超过 5% 的样本。质量流量/焓流最差全程相对 L2 误差分别为 **0.008262% / 0.007048%**,相对 L1 误差分别为 **0.010307% / 0.010197%**。
|
||||
|
||||
接近零的绝对异常少于循环工况:流量 11 个样本,焓流 1 个;加上相对异常,共涉及 13 个不重复时刻,占 5,001 个时刻的 **0.25995%**。这支持主要剩余相对差属于初始衰减尾部,不是循环越多便持续积累的整体偏离。
|
||||
|
||||
## 7. 展示用结论与复现
|
||||
|
||||
可以在当前基线展示中使用以下表述:
|
||||
|
||||
> 在与 Amesim 对齐工况和事件输出阶段后,0–50 s、10 ms 共同输出网格上的主要响应曲线具有良好的数值一致性。质量流量和焓流最差全程相对均方根误差分别约为 0.0086% 和 0.0074%;较大的逐点相对差主要集中于近零衰减尾部,对累计输送量的影响很小。该评价不覆盖共同网格之间的全部极短瞬态。
|
||||
|
||||
本次不需要为整体展示而优先修改流量或焓流公式。若后续目标是低流量尾部、微小泄漏或每一事件内部瞬态的精确复现,再针对这些区间增加密集采样与根因定位;现有占比不应被当作这类目标已经通过的证据。
|
||||
|
||||

|
||||
|
||||
- [完整统计:两种工况、所有曲线、区间及异常点](../../test/mql8-curve-coverage-20260917/coverage.json)
|
||||
- [只读分析脚本](../../tests/manual/analyze_mql8_curve_coverage.py)
|
||||
- [上一步力差与事件输出定位报告](LSTP主路接入与八路力差定位-2026-09-17.md)
|
||||
|
||||
复现统计无需重新仿真:
|
||||
|
||||
```powershell
|
||||
.\.venv-win\Scripts\python.exe -X utf8 tests/manual/analyze_mql8_curve_coverage.py
|
||||
# 本机已有 matplotlib 的环境可同时生成图:
|
||||
F:\Anaconda\python.exe -X utf8 tests/manual/analyze_mql8_curve_coverage.py --plots
|
||||
```
|
||||
|
||||
脚本核验:全部输入有限、共同网格完整配对、时间严格递增、积分权重合计 50 s;逐条曲线重算的相对异常数和近零异常数与此前报告完全一致;读取前后的输入 SHA-256 不变。原平台代码与仿真结果未改动。
|
||||
@@ -0,0 +1,165 @@
|
||||
# 八路模型正确性初评与展示建议
|
||||
|
||||
日期:2026-09-17。代码提交:`1aac2200843009a86066271d3bfb1053bd8d6b2d`。本机 Windows / Python 3.12.3 / GCC 8.1 / SUNDIALS 7.4.0。
|
||||
|
||||
## 评价结论
|
||||
|
||||
**平台已具备初步展示核心仿真功能的条件,但尚不能表述为“全部结果与 Amesim 一致”或“已完成工程精度验证”。**
|
||||
|
||||
本轮重新执行当前 Amesim 模型程序和当前平台代码,共完成六组对照,每组比较 238 条关键曲线。20 项相关自动化回归全部通过。压力、温度、常规行程和质量守恒表现较好;当前仍需处理默认模型配置不一致、循环信号边界不一致,以及小流量/焓流的局部偏差。
|
||||
|
||||
原始模型输入和 143 个已跟踪生产文件的 SHA-256 在评估前后均未变化。本轮新增评估脚本、图片和报告,没有修改组件公式、求解器或默认工程。
|
||||
|
||||
## 1. 首先发现:当前两份默认模型并非相同工况
|
||||
|
||||
| 项目 | 当前平台 JSON | 当前 Amesim AME |
|
||||
| --- | --- | --- |
|
||||
| 文件 | `tests/data/test-mql-8-corrected.json` | `tests/data/test_mql.ame` |
|
||||
| 两个 UD00 信号 | 非循环,`iscyclic=0` | 循环,Amesim 枚举值为 2 |
|
||||
| 仿真终点 | 10 s | 50 s |
|
||||
| 输出间隔 | 0.01 s | 0.05 s |
|
||||
| 误差限数值 | 后端默认 rtol=1e-8 | tolerance=1e-7 |
|
||||
|
||||
结构审计得到 **157 个元件、178 条逐端口连接、1,092 项公开参数**;只有两个 UD00 的循环参数不匹配,连接差异为 0。当前 AME 的 SHA-256 为 `0ad9117d88c64c743fcfc41c7b1c5d10854527ab6478cc76ffa092913e52ada3`,与 9 月 14 日旧报告的 `251b2f…` 不同,不能直接复用旧报告作为当前输入的结论。
|
||||
|
||||
正式对照在新建 JSON 副本中,仅将这两个循环参数按 Amesim 语义设为 1;再次审计后 **1,092 项参数及全部连接一致**,并完成 1,015 项图纸参数与归档运行参数交叉核验。运行时间、输出间隔、误差限在两边的副本中统一。原文件保持原样。
|
||||
|
||||
证据:[原始审计](../../test/evaluation-mql8-20260917/audit-original/audit.json)、[两个参数的对齐记录](../../test/evaluation-mql8-20260917/alignment-changes.json)、[对齐后审计](../../test/evaluation-mql8-20260917/audit-aligned/audit.json)。
|
||||
|
||||
## 2. 本轮实际运行与比较口径
|
||||
|
||||
| 工况 | 信号 | 时长 | 输出间隔 | 两边误差限数值 | 结果 |
|
||||
| --- | --- | ---: | ---: | ---: | --- |
|
||||
| 对齐后的短演示 `default` | 循环 | 10 s | 0.01 s | 1e-8 | 两边完成 |
|
||||
| 当前模型全程 `full` | 循环 | 50 s | 0.01 s | 1e-8 | 两边完成 |
|
||||
| 启动细采样 `startup` | 循环 | 0.15 s | 0.0001 s | 1e-8 | 两边完成 |
|
||||
| 启动容差收紧 `startup-refined` | 循环 | 0.15 s | 0.0001 s | 1e-10 | 两边完成 |
|
||||
| 最初压缩过程 `volume-startup` | 循环 | 2 μs | 2 ns | 1e-10 | 两边完成 |
|
||||
| 非循环对照 `noncyclic` | 非循环 | 50 s | 0.01 s | 1e-8 | 两边完成 |
|
||||
|
||||
非循环对照使用已保存、重新审计的旧版非循环 AME 与当前默认 JSON,只在副本中统一运行设置;同样重新执行程序,没有读取旧运行曲线代替新结果。其余五组使用当前 AME。
|
||||
|
||||
Amesim 端提取源归档内的可执行程序与运行输入后重新运行;没有重新编译 Amesim。除 `.sim` 前五个运行设置外,提取文件逐字节校验不变。平台走 JSON→System XML→组件网络→当前原生 C 编译/运行。平台使用 CVODE BDF,最大步长为 1e30;Amesim 保留其余原运行选项。相同误差限数字不代表两套求解器的误差权重和算法完全相同。
|
||||
|
||||
每组映射压力、温度、位移、速度、8 路接触力与间隙、节点焓流/质量流、气室质量/容积/容积功、活塞容积及信号,共 **238 条曲线**。平台完整输出为 **1,784 条**;其余输出检查了有限性,未逐条声明与 Amesim 相符。节点焓流由保存的各支路流量和流入焓按符号重构;Amesim 气室体积功按其保存的压力、连接容积变化率及容积下限条件重构。
|
||||
|
||||
单位统一为 SI:Amesim 表压加 101300 Pa,g 转 kg,cm³ 转 m³,L/min 转 m³/s,间隙 mm 转 m。映射来自元件拓扑和端口审计,没有交换元件、拟合时间轴或任意改符号。
|
||||
|
||||
**时间比较方法:**在共同规则网格上,若原始保存时刻距名义采样时刻不超过输出间隔的 1e-7,直接读取最近保存值;其他点线性插值。保留原记录的事件侧别,不平均、不平滑尖峰。直接对 `1e17→49000` 的巨大跳变做插值,会因输出时间浮点漂移在 0.81 s 伪造 57888 等尾值。本轮已用原始样本消除这一比较器伪差;原始结果、原始时刻及朴素插值诊断仍保留。
|
||||
|
||||
所有“最大差”均指所述采样网格,不是连续时间极值。事件点不从主统计中删除;另外的事件外指标仅用于定位问题。
|
||||
|
||||
## 3. 主要结果
|
||||
|
||||
| 指标 | 50 s 循环全程,10 ms 采样 | 启动 0.15 s,0.1 ms 采样 |
|
||||
| --- | ---: | ---: |
|
||||
| 最大绝对压力差 | **65.687 Pa** | **4,641.503 Pa** |
|
||||
| 最大温差 | **0.3954 K** | **0.4575 K** |
|
||||
| 压力最大逐点相对差 | 0.000319% | 0.02022% |
|
||||
| 温度最大逐点相对差 | 0.004197% | 0.007854% |
|
||||
| 节点焓流最大绝对差 | 141.920 W | 27,064.123 W |
|
||||
| 节点质量流最大绝对差 | 1.3268e-5 kg/s | 0.390305 kg/s,位于 0.04 s 阶跃点 |
|
||||
| 8 路接触力最大绝对差 | **1,285,489.483 N**,32.4 s | 105.579 N |
|
||||
| 普通质量块最大位移差,排除特殊 #9 | 1.2930e-8 m | 7.4362e-13 m |
|
||||
|
||||
表中各指标取该类全部映射曲线中的最大值,最大绝对差与最大相对差可能属于不同曲线和时刻。
|
||||
|
||||

|
||||
|
||||
### 完成状态与基本物理检查
|
||||
|
||||
- 六组均完成指定终点;所有读取的结果数值有限,输出时间有序。50 s 循环运行到达 50 s,没有再出现早期的 10.8 s 提前退出。
|
||||
- 56 个气体质量状态合计初值约 **5.566893 kg**。六组中最大总质量漂移为 **4.3521e-14 kg**,相对漂移约 **7.82e-15**。
|
||||
- 所检查的保存结果中气体质量、绝对压力和温度均为正。质量守恒通过不等于能量及所有本构关系均已验证。
|
||||
- 20 项回归全部通过,覆盖默认非循环八路 10 s 完整运行、节点能量与容积传递、容积功和下限、氦气物性与反解、UD00 信号链路、压力单位、CSV 导出。首次运行中的部分 GCC 启动失败经现有重试机制恢复;最终没有测试失败。
|
||||
|
||||
### 容积下限的快速过程
|
||||
|
||||
普通 10 ms 采样看不到最初快速压缩,不能只拿恒定容积说明实现正确。2 ns 采样下,双方第 15 个气室都在 32 ns 的首个下限采样点达到 **0.15 L**,此前初值为 15 L。八个气室最大容积差约 **1.716e-13 m³**;体积功率最大绝对差约 **5.306e5 W**,最大逐点相对差约 **4.786e-6%**,参考功率本身约为 1e13 W 量级。
|
||||
|
||||

|
||||
|
||||
该八路文件中的活塞直接连接气室;经节点传递容积与非零预设容积变化率的覆盖来自本轮通过的专项测试,不能仅由这张图推断。
|
||||
|
||||
## 4. 仍不能验收为全部一致的部分
|
||||
|
||||
### 4.1 循环事件与采样边界:已确认存在实现缺陷
|
||||
|
||||
当前原生信号函数分别通过 `fmod` 判断周期位置、通过周期乘法定位事件。本轮直接编译调用当前源文件,得到:
|
||||
|
||||
| 事件函数返回时刻 | 该时刻信号求值 | 应进入的阶段值 | 下一个 double 时刻的值 |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| 44 s | 1e17 | 49000 | 49000 |
|
||||
| 54 s,补充探针 | 49000 | 1e17 | 1e17 |
|
||||
|
||||
这证明同一数值时刻上的事件定位和信号求值不一致;不需要积分器即可复现。定位文件:[signal.c](../../native/components/modules/signal.c)。证据:[探针输出](../../test/evaluation-mql8-20260917/signal-probe/signal-boundaries.csv)。
|
||||
|
||||
32.4 s 的大接触力差还包含另一层问题:平台保存时间为 `32.4`,此时 UD00 为 49000;Amesim 保存时间为 `32.40000000000221`,UD00 为 1e17。第 2 路接触力分别为 **468662.661 N** 和 **1754152.144 N**。显示相同的小数时间并不保证处于跳变的同一侧,不能把该差额直接认定为接触力本构公式错误。
|
||||
|
||||
仅作定位:保留 t≥0.1 s 并避开各信号边界前后 0.02 s 后,8 路接触力最大差为 **0.276 N**,普通质量块速度最大差约 **1.35e-7 m/s**。这不能替代包括事件点的整段验收。
|
||||
|
||||
此外,平台原始额外事件样本在约 `32.40035510065 s` 保存了约 **−2.084e14 N** 的接触力;共同 10 ms 网格未包含这个样本,Amesim 本轮保存点也未覆盖同一时刻。因此本轮无法对该窄峰完成同侧、同分辨率定量验收,不能把共同网格最大差当作全部原始事件样本的上界。
|
||||
|
||||
### 4.2 小流量与焓流:绝对差小,但局部相对差仍明显
|
||||
|
||||
沿用此前报告的诊断分界:焓流参考绝对值超过 1 W、质量流超过 1e-6 kg/s 时计算逐点相对误差;参考更接近零时单列原值和绝对差。**±5% 是本轮筛查线,不是用户批准的工程公差。** 其他物理量分界及分界乘/除 10 的敏感性保存在指标文件中。
|
||||
|
||||
| 50 s 工况中的样本 | Amesim | 当前平台 | 绝对差 | 相对差 |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| P4NODE2_1 参考焓流,0.32 s | −2.375850 W | −1.641047 W | 0.734803 W | −30.928% |
|
||||
| P4NODE2_2 参考质量流,0.32 s | 3.260972e-6 kg/s | 8.351735e-6 kg/s | 5.090763e-6 kg/s | +156.112% |
|
||||
|
||||
50 s 循环共同网格中,明确非零的超 5% 样本为 **61 个**:接触力 24、速度 2、信号 5、焓流 7、质量流 23。其中 **30 个位于信号事件点之外**,全部属于上述焓流/质量流;不能将所有差异解释成事件侧别。参考近零的异常另计,没有因为不算相对误差而自动通过。
|
||||
|
||||
启动段 0.04 s 的质量流约 0.390305 kg/s 差异位于阶跃点;收紧双方误差限后,该点差异消失,启动质量流最大差降为 0.0009686 kg/s。另一方面,启动焓流过零附近仍有约 0.32 W 差异。收紧容差后最大压差仍约 **4.551 kPa**,最大温差为 **0.5214 K**,说明剩余偏差没有简单随误差限收紧消失。
|
||||
|
||||
本轮没有证明管阻公式、近零流量闭合或积分误差中的哪一项是剩余偏差的唯一原因。应在相同状态输入下逐项比较,再决定修改位置。
|
||||
|
||||

|
||||
|
||||
### 4.3 输入本身属于极端工况,数值对齐不等于物理有效
|
||||
|
||||
模型包含 1e17 量级激励;无限位、无摩擦的特殊质量块 #9 在循环 50 s 时位移约 **1.12e17 m**。其最大绝对位移差约 **3.056e10 m**,最大逐点相对差约 **9.78e-5%**。该量及相连活塞的巨大几何容积必须单独列出,不能与普通行程的绝对误差混合评价。
|
||||
|
||||
启动细采样的气体温度达到约 **11759 K**;当前物性诊断也报告状态方程有效上限 1500 K 被越过,并报告内部理想热量学查询约 39.44 K 低于其 200 K 下限。39.44 K 是内部物性查询温度,不是初始气室温度。这些提示来自本次实际运行。
|
||||
|
||||
因此该输入适合展示复杂网络、刚性系统、事件和诊断能力;若用于展示某个真实设备的预测精度,需要另行明确合理的载荷、约束和物性适用工况,并以实验或可靠工程基准验证。
|
||||
|
||||
## 5. 建议修改优先级与验收方式
|
||||
|
||||
| 优先级 | 修改对象 | 依据 | 修改后应如何验收 |
|
||||
| --- | --- | --- | --- |
|
||||
| P1,展示前 | 默认 AME/JSON 的工况管理 | 两个循环开关、终点、采样间隔不同 | 明确主展示工况;保存成对的 AME/JSON 与哈希;参数、端口和运行设置审计一致 |
|
||||
| P1,正确性 | UD00 的阶段判定、事件定位和输出侧别 | 当前 44 s/54 s 探针直接失败;循环接触力事件点差异大 | 为所有边界检查前一个 double、边界、本身之后一个 double;约定事件前/后输出;比较事件时刻、同侧力与速度及窄窗口原始样本 |
|
||||
| P2,精度 | 启动残差与小流量/焓流 | 事件之外仍有偏差,收紧容差后未完全消失 | 先做同状态物性、管流、节点输入输出探针;再做分辨率/容差收敛;同时报告绝对误差和非零相对误差 |
|
||||
| P2,展示模型 | 极端载荷、自由质量块与物性适用域 | 巨大位移、超温、纳秒级压缩 | 保留当前模型作为压力测试;另建有合理量级和约束的展示工况,重新对齐两平台,不能仅缩坐标轴隐藏异常 |
|
||||
|
||||
现有结果不足以支持“先更换积分器”或“继续优化求解器即可修复曲线差异”。已证明的边界缺陷和输入一致性应优先处理。
|
||||
|
||||
## 6. 可用于初步展示的内容
|
||||
|
||||
建议展示顺序为:加载八路工程 → 查看元件、连接与信号设置 → 运行 → 叠加两平台压力/温度/普通行程 → 展示误差曲线 → 查看物性诊断与事件差异 → 导出结果。
|
||||
|
||||
可直接导入的评估副本:[10 s 对齐工程](../../test/evaluation-mql8-20260917/default/platform.json)、[50 s 循环工程](../../test/evaluation-mql8-20260917/full/platform.json)。两者已与当前 AME 的物理输入对齐。
|
||||
|
||||
可用表述:“已完成 157 元件、132 状态八路网络的原生求解及结果输出,对 238 条关键曲线进行了 Amesim 对照;主要连续状态吻合较好,事件边界和小流量精度仍在完善。”
|
||||
|
||||
本轮没有执行真实浏览器中的拖拽、导入按钮、持久化恢复、绘图及取消全流程,不将后端测试通过等同于前端展示流程已经验收。单次 50 s 循环平台求解约 12.41 s,Amesim 完整进程约 7.59 s;计时边界不同且未重复测量,**不据此计算性能优劣比**。
|
||||
|
||||
## 7. 交付与复现
|
||||
|
||||
全部本机证据在 `test/evaluation-mql8-20260917/`,该目录按仓库规则被 Git 忽略;报告及四个脚本为新增可跟踪文件。
|
||||
|
||||
- [总指标与运行状态](../../test/evaluation-mql8-20260917/summary.json)、[输入/代码哈希](../../test/evaluation-mql8-20260917/manifest.json)、[评估结束哈希核验](../../test/evaluation-mql8-20260917/source-verification.json)。
|
||||
- [1,428 条分工况曲线指标 CSV](../../test/evaluation-mql8-20260917/curve-errors.csv)、[18 条展示变量的双平台曲线 CSV](../../test/evaluation-mql8-20260917/showcase-curves.csv)。每个工况另有完整 `curves.npz`、`comparison.json`、映射、原始结果、日志和事件邻近样本。
|
||||
- [20 项回归日志](../../test/evaluation-mql8-20260917/regression.log)、[信号边界探针](../../test/evaluation-mql8-20260917/signal-probe/signal-boundaries.csv)、[采样匹配检查](../../test/evaluation-mql8-20260917/sampling-verification.json)。
|
||||
- [主评估脚本](../../tests/manual/evaluate_mql8_correctness.py)、[曲线映射](../../tests/manual/mql8_comparison.py)、[边界探针脚本](../../tests/manual/probe_mql8_signal_boundaries.py)、[绘图脚本](../../tests/manual/plot_mql8_evaluation.py)。
|
||||
|
||||
从仓库根目录使用新的输出目录重跑当前循环模型五组对照:
|
||||
|
||||
```powershell
|
||||
.\.venv-win\Scripts\python.exe tests/manual/evaluate_mql8_correctness.py --output test/evaluation-mql8-rerun --ame-home F:/AMESim2404/Amesim --align-cyclic-from-ame
|
||||
.\.venv-win\Scripts\python.exe tests/manual/probe_mql8_signal_boundaries.py --output test/evaluation-mql8-rerun/signal-probe
|
||||
```
|
||||
|
||||
可选追加 `--noncyclic-ame test/node-fixes-amesim-20260914/test_mql.ame --noncyclic-project tests/data/test-mql-8-corrected.json`,重跑第六组非循环对照;该历史副本只存在于当前工作站证据目录。绘图脚本需要 Matplotlib,本轮使用已安装该库的 `F:/Anaconda/python.exe`。主评估脚本仅需项目既有运行依赖与 NumPy。
|
||||
@@ -0,0 +1,101 @@
|
||||
# 循环 UD00 事件边界修复与独立验证
|
||||
|
||||
日期:2026-09-17。环境:Windows,项目 `.venv-win`,MinGW GCC 8.1.0,原生 C 运行库,CVODE 7.4.0 BDF / RK45。
|
||||
|
||||
## 1. 本次完成的第一步
|
||||
|
||||
修复 UD00 的信号求值与事件时间计算不一致。实现位于 [signal.c](../../native/components/modules/signal.c),新增回归位于 [test_native_signal_boundaries.py](../../tests/test_native_signal_boundaries.py)。
|
||||
|
||||
原来信号值用 `fmod(t - tstart, period)` 判断当前阶段,事件查询另用绝对时间计算。两种浮点运算可能落在边界两侧。例如阶段时长为 0.8 s 和 10 s 时,事件查询已经返回 44 s,而取模仍小于 0.8,信号在该时刻仍输出上一段的 `1e17`。
|
||||
|
||||
现在 `native_signal()` 与 `native_signal_break()` 共用 `signal_interval()`,共同确定当前阶段、阶段起点及下一边界。阶段内部仍按线性插值计算;周期结束统一使用下一周期的起点,避免同一事件出现两个相邻浮点时间。
|
||||
|
||||
本次没有修改八路工程 JSON、Amesim 文件、积分算法或结果采样协议。已有 UD00 的调用接口保持不变,两条原生生成路径均自动使用修复后的内核。
|
||||
|
||||
## 2. 修改后的事件定位及处理
|
||||
|
||||
### 时间边界定位
|
||||
|
||||
设信号开始时间为 `s`,各段累计时长为 `offset[i]`,周期为 `P`:普通阶段边界按 `(s + offset[i]) + k * P` 计算;周期终点统一采用下一周期起点 `s + (k + 1) * P`。这些表达式的浮点运算顺序也是合同的一部分,求值与事件查询共同使用同一函数。
|
||||
|
||||
当前周期由估算值开始,再依据绝对周期起点修正。阶段采用左闭右开区间:严格早于边界时仍在前段,恰好等于边界时进入后段;零时长阶段被跳过。查询返回严格晚于当前时间的最近事件,无后续事件或事件超过仿真终点时返回仿真终点。
|
||||
|
||||
### 运行库处理
|
||||
|
||||
1. 生成的 `model_next_break(t, end)` 汇总各信号的下一边界,选择最早一个。
|
||||
2. BDF / RK45 在这个时间边界处分段积分。对仿真内部的边界,旧段积分终点是边界左侧相邻浮点数 `nextafter(boundary, -INFINITY)`。
|
||||
3. 到达边界后保留连续状态,将时间推进到该边界,并重新启动积分。此时信号求值已切换到新段,导数计算使用新信号。
|
||||
4. 结果输出仍按保存的实际时间和状态调用 `model_eval()` 重放。因为信号阶段是时间的纯函数,求解试算、回退和重放不会推进或污染一个全局阶段计数器。
|
||||
|
||||
第 1~4 项的运行库流程原来已经存在;本次让第 3、4 项使用的信号值与第 1 项报告的边界保持一致。连续状态如位置、速度不会仅因信号切换被重置;代数量如输出信号和力可以立即改变。机械碰撞、摩擦等由状态触发的事件仍使用各自的状态事件处理。
|
||||
|
||||
### 与 Amesim 对齐的范围
|
||||
|
||||
本次确立平台自身一致的右连续规则。Amesim 的 UD00 还维护当前阶段及 `TNEXT`,通过离散时间事件调用更新阶段;本次没有完整复制这套离散调用和结果保存协议。
|
||||
|
||||
尤其是普通浮点数 `32.4` 与本工况计算出的事件时间 `32.400000000000006` 不相等。前者仍属于边界前,测试专门保留这一点,没有使用全局 epsilon 提前切换。后续对照 Amesim 的原始采样时,应继续区分实际时间和事件前/后侧;此次不能直接推出此前八路模型在 32.4 s 的力尖峰差异已经消失。
|
||||
|
||||
## 3. 独立信号测试结果
|
||||
|
||||
测试网络只有一个循环 UD00:第一段 `1e17`,持续 0.8 s;第二段 `49000`,持续 10 s;从 0 s 开始循环。两种求解器均运行至 60 s,以 0.01 s 保存结果,共 6,001 个采样点。该模型没有物理动态状态,运行库使用一个内部常量状态执行真实求解及输出重放流程。
|
||||
|
||||
| 验证项 | 结果 |
|
||||
| --- | --- |
|
||||
| BDF 独立仿真 | 成功完成 60 s;6,001 点逐点符合冻结边界期望值 |
|
||||
| RK45 独立仿真 | 成功完成 60 s;6,001 点逐点符合冻结边界期望值 |
|
||||
| 两种求解器比较 | 全部采样值相同 |
|
||||
| 事件分段 | 两种求解器均启动 12 次:初始启动一次,11 个内部时间事件后分别重启 |
|
||||
| 44 s 信号 | 修改前 `1e17`;修改后 `49000`,符合后一段 |
|
||||
| 54 s 信号 | 修改前 `49000`;修改后 `1e17`,符合下一周期 |
|
||||
| 八段信号 1,000 周期 | 连续检查 8,000 个边界,无漏报、重复;边界左邻/本身/右邻均正确 |
|
||||
| 非零起点与小周期 | 3 组工况,各 900 个边界通过 |
|
||||
| 含零时长阶段的循环 | 连续 2,000 个边界通过;周期尾部零时长段不泄漏瞬时值 |
|
||||
| 其他 | 斜坡、非循环终值、零总时长、单段锯齿、乱序重放通过 |
|
||||
|
||||
新增 7 个测试方法及相关 3 个既有测试全部通过(最终版本 10 / 10,39.033 s,包含积分启动次数断言)。修改前先运行关键边界测试,已复现 44 s、54 s 及多阶段循环边界失败,详见保留日志。独立测试用于确认信号内核和求解/重放接入,不替代八路气动与机械系统的精度验收。
|
||||
|
||||
测试过程中曾遇到测试子进程返回空输出及 GCC 进程启动重试。边界查询已合并为单次批量调用,数值判定保持严格;最终定向测试通过。相关中间日志保留在验证目录,不把进程空输出当成边界数值错误,也不将一次成功重跑解释为环境问题已修复。
|
||||
|
||||
### 完整回归的结果与限制
|
||||
|
||||
另执行 `python -m unittest discover -s tests -v`,共运行 458 项,耗时 1,534.126 s,报告 7 个错误、25 项跳过,不能记为整库回归通过。新增 7 项信号测试、既有 UD00 XML、阶跃重启、信号驱动力以及当前八路工程保存配置的完整运行测试均通过。
|
||||
|
||||
| 错误来源 | 实际失败点与处理 |
|
||||
| --- | --- |
|
||||
| 管道多变过程测试 | `model --init` 输出不能解析为 JSON,尚未进入数值断言;单独复核又遇到 GCC 预处理超时 |
|
||||
| 冻结参考网络 38 | 发布编译缓存时目录重命名报 Windows `WinError 5` |
|
||||
| 雅可比固定状态夹具 | 夹具保存的输入哈希与当前八路 JSON 不一致,类初始化被主动阻止 |
|
||||
| 物性警告测试 | GCC 预处理超时;残留预处理进程退出后测试序列继续 |
|
||||
| 工程输入合同的三项测试 | 默认 GBK 解码 UTF-8 JSON 失败;仅加 `-X utf8` 单独重跑,3 / 3 通过 |
|
||||
|
||||
夹具期望输入 SHA-256 为 `670977bef67e62d9c66e8af497bada208bd72a7301be45128d185d47282cf288`;实际工作树及 `HEAD` 中八路 JSON 的 SHA-256 均为 `60ed16c71b72be4ae71ca7980f4f8cdcdf6b4c4c4c8950863c2390960b71ced4`,确认这项输入不匹配不是本次修改引入。没有为使回归通过而更新参考夹具、修改其他内核或放宽断言。本次仅在 Windows 验证,未声明 Linux 验收通过。
|
||||
|
||||
验证文件:
|
||||
|
||||
- [修改前失败日志](../../test/ud00-boundaries-20260917/before-tests.log)
|
||||
- [最终定向测试通过日志](../../test/ud00-boundaries-20260917/final-verified-tests.log)
|
||||
- [边界及左右相邻浮点值](../../test/ud00-boundaries-20260917/after-probe/signal-boundaries.csv)
|
||||
- [双求解器独立运行摘要](../../test/ud00-boundaries-20260917/isolated-summary.json)
|
||||
- [6,001 点结果及期望值](../../test/ud00-boundaries-20260917/isolated-signal-samples.csv)
|
||||
- [完整回归日志](../../test/ud00-boundaries-20260917/regression-tests.log)
|
||||
- [UTF-8 编码复核日志](../../test/ud00-boundaries-20260917/utf8-recheck.log)
|
||||
|
||||
复现定向测试:
|
||||
|
||||
```powershell
|
||||
.\.venv-win\Scripts\python.exe -m unittest tests.test_native_signal_boundaries tests.test_amesim_ud00_xml tests.test_amesim_semantics.NativeComponentSemanticTests.test_signal_endpoints_and_exponential_contact_law_in_c -v
|
||||
```
|
||||
|
||||
## 4. 新注册类似信号组件时需要什么
|
||||
|
||||
| 情况 | 事件方面的工作 |
|
||||
| --- | --- |
|
||||
| 新增现有 UD00 实例或调整其参数 | 无需额外注册,直接使用已有求值和事件内核 |
|
||||
| 新型号复用 UD00 分段语义 | 接入已有 `native_signal` 和 `native_signal_break`,并把后者汇入 `model_next_break` |
|
||||
| 新阶跃、脉冲、分段周期信号 | 除输出公式,还要提供下一时间事件;与输出共享边界计算和相等判定 |
|
||||
| 无分段的光滑信号,如正弦 | 通常无需专门时间事件 |
|
||||
| 由压力、位置等状态触发的切换 | 需要相应状态事件定位与切换机制,时间事件表不足以实现 |
|
||||
|
||||
仅在 `library.py` 注册类型,或填写 `PORTS` / `PARAMETERS` / `RESULT_VARIABLES`,不会自动实现这些事件。默认在 `native_codegen/extended.py` 接入;若新型号也进入 `compiler.py` 紧凑路径,两条路径都要覆盖。新增 C 函数时同步公共声明与模块导出/依赖。
|
||||
|
||||
新组件通常只负责描述事件时刻及切换语义,由运行库统一执行积分分段与重启。相关要求已写入[元件开发规范第 12.1 节](../standard/component-model-authoring-spec-v1.md#121-分段信号的时间事件)。
|
||||
@@ -0,0 +1,136 @@
|
||||
# 机械元件事件覆盖与 Amesim 对照
|
||||
|
||||
本次核查基于当前平台源码、八路工程的实际生成代码、本机 Amesim 2404 子模型源码及随安装提供的帮助。没有修改机械内核,也没有重新运行 Amesim;数值验收证据引用上一轮修复后的回归日志。
|
||||
|
||||
## 1. UD00 修复的影响范围
|
||||
|
||||
生产代码改动仅在 `native/components/modules/signal.c`。MASS、接触力公式、机械事件定位及求解器重启代码没有修改。已有机械事件仍然生效,不需要因为这次信号修复而重新注册。
|
||||
|
||||
若机械系统由 UD00 驱动,修正信号边界的取值会影响驱动力、后续轨迹和碰撞时刻;积分步分布也可能变化。因此“机械事件机制没有改动”不代表耦合系统的每一个数值结果都保持不变。纯机械模型若没有使用 UD00,则没有这条直接数值调用依赖。
|
||||
|
||||
## 2. 逐类比较
|
||||
|
||||
| 元件或模式 | 当前平台 | Amesim 2404 本机证据 | 判断 |
|
||||
| --- | --- | --- | --- |
|
||||
| MECMAS21 理想限位,`stoptype=1` | 注册 `NativeStop`;在接受步内用密集插值和二分定位上下界;命中后位置置于界面,速度置零,再重启积分 | `MECMAS21.c` 调用 `endst2_`;帮助说明其碰撞处理为位置等于限位、速度为零,并维护状态标记 | 撞击事件已具备,无需重复添加;应核验脱离限位、初始就在限位及同时事件 |
|
||||
| MECMAS21 恢复碰撞,`stoptype=3` | 注册相同的限位定位;入射速度超过阈值时按恢复系数反向,否则置零 | 调用 `endstrc_`;帮助说明恢复系数及防止无限反弹的低速阈值 | 核心撞击事件已具备;保留并补边界组合验收 |
|
||||
| MECMAS21 弹性限位,`stoptype=2` | 计算上下限穿透及弹簧阻尼力,未向 `NativeStop` 或其他通用事件表注册接触/脱离 | 允许负力时调用 `endst1b_`,否则调用 `mecEndStop_` 且 `handle_disc=1`;帮助说明维护接触状态 | 建议补充上下界接触/脱离事件,非负力模式还应处理原始接触力的截断边界 |
|
||||
| LSTP00A 弹性接触 | 用间隙计算非负穿透,再调用 `native_contact`;没有接触状态事件注册 | 与弹性限位复用上述接触工具;`mecEndStop_` 明确启用不连续处理 | 当前八路模型应优先补充这一项 |
|
||||
| 静摩擦、库仑摩擦、Karnopp/Stribeck 模式 | 已有 `NativeFriction`、保存的离散模式、停滑与起滑定位;密集插值定位速度阈值和净驱动力超过静摩擦阈值的时刻 | `MECMAS21.c` 调用摩擦工具;`linert1c` 帮助说明低速区、起滑阈值及保存的模式标记 | 已有基础,不是缺失整套事件;需核验换向、阈值相等、与限位/信号同时触发 |
|
||||
| 无限位 MASS,`stoptype=4` | 不注册限位;若启用干摩擦仍有摩擦事件 | 同样绕过限位工具,保留所选摩擦模型 | 无需人为添加上下限位事件 |
|
||||
| 普通双向线性弹簧、黏性阻尼 | 当前公开机械目录主要提供 LSTP00A 接触件;不能把它等同于普通双向弹簧阻尼 | Amesim `SD0000.c` 直接计算连续的弹簧、阻尼力及导数 | 将来新增这类光滑模型通常不需要事件;出现间隙、单向作用、饱和或摩擦切换时再添加 |
|
||||
|
||||
平台依据:
|
||||
|
||||
- [机械力公式](../../native/components/modules/mechanics.c):`native_contact`、`native_stop_motion`。
|
||||
- [机械事件定位与状态更新](../../native/runtime/common.c):`locate`、`locate_breakaway`、`native_accept`。
|
||||
- [生成器的接触方程、摩擦与限位注册](../../app/simulation/native_codegen/extended.py):接触力约在 559 行,MASS 弹性力约在 571 行,限位注册约在 625 行。
|
||||
- [紧凑生成路径](../../app/simulation/native_codegen/compiler.py):支持的限位模式也生成 `NativeStop`;其他模式由扩展生成路径处理。
|
||||
|
||||
Amesim 依据:
|
||||
|
||||
- [MECMAS21.c](F:/AMESim2404/Amesim/libmec/submodels/MECMAS21.c:547):理想、弹性、恢复碰撞和摩擦模式的实际调用分支。
|
||||
- [LSTP00A.c](F:/AMESim2404/Amesim/libmec/submodels/LSTP00A.c:294):接触工具调用及 `handle_disc=1`。
|
||||
- [SD0000.c](F:/AMESim2404/Amesim/libmec/submodels/SD0000.c:267):普通弹簧阻尼连续方程。
|
||||
- 本机 [amehelp.qch](F:/AMESim2404/Amesim/doc/amehelp.qch) 内的 `libmec/doc/html/utils/endst1b.html`、`mecEndStop.html`、`endst2.html`、`endstrc.html`、`linert1c.html`。这些帮助页通过只读查询 Qt 帮助数据库取得。
|
||||
|
||||
本机安装未提供上述接触工具的完整内部源代码。因此可以确认 Amesim 的接触状态管理和不连续处理接口,但不据此声称已完全复原其全部根函数、内部容差或同一时刻的执行顺序。
|
||||
|
||||
## 3. 当前八路工程的优先级
|
||||
|
||||
从 `tests/data/test-mql-8-corrected.json` 实际生成得到:
|
||||
|
||||
- 共 10 个 MECMAS21:9 个无限位,1 个理想限位;理想限位元件为 `amesim_mecmas21_10`,范围 `[0, 0.37] m`。
|
||||
- 共 8 个 LSTP00A,均为数值刚度、允许负接触力;`kcont=1e11 N/m`、`rcont=1e11 N·s/m`、`Pdis≈1e-7 m`。
|
||||
- 生成头文件为 `NSTATES=132`、`NSTOPS=1`、`NFRICTIONS=0`。这 1 组 `NativeStop` 包含上下两个位置界面,不代表只有一个事件时刻。
|
||||
- `model_next_break` 只汇总信号时间事件,没有注册这 8 个接触件的间隙事件。接触力仍被计算,只是没有单独定位接触/脱离时刻。
|
||||
|
||||
建议优先顺序:
|
||||
|
||||
1. **先补 LSTP00A 的接触/脱离定位。** 它直接覆盖当前八路模型的 8 个接触件。
|
||||
2. **复用同一机制覆盖 MASS 弹性限位。** 当前八路工程没有启用该模式,但这是平台组件能力中明显未显式覆盖的事件。
|
||||
3. **完善已有理想/恢复限位和摩擦的组合边界。** 当前理想限位通过 `native_stop_motion` 的条件方程处理保持与离开,没有单独注册“约束反力消失/自由净驱动力反向”的根函数;应核验连续驱动力下的离开时刻,再补充需要的释放事件。
|
||||
|
||||
缺少接触事件不等于当前接触力公式错误。自适应积分可以通过缩小步长处理部分分段变化,已有温和工况也能通过对照。显式事件的目的,是更稳定地确定作用阶段、接触时刻及峰值附近的积分历史。此次核查不能证明之前八路模型的全部力峰差异均由这一缺口导致。
|
||||
|
||||
## 4. 应怎样添加
|
||||
|
||||
这类事件由状态决定,不能像 UD00 那样只向 `model_next_break(t,end)` 添加预定时间。应扩展状态事件接口,允许组件提供事件面、穿越方向、有效模式及事件后的操作。
|
||||
|
||||
- **接触边界:** LSTP00A 使用带符号间隙 `gap = gap0 + x2 - x1` 的 `gap=0`;MASS 弹性限位使用 `x-xmin=0`、`x-xmax=0`。不要用已截成非负的 penetration 作为唯一找根量,否则脱离区间整段为零,失去跨越方向。
|
||||
- **非负接触力边界:** 仅在 `discContactOption=2` 且处于接触区时,处理未截断力 `Fraw=0` 的分支切换。允许负力的模式没有这个截断开关,不应因力过零就重启。
|
||||
- **事件动作不同:** 弹性接触只重新确认分段并重启积分,位置和速度保持连续;理想碰撞、恢复碰撞才按其模型重置状态。不能把弹性接触事件直接当成硬碰撞。
|
||||
- **不需要的事件:** `Pdis` 是指数过渡尺度,不是“穿透达到它就突然切换”的阈值;也不应在 `3*Pdis` 处造事件。数值刚度/几何刚度是初始化参数模式,若运行中不切换,也不产生事件。
|
||||
- **防止重复触发:** 初始恰好接触、贴边不动、离开后重新接触、同一时刻多个接触和信号跳变都需明确阶段与方向,并保证试探求值不提交离散模式。
|
||||
|
||||
最低验收应覆盖:单 MASS 上下碰撞及释放、单弹性限位、双质量块 LSTP00A 接触/脱离、允许/禁止负力两种模式、非零/零阻尼过渡尺度,并对 BDF/RK45、不同最大步长比较事件时刻和接触峰值。与 Amesim 对照时还需区分事件前后值。
|
||||
|
||||
## 5. 已有验证能说明什么
|
||||
|
||||
上一轮修复后的[完整回归日志](../../test/ud00-boundaries-20260917/regression-tests.log)中,恢复碰撞双求解器测试、LSTP00A 接触测试、MASS 摩擦保持以及 `test_amesim_stick_slip_endstops_and_joint_circuits` 均通过。
|
||||
|
||||
最后一项使用独立 Amesim 2404 运行生成的参考数据,覆盖理想限位、弹性限位、摩擦与联合机械等场景;每个参考场景检查 40 个选定时刻,测试设置最大步长 0.002 s。它支持“相关常规数值行为仍可用”,不足以证明当前八路模型的高刚度接触全过程、所有边界组合都与 Amesim 严格一致。
|
||||
|
||||
## 6. 补充接触/脱离事件的求解时间成本
|
||||
|
||||
### 结论及适用范围
|
||||
|
||||
事件检查、定位和处理会增加计算工作,但总求解时间不一定增加。若它减少了跨接触边界的拒步、非线性迭代和反复缩步,这些节省可能抵消部分甚至全部开销。当前尚未实现接触事件,不能给出已测得的变慢百分比。
|
||||
|
||||
以下分析针对前文建议的“状态事件定位后重启积分”实现。单纯记录零点与切换接触阶段不是同一件事,也不应假设所有事件定位都必然要求相同的重启方式。
|
||||
|
||||
### 成本来自哪里
|
||||
|
||||
| 环节 | 当前代码依据及新增成本 | 判断 |
|
||||
| --- | --- | --- |
|
||||
| 每个接受步检查接触状态 | `native_accept` 已经检查硬限位/摩擦;新增 LSTP00A 间隙可直接由两个位置状态及常数计算 | 对 8 个接触件,轻量状态判断预计成本较低;这是算法量级判断,不是计时结果 |
|
||||
| 定位实际跨越时刻 | 现有 `locate` 固定执行 60 次二分,每次调用密集插值;BDF 使用 `CVodeGetDky`,RK45 计算状态插值多项式 | 纯间隙根函数不需要重算整个气动网络;定位次数和精度决定成本 |
|
||||
| 截断并重启积分 | `native_accept` 可把已接受步截回事件;BDF 调用 `CVodeReInit`,RK45 重新计算导数和初始步长 | 会放弃事件之后那部分试算工作,并产生重新起步的工作;BDF 的历史重建尤其值得关注 |
|
||||
| 雅可比及线性求解 | BDF 原生路径使用差分雅可比和稠密线性求解器;新起步需要相应初始化与后续数值建立工作 | 成本作用于整个耦合系统,而非只作用于触发事件的那一个弹簧 |
|
||||
| 保存事件点及输出重放 | 若沿用现有状态事件存储流程,每个新增事件时刻会保存状态,输出阶段再次调用 `model_eval` | 通常少量事件时不突出;大量事件会增加结果体积与后处理时间,需要与纯求解耗时区分 |
|
||||
|
||||
CVODE 7.4.0 的官方实现中,`CVodeReInit` 将当前阶次重设为 1,并重置步数/历史起点;下一次积分进入初始设置与初始步长计算。它复用已有内存,不是重新编译模型或重新分配整个求解器。见 [CVODE 7.4.0 官方源代码](https://github.com/LLNL/sundials/blob/v7.4.0/src/cvode/cvode.c#L518)。平台对应入口见 [cvode_solver.c](../../native/runtime/cvode_solver.c:357)、[rk45.c](../../native/runtime/rk45.c:57) 和 [common.c](../../native/runtime/common.c:137)。
|
||||
|
||||
因此,主要风险是频繁切换造成的整系统重新起步,不是“多写了几个 if 判断”。重启不清除从仿真开始以来的物理运动结果,而是从事件处的状态继续积分。
|
||||
|
||||
### 既有八路运行数据能支持什么判断
|
||||
|
||||
早先正确性评估中的 **50 s 循环工况**记录如下,来源为 [native-summary.json](../../test/evaluation-mql8-20260917/full/native-summary.json)。这是 UD00 修复前的历史样本,仅用于估计工作量,不能作为当前代码已经完成的性能 A/B 对比。
|
||||
|
||||
| 指标 | 历史样本 |
|
||||
| --- | ---: |
|
||||
| 求解壁钟时间 `solveSeconds` | 12.414 s |
|
||||
| 接受步数 | 19,412 |
|
||||
| 误差测试失败次数 `rejectedSteps` | 1,511 |
|
||||
| 方程求值计数 `nfev` | 84,268 |
|
||||
| 其中雅可比差分求值 | 50,512 |
|
||||
| 雅可比刷新次数 | 1,804 |
|
||||
| 线性求解器 setup 次数,输出字段 `nlu` | 5,903 |
|
||||
| 求解器启动次数,含初次启动 | 20 |
|
||||
| 已注册状态事件的触发批次数 | 9 |
|
||||
|
||||
该生成模型包含 132 个状态、1,784 个输出和 27 个雅可比分色组。历史数据中每次雅可比刷新对应 28 次方程求值(27 组扰动加一个基准求值),合计 `1804 × 28 = 50512`。这说明多余的整模型求值、雅可比刷新和重新起步比单纯间隙算术更值得控制;不能把方程调用次数占比直接当作耗时占比。
|
||||
|
||||
若接受步数暂按历史样本不变估算,8 个接触件每步检查一次是 `8 × 19412 = 155296` 次简单间隙检查;两个端点均重算则约为其两倍。间隙直接读取位置即可,不需要为这些检查各自求解气动物性、管道流量和全部输出。
|
||||
|
||||
另一方面,历史的 `stateTransitions=9` 不包含当时没有注册的 LSTP00A 接触/脱离,所以不能据此预测新增事件数量。8 个接触件可能长期保持接触,也可能反复接触和脱离;真正影响重启成本的是整个仿真期间的切换次数,以及是否出现数值反复触发。
|
||||
|
||||
不能将 12.414 s 除以启动次数来推算单次事件成本,也不能把平台求解时间与报告中的 Amesim 完整进程时间直接比较。
|
||||
|
||||
### 建议采用的成本控制措施
|
||||
|
||||
1. **专门生成轻量事件函数。** 直接读取位置/速度状态,批量计算间隙和需要的局部接触力;避免为了事件检查调用完整 `model_eval`。在不需要新增物理动态量时,不人为增加连续状态维度。
|
||||
2. **先筛查,后定位。** 只对可能跨界的区间执行找根;同时覆盖区间内转向等情况,不能为了省时漏掉端点同号但中间跨界的情形。定位达到所需精度或浮点区间不再可分后停止,不必机械重复满 60 次。
|
||||
3. **仅在阶段实际切换时处理。** 保持接触期间不反复重启;明确初始贴边、穿越方向和离开后的再次触发规则。不能以放大物理间隙、移动事件时间或粗暴忽略真实小振荡来换速度。
|
||||
4. **同一时刻的多个事件批量提交、一次重启。** 包括多个接触件,以及与信号边界重合的情况;不得为了减少启动次数把有真实先后关系的事件强行合并。
|
||||
5. **只注册启用模式所需的边界。** 当前八路的接触件均允许负力,不额外注册非负力截断事件;也不在 `Pdis` 或 `3*Pdis` 处造事件。
|
||||
|
||||
按上述实现,接触/脱离次数较少时,额外成本预期可控;频繁真实碰撞或边界数值反复触发时,成本可能明显增加。事件处理不会消除模型本身的高刚度,也不能保证 RK45 因此适合所有高刚度工况。
|
||||
|
||||
### 如何验证增量成本
|
||||
|
||||
完成实现后,在同一份 JSON、求解器、容差、最大步长和输出设置下,对修改前后分别重复运行,使用已构建的可执行文件,比较中位数并记录波动。分别记录纯求解时间、进程总时间、事件检查/定位次数、实际切换数、启动次数、接受步/拒步、`nfev`、`njev` 和线性 setup 次数。
|
||||
|
||||
平台 `solveSeconds` 不包含后续全部输出重放和 JSON 写出,所以事件点增多的输出成本还应检查总进程时间。现有 `nfev` 也不统计纯密集插值调用,新增定位计数/耗时才能解释这部分成本。
|
||||
|
||||
除当前八路模型外,至少检查长期不接触、持续接触、单次接触/脱离及反复碰撞四种情况;在事件时刻与接触力精度得到验证的前提下评估速度。本轮仅完成成本评估,没有修改机械事件实现或进行新增事件的性能实测。
|
||||
Reference in new issue
Block a user