SystemSimulationApp

SystemSimulationApp 是一个面向系统仿真的可视化建模原型。当前项目已经具备两条基础能力:

  • 使用 FastAPI 嵌入 draw.io,提供可视化拖拽建模界面。
  • 使用 PythonModels 中已有的 Python 仿真模型,运行当前固定拓扑的 TestModelSystem。

下一阶段的目标是把这两条能力接起来,先完成一个小 MVP:

draw.io 画图
  -> 解析 draw.io XML
  -> 生成 SystemModel
  -> 映射到 PythonModels.TestModelConfig
  -> 调用 run_testmodel()
  -> 返回并展示仿真结果

当前状态

已有前端和接口基础

  • app/main.py: FastAPI 主入口。
  • app/static/index.html: 当前 draw.io iframe 页面。
  • /api/component-library.drawiolib: 当前 draw.io 自定义组件库接口。
  • /api/system-xml: 当前 draw.io XML 到简单系统 XML 的导出接口。
  • /drawio/: FastAPI 到 draw.io Docker 的同源代理入口。

已有 Python 仿真模型

PythonModels 目录里已经有一套 Python 仿真骨架:

PythonModels/components/
  cylinder.py   -> Cylinder,端口 port_b
  tank.py       -> Tank,端口 port_a
  pipe.py       -> Pipe,端口 port_a / port_b
  orifice.py    -> Orifice,端口 port_a / port_b
  tee.py        -> Tee,端口 port_in / port_out1 / port_out2

PythonModels/core/
  network.py    -> SimulationNetwork / Connection
  ports.py      -> PortState
  solver.py     -> integrate_ode / SolveIVPConfig

PythonModels/systems/
  testmodel.py  -> 当前唯一可运行系统 TestModelSystem

当前 TestModelSystem 支持的是固定拓扑:

mycylinder
  -> mytee
    -> myorifice  -> mypipe
    -> myorifice1 -> mypipe1
  -> mytee1
  -> mytank

因此第一版不要做任意拓扑仿真,而是先把 draw.io 中画出的这个固定拓扑映射到现有 TestModelSystem。

核心原则

不要让仿真逻辑直接依赖 draw.io XML。

推荐分层:

draw.io XML
  -> SystemModel
  -> PythonModels adapter
  -> PythonModels runner
  -> SimulationResult

其中:

  • draw.io XML 只是可视化画布格式。
  • SystemModel 是系统仿真的核心结构化数据。
  • PythonModels adapter 负责把 SystemModel 转成 TestModelConfig / TestModelRunConfig。
  • 仿真器只认结构化模型,不直接解析画布。

这样后续即使替换 draw.io,仿真层也不用推倒重来。

MVP 范围

第一版只支持当前 TestModelSystem 对应的拓扑:

cylinder -> tee -> valve/orifice -> pipe -> tee -> tank
              -> valve/orifice -> pipe ->

第一版支持的组件:

draw.io 类型 PythonModels 类型 配置对象 端口
cylinder Cylinder CylinderConfig port_b
tank Tank TankConfig port_a
pipe Pipe PipeConfig port_a, port_b
valve / orifice Orifice OrificeConfig port_a, port_b
tee Tee 暂无独立配置 port_in, port_out1, port_out2

前端可以继续显示“阀门”,但底层建议使用:

modelType="orifice"

因为 PythonModels 里实际对应的是 Orifice。

SystemModel 设计

建议新增统一结构:

{
  "name": "testmodel_from_drawio",
  "components": [
    {
      "id": "mycylinder",
      "type": "cylinder",
      "role": "cylinder",
      "parameters": {
        "volume": 0.01,
        "p0": 35000000,
        "T0": 300
      }
    }
  ],
  "connections": [
    {
      "source": {
        "component": "mycylinder",
        "port": "port_b"
      },
      "target": {
        "component": "mytee",
        "port": "port_in"
      }
    }
  ],
  "simulation": {
    "t_start": 0,
    "t_stop": 20,
    "step": 0.1,
    "method": "BDF"
  }
}

draw.io XML 扩展约定

组件节点需要补充仿真语义:

<object
  id="mycylinder"
  label="气瓶"
  componentType="cylinder"
  modelType="cylinder"
  role="cylinder"
  volume="0.01"
  p0="35000000"
  T0="300">
  ...
</object>

管段示例:

<object
  id="mypipe"
  label="上支路管段"
  componentType="pipe"
  modelType="pipe"
  role="upper_branch.pipe"
  length="5.0"
  diameter="0.02"
  lambda_darcy="0.02"
  p0="100000"
  T0="300">
  ...
</object>

孔板 / 阀门示例:

<object
  id="myorifice"
  label="上支路孔板"
  componentType="valve"
  modelType="orifice"
  role="upper_branch.orifice"
  K="0.00001"
  opening="1.0">
  ...
</object>

连接需要从“组件级”升级到“端口级”:

<object
  id="edge1"
  sourcePort="port_b"
  targetPort="port_in">
  <mxCell edge="1" source="mycylinder" target="mytee" />
</object>

如果第一版来不及做端口选择,可以后端按组件类型和拓扑位置推断默认端口,但这只能作为 MVP 兜底。

参数映射

从 draw.io / SystemModel 解析出的参数映射到 PythonModels 配置对象:

cylinder.volume -> CylinderConfig.volume
cylinder.p0     -> CylinderConfig.p0
cylinder.T0     -> CylinderConfig.T0

tank.volume     -> TankConfig.volume
tank.p0         -> TankConfig.p0
tank.T0         -> TankConfig.T0

pipe.length       -> PipeConfig.length
pipe.diameter     -> PipeConfig.diameter
pipe.lambda_darcy -> PipeConfig.lambda_darcy
pipe.p0           -> PipeConfig.p0
pipe.T0           -> PipeConfig.T0

orifice.K       -> OrificeConfig.K
orifice.opening -> OrificeConfig.opening

注意:当前 Orifice 类支持 opening,但 OrificeConfig 暂时只有 K。建议后续给 OrificeConfig 增加 opening 字段,这样前端“阀门开度”才有实际落点。

建议新增后端模块

app/models/system.py
app/services/drawio_parser.py
app/services/model_validator.py
app/services/pythonmodels_adapter.py
app/services/simulation_runner.py

职责:

app/models/system.py
  定义 SystemModel、ComponentInstance、Connection、SimulationConfig。

app/services/drawio_parser.py
  负责 draw.io XML -> SystemModel。

app/services/model_validator.py
  检查组件、端口、参数、拓扑是否合法。

app/services/pythonmodels_adapter.py
  负责 SystemModel -> TestModelConfig / TestModelRunConfig。

app/services/simulation_runner.py
  调用 PythonModels,并把结果整理成前端可消费的 JSON。

建议新增接口

POST /api/models/from-drawio
  输入 draw.io XML
  输出 SystemModel JSON

POST /api/models/validate
  输入 SystemModel
  输出校验结果

POST /api/simulations/testmodel
  输入 SystemModel + 仿真配置
  输出仿真结果

POST /api/simulations/testmodel/from-drawio
  输入 draw.io XML
  一步完成解析、校验、仿真

第一版可以优先实现:

POST /api/simulations/testmodel/from-drawio

这样页面点击“运行仿真”时可以直接把 draw.io XML 发给后端。

第一版拓扑校验规则

第一版只支持固定 TestModelSystem 拓扑,因此校验可以严格一点:

  • 必须有 1 个 cylinder。
  • 必须有 1 个 tank。
  • 必须有 2 个 tee。
  • 必须有 2 个 orifice 或 valve。
  • 必须有 2 个 pipe。
  • 连接必须形成两条支路。
  • 每条支路必须是 orifice -> pipe。
  • 上游必须从 cylinder 到第一个 tee。
  • 下游必须汇入第二个 tee 再到 tank。

第一版不支持任意拓扑。

实现步骤和进度

A. draw.io 侧建模增强

  • 扩展组件库,增加 cylinder / tee / orifice / pipe / tank。
  • 给每个组件写入 modelType、role、默认参数。
  • 给组件补充端口语义。
  • 给连接 edge 补充 sourcePort / targetPort。
  • 前端增加“运行仿真”按钮。

B. SystemModel 数据层

  • 新增 app/models/system.py。
  • 定义 SystemModel。
  • 定义 ComponentInstance。
  • 定义端口级 Connection。
  • 定义 SimulationConfig。

C. draw.io 解析

  • 新增 app/services/drawio_parser.py。
  • 支持 mxGraphModel 输入。
  • 支持 mxfile 输入。
  • 解析 <object> 组件。
  • 解析 <mxCell edge="1"> 连接。
  • 把 draw.io 参数转换成正确的 Python 类型。
  • 输出标准 SystemModel。

D. 模型校验

  • 新增 app/services/model_validator.py。
  • 校验组件类型是否合法。
  • 校验必填参数是否存在。
  • 校验数值参数范围。
  • 校验端口名是否合法。
  • 校验连接 source / target 是否存在。
  • 校验是否符合固定 TestModel 拓扑。
  • 返回结构化错误列表。

E. PythonModels 适配层

  • 新增 app/services/pythonmodels_adapter.py。
  • 实现 SystemModel -> CylinderConfig。
  • 实现 SystemModel -> TankConfig。
  • 实现 SystemModel -> PipeConfig。
  • 实现 SystemModel -> OrificeConfig。
  • 实现 SystemModel -> TestModelConfig。
  • 实现 SimulationConfig -> SolveIVPConfig。
  • 如需要,给 OrificeConfig 增加 opening 字段。

F. 仿真运行

  • 新增 app/services/simulation_runner.py。
  • 调用 PythonModels.scripts.run_testmodel.run_testmodel()。
  • 整理返回的 series。
  • 返回 mytank.p / mytank.T / mycylinder.p / mycylinder.T。
  • 返回 branch.<name>.p / in / out。
  • 保留初始化诊断和求解诊断。

G. FastAPI 接口

  • 新增 POST /api/models/from-drawio。
  • 新增 POST /api/models/validate。
  • 新增 POST /api/simulations/testmodel。
  • 新增 POST /api/simulations/testmodel/from-drawio。

H. 前端结果展示

  • 点击“运行仿真”后导出当前 draw.io XML。
  • 调用 /api/simulations/testmodel/from-drawio。
  • 展示校验错误。
  • 展示仿真成功 / 失败状态。
  • 展示结果表格。
  • 展示压力、温度、流量曲线。
  • 支持下载结果 JSON / CSV。

MVP 验收标准

第一版完成后,应能做到:

  • 打开 FastAPI 页面。
  • 在 draw.io 画布中拖入气瓶、三通、阀门/孔板、管段、贮箱。
  • 按固定 TestModel 拓扑连接组件。
  • 配置主要参数。
  • 点击运行仿真。
  • 后端解析 draw.io XML。
  • 后端生成 SystemModel。
  • 后端映射到 TestModelConfig。
  • 后端调用 run_testmodel()。
  • 前端展示 mytank.p、mytank.T、mycylinder.p、mycylinder.T。
  • 前端展示两条支路的压力和流量。

后续阶段:通用拓扑仿真

固定 TestModel 跑通后,再考虑通用拓扑:

SystemModel
  -> instantiate components
  -> SimulationNetwork.add_component()
  -> SimulationNetwork.connect()
  -> 自动生成 rhs
  -> integrate_ode()

这一步需要新增:

  • 通用 connector / stream 求解。
  • 通用代数闭合。
  • 任意 Tee / Pipe / Orifice 网络流量求解。
  • 自动状态向量组装。
  • 自动 rhs 生成。

当前不建议立刻做这一步,因为 PythonModels/systems/testmodel_closure.py 仍然是为 TestModelSystem 专门写的闭合器,不是任意拓扑求解器。

当前优先级

下一步优先做:

draw.io XML
  -> SystemModel
  -> TestModelConfig
  -> run_testmodel()

暂时不要直接做:

draw.io XML
  -> PythonModels 任意网络

这样最贴合现有代码,成本最低,技术债也最可控。

S
Description
No description provided
Readme
169 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 72.4%
TypeScript 23.7%
C 1.8%
CSS 1.6%
Shell 0.2%
Other 0.2%