12 KiB
物性复用与管流求根:实现及验证
已在 system-optimization 工作区将三项物性优化接入正式 C 内核:共享同一次试算的物性状态、复用等熵计算中的上游密度,以及用已有内能、压力和密度求焓。两条代码生成路径均已接入。此前验证过的管流求根方案也已一并落实。
最终版本中,MQL4 的纯求解中位耗时从 3.138 s 降至1.391 s,减少55.7%;skill-test 从 0.255 s 降至0.139 s,减少45.6%。本机后台已启动新版本,通过真实 HTTP 流式仿真请求验证,结果与独立EXE逐点一致。本次没有提交或推送Git。
物性状态如何共享
每次生成的 model_eval 都在自己的栈上建立 NativePropertyCache,随后将同一个上下文传给部件和局部压力、焓闭合计算。记录保存介质参数副本、压力、温度、焓、密度、黏度,以及已算出的等熵修正系数和指数;标志位区分哪些量已经有效。
气体容腔恢复状态后,先登记已有的温度、焓和密度。管路、阀口需要温度时,按介质与精确的压力、焓查找。相同状态直接读取温度,未知状态仍使用原来的反算。需要密度、黏度或等熵修正时,仅补算缺少的量,后续计算继续复用。
这一版采用完整输入查询和共享状态引用,尚未把所有端口都静态替换成无需查询的状态指针;它已经覆盖当前两条生成路径的相关气体、阀口和管路调用。
有效性规则如下:
- 压力和焓必须精确匹配,压力、温度查询也必须精确匹配。没有“差不多就沿用”的近似缓存。
- 介质按全部数值参数核对,并保存参数副本;改变压力、焓、介质参数,都不会误用旧状态。
- 节流后的压力变化、气流混合产生的新焓,会触发新状态查询或反算。同焓不能直接推断同温度。
- 每次系统试算重新初始化缓存;不同仿真、线程和独立调用不共享可变全局缓存。没有把上一时刻的物性直接拿来代替本次试算。
- 编译器按模型规模分配16~256条记录,控制栈空间。容量满后转为正常计算,不丢失正确性。未来大规模模型可进一步改善索引与容量策略。
- 真实氦气在临界温度以下及临界温度处,保留原有气相根和PH反算路径;不把本次优化当作两相物性支持。
两个次级机会的实现
第一项已落实到可压缩流动函数内部。等熵修正计算出的上游密度,直接用于随后流量、流速计算。上下游状态分别保存;下游压力、温度不同就有自己的记录。同一个状态的等熵系数也可以重复使用。管路诊断中的重复黏度计算同时合并。
第二项在当前真实氦气单根区域使用 h = u + p/ρ。这里的 u 为已有比内能,p 为绝对压力,ρ 为已有密度,单位分别为J/kg、Pa、kg/m³。与本内核的内能和焓参考点一致,避免再次从压力、温度求真实气体焓。低温的原有气相根选择保留回退。理想气体已有的简单焓表达式继续使用。
这些优化没有引入物性查表、插值或额外近似。
管流收敛修正为什么一并接入
最初只接入全组物性优化时,MQL4仍能运行到10 s,但PNL0002_10的一条温度曲线在存档参考点的最大偏差为0.019965 K,超过现有0.015 K门槛。分项试验表明,极小的物性数值变化会改变BDF的试算路径;结合前一轮“管流几乎总达到16次上限”的证据,不能把这个完整系统偏差简单解释为物性公式算错,也不能只保留更快的计时。
因此一并接入此前试验的管流求根方案,并保持原有曲线门槛。最终完整1001个公共时间点上的最大温度差为0.009901 K,通过验收。上述分项结果保留在 decomposition.json 和 final-benchmark.json,未以放宽误差门槛代替修正。
管流仍使用原有可压缩关系、摩擦系数混合公式、流向和近平衡平滑。内部将流量关系整理为 Re² × f(Re) = K,使用带区间保护的局部Newton求根;越界则二分回退。PNL00R原有的直接层流分支保留。
返回前会在实际返回点检查方程相对残差,要求不超过 1e-9,同时使用局部流量变化判据。接口 native_pipe_resistance 可返回收敛状态、迭代次数、二分回退次数和残差;异常输入或达到上限仍不合格时返回非有限失败值,交由现有模型有效性检查拒绝,不再静默接受未收敛的流量。
这里仅使用管流内部一个标量关系的斜率。系统雅各比矩阵策略、BDF/RK45积分器和模型误差设置均未调整。
实测耗时:完整系统与分项对照
性能测试使用独立EXE,关闭性能探针,三轮交错运行并取中位数。只统计C求解过程,不含Python前处理、编译、进程启动、结果输出、网页传输或绘图。全部运行至10 s。
MQL4:BDF,相对误差限 1e-7,最大积分步长 1e30,其余状态绝对误差限沿用生产配置。
| 方案 | 求解中位耗时 / s | 三轮范围 / s | 方程调用次数 | 说明 |
|---|---|---|---|---|
| 修改前基准 | 3.138 | 3.126~3.175 | 24,941 | 原有物性和管流迭代 |
| 仅局部密度、黏度去重 | 3.027 | 3.021~3.108 | 24,941 | 全部时间及输出序列逐点完全一致 |
| 全组物性优化,保留旧管流迭代 | 1.974 | 1.973~2.030 | 24,612 | 温度参考门槛未通过,不作为最终版本 |
| 最终组合,但关闭焓直接计算 | 1.518 | 1.514~1.611 | 24,481 | 用于评估第二个次级机会 |
| 最终组合:全部物性优化+管流求根 | 1.391 | 1.382~1.456 | 24,262 | 完整曲线验收通过 |
局部密度、黏度去重单独减少约3.5%完整系统耗时;在最终组合中加入焓直接计算,耗时从1.518降至1.391 s,进一步减少约8.4%。后一项也伴随试算路径变化,因此不是单纯的函数微基准。两项与主物性复用、管流求根存在重叠,不能将各百分比直接相加。
skill-test采用仓库 tests/data/native-skill-test.xml,这是之前skill-test模型的回归输入;RK45、最大步长0.001 s、相对误差限 1e-7:
| 方案 | 求解中位耗时 / s | 方程调用次数 | 接受步数 |
|---|---|---|---|
| 修改前 | 0.255 | 60,278 | 10,022 |
| 最终版本 | 0.139 | 60,278 | 10,022 |
skill-test的计算次数和步数相同,这一组能更直接地反映每次物性计算变轻带来的收益。它没有MQL4中的管路网络,因而也验证了物性优化在另一种模型和积分器下的效果。
计算次数确实减少了多少
另行构建只加计数、不用于性能比较的程序,限定在系统方程回调内计数,排除初始化和输出重算。计数版的全部序列分别与对应无探针版本完全一致。
| MQL4求解中的计算 | 修改前 | 最终版本 |
|---|---|---|
| 真实气体状态方程求根 | 6,202,660 | 690,869 |
| 压力、焓反求温度 | 646,040 | 0 |
| 黏度计算 | 1,626,172 | 333,213 |
| 摩擦系数普通计算函数 | 8,285,496 | 1,360,592 |
最后一行只统计普通摩擦系数函数。新Newton步骤还会在“摩擦系数及其斜率”联合函数中计算摩擦关系,因此不能据此声称全部摩擦计算工作减少了同样比例;管流性能应以上面的完整计时及独立求根验证为准。
PH反算降至0,仅说明本模型的请求都能找到本次试算的已知状态。对压力变化、焓混合、其他模型和不适用快路径的低温工况,反算功能仍然存在。
曲线、守恒和事件验证
与此前官方重新编译的四支路Amesim存档比较,72条压力、温度、位移、速度和阀口流量曲线使用完整1001个共同输出时间点。没有重跑Amesim或重新解读其内部算法。
| 量 | 最大绝对差 | 原有验收门槛 |
|---|---|---|
| 压力 | 199.863 Pa | 250 Pa |
| 温度 | 0.009901 K | 0.015 K |
| 位移 | 7.49e-7 m |
2e-6 m |
| 速度 | 2.64e-6 m/s |
1e-5 m/s |
| 阀口质量流量 | 1.55e-5 kg/s |
3e-5 kg/s |
闭合气路总质量最大漂移约 1.33e-14 kg。
LSTP四个接口力另行比较。第一个接口力在共同网格上与Amesim的最大差为0.6135 N;四个接口中最大差为1.123 N。新增事件点未并入普通网格误差,以免把瞬时峰值插值成虚假的长三角形。
首次碰撞时间为1.201137461445 s,峰值约 1.49858577e11 N,相对修改前的峰值变化约 −1.94e-6。另行记录内部接受的积分点:峰值降至一半约0.348 ns,降至1%约2.336 ns。事件记录不改变最终输出序列,先前发现的极短脉冲没有被省略。Amesim存档缺少同等密度的内部采样,仍不能由本次验证断言其内部是否存在同一脉冲。
skill-test的输出时间序列一致,最大压力差约 1.70e-7 Pa,最大温度差约 2.39e-12 K;所检查的位移、速度和力序列完全一致。
后台已生效
检查时本机8000端口无运行中的服务,随后以当前工作区启动后台。启动日志确认数值引擎为 native。真实请求:
POST http://127.0.0.1:8000/api/system-xml/simulate-stream
此次请求完成0~10 s,C纯求解1.507 s,HTTP全程3.967 s,收到21个进度事件。HTTP时间包含前处理、进程启动、输出序列化及传输,不能与纯求解时间等同,也未包含浏览器绘图测量。
后台返回的构建标识为 9fdd91da210e189d1e44de686d6109bbdb5be56c284450b41364486160bfe494,与最终独立EXE相同;全部时间和输出序列逐点一致。后台日志、启动进程号及HTTP结果均保存在实验目录。
回归与通用性边界
最终完整复核命令的25项相关测试在23.898 s内全部通过(regression-final.log),包含:
- 50组元件网络的冻结物性参考、守恒及未改变模型的完整参考对照;两条代码生成路径。
- BDF、RK45、原生后端默认路径,以及不依赖NumPy/SciPy的编译导入路径。
- 缓存跨试算失效、独立上下文、容量耗尽回退、一个浮点单位的压力变化、焓变化及每个介质参数变化。
- 真实氦气与含温度相关热容的理想气体,在100~1000 K、
1e4~1e8 Pa的状态往返检查,以及低温氦气保留原有路径的检查。 - 管流求根的2718组工况:雷诺数
1e-6~1e9、相对粗糙度0~0.1,三个不同流量尺度;均与独立100次二分求解比较。检查返回残差、区间回退、非法输入失败、零流量和PNL00R层流分支。 - 独立压力回路与直接支路组合前后的结果隔离、流向反转、焓混合回路,以及MQL4的已有曲线验收。
旧冻结参考中的PNL流量包含原先迭代达到上限的值。现在所有PNL共用检查残差的求根器,因此保留这些网络的独立物性与守恒参考,并由独立二分、管路物理测试和Amesim系统曲线验证流量;没有要求新算法重现旧的未收敛迭代值。
一次目录复测曾有两个短进程的 --init 返回空标准输出;随后这两个进程各自连续5次核验正常,50组目录整套复测也通过。未为此增加忽略错误或自动重试逻辑,原始与复测日志均保留。
代码与复现记录
- C接口与实现:
native/include/kernels.h、native/components/kernels.c。 - 生成与上下文传递:
app/simulation/native_codegen/compiler.py、extended.py、schedule.py。 - 新增及更新测试:
tests/test_native_properties.py、test_native_pipe_physics.py、test_native_catalog.py。 - 本次数据:
test/property-implementation-20260911/,包括final-benchmark.json、counter-audit.json、http-and-curves.json、event-audit.json及完整结果、源文件、EXE和日志。 - 前一轮剖析与原型:
test/property-pipe-profile-20260911/,原报告保留为历史测试记录。
复核命令:
./.venv-win/Scripts/python.exe -m unittest tests.test_native_properties tests.test_native_pipe_cache tests.test_native_pipe_physics tests.test_native_codegen tests.test_native_schedule tests.test_native_catalog tests.test_native_only_backend -v
实验记录和生成EXE遵循现有 /test 忽略规则;正式实现、测试和文档位于受版本管理的目录。本次未修改用户输入JSON、Amesim文件或前端模型参数。