# 新版本仿真计算方法 新版本仿真计算采用 **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,实现边计算边推送。