Files
SystemSimulationApp/docs/standard/component-registration-example-v1.md
T

11 KiB
Raw Blame History

新组件注册示例与验证记录

文档版本:1.0.0;修订日期:2026-09-12;代码基线:22579e5。

本文由原 app/simulation/components/example.md 迁入并重写,配合注册流程、建模规范和库读取规范使用。示例在隔离源码副本中实际执行,正式组件库不增加演练型号。它验证当前接入流程,不是待发布的新物理模型。

1. 示例合同

新建第三个库 registration_demo、分类 signals、型号 registration_demo_ramp,类名 DemoRamp,模型版本 1.0.0。复用图形键 amesim_step0,增加 C 模块 demo_signal;图形键不决定数值行为。

公式为:

y(t) = offset + amplitude × t / duration
参数 SI / 默认值 约束
offset 无量纲 / 2 有限值
amplitude 无量纲 / 3 有限值
duration s / 1 有限且严格大于零

唯一端口 out 是信号输出,显示在右侧。组件输出 y 与端口输出 out.signal 相同。模型无积分状态、无事件、无气动参考口。Python 类显式声明 MODEL_TYPE/MODEL_VERSION/PORTS/PARAMETERS/RESULT_VARIABLES/DISPLAY/create;构造函数保存参数并注册端口。完整可执行类及各处接入代码保存在后端演练脚本,不再维护另一份易过期的代码副本。

C 函数是:

#include "kernels.h"
double native_demo_ramp(double t, double offset, double amplitude, double duration) {
    return offset + amplitude * t / duration;
}

duration > 0 由组件参数合同检查。本演练用已校验的参数生成 C 常量,不能据此认为任意外部输入都已校验,或任意有限幅值不会溢出;它是受限输入的接入示例。

2. 分阶段注册:有意遗漏与实际失败

每阶段使用新 Python 进程,避免已导入模块掩盖发现入口变化。脚本在对应失败处断言错误原因,最终阶段要求成功。

阶段 已完成的步骤 实际结果 / 规范含义
unlisted 新类和库文件存在,未启用库 注册表没有新型号;目录扫描不会自动注册
catalog_only 启用新库与清单 目录、参数和 XML 校验通过;原生生成报 no native contract
native_discovery_only 将新库加入 extended.catalog_contracts() 原生版本与模型合同不匹配;还需 SUPPORTED_VERSIONS
contract_only 补支持版本 报 Native output mapping incomplete,缺少 ramp_1.y 和 ramp_1.out.signal;版本白名单不会实现方程
lowered_without_module_export 扩展生成器输出分支、C 函数和公共头文件 链接报 undefined reference to native_demo_ramp;模块未纳入按需导出
complete 补 modules.py::EXPORTS、诊断聚合包含清单、经核对的函数识别 构建与 RK45/BDF 运行通过

实际修改仅发生在生成的 sandbox/:新库的四个 Python 文件、registry.py、extended.py、contracts.py、modules.py、jacobian.py、kernels.h、新 C 模块及诊断聚合入口。生产源码没有新增该类型。

该函数只读取时间和参数,没有状态依赖。将其纳入受控函数识别集不等于验证了任意多输出函数、投影或新动态模型的雅可比结构;这些仍按专项规范审查。

3. 浏览器导入过程中发现的额外边界

初次尝试 实际行为 已采用的处理与规范修订
把目录 ports 原样写入工程 信号端口带 positiveFlowDirection: null,浏览器拒绝;后端仍可转出有效 XML 工程快照按前端结构规范化,信号端口省略该字段;保留错误导入检查
连线只写端点 缺 data.isContactEdge,浏览器拒绝 普通连线显式保存 data: {"isContactEdge": false}
尝试把时长从 s 切到 ms 当前只有 s 选项 验证已有 SI 参数编辑;不把新增单位描述成目录自动支持
使用未接线的独立信号源点击运行 后端是未接端口警告,前端检查为错误并阻止仿真 网页改用完整接线网络;区分单元件后端测试与网页系统测试

合法信号端口快照示例:

{"name":"out","kind":"signal","domain":"signal","nominalRole":"output","side":"right"}

网页案例使用四个元件、三条连接:

ramp_1.out     -> force_1.res
force_1.port_2 -- mass_1.port_2
mass_1.port_1  -- zero_1.port_1

force_1 使用 FORC 的正向信号转力,mass_1 使用 MECMAS21(质量 10 kg、零初始位移/速度、禁用摩擦和限位),zero_1 是 F000。网页把 duration 从 1 s 改为 2 s,因此 F(t)=2+1.5t N,质量块的独立解析参考为:

v(t) = 0.2t + 0.075t²
x(t) = 0.1t² + 0.025t³

4. 本版规范的逐项校正

