Files
SystemSimulationApp/docs/other/物性复用与管流求根实现及验证-2026-09-11.md

144 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 物性复用与管流求根:实现及验证
已在 `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/`,原报告保留为历史测试记录。
复核命令:
```powershell
./.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文件或前端模型参数。