相较上一版 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 通过。
165 lines
25 KiB
Markdown
165 lines
25 KiB
Markdown
# C 数值后端
|
||
|
||
MECMAS21 已支持静摩擦保持与脱离、高级低速区间和 Stribeck 过渡;内部摩擦状态随接受的事件更新并保存,BDF/RK45 共用该机制。LSTP00A、MECMAS21 弹性限位和 PNL0001/2/3 的本轮语义及 Amesim 实测范围见 [功能验证报告](../docs/other/Amesim摩擦与管路功能补齐验证-2026-09-13.md)。
|
||
|
||
后端 Python 校验 XML、检查连接、生成系统专用 C 并编译;独立 EXE 执行完整数值循环。原生运行不调用 Python。当前构建支持 Windows x64 和 Linux x86_64;Linux 使用静态链接的 SUNDIALS。
|
||
|
||
平台相关修改遵循 [Windows 与 Linux 交付约定](../docs/standard/跨平台交付约定.md)。缓存时间戳更新按 `os.supports_follow_symlinks` 检测运行平台能力,Windows 不支持该可选操作时对已校验的普通缓存目录使用常规 `utime`。缓存集成回归可在两平台使用真实工具链执行:`python -m unittest tests.test_native_cache_storage tests.test_native_cache_platform -v`;设置 `SIMULATION_NATIVE_REQUIRE_TOOLCHAIN=1` 时工具链缺失将失败而不会跳过。
|
||
|
||
两平台所需 Python 包、GCC、SUNDIALS 库文件和测试/剖析依赖见 [平台依赖说明](../docs/standard/platform-dependencies.md)。本轮 Jacobian 复用继续使用现有五个原生链接库;时间剖析使用同一 SUNDIALS 7.4 公共接口,不需要额外的 Python profiler 或自动微分库。
|
||
|
||
## 启用网页后端
|
||
|
||
当前默认使用 `native`。也可在启动后端的 PowerShell 中显式设置:
|
||
|
||
```powershell
|
||
$env:SIMULATION_NUMERIC_ENGINE = 'native'
|
||
$env:SIMULATION_NATIVE_CC = 'F:/Projects/mingw64/bin/gcc.exe'
|
||
$env:SUNDIALS_ROOT = 'F:/Anaconda/Library'
|
||
.venv-win/Scripts/python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000
|
||
```
|
||
|
||
Linux 使用现有 Python 虚拟环境,并将 C 依赖独立放在 `.venv/native/`:
|
||
|
||
```bash
|
||
bash bat/setup-native-linux.sh
|
||
.venv/bin/python -m uvicorn app.main:app --host 127.0.0.1 --port 8000
|
||
```
|
||
|
||
脚本下载并校验固定版本 SUNDIALS 7.4.0,在本地构建静态库;不会安装系统包。构建器先读取 `SUNDIALS_ROOT`,未指定时查找当前 Python 环境的 `native/sundials-7.4.0`、`/usr/local` 和 `/usr`。Linux 安装需包含静态 `.a` 库;生成的 ELF 程序名为 `model`,不依赖 SUNDIALS 共享库或 Python。`.venv/`、`app/data/` 和 `test/` 均在 Git 忽略范围。
|
||
|
||
沿用 `/api/system-xml/simulate` 与 `/api/system-xml/simulate-stream`。`native` 遇到不支持的组件或方法时报告错误,不静默切换。旧 Python 后端已退役,显式选择 `python` 会报错。
|
||
|
||
`bat/start-backend.bat`、`bat/start-backend.sh` 及其 `start-all` 上层入口默认设置 `native`,保留明确指定的环境变量覆盖。直接通过 uvicorn 启动也使用相同的默认选择。启动日志显示所选内核;C 模式只检查工具链与 XML Schema,不再预热 SciPy 积分/代数求解器。工具链检查失败会记录启动诊断,编辑器仍可使用,提交仿真时会明确报错,不会自动调用 Python 数值后端。
|
||
|
||
通用诊断包含 `stateCount`、`sampleCount`。`pressureFlow`、`stream` 属于 Python 后端的可选诊断;C 后端不报告未计算的方程残差,网页仅在该值存在时显示它。
|
||
|
||
### 事件输出语义(version 2)
|
||
|
||
原生结果的 `outputSemantics` 描述采样合同。规则网格保持实际浮点时间,不吸附到附近事件。内部时间事件额外保存 `nextafter(event, -INFINITY)` 和事件时刻:前者是积分段的实际左侧终点,后者沿用连续状态、使用事件后的信号。状态重置事件在可用的积分区间内额外保存左邻时刻的插值状态,再保存事件后的接受状态。同一实际时间仍以后一次接受状态为准;时间序列严格递增,采样总数可能超过规则网格点数。
|
||
|
||
输出根据保存时间及完整状态重放;已有摩擦离散模式随状态保存。事件左邻样本是有限精度下的左侧样本,不声称保存了同一数学时刻的精确左极限。初始时刻或当前步起点的即时状态重置没有新的左侧区间,不倒填样本。仿真终点不额外制造一个时间事件。纯求解模式不增加采样或模型输出求值;此改动不注册新的机械事件。
|
||
|
||
与外部结果对照时,必须核验事件侧别。八路评估脚本使用全部 STEP/UD00 输出核验驱动阶段,所有变量共用同一对原始样本行;仅允许在输出间隔的 `1e-7` 范围内匹配时间舍入误差。无法匹配的点明确报告,不跨跳变插值、不根据力或压力误差选择样本。这个规则不代表已验证未注册的接触模式。
|
||
|
||
原生运行库已在本机 GCC 8.1 / SUNDIALS 7.4.0 验证。构建需要对应 C 头文件、导入库和 DLL,单纯安装 Python 包不能代替这些文件。构建器根据环境变量或当前 Python 基础环境查找 SUNDIALS,根据环境变量或 PATH 查找 GCC。
|
||
|
||
## 仿真结果分块存储
|
||
|
||
网页和 Python 原生运行入口将采样结果写入项目根目录的 `simresults/run-<id>/`,不依赖启动时的工作目录。每次运行保存 `manifest.json`、`states.bin` 与 `outputs.bin`;纯求解(`--solve-only`)不创建结果档案。此目录已加入 Git 忽略。
|
||
|
||
清单和返回诊断中的 `directory` 为相对项目根目录的 `simresults/run-<id>`,统一使用 `/`,`directoryBase` 为 `project`。读取时使用 `result_storage.result_archive_path(id)` 根据当前代码位置定位;旧清单中的绝对目录提示不参与定位。停止应用、移动或复制整个项目(保留 `simresults`)、重新启动后,结果随项目迁移。运行中传给原生进程的绝对路径由当前目录重新计算,不固定盘符或机器路径;不支持运行过程中移动项目目录。
|
||
|
||
- **容量**:默认 1 GiB(1,073,741,824 字节),通过后端环境变量 `SIMULATION_RESULT_STORAGE_MB` 配置,单位 MiB,必须是正整数。例如 PowerShell 使用 `$env:SIMULATION_RESULT_STORAGE_MB = '1024'`,Linux 使用 `export SIMULATION_RESULT_STORAGE_MB=1024`。按文件逻辑字节计量,不包含文件系统分配单元的额外开销。
|
||
- **自动清理**:写每个采样块前,为状态块及其未来输出块一起预留空间。总配额涵盖所有结果档案和元数据;空间不足时依次删除最早结束的非活动档案(异常退出且未结束的档案按创建时间排序)。跨进程锁保护配额分配和正在使用的档案。符号链接、目录联接及用户另外放入的文件不会被自动删除;这些内容仍计入目录用量。活动档案、孤儿但仍存活的工作进程被保留。旧结果属于可淘汰历史,需要长期保留的结果应导出另存。
|
||
- **空间仍不足**:停止采样并报告 `storage-quota`,保留此前完整提交的块,不删除当前运行的数据,不悄悄丢样后继续报告成功。结果诊断 `native.resultStorage` 分别记录求解状态、状态/输出样本数、已存储到的时间及有效字节数;已存储时间可能早于求解器最终到达时间。
|
||
- **有限缓冲与背压**:采样缓冲最多 1024 行,按状态和输出列数进一步限制到约 1 MiB(单行更大时至少容纳一行)。缓冲写满后复用;采用同步批量写入,磁盘慢时求解线程等待,没有无限增长的异步写入队列。求解结束后逐块计算和写入输出,再分块生成兼容 JSON,原生工作进程不分配完整历史状态或输出数组。
|
||
- **数值隔离**:只替换结果记录缓冲,保留 RK45/CVODE 当前状态、稠密输出和事件定位数据。输出计算维持原先的结束后顺序,避免在求解过程中改变模型缓存。相同时间戳沿用原有“后值替换前值”规则,包括块边界。
|
||
- **取消与异常**:正常取消、求解失败会补写最后一个不满的块。每块具有 CRC32 校验和提交标记;强制终止后可通过 `result_storage.scan_blocks` 扫描完整前缀,截断尾块和损坏块不计为有效样本。强制终止时尚未计算的输出不会被伪造,已有状态块仍保留。元数据通过临时文件替换发布;块完成执行 `fflush`,不逐块强制物理落盘,因此这不是断电零丢失承诺。
|
||
|
||
块格式为 `SIMBLK01` + 四个小端 uint64(块序号、行数、列数、CRC32)+ 按列连续的小端 Float64 数据 + `COMMIT01`;每个块的第一列是时间。各文件的完整列顺序由清单的 `metadata.stateColumns`、`metadata.outputColumns` 指定;纯代数模型内部占位状态以 `null` 标记。公开状态和变量元数据仍保存在 `metadata.stateKeys`、`metadata.variables`。Windows/Linux 共用格式和 64 位文件偏移。
|
||
|
||
本阶段保留现有完整 JSON 传输和浏览器加载契约:后端返回结果和浏览器显示时仍可能加载完整数据。变量/时间范围查询和浏览器按需加载属于后续阶段;现有百万采样点保护仍保留。
|
||
|
||
回归入口(Windows 和 Linux 使用各自的 Python 环境):
|
||
|
||
```text
|
||
python -W error::ResourceWarning -m unittest tests.test_result_storage tests.test_native_sample_storage tests.test_native_result_transport tests.test_native_worker_control -v
|
||
```
|
||
|
||
## 独立生成与运行
|
||
|
||
```powershell
|
||
.venv-win/Scripts/python.exe -m app.simulation.native_codegen tests/fixtures/native-skill-test.xml --output-dir test/native-v1/example-run --runs 3 --solve-only
|
||
```
|
||
|
||
输入支持 XML,或带普通算术表达式的工程 JSON。JSON 普通数字已经是 SI 值;算术表达式按编辑器所选单位换算,例如 `3.14*10**2/4 mm2` 转为 `0.0000785 m2`。较复杂的表达式应先在网页导出 XML。CLI 不执行任意 Python/JavaScript 表达式。
|
||
|
||
输出目录包含 `input.xml`、`model-manifest.json`、`program/`、预热和各次运行结果,以及 `summary.json`。`program/` 包含 EXE、生成的模型 C/头文件、SUNDIALS DLL 和依赖声明,可以复制整目录独立运行:
|
||
|
||
```powershell
|
||
test/native-v1/example-run/program/model.exe --method RK45 --start 0 --stop 10 --sample-step 0.02 --max-step 0.001 --rtol 1e-6 --output test/native-v1/standalone-result.json
|
||
```
|
||
|
||
EXE 不需要 Python、SciPy、XML 或原工程文件。DLL 需要与 EXE 一同保留。默认运行设置是 RK45、0–10 s、最大步长 0.001 s;按需要传入运行选项。
|
||
|
||
`--solve-only` 关闭轨迹采样,只输出最终状态与诊断。`solveSeconds` 是程序内部数值求解墙钟时间,包含求解必需的 RHS 和事件定位,排除模型初始化、求解结束后的结果投影与 JSON 写入;启用采样时包含积分期间分块写盘及等待配额的时间。`processWallSeconds` 另含进程启动与结果处理。预热一次后报告三次求解的中位数。
|
||
|
||
## 求解器外层终止行为
|
||
|
||
BDF 外层仅在 CVODE 返回负错误码、返回非法时间/状态或触发取消、实际超时及资源保护时结束。成功返回但时间暂时未变时保留求解器历史继续调用,不以重复次数判失败,也不人为推进时间或重启来跳过该段。持续不推进沿用当前整次求解的墙钟时限;默认 300 秒,Python 进程监控另有 5 秒退出宽限。用户取消后,进程仍不响应且被强制结束时返回取消状态,并明确没有完整结果文件,只保留最后一次进度报告。
|
||
|
||
独立结果的 `solverControl`(网页位于 `diagnostics.native.solverControl`)记录终止原因、操作、CVODE 返回码、同时间返回次数和最长连续次数,以及最后的内部时间与步长。CVODE 数值诊断仅用于 BDF。正常返回的 `1` 表示到达指定停止边界;非有限诊断数值写为 JSON `null`。取消/超时的原因不会被随后产生的 CVODE 回调错误覆盖。强制取消没有可信轨迹时,`series`/`final` 为空,未知求解统计不填零,`statisticsComplete=false`。
|
||
|
||
原八路 10.8 秒退出问题的对照复现、50 秒完成验证及异常分支测试见 [封装修复验收报告](../docs/other/求解器外层提前终止修复与验收-2026-09-14.md)。专项回归:`python -m unittest tests.test_native_solver_control tests.test_native_worker_control -v`。
|
||
|
||
## 雅可比分组差分与诊断
|
||
|
||
BDF 默认使用结构着色差分,无需环境变量或网页选项。修正八路的 132 个状态合并为 27 个扰动组,每次另算 1 次专用基准 RHS,共 28 次系统求值。普通积分 RHS、`rtol=1e-8` 和 Dense LU 沿用当前设置。用户已接受报告中的数值差异,正式网页与独立 C 程序采用同一默认策略。
|
||
|
||
旧 `SIMULATION_NATIVE_JACOBIAN` 选择器和 `--jacobian dense|auto|verify` 入口已删除。独立 C 程序仅保留无参数诊断标志 `--verify-jacobian`,它会逐次核对完整 canonical 雅可比矩阵,增加计算量,不用于速度测量。RK45 不构造雅可比。
|
||
|
||
无法证明结构、没有分组收益的模型继续使用必要的逐列差分;分组扰动失败时也保留 canonical 逐列恢复。这些是当前算法的兼容与恢复路径。当前启用及网页验证见 [正式启用报告](../docs/other/雅可比算法正式启用与网页验收-2026-09-11.md),机制、历史性能与误差见 [试验报告](../docs/other/雅可比结构着色试验与八路验证-2026-09-11.md)。
|
||
|
||
## 能力与限制
|
||
|
||
Jacobian 构建内现已按完整输入的浮点位复用储气物性、PH 温度反算、密度及管路求根结果,详见 [确定性复用说明](../docs/standard/native-jacobian-reuse.md)。独立耗时和求解计数调查工具见 [时间剖析说明](../docs/standard/native-solver-profiling.md);正常运行不加入该诊断插桩。
|
||
|
||
- 已实现当前注册的 27 类组件:22 类 Amesim 公开组件(含空气、氦气两种介质定义)和 5 类实验组件。完整清单及验证说明见 [组件覆盖记录](../docs/other/C内核组件库覆盖记录.md)。介质定义在编译期选择对应的 C 物性函数。
|
||
- 管路覆盖 PNL00R、PNL0001/2/3;阀覆盖 PNOR001、固定/信号开度 PNVO001 及面积/Cv/Kv 模式;连接件覆盖 PN3NODE2、P4NODE2、LMECHN1。支持串联阻力的压力求解、节点焓混合及温度参考、刚性质量合并、兼容管路容腔的等密度状态投影。
|
||
- MECMAS21 支持现有 Python 方程中的摩擦、风阻、柔性限位和 `stoptype=1/2/3/4`,含反弹系数与速度阈值;气腔和管路支持换热。LSTP00A 接受两种刚度模式及接触力符号模式,严格沿用当前组件方程。已有参数中尚未参与 Python 方程的物理效应不会在 C 端凭空补造,详见覆盖记录。
|
||
- 扩展编译器上限 1024 状态、16384 输出;无连续状态的信号系统使用隐藏常量状态驱动输出。气动网络必须有压力状态锚点;独立气腔之间不能无阻力直接相连。兼容固定管路容腔是已实现的合并例外。闭合未收敛或方程欠定时明确失败,不静默回退。
|
||
- 支持原生 RK45 与 CVODE BDF。CVODE 默认按可证明的结构启用着色差分,使用稠密线性求解;不支持分组的模型自动保留逐列差分。
|
||
- 网页和 Python CLI 默认 `rtol=1e-8`;生成的状态绝对误差限为质量 `1e-14 kg`、内能 `1e-8 J`、速度/位移 `1e-12`(各自 SI 单位)。独立 C 程序默认 `rtol=1e-6`,对照时应显式传入。CLI 可覆盖 rtol;本版不支持自定义 atol 或 first_step。不同积分器相同局部容差不保证全局曲线误差完全相同。
|
||
- 时间信号显式分段,塑性/反弹端挡用稠密插值定位并重启。LSTP00A 默认定位间隙过零;非负力模式还定位接触区内的原始力过零。两个生成路径均从机械状态索引发出 `NativeContact` 描述,检测不调用整模型 RHS,接触事件不重置位移/速度。试探 RHS 不修改已接受状态,接触力仍用原分段公式。MASS 弹性限位及连续释放的独立实验没有合入默认路径。
|
||
- LSTP 的防重复触发记录仅在接受事件时提交,不参与 RHS、雅可比或输出重放;同一浮点时刻的接触事件合并重启,并沿用输出语义 v2 保存两侧。结果的 `contactEvents` 提供检查、密集插值、二分和接触/力截断计数。相对速度换向时分段检测同号间隙的中间过零;这依赖已解析的积分步,不能保证捕获一步内任意多次未解析振荡。专项见 `tests/test_native_contact_events.py`。
|
||
- 每任务独立进程,支持进度、取消及超时。进程崩溃不会作为成功返回,受控失败保留最后接受状态。
|
||
- 编译缓存位于 `app/data/native-builds/`:`models/<SHA>/` 保存完整模型,`objects/<SHA>/` 保存可跨模型复用的模块目标文件。按当前模型使用的元件函数及其依赖选择模块,最多并行编译 4 个缺失单元。预处理后的实际 C 内容、工具链和编译选项组成对象键;完整模型键另含生成源码、组件合同及链接依赖。模型数值参数仍特化入 C,但仅重编受到影响的单元;时间、步长、rtol、采样选项仍是运行参数。
|
||
- 完整模型默认预算 256 MiB、对象预算 128 MiB,可分别设置非负整数环境变量 `SIMULATION_NATIVE_MODEL_CACHE_MB`、`SIMULATION_NATIVE_OBJECT_CACHE_MB`。按目录最近使用时间执行 LRU;活跃构建/运行及最后一个单独超额的条目保留并报告超额,因此是安全软上限。预算计算受管理文件的逻辑字节,不含旧版根级缓存、锁及文件系统元数据。
|
||
- 缓存读写带跨进程使用锁,命中时核验工件和身份,损坏缓存明确失败。对象复制到构建私有目录后再链接;模型使用锁一直保留到进程退出和结果读回。失败正常清理临时文件;进程被杀遗留的新格式构建目录在下一次清理时按锁状态回收。旧格式缓存保留,不自动迁移或删除,避免影响旧服务。
|
||
- Python 调用者若长期保留 `NativeBuild`,需在最后一次执行/打包后调用 `build.close()` 释放使用保护并触发清理;网页 runner 自动处理。返回的 `buildDetails` 区分完整命中、目标文件命中/编译次数、预处理、并行编译墙钟、编译任务耗时之和、链接和容量清理结果。
|
||
|
||
## 代码职责
|
||
|
||
后端启动后会异步执行原生环境自检,编辑器和 API 无需等待。首次检测失败后最多再重试 5 轮,共最多 6 次检测;每轮失败后等待 0.5 秒再开始下一轮,任一轮成功即停止。自检使用现有 `SIMULATION_NATIVE_CC`/PATH、`SUNDIALS_ROOT` 和默认探测方式,不写入机器专用编译器路径。它与正式构建共用编译选项和链接库,依次预处理、编译、链接并运行一个一状态 BDF 程序,核对已知解和成功标记;每轮都实际编译,不使用模型缓存。
|
||
|
||
`GET /api/simulation/runtime-check` 只读取本次启动自检的状态,返回当前阶段、轮次、结果和耗时,不触发新的检测。网页仿真控制台显示阶段变化;中间失败只提示未通过及正在重试,不展示报错详情,后端也不立即打印异常堆栈。全部检测失败后才显示最后一次的失败阶段、编译器、命令、工作目录、退出码及错误输出。进程未启动时退出码为 null;stdout/stderr 各保留最后 8000 字符。终态响应中的 `attemptHistory` 保留各轮结果、耗时和失败详情,便于追查首次故障;`durationMs` 是包括重试等待在内的总耗时,`startedAt`/`finishedAt` 使用 UTC 时间。
|
||
|
||
检测及重试期间每 0.5 秒查询,结束后停止定时查询;切回页面时读取一次结果以识别后端重启。提示明确描述“本次启动自检”,不代表持续的健康监测,也不改动仿真进度或阻断编辑器。检测通过仅表示本次工具链检查通过,不保证任意模型都能仿真成功。
|
||
|
||
Windows 使用 EXE 和与正式构建相同的 DLL 复制规则;Linux 使用现有静态库及链接分组规则。临时自检程序位于 `app/data/native-runtime-checks/`,正常完成、失败或取消后清理,避免 Linux `/tmp` 的 noexec 挂载产生误报。编译各阶段有 30 秒超时,运行有 10 秒超时;取消/超时会终止本次检测创建的进程树。既有 `SIMULATIONAPP_WARMUP=off` 仍可关闭检测,网页会明确提示已关闭。后台服务不会因普通自检失败而退出,也不会自动修改 PATH 或切换求解内核。
|
||
|
||
- `app/simulation/native_codegen/input.py`:CLI 输入适配。
|
||
- `contracts.py`:逐组件 C 实现版本白名单,新增模型或版本不会自动视为已支持。
|
||
- `compiler.py` / `extended.py`:能力检查、状态/输出布局、连接分组、常系数约束消元、C 生成。保留已验证的简单拓扑快速生成路径,两条路径均只运行 C 数值代码。
|
||
- `build.py` / `modules.py` / `cache_storage.py`:按需模块、两层编译缓存、完整性校验与有界 LRU;`runner.py`:隔离执行、使用保护与结果适配。
|
||
- `native/components/modules/`:物性、孔口、管路、机械和信号模块。`kernels.c` 仅供诊断的聚合入口,生产构建不再将聚合入口与模块重复编译。
|
||
- `native/runtime/`:RK45、CVODE 适配、事件定位、采样与 CLI。
|
||
- `app/simulation/backends.py` / `results.py`:共用执行入口与结果合同。
|
||
|
||
执行 `.venv-win/Scripts/python.exe -m unittest tests.test_native_catalog tests.test_native_codegen tests.test_simulation_warmup` 可验证全部注册合同、空气/氦气正反向流、换热/摩擦、节点和串联闭合、刚性与管路状态合并、反弹事件、纯信号系统、缓存、独立 EXE、取消及默认 C 的 XML 接口。新增组件库对照测试需要可用的 C 工具链。
|
||
|
||
## Python 保留范围
|
||
|
||
- `app/main.py`、`system_xml.py`:HTTP、XML 校验与结果返回。
|
||
- `registry.py`、`core/`、`components/`、`systems/network.py`:参数、端口、介质常量、输出与方程结构声明;不执行模型数值公式。
|
||
- `native_codegen/`:生成系统 C、构建缓存、管理独立进程。
|
||
- `config.py`、`sampling.py`、`results.py`:配置、进度、采样合法性和结果合同。
|
||
- `performance.py`:Python 编排阶段计时,求解耗时读取 C 报告。
|
||
|
||
`solvers/`、`systems/generic.py`、旧示例、Python 物性/流量/机械公式和物性缓存已删除。数值回归读取 `tests/baselines/native/native-python-reference.json` 的 50 个网络、112 组冻结参考状态,不需要 Python 求解器。旧算法及历史对照资料可从 Git 历史找回。
|
||
|
||
测试安装:`python -m pip install -r requirements-test.txt`。完整数值测试需要 GCC 与 SUNDIALS;Windows x64 使用导入库/DLL,Linux x86_64 使用静态库。
|
||
|
||
## AME 对齐后的工程输入
|
||
|
||
当前用户运行请使用 `tests/data/test-mql-4-corrected.json` 或 `tests/data/test-mql-8-corrected.json`。执行 XML 从当前 JSON 按需生成;原独立四路 XML 和 legacy 八路夹具已删除。历史八路 JSON/XML 在 `tests/baselines/simulation/test_mql_8/sources/`,其 AME 在 `tests/data/AmesimModels/test_mql.ame`,仅用于冻结基准核对,不能与当前 corrected 输入混用。路径、生成方式和测试入口见 [测试文件说明](../tests/data/README.md)。`test-mql-4-amesim-reference.json` 是曲线基准,不是工程输入。模型复核、P4 端口图形修正、默认 `rtol=1e-8` 的验收和速度记录见 [本轮验证报告](../docs/other/牛顿管流求根与四路网页验证-2026-09-11.md)。
|
||
|
||
后续优化和网页计时默认使用修正后的八路工程;仅当八路无法运行且短期不能解决时退回四路。选择规则见 [优化验证约定](../docs/standard/optimization-benchmark-model.md),当前效率、迭代触顶与网页分阶段记录见 [八路评估报告](../docs/other/八路模型计算效率与网页阶段计时-2026-09-11.md)。
|
||
|
||
## 结果传输与网页后处理
|
||
|
||
网页流式请求使用 C 的可选 `--result-index` 字节索引,Python 只解析小元数据,将原有 JSON 的 `series` 原样放入 NDJSON 结果事件;任务结果查询同样支持原样返回。独立 CLI 与默认同步调用仍返回普通 JSON/结果对象,JSON结构、积分和采样保持一致。前端结果保存改为打包 Float64 块的原子事务,CSV 由工作线程本地生成,兼容旧缓存及旧 HTTP CSV 接口。完整结果、取消与刷新回归及八路前后计时见 [结果处理优化报告](../docs/other/八路结果处理与网页保存优化-2026-09-11.md)。
|
||
|
||
C结果的 `series/final/finalState` 现使用固定版本Ryu binary64编码及64 KiB批量写出;在精确回读前提下选择更短的普通/科学token,负零保留为 `-0.0`,非有限值或写出失败阻止索引发布。数字文本允许变化,索引元数据保持整数。嵌套Ryu头文件参与缓存哈希;源码和Boost许可随项目保留。本轮研究、逐位验证和八路网页前后计时见 [C结果编码优化报告](../docs/other/C端结果编码与写出优化-2026-09-11.md)。
|