旧规范不匹配之处 本版处理
仅描述 experimental,仍计划未来建立正式库 核对当前 experimental/amesim 两库;临时隐藏由库 ID 决定
“加入 library 就完成注册/无需其他修改” 明确元数据发现与原生发现、版本、方程和模块链接四个独立检查点
C 公式仍要求放 kernels.c 改为 modules/*.c、kernels.h 和模块导出/依赖;聚合文件仅用于诊断
启动校验要求 Python component_result_values() 删除过期要求,改为元数据校验、C 输出映射及 EXE 输出的分层检查
Python 状态声明容易被理解为自动得到 C 状态 明确索引、初值、导数和结果由具体生成路径实现
前端新增能力仅需图标 补齐动态端口、新编辑器、新物理量/单位、介质和连线规则的条件修改范围
目录、工程和 XML 合同被混用 补信号端口 null、连线 data 字段、SI 参数、完整参数、网页必接端口要求
无原生模块缓存、雅可比、新状态尺度要求 新增导出/依赖、缓存失效、状态依赖和容差量纲检查项
“不支持迁移”的表述过于绝对 区分 XML 精确版本、前端型号专用处理和未实现的通用迁移框架
未区分跨平台适配与实际验收 分别记录 Linux/Windows 状态,新 C/构建/缓存能力同样适用

修改发生在现行规范正文,不只在本表列出待办。文件分工和迁移位置见规范索引。

5. 验证结果与范围

最终可复现记录放在本地 test/component-registration-20260912-verified/,该目录被 Git 忽略。

验证 结果与边界
六阶段发现、版本、输出、链接检查 全部符合阶段预期,最终构建成功
后端独立元件,RK45 与 BDF 0~1 s,0.1 s 采样,各 11 点;y 解析误差为 0,端口输出与组件输出相同
重复构建 完整模型命中,对象编译 0 次
参数 duration 1→2 模型对象重编译 1 次,其余 8 个对象复用,最终输出 3.5
失败输入 错误 modelVersion、零 duration、XML 缺 duration 均被拒绝
浏览器 真实 Chromium、真实目录/API/C 程序;发现、拖入、错误 JSON 拒绝、完整工程导入、参数编辑、JSON/XML 导出、两次 BDF、曲线显示、结果文件/CSV、刷新恢复
网页解析对照 信号与输出力逐点误差 < 1e-12;质量块最大位移差 1.26236e-11 m、速度差 2.36616e-13 m/s(门槛分别为 1e-7)
网页缓存与保存 第二次运行完整模型缓存命中;CSV 中新元件两列符合解析值;刷新恢复与保存结果完全一致
生产目录回归 注册、目录、元数据共 23 项测试通过;生产仍为 27 类,原生版本一致,演练类型未进入生产库
Windows 未实际执行;本机无 Windows 运行环境,不宣称双平台验收完成

第一轮缺导出的链接失败已生成部分共享对象,因此 firstCompleteBuild 不是全空缓存耗时;本演练不作性能优化结论。目录结构、失败阶段、函数接入在 Linux 得到实证,Windows 仍需用现有工具链执行复现与对应回归。

本案例不覆盖新物理域、动态端口、新编辑器、非平凡的雅可比着色、新非线性环或气动固定参考口,也不代表完成了 Amesim 等价性验证。此次修改仅为规范和演练工具,未修改共享求解行为,因此没有再次运行八路性能基准。

主要证据文件:summary.json、各阶段 *.json/*.log、input.xml、project.json(后端独立案例)、browser-project.json(网页完整网络)、browser/summary.json、网页导出与截图。探索中的失败记录在旁边的 test/component-registration-20260912/ 和 test/component-registration-20260912-final/;最终结论以 -verified 目录为准。

6. 复现方法

前提:仓库 Python 依赖、现有 C/SUNDIALS 工具链和前端依赖可用。前端源代码变化后先在 frontend/ 执行 npm run build,演练会复制现有 frontend/dist/。环境、工具链和浏览器不随 Git 提交。

Linux,从仓库根目录生成全新目录(已存在会拒绝覆盖):

.venv/bin/python tests/manual/rehearse_component_registration.py --output-dir test/registration-replay

另开终端启动隔离后端,使用同一 Python 环境:

registration_repo="$PWD"
cd test/registration-replay/sandbox
"$registration_repo/.venv/bin/python" -m uvicorn app.main:app --host 127.0.0.1 --port 8036

回到仓库根目录运行浏览器脚本:

node tests/manual/browser_component_registration.mjs test/registration-replay/browser-project.json test/registration-replay/browser http://127.0.0.1:8036

本机采用 .tools/node-v24.18.0-linux-x64/bin/node。若使用此前补充的浏览器动态库,在命令前设置:

export LD_LIBRARY_PATH="$PWD/.venv/native/browser-libs/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"

Windows PowerShell 对应入口(须先配置现有 Windows C/SUNDIALS 工具链及 Playwright 浏览器,以下不是已通过记录):

$registrationRepo = (Get-Location).Path
$registrationPython = Join-Path $registrationRepo '.venv-win\Scripts\python.exe'
& $registrationPython tests/manual/rehearse_component_registration.py --output-dir test/registration-replay-win
Set-Location test/registration-replay-win/sandbox
& $registrationPython -m uvicorn app.main:app --host 127.0.0.1 --port 8036

在另一个 PowerShell 终端回到仓库,运行同一 .mjs 脚本,输入换成 test/registration-replay-win/browser-project.json,Node 使用本机 Windows 路径。浏览器与 Python 均使用原平台环境,不复制 Linux 动态库。

完成后在启动 uvicorn 的终端按 Ctrl+C。演练使用临时端口 8036;本次未启动用户已停止的 5173/8000。删除生成目录即可清理演练源码、结果与缓存;生产组件及现行规范不依赖这些生成物。