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

19 KiB
Raw Blame History

新组件注册流程与交付规范

文档版本:1.1.0 修订日期:2026-09-12 核对代码基线:22579e5(缓存功能 Windows 平台适配)。本文是新增网页建模与原生仿真组件的总流程;专项字段规则见规范索引,执行证据见注册示例与验证。文档版本独立于模型和协议版本。

本版通过隔离源码中的斜坡信号源注册演练校正现有规范。演练组件和编译缓存不加入正式组件库;可复现脚本保留在 tests/manual/。

1. 当前架构与完成边界

当前有两条接入链路。元数据注册控制组件发现和编辑;原生支持控制能否生成并执行数值模型。注册类不会自动获得 C 求解能力。

flowchart TD
    A[组件物理定义与 Python 声明] --> B[library.py 与注册校验]
    B --> C[组件目录 API]
    C --> D[前端组件库、参数面板和端口]
    D --> E[工程 JSON 与执行 XML]
    E --> F[校验并构造网络]
    B --> F
    F --> G[C 支持合同与系统代码生成]
    H[公共 C 数值模块] --> I[按需编译、缓存和链接]
    G --> I
    I --> J[独立 C 程序积分与输出]
    J --> K[网页结果、保存和 CSV]

源码依据:

  • 注册中心:ENABLED_COMPONENT_LIBRARIES → library.py → validate_component_model_class() / create() → 注册表。
  • 目录 API 与网络构造:/api/components/catalog、compile_system_xml_network()、_compile_solver_network()。
  • 原生入口:compile_native_program() 检查类型和版本,再选择紧凑路径或扩展路径。
  • 扩展生成器:按具体模型实现状态、方程与输出映射。
  • 前端工作台:normalizeComponentCatalog()、工程读写及通用参数处理。

本次直接加载注册目录核对:experimental 5 类、amesim 22 类,共 27 类;原生版本表与注册版本一致。这是当前快照,不应成为未来新增组件后的固定数量要求。

以下标识不可混为一谈:

标识 作用 示例
library.id 发布和发现边界 amesim
category.id 前端组件面板分组 flow
MODEL_TYPE 工程/XML/原生支持的模型类型 amesim_pnor001
DISPLAY.symbol 前端图形渲染键 可以与 MODEL_TYPE 相同,也可以复用已有图形
C 功能模块 数值代码组织及对象缓存粒度 orifice、pipe

界面分类与 C 功能模块没有自动的一一映射。不同型号可以调用同一个公共 C 函数;同一型号也可以依赖多个模块。

2. 新增组件的实际步骤

第一步:确定物理合同和接入范围(必做)

先整理模型依据、适用介质/物理域、计算公式、符号约定、有效范围和未支持能力。明确它是无状态代数组件、动态组件,还是编译期介质定义。若是新增物理域或新种类的介质,须单独评估网络、XML、前端连线、物性和原生生成支持,不能只新增一个 domain 或类型字符串。

建议首先形成四张表:

  • 参数:机器名、物理意义、SI 单位、默认值、范围、枚举、显示条件和是否影响端口/状态数量。
  • 端口:稳定名称、物理域、连接类型、各变量含义、正方向、供需关系、参考来源及是否必须连接。
  • 状态:名称、含义、单位、初值公式、导数公式、允许范围、绝对误差尺度及相关事件。
  • 输出:稳定名称、含义、单位、显示名称、计算公式和所属组件/端口。

第二步:编写 Python 组件声明(必做)

文件放在 app/simulation/components/<library>/<category>/,参照同类模型。现有代码存在一个文件容纳多个相关型号的情况;“每模型单文件”是整理建议,不是注册器的硬性要求。

公开模型类必须在自己的类体显式声明:

MODEL_TYPE
MODEL_VERSION
PORTS
PARAMETERS
RESULT_VARIABLES
DISPLAY

@classmethod
def create(cls, *, name, medium, parameters):
    ...

这七项由 registry.py 检查,不能只从父类隐式继承。可以显式引用已有声明,例如 RESULT_VARIABLES = Parent.RESULT_VARIABLES。

构造过程调用 set_parameter_values() 保存完整规范化参数,使用 register_declared_port() 注册声明的端口,并保存介质和常量。参数合法性包括单字段范围和跨参数约束;默认参数必须能够创建描述对象。公共创建入口填充缺省值后还会核对实例类型、端口和参数是否与声明一致。

