# 关于不同形状设备尺寸信息获取建议 当前 `SimBuilder` 中的 `injectDeviceSize` 方法仅处理了简单的 `diameter` (或 `outer_diameter`) 和 `height` 属性,主要适用于 `CylindricalTank`(圆柱槽)和 `AnnularTank`(环形槽)。根据文档《关于不同形状设备尺寸信息.md》,系统中存在多种形状复杂的设备,其尺寸信息结构各异。 为了确保仿真模型能够准确获取各类设备的几何参数,建议对 `injectDeviceSize` 方法进行如下扩展: ## 1. 设备类型与尺寸结构分析 | 设备类型 (type) | 中文名称 | JSON 结构示例 | 需提取的关键属性 | 备注 | | :--- | :--- | :--- | :--- | :--- | | **FlatTank** | 扁平槽 | `{"width": 40, "height": 15, "length": 100}` | `width`, `height`, `length` | 平板几何,无直径概念 | | **CylindricalTank** | 圆柱槽 | `{"height": 120, "diameter": 200}` | `diameter`, `height` | 已支持 | | **AnnularTank** | 环形槽 | `{"height": 150, "outer_diameter": 100}` | `outer_diameter`, `height`, `inner_diameter` (如有) | 环形,通常关注外径 | | **TubeBundleTank** | 管束槽 | `{"height": 200, "outer_diameter": 120}` | `outer_diameter`, `height` | 结构类似圆柱,但内部有管束 | | **ExtractionColumn** | 萃取柱 | `{"tray_section": {"height": 800, "diameter": 100}, "lower_expanded": {...}, ...}` | 复合结构。建议提取**主体段** (tray_section) 的尺寸,或展平所有段的尺寸。 | 结构复杂,需分段解析 | | **FluidizedBed** | 流化床 | `{"expanded_section": {...}, "reaction_section": {...}, ...}` | 复合结构。建议提取**反应段** (reaction_section) 的尺寸。 | 结构复杂,需分段解析 | | **ACFTank** | 锥底环形槽 | `{"frustum_bottom": {...}, "annular_cylinder": {...}}` | 复合结构。建议提取**圆柱段** (annular_cylinder) 的尺寸。 | 结构复杂,需分段解析 | ## 2. 代码修改建议 建议将 `injectDeviceSize` 重构为基于 `deviceType` 的分发逻辑,针对不同设备类型采用不同的解析策略。 ```java private void injectDeviceSize(Device device, Map staticProps) { try { String sizeJson = device.getSize(); if (sizeJson == null || sizeJson.isBlank()) return; JsonNode sizeNode = objectMapper.readTree(sizeJson); String type = device.getType(); // 假设 Device 有 getType() 方法,或从外部传入 if (type == null) { // Fallback: 尝试通用解析 (现有逻辑) parseCommonSize(sizeNode, staticProps); return; } switch (type) { case "FlatTank": if (sizeNode.has("width")) staticProps.put("width", sizeNode.get("width").asDouble()); if (sizeNode.has("length")) staticProps.put("length", sizeNode.get("length").asDouble()); if (sizeNode.has("height")) staticProps.put("height", sizeNode.get("height").asDouble()); break; case "CylindricalTank": case "AnnularTank": case "TubeBundleTank": parseCommonSize(sizeNode, staticProps); break; case "ExtractionColumn": // 优先提取 tray_section (塔身) if (sizeNode.has("tray_section")) { parseCommonSize(sizeNode.get("tray_section"), staticProps); } // 可选:将其他段的尺寸作为特殊属性注入,例如 lower_expanded_height break; case "FluidizedBed": // 优先提取 reaction_section (反应段) if (sizeNode.has("reaction_section")) { parseCommonSize(sizeNode.get("reaction_section"), staticProps); } break; case "ACFTank": // 优先提取 annular_cylinder (圆柱段) if (sizeNode.has("annular_cylinder")) { parseCommonSize(sizeNode.get("annular_cylinder"), staticProps); } break; default: parseCommonSize(sizeNode, staticProps); } } catch (Exception e) { System.err.println("解析Device.size失败:" + e.getMessage()); } } private void parseCommonSize(JsonNode node, Map staticProps) { if (node.has("outer_diameter")) { staticProps.put("diameter", node.get("outer_diameter").asDouble()); } else if (node.has("diameter")) { staticProps.put("diameter", node.get("diameter").asDouble()); } if (node.has("height")) { staticProps.put("height", node.get("height").asDouble()); } } ``` ## 3. 注意事项 1. **复合结构处理**:对于 `ExtractionColumn` 等分段设备,目前的建议是提取“主体段”的尺寸作为该设备的代表尺寸(diameter/height)。如果仿真计算需要每一段的精确尺寸,建议将 `staticProps` 的结构进行展平(例如 `tray_section_diameter`, `lower_expanded_height`)或嵌套存储(需修改 SimUnit 和 SimResultConverter 以支持嵌套 Map)。 2. **单位统一**:确保 JSON 中的数值单位与仿真模型要求的单位一致(通常为 cm 或 mm)。 3. **鲁棒性**:解析时需判空,避免因 JSON 结构缺失导致异常。