相较上一版 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 通过。
15 KiB
机械元件事件覆盖与 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_contact、native_stop_motion。 - 机械事件定位与状态更新:
locate、locate_breakaway、native_accept。 - 生成器的接触方程、摩擦与限位注册:接触力约在 559 行,MASS 弹性力约在 571 行,限位注册约在 625 行。
- 紧凑生成路径:支持的限位模式也生成
NativeStop;其他模式由扩展生成路径处理。
Amesim 依据:
- MECMAS21.c:理想、弹性、恢复碰撞和摩擦模式的实际调用分支。
- LSTP00A.c:接触工具调用及
handle_disc=1。 - SD0000.c:普通弹簧阻尼连续方程。
- 本机 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 个接触件的间隙事件。接触力仍被计算,只是没有单独定位接触/脱离时刻。
建议优先顺序:
- 先补 LSTP00A 的接触/脱离定位。 它直接覆盖当前八路模型的 8 个接触件。
- 复用同一机制覆盖 MASS 弹性限位。 当前八路工程没有启用该模式,但这是平台组件能力中明显未显式覆盖的事件。
- 完善已有理想/恢复限位和摩擦的组合边界。 当前理想限位通过
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. 已有验证能说明什么
上一轮修复后的完整回归日志中,恢复碰撞双求解器测试、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 官方源代码。平台对应入口见 cvode_solver.c、rk45.c 和 common.c。
因此,主要风险是频繁切换造成的整系统重新起步,不是“多写了几个 if 判断”。重启不清除从仿真开始以来的物理运动结果,而是从事件处的状态继续积分。
既有八路运行数据能支持什么判断
早先正确性评估中的 50 s 循环工况记录如下,来源为 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 完整进程时间直接比较。
建议采用的成本控制措施
- 专门生成轻量事件函数。 直接读取位置/速度状态,批量计算间隙和需要的局部接触力;避免为了事件检查调用完整
model_eval。在不需要新增物理动态量时,不人为增加连续状态维度。 - 先筛查,后定位。 只对可能跨界的区间执行找根;同时覆盖区间内转向等情况,不能为了省时漏掉端点同号但中间跨界的情形。定位达到所需精度或浮点区间不再可分后停止,不必机械重复满 60 次。
- 仅在阶段实际切换时处理。 保持接触期间不反复重启;明确初始贴边、穿越方向和离开后的再次触发规则。不能以放大物理间隙、移动事件时间或粗暴忽略真实小振荡来换速度。
- 同一时刻的多个事件批量提交、一次重启。 包括多个接触件,以及与信号边界重合的情况;不得为了减少启动次数把有真实先后关系的事件强行合并。
- 只注册启用模式所需的边界。 当前八路的接触件均允许负力,不额外注册非负力截断事件;也不在
Pdis或3*Pdis处造事件。
按上述实现,接触/脱离次数较少时,额外成本预期可控;频繁真实碰撞或边界数值反复触发时,成本可能明显增加。事件处理不会消除模型本身的高刚度,也不能保证 RK45 因此适合所有高刚度工况。
如何验证增量成本
完成实现后,在同一份 JSON、求解器、容差、最大步长和输出设置下,对修改前后分别重复运行,使用已构建的可执行文件,比较中位数并记录波动。分别记录纯求解时间、进程总时间、事件检查/定位次数、实际切换数、启动次数、接受步/拒步、nfev、njev 和线性 setup 次数。
平台 solveSeconds 不包含后续全部输出重放和 JSON 写出,所以事件点增多的输出成本还应检查总进程时间。现有 nfev 也不统计纯密集插值调用,新增定位计数/耗时才能解释这部分成本。
除当前八路模型外,至少检查长期不接触、持续接触、单次接触/脱离及反复碰撞四种情况;在事件时刻与接触力精度得到验证的前提下评估速度。本轮仅完成成本评估,没有修改机械事件实现或进行新增事件的性能实测。