Python 可以做参数验证和常量几何换算;运行时物性、流量、力和状态导数由 C 计算。EQUATIONS / equation_definitions() 是结构化约束声明,不会被自动翻译成完整 C 数值方程。仅设置 DynamicComponent.state_size 也不会自动分配原生积分状态。

第三步:落实端口语义(必做,静态与数值两侧一致)

PORTS 是物理接口来源,DISPLAY.ports 是显示布局,两者的名称集合必须一致。当前显示端口基础声明支持 left/right,旋转和镜像由前端处理,不能直接写未经实现的显示边。

气动端口需要区分:

  • 名义入口/出口及实际正反流。
  • 哪些量由本端提供,哪些量由对端提供。
  • 是否是固定供需的参考口或支路口;reference_port 指向哪个真实参考来源。

使用 port_computation.py 的既有合同或声明准确的新合同。参考关系不会随流向反转而自动改变;不能从图标左右位置推断物理参考口。端口流量遵守现有“流入组件为正”的合同。

参数决定端口启停时,同时实现类级和实例级有效端口查询,并核对必须连接的端口。前端目前对 LMECHN1 的动态端口还有专门逻辑,尚无统一的参数化端口目录协议;新动态端口模型要明确补齐前端规则及变更参数后旧连线的处理。

第四步:加入受控组件清单(必做)

在所属库 library.py 的 models 中加入 完整模块路径:类名。如新增界面分类,同步该库 categories 和 DISPLAY.category_id。不要直接修改运行时 COMPONENT_MODEL_REGISTRY,也不要扫描目录执行任意 Python 文件。

新库需增加 ComponentLibrarySpec,并加入 registry.py 的 ENABLED_COMPONENT_LIBRARIES。另外,当前 extended.py::catalog_contracts() 仍显式读取 amesim 和 experimental 两个库,新增第三个库还必须扩展这一原生发现入口。

前端当前按库 ID 隐藏 experimental。加入实验库的模型可以被后端发现,但不会出现在左侧公开组件列表;temporary 标记不是现有隐藏规则。

第五步:实现或复用 C 数值内核(数值接入必做,新增 C 文件按需)

先判断现有公共函数是否已经满足方程。如果只需已有内核加不同参数或组合,可以复用,避免按元件实例复制内核。

新增函数应放在 native/components/modules/ 的合适模块,公共接口在 kernels.h 声明;新增独立模块时再建立新的 .c。当前五模块为物性、孔口、管路、机械和信号。

按需构建由 modules.py 的 EXPORTS 和 DEPENDENCIES 决定。增加新导出函数或模块依赖时应同步这里;只在头文件写声明不会保证模块进入链接。新模块如需参与聚合诊断,还要加入 native/components/kernels.c 的包含清单。

kernels.c 现在是诊断聚合入口,生产构建不直接编译它;不能同时链接聚合入口与各模块,否则产生重复定义。

内核应说明非法状态、非有限值及迭代失败的处理。新气动计算优先传递现有 NativePropertyCache 上下文;试算不能污染已接受状态,也不能把跨状态的旧物性无条件复用。沿用 C11、严格浮点和已有 Windows/Linux 构建约定。

第六步:接入系统代码生成、依赖和数值精度(必做)

在 native_codegen/extended.py 接入该具体型号的:

  1. 有效端口、连接组及介质选择。
  2. 状态编号、初值、必要的状态约束/投影。
  3. 代数关系、流量、焓和力计算。
  4. 状态导数及全部可见输出赋值。
  5. 分段信号、限位或其他事件(适用时)。

目前这些逻辑包含具体类型集合与分支,例如 GAS_TYPES、NODES、RESISTORS;简单地把新型号塞进某个集合,不能保证后续分支正确处理它。

计算输入/输出通过 Computation / EvaluationSchedule 接入 求值排序。多输出函数要准确声明读取量和写出量;参考值复制与依赖流量的混合计算应分开;正流、逆流、零流量和各离散模式的依赖均需覆盖。新增不被当前局部求解器支持的非线性环,要实现对应求解或明确拒绝。

还需核对 雅可比结构 的状态依赖。新的多输出调用、投影和分支不能遗漏依赖;无法证明时允许使用保守逐列差分,不能为保持着色而把未知依赖当作常量。适用时给生成的 model/model.exe 传入 --verify-jacobian 核对;Python 包装 CLI 没有同名选项。

新增状态量需要检查 绝对误差尺度。当前按状态字段名区分质量、位移/速度,其余默认 1e-8;新物理量不能未经量纲评估直接套默认值。

compiler.py 保留紧凑生成路径,但新型号不一定需要同步实现第二套路径。正确做法是确认它被路由到已支持的生成路径;只有纳入紧凑路径或改变两路径共享行为时,才同步实现并做路径对照。不要只扩充 _STORAGE_ANCHORED_TYPES 却漏掉对应计算。

实现并验证后,将 MODEL_TYPE: MODEL_VERSION 加入 contracts.py。这是支持承诺,不能用加入白名单代替真正的数值实现。

第七步:核对前端图形与交互(必查,代码修改按需)

对普通固定端口、现有编辑器和现有单位的模型,组件库列表、参数名称/默认值/边界/枚举/显隐条件通过目录自动生成。通常不用在 App.tsx 再添加一份型号参数表或新建仿真 API。

需要新图形时,在 frontend/src/componentSymbols/ 实现渲染,并加入 ComponentSymbol.tsx 的 symbolRegistry。完整图形定义包含 viewBox、图标尺寸、节点占地、端口锚点;按参数变化的图形还需相应布局函数。没有专用图形时当前有通用边框回退,但它不代表专用图形已经验收。

以下情况需额外前端工作:

新能力 需要核对的入口
新图形/锚点 componentSymbols/*、ComponentSymbol.tsx
新参数编辑器 core/metadata.py / 注册校验、目录解析、ParameterTable.tsx / App.tsx
新单位或物理量的单位切换 后端 SI_UNIT_BY_QUANTITY、共享参数 schemas/parameter-units.json、结果 RESULT_UNIT_OPTIONS;三入口回归
动态端口 后端有效端口接口、前端端口显示/连线处理和参数变更逻辑
新物理域/连接规则 core/ports.py、网络/XML 校验、前端连线检查及 C 生成
特殊介质定义/引用 XML/前端的目录角色、网络识别的介质定义基类、介质注册与引用选择逻辑

浏览器检查应覆盖端口号、实际连线端点、旋转/镜像、参数改变后的布局及导入导出。图形变了不能偷偷改变物理端口名称或参考关系。

第八步:核对工程文件、版本和输出(必做)

普通已有协议下的模型通过注册表即可被通用 XML 流程识别,通常不需要修改 XSD 或添加型号专用 API。

  • XML 要求精确匹配 modelVersion,参数集合完整且没有未知字段;Python 工厂可填默认值不等于 XML 可以任意缺参数。
  • 外部工程 JSON v2 的数值和表达式统一按所选单位解释,网页/HTTP/CLI 预处理后才进入 SI 数值边界。旧 v1 数值不能重复换算。组件版本差异提示后允许执行;型号、端口、参数错误继续拒绝。导出时只对通过校验的节点升级版本,按输入合同验收旧文件和重新导出的文件。
  • 采用实际浏览器导出的工程结构,不直接复制目录对象。例如信号端口快照须省略 positiveFlowDirection: null;连线须保存 data.isContactEdge 布尔字段;后端转 XML 成功不能代替浏览器导入检查,见目录与快照差异。
  • 网页当前要求所有显示端口恰好连接一次。后端单元件算例的未接端口警告不能替代网页完整网络验收。
  • 发布后保持模型/端口/参数/结果机器名稳定。提高版本可能使旧 XML 被拒绝;当前没有通用自动迁移框架,前端仅存在部分特定型号迁移逻辑。
  • RESULT_VARIABLES 中可见项与活动端口的可见变量必须在实际 C 输出中全部赋值,结果键/单位应与网页、缓存恢复、CSV 一致。

第九步:分层测试和双平台验收(必做,按物理适用性选择案例)

层次 最少核验内容 现有入口示例
声明与注册 全局类型唯一、版本、默认可创建、非法/边界参数、端口/显示/结果一致 test_component_registry、test_component_catalog、test_component_metadata
接口与文件 正确连接、缺口/错误参考被拒绝、JSON/XML 往返、版本不兼容 test_port_computation、test_system_xml_v3、型号专项
元件数值 独立公式或可信参考、正常/零值/边界/逆向、守恒和明确失败 型号 C 专项、--init / --probe
系统求解 包含新元件的最小闭合网络,RK45/BDF(适用时),事件、顺序打乱与输出完整 test_native_codegen、test_native_schedule、test_native_catalog
雅可比 状态依赖覆盖、模式切换、必要的完整矩阵核对 test_native_jacobian_structure、test_native_jacobian_runtime
编译与缓存 空缓存构建、完整命中、参数/模块变化后正确失效、缺失模块链接失败能被发现 test_native_build_cache、test_native_cache_platform
浏览器 发现/拖入/编辑/连线/旋转镜像、运行、结果可查看、IndexedDB 保存、下载/CSV/刷新恢复分别核查 frontend/tests/e2e/ 的相关测试
双平台 Windows 与 Linux 实际构建和运行;Windows .exe / DLL / 路径 / 文件系统能力 native-windows CI、跨平台集成测试

新增模型要有自己的可执行案例,不能只改变“现有 27 类”的数量断言。已有测试包含固定类型清单/数量,新增后需合理更新覆盖期望,并证明新型号确实执行。

数值参考来自独立解析结果、可信外部结果或经过审查的冻结基准;不能从待验实现自动生成“预期值”来证明自身正确。保留原有参考,不直接覆盖历史基线掩盖差异。

对共享内核/求解器的修改,沿用修正八路作为系统回归与性能案例;新元件自身仍需最小闭合案例。只有八路无法运行且短期无解,才退回四路。性能对照分别记录构建、求解、结果处理与网页可查看/保存;无可信 Amesim 曲线或耗时则明确跳过相应对比。

Windows 验收遵循 跨平台交付约定。模拟测试与代码适配不能代称 Windows 实机运行通过。

3. 常见修改范围

文件/区域 新增普通型号时是否必改
所属组件库中的 Python 声明 必改
所属库 library.py 必改
native_codegen/extended.py 或已确定的生成适配入口 必须接入;当前通常需修改
native_codegen/contracts.py 必改
native/components/modules/*.c / kernels.h 新数值函数才改;已有内核可复用
native_codegen/modules.py 新导出函数或新模块依赖时改
native_codegen/compiler.py 紧凑路径 新型号纳入该路径或共享行为受影响时改
schedule.py / jacobian.py / tolerances.py 核对生成器接入;现有机制不足、新函数依赖或新状态尺度需要时改
前端图形注册与渲染 需要专用图形或布局时改
App.tsx / ParameterTable.tsx 动态端口、新编辑器、新单位等现有元数据能力不足时改
app/main.py / app/system_xml.py / XSD 普通型号通常不改;新协议/物理域/介质机制时改
注册、型号数值、系统和浏览器测试 增加相应案例并更新受影响的覆盖期望

4. 组件接入交付资料

每个拟交付的新型号提供“组件接入说明”,按适用性填写以下栏目;未涉及的能力写明不适用:

  1. 身份与版本:类型、类路径、所属库/分类、模型版本、图形键、关联已有型号及兼容性处理。
  2. 物理依据:参考来源、完整方程、假设、适用范围、未支持功能。
  3. 参数表:SI 值、默认值、边界、枚举、条件显示、几何常量预处理。
  4. 端口表与标号图:变量、正方向、供需、参考口、动态启停和必接要求。
  5. 状态/事件/结果表:初值、导数、误差尺度、事件行为、输出键和单位。
  6. 原生接入表:C 函数、所属模块、依赖、生成路径、计算顺序、雅可比依赖与缓存失效范围。
  7. 前端/文件合同:图形及锚点、单位和编辑器、JSON/XML 示例、旧工程处理。
  8. 验证记录:最小算例、独立参考来源、误差门槛、失败路径、Windows/Linux 实际结果和网页验证;性能数据按阶段区分。

验证记录区分三个完成状态:

  • 已注册:目录/工厂/XML 类型与参数校验通过。
  • 可求解:原生构建、独立数值对照、闭合网络运行和输出检查通过。
  • 可交付:浏览器交互/文件往返/保存及 Windows/Linux 验证通过,兼容性和资料齐全。

这些是文档中的验收状态,当前目录 API 尚未提供对应的统一字段;不要向工程 JSON 添加未实现的状态协议。

5. 本版修订与维护

本版已在专项规范中修正:旧 C 文件入口、移除的 Python 结果接口、新库的两条发现入口、原生版本与方程的独立接入、前端条件能力、目录与工程快照差异、网页完整接线要求、精确版本和专用迁移的边界,以及模块缓存、雅可比依赖和 Windows 验证要求。

具体逐项对照、失败阶段和最终测试结果见注册示例与验证。后续代码架构变更时更新对应专项规范及本流程;不在文档中维护第二份可执行型号参数表。