85 lines
5.5 KiB
Markdown
85 lines
5.5 KiB
Markdown
# 新版本仿真计算方法
|
||
|
||
新版本仿真计算采用 **SimController** 统一入口,通过 **SimDataFacade** 加载数据,**SimBuilder** 构建模型,**SimService** 执行核心计算,最终由 **SimResultConverter** 转换结果。相较于旧版本(`ProjectController` + `ProjectServiceImpl` + `DeviceInferService`),新架构职责更清晰,扩展性更强。
|
||
|
||
## 1. 核心流程
|
||
|
||
1. **入口**: `SimController.run(req)`
|
||
* 接收 `projectId`, `scenarioId`, `steps` 参数。
|
||
2. **数据加载**: `SimDataFacade.loadSimulationData`
|
||
* 加载 `Project` (拓扑), `Device` (设备列表), `Events` (场景事件)。
|
||
3. **模型构建**: `SimBuilder.buildUnits` & `buildEvents` & `buildInfluenceNodes`
|
||
* **Units**: 将设备和物料转换为 `SimUnit`,注入静态属性(包括从 `Device.size` 解析的几何尺寸,从 `Material` 表加载的物理化学属性)。
|
||
* **Events**: 将 `Event` 数据转换为 `SimEvent` 时间序列。
|
||
* **Influence**: 解析拓扑中的 `influence` 节点,构建 `SimInfluenceNode` 依赖关系图。
|
||
4. **核心计算**: `SimService.runSimulation`
|
||
* **初始化**: `t=0`,写入所有 `SimUnit` 的静态属性。
|
||
* **时间步推进**: `t=1` to `steps`
|
||
1. **Apply Events (Input)**: 应用普通设定值事件。
|
||
2. **Apply Influence**: 基于拓扑关系计算派生属性(如 `bias + coeff * source`)。
|
||
3. **Apply Events (Override)**: 应用强制覆盖事件(如故障注入)。
|
||
4. **Snapshot**: 保存当前步所有属性状态。
|
||
5. **结果转换**: `SimResultConverter.toFrames`
|
||
* 将 `SimContext` 中的时间轴数据转换为前端所需的 Frame 结构。
|
||
* **补全静态属性**: 确保每一帧都包含设备的不变属性(如 `diameter`, `height`)。
|
||
* **封装元数据**: 添加 `projectId`, `scenarioId` 等信息,遵循统一响应格式。
|
||
|
||
## 2. 与旧版本对比
|
||
|
||
| 特性 | 旧版本 (`ProjectController` / `ProjectServiceImpl`) | 新版本 (`SimController` / `SimService`) |
|
||
| :--- | :--- | :--- |
|
||
| **架构模式** | 事务脚本模式,逻辑集中在 ServiceImpl | 领域模型模式,组件职责分离 (Builder, Engine, Facade) |
|
||
| **计算逻辑** | 混合了 JSON 解析、数据查询和硬编码公式 | 基于 `SimUnit`, `SimEvent`, `SimInfluenceNode` 的抽象模型计算 |
|
||
| **扩展性** | 难以扩展新设备类型或计算规则 | 易于扩展(只需修改 Builder 或 Engine 策略) |
|
||
| **数据完整性** | 容易遗漏属性(如 `size` 解析分散) | `SimBuilder` 集中处理属性注入,`ResultConverter` 保证输出完整 |
|
||
| **推理集成** | 强依赖 `DeviceInferService`,解析前端传入的 JSON | **按需集成**,直接基于仿真计算生成的 `SimContext` 数据进行推理 |
|
||
|
||
## 3. 关键组件详解
|
||
|
||
### 3.1 SimBuilder (模型构建)
|
||
负责将异构的原始数据(JSON 拓扑、数据库实体)标准化为仿真计算单元。
|
||
* **多态尺寸解析**: `injectDeviceSize` 支持 `FlatTank`, `ExtractionColumn` 等多种设备几何解析。
|
||
* **全量物料属性**: `buildMaterialStaticFromDb` 加载所有物料理化性质。
|
||
|
||
### 3.2 SimService (计算引擎)
|
||
纯内存计算引擎,支持:
|
||
* **静态基线**: `t=0` 状态。
|
||
* **动态演变**: `Event` 驱动的状态变化。
|
||
* **级联影响**: 拓扑网络中的属性传播(支持延迟 `delay` 和系数 `coeff`)。
|
||
|
||
### 3.3 SimResultConverter (结果适配)
|
||
* **Frame 生成**: 将离散的 `SimContext` 转换为连续的动画帧。
|
||
* **数据补全**: 自动将 `staticProperties` 注入每一帧,解决前端渲染缺失静态参数的问题。
|
||
|
||
## 4. 推理调用与结果持久化优化 (New)
|
||
|
||
新版本针对推理接口调用和结果入表逻辑进行了深度优化,消除了对前端 JSON 格式的强依赖。
|
||
|
||
### 4.1 旧版本逻辑回顾
|
||
* **流程**: `ProjectController` -> `ProjectServiceImpl` -> `DeviceDataParser` -> `DeviceInferService` -> `Python API` -> `ScenarioResult` 表。
|
||
* **痛点**: 依赖前端传入的特定格式 JSON (`params`);`DeviceDataParser` 解析逻辑复杂且脆弱;推理逻辑与 Service 强耦合。
|
||
|
||
### 4.2 新版本优化方案
|
||
1. **直接基于 SimContext 推理**:
|
||
* 仿真计算完成后,直接从 `SimContext` 提取每一帧的属性状态,不再需要 `DeviceDataParser` 解析 JSON 字符串。
|
||
* `SimService` 提供 `getDeviceStateList(deviceId)` 方法,快速导出时序数据。
|
||
2. **组件化推理服务**:
|
||
* 引入 `SimInferService`,负责封装 `SimContext` 为 `InferRequest` 格式。
|
||
* 异步调用 Python 接口,提高系统响应速度。
|
||
3. **批量持久化**:
|
||
* 推理结果 (`Keff`, `features`) 统一封装为 `ScenarioResult` 列表,使用 `MyBatis-Plus` 的 `saveBatch` 异步写入,避免频繁数据库操作。
|
||
|
||
### 4.3 核心伪代码示例
|
||
```java
|
||
// 在 SimController 中调用
|
||
SimContext ctx = simService.runSimulation(units, events, nodes, steps);
|
||
// 异步执行推理并入表
|
||
simInferService.asyncInferAndSave(projectId, scenarioId, ctx, units);
|
||
```
|
||
|
||
## 5. 后续演进建议
|
||
|
||
1. **集成 Python 推理**: 目前 `SimService` 主要执行线性影响计算。如需复杂机理模型(如 Keff 计算),可在 `SimService` 中通过 `DeviceInferService` 调用 Python API。
|
||
2. **性能优化**: 对于长时序、大规模拓扑,`SimContext` 可优化为基于数组的存储,而非 Map。
|
||
3. **实时流式输出**: 支持 WebSocket 或 SSE,实现边计算边推送。
|