# OpticsFEM × LASPCEM(Design.em)接口规范 | 项目 | 说明 | |------|------| | 版本 | v0.1(草案) | | 日期 | 2026-06-02 | | 适用范围 | `laspcem-case` 五个 HFSS/LASPCEM 算例 → `opticsfem-master` 三维矢量 FEM | | 参考材料 | `C++代码后端-有限元接口.xmind`、`C++有限元程序接口及对应页面设计.pdf`、`二维有限元思维导图.xmind`、`opticsfem-master/Interface/FEM_Interface.*`、`测试数据集/*/case*.json` | --- ## 1. 目标与原则 ### 1.1 目标 在**不改造 LASPCEM 前端与网格导出**的前提下,复用其求解输入: - **`Design.em`**:物理模型、材料、边界、激励、频率(对应原「前端输入 JSON」角色) - **`Design.em.mesh`**:二阶 Nedelec 四面体网格(对应原「网格 .dat / mesh.json」角色) 由 OpticsFEM 侧新增 **LASPCEM 适配层**,将上述文件转换为内部统一的 **OpticsFEM JSON + 网格文件**,再走现有或规划中的 3D 求解流程。 ### 1.2 设计原则(对齐既有思维导图 / PDF) | 原则 | 说明 | |------|------| | 单一 API 入口 | 延续 `OpticsFEM_API::OpticsFEM_All(OpticsFEMData)`,对外仍为一个 DLL 接口 | | JSON 为内核语言 | 适配层输出符合 `Phy/Material/Mesh/Solver` 已实现的 JSON 字段;`.em` 不直接进入组装器 | | 前后端解耦 | 页面 / 脚本只提交「案例目录 + 输入模式」;`.em` 解析在 C++ 适配模块完成 | | 案例可回归 | 以 `laspcem-case` 五例为验收基线,逐例对比场分布或 S 参数(允许数值容差) | --- ## 2. 现有 OpticsFEM 接口(基线) ### 2.1 调用约定 ```cpp struct OpticsFEMData { double test1; double test2; char* data; // UTF-8 JSON 字符串,单行或紧凑格式 }; class OpticsFEM_API { public: static int OpticsFEM_All(OpticsFEMData data); int OpticsFEM_Test(OpticsFEMData data); }; ``` ### 2.2 `FemType` 路由(二维,已实现) | FemType | 问题类型 | 主要 JSON 依赖 | |---------|----------|----------------| | 0 | 本征模式 `EigenMode` | `NbrMode`, `searchValue`, `lambda0`, … | | 1 | 本征频率 `EigenFreq` | `NbrMode`, `searchValue`, `EletricType`, … | | 2 | 散射 `Scatter` | `lambda`, `sbc`/`port`/`pml`/… | | 3 | 散射(按频率) | `freq`, `EletricType`, … | 读取链路(现状): 1. `json::parse(data.data)` → `FemType`, `MeshFile` 2. `Phy_WaveOpticsModel::Test_ReadData(str)` 3. `MaterialLib::Test_ReadData(str)` 4. `Mesh_2D::GetMesh(meshFile, str)` — **仅 2D `.dat`** ### 2.3 二维 JSON 核心字段(摘自 `测试数据集` / `Test_ReadData.cpp`) **公共** - `FemType`, `EletricType`, `NbrBoundary`, `BoundaryFlag[]` - `NbrDomain`, `matType[]`, `epsilonrR/I`, `murR/I`, `sigma`, `chiheR/I`, `chiehR/I`, `n`, `k` - `MeshFile`, `OutFile` **边界扩展(按 `js.contains` 可选)** - `sbc`, `ef`, `mag`, `scd`, `pbc`, `mpd`, `epd`, `bele`, `pml`, `port`, `beam` **求解** - 本征:`NbrMode`, `searchType`, `searchValue`, `solverType`, `maxIterNum`, `tol`, `tolType`, `lambda0` - 散射:`lambda` 或 `freq` ### 2.4 二维网格 `.dat`(`Mesh_2D::GetMesh`) 顺序读取关键字:`NbrVertex` → `Vertex` → `NbrEdge` → `Edge` → `NbrTri` → `Tri` → `EdgeOfTri` → `DomainOfTri` → `NbrEdges` → `CoonOfEdges` → `DomainOfEdges` → `normal` → `CopyOfEdges` → … > **与 LASPCEM 无直接兼容**;3D 需单独定义 `Mesh_3D` 读入格式(见 §5)。 --- ## 3. LASPCEM 输入文件规范 ### 3.1 文件对与路径约定 每个算例在求解完成后,在 **`out/<工程名>/1_Result/`** 下生成一对文件(推荐作为适配入口): | 文件 | 角色 | |------|------| | `Design.em` | 前端 + 求解配置(HOFEM 脚本) | | `Design.em.mesh` | 网格(由 `mesh_filename` 引用,须与 `.em` 同目录) | 五例标准路径见 **§7 案例对照表**。 > 说明:同目录下可能存在 `.../1_Result/<工程>/1_Result/` 与 `_cur` 副本;**默认使用顶层 `1_Result`**,自适应加密后以日志 `READING INPUT FILE... Design.em` 所指路径为准。 ### 3.2 `Design.em` 结构(章节) | 章节 | 关键变量 | 用途 | |------|----------|------| | Physic & formulation | `physics`, `basis_functions`, `variational_order`, `geometrical_order` | 确认波动方程 + Nedelec 阶次 | | Geometry & Mesh | `geometry_units`, `mesh_format`, `mesh_filename` | 单位与网格文件名 | | Frequency | `Freq_distribution_num`, `Freq_distribution_type`, `Freq_distribution_info` | 频点扫描;`type=4` 为单频点 | | Material | `num_materials`, `material_name_i`, `permittivity_i`, … | 材料库 | | Boundary | `num_boundary_conditions`, `bound_mark_i`, `bound_type_i` | 面标记与 BC | | Excitation | `num_*_excitations`, `general_*`, `lumped_*`, `exterior_*` | 波端口 / 集总 / 平面波 | | IIEE | `iiee_truncation_method`, … | 积分方程加速(FEM027 等) | ### 3.3 `Design.em.mesh` 结构(ASCII,二阶四面体) 根据 `FEM001` 样例解析,格式草案如下: ``` # 样例为 0 # 样例为 0 × nVertex 每行: x y z (科学计数, geometry_units 一致, 样例为 mm) × nTet 每行: v0 v1 v2 v3 e0 e1 e2 e3 e4 e5 0 0 0 └─4 顶点索引(1-based)─┘ └─6 边索引─┘ └占位┘ ``` - `variational_order = 2` 时,每单元 6 条边 DOF,与行内 6 个边号一致。 - 后续可能还有三角面 / 边界标记块(需在适配器首版用 LASPCEM 日志或 `Design_innerPartsIDs.dat` 交叉验证)。 **禁止**假定与 `project_*.dat` 行格式相同;必须经 **`EmMeshImporter`** 转为 OpticsFEM 3D 网格(§5.2)。 --- ## 4. 适配架构 ``` ┌─────────────┐ ┌──────────────────┐ ┌─────────────────────┐ │ 前端/脚本 │────▶│ OpticsFEM_All │────▶│ 3D FEM 内核 │ │ casePath │ │ + LASPCEM 分支 │ │ (EigenMode/Freq/ │ │ InputMode │ └────────┬─────────┘ │ Scatter 3D) │ └─────────────┘ │ └─────────────────────┘ ▼ ┌──────────────────┐ │ LaspcemAdapter │ │ · EmParser │ │ · EmMeshImporter │ │ · EmToJson │ └────────┬─────────┘ ▼ ┌──────────────────────────────┐ │ 内部: opticsfem_case.json │ │ mesh_3d.dat|json │ └──────────────────────────────┘ ``` 建议新增源文件: - `opticsfem-master/Interface/LaspcemAdapter.h|.cpp` - `opticsfem-master/mesh/Mesh_3D_Laspcem.cpp`(或扩展现有 `Mesh_3D_Interface.cpp`) --- ## 5. OpticsFEM 侧扩展接口 ### 5.1 对外 JSON 包装(调用 `.em` 时) 在 `OpticsFEMData.data` 中增加 **包装对象**(兼容原纯 JSON 调用): ```json { "InputMode": "laspcem", "CaseId": "FEM001_RecHorn", "EmPath": "Z:/.../laspcem-case/FEM001_RecHorn/out/FEM001-RectHorn/1_Result/Design.em", "WorkDir": "Z:/.../output/FEM001_run1", "OutFile": "./OutFile", "OverwriteConverted": false } ``` | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `InputMode` | string | 是 | 固定 `"laspcem"`;缺省或其它值走原 JSON 路径 | | `EmPath` | string | 是 | `Design.em` 绝对或相对路径 | | `WorkDir` | string | 否 | 转换产物目录;默认 `EmPath` 所在目录 | | `CaseId` | string | 否 | 五例 ID,用于加载内置映射缺省值 | | `OutFile` | string | 是 | 结果输出目录(与原 API 一致) | | `OverwriteConverted` | bool | 否 | 是否强制重新解析 `.em` | **返回值扩展**(`OpticsFEM_All`): | 返回值 | 含义 | |--------|------| | 0 | 失败 | | 1–3 | 原 2D FemType 成功 | | 10 | LASPCEM → 3D 本征频率成功(规划) | | 11 | LASPCEM → 3D 散射成功 | | 12 | 仅完成转换,未求解(调试) | ### 5.2 适配器输出:内部 `opticsfem_case.json` 适配器根据 `Design.em` 生成,字段 **超集** 于二维 JSON,并增加 3D 专用项: ```json { "FemType": 11, "Dimension": 3, "InputSource": "laspcem", "SourceEm": "Design.em", "EletricType": 2, "ElementOrder": 2, "GeometryUnits": "mm", "NbrDomain": 3, "matType": [0, 0, 0], "epsilonrR": [1.0, 1.0, 1.0], "epsilonrI": [0.0, 0.0, 0.0], "murR": [1.0, 1.0, 0.999991], "murI": [0.0, 0.0, 0.0], "sigma": [0.0, 1e30, 5.8e7], "NbrBoundary": 6, "BoundaryFlag": [0, 1, 0, 0, 2, 7], "freq": 8.43e9, "MeshFile": "mesh_3d_converted.dat", "OutFile": "./OutFile", "laspcem": { "bound_map": [{"mark":0,"type":"NULL"}, {"mark":1,"type":"PEC"}], "excitations": {"waveport_general": 1} } } ``` 说明: - `FemType: 11` 为本文建议的 **LASPCEM 3D 散射** 专用路由(实现前可用 `FemType: 2` + `Dimension: 3` 过渡)。 - `freq`:由 `Freq_distribution_info` 首项(MHz)× `1e6` 得到 Hz(五例均为单频 `Freq_distribution_type=4`)。 - `laspcem` 子对象存放 **无法直接映射** 的原始信息,供调试与后续扩展。 ### 5.3 三维网格输出 `mesh_3d_converted.dat`(建议) 对齐 `3d光学fem完整实现_f4164ab1.plan.md`,采用关键字文本或 JSON: ``` NbrVertex Vertex x y z ... NbrEdge Edge i j ... NbrTet Tet v1 v2 v3 v4 EdgeOfTet e1 e2 e3 e4 e5 e6 DomainOfTet NbrTri Tri ... DomainOfTri ... NormOfFace nx ny nz ``` 索引规则: - LASPCEM `.mesh` 若为 **1-based**,导入 OpticsFEM 时统一转为 **0-based**(与二维 `DomainOfTri` +1 逻辑相反,需在适配器文档与代码中固定一种约定并在五例测试中锁定)。 --- ## 6. 字段映射规范 ### 6.1 问题类型判定 | LASPCEM 特征 | OpticsFEM `FemType` | 备注 | |--------------|---------------------|------| | `physics = wave_equation` + 端口/平面波激励 | **11**(3D Scatter) | 五例均属此类 | | 无激励 + 腔体本征(未在五例出现) | 10(3D EigenFreq) | 预留 | | `iiee_truncation_method = true` | 仍 FEM 主求解,IIEE 仅加速 | 不单独改变 FemType | ### 6.2 频率 | Design.em | OpticsFEM | |-----------|-----------| | `Freq_distribution_type = {4}` 单频 | 单频散射 | | `Freq_distribution_info = { fMHz, fMHz, 1 }` | `freq = fMHz × 1e6`(Hz) | | 波长需求 | `lambda = c0 / freq`(`c0 = 299792458` m/s,与 `Solver_LdaDom::GetSolver2` 一致) | ### 6.3 材料 `material_name_i` → `matType` / 电磁参数 | LASPCEM | 条件 | `matType` | OpticsFEM 字段 | |---------|------|-----------|----------------| | Vacuum | `permittivity=1`, 无损耗 | 0 | `epsilonrR=1`, `sigma=0` | | PEC | `electric_conductivity ≥ 1e20` 或名称 PEC | 0 | `sigma=1e30`(或边界 PEC 处理) | | 各向同性介质 | `definition_type = Isotropic` | 0 | `epsilonrR`, `murR`, `sigma` 或 Tanδ 换算 | | 各向异性 | `definition_type = Anisotropic` | **2**(对角)或 **3**(全张量,扩展) | `epsilonrR` 取 3×3 对角;非对角项进 `laspcem.anisotropic` | **Tanδ → 损耗**:`epsilonrI = epsilonrR * tanδ`(各向异性时对角元分别处理)。 **域 ID**:由 `.mesh` 单元块或 `MESH/Design_innerPartsIDs.dat` 提供;无域表时,按材料名绑定默认域序号(适配器配置表)。 ### 6.4 边界 `bound_type` → `BoundaryFlag` | bound_type | bound_mark | BoundaryFlag | OpticsFEM 结构 | |------------|------------|--------------|----------------| | NULL | m | 不占用边界数组 | — | | PMC | m | **0** | 内置 PMC 列表 | | PEC | m | **1** | 内置 PEC 列表 | | ABC | m | **2** | `sbc`(吸收边界,类型待定义) | | FCBC | m | **7**(扩展) | 有限电导面;`laspcem.fcbc={sigma,mur}` | | GEN | m | **8**(扩展) | 广义波端口;映射 `port` 或 `laspcem.waveport` | | LPO | m | **9**(扩展) | 集总端口;`laspcem.lumped={R,X,integ}` | > 二维已有:`0=PMC, 1=PEC, 2=SBC, 3=ELE, 4=PBC, 8=MAG, 9=SCD`。三维 LASPCEM 扩展标志 **7–9** 需在 `Phy_WaveOpticsModel::Test_ReadData` 3D 分支中实现。 ### 6.5 激励 | LASPCEM 块 | 条件 | OpticsFEM | |------------|------|-----------| | `num_waveport_excitations` 第三项 > 0 | `general_*` + `bound_type=GEN` | `port` 或 `laspcem.waveport.general` | | `num_waveport` 第四项 > 0 | `lumped_*` + `LPO` | `laspcem.lumped`(电阻、积分线坐标) | | `num_exterior_excitations` 第一项 > 0 | `exterior_*` 平面波 | `sbc` 入射波 + `bound_type=ABC` 面 | | 多入射角 `exterior_type=Multiple` | FEM049 | `laspcem.exterior.scan[]`,首版可只取第一组角度 | ### 6.6 单元阶次 | Design.em | OpticsFEM | |-----------|-----------| | `variational_order = 2` | `ElementOrder = 2`,组装二阶 Nedelec(20 DOF/四面体,见规划文档) | | `geometrical_order = 2` | 几何二阶映射到 `Mesh_3D` 高阶几何节点(可选) | --- ## 7. 五案例对照表 统一入口目录:`laspcem-case//out//1_Result/` | CaseId | Project | Design.em / .mesh | 频率 (GHz) | 材料数 | 边界要点 | 激励要点 | 建议 OpticsFEM 路由 | |--------|---------|-------------------|------------|--------|----------|----------|---------------------| | **FEM001_RecHorn** | FEM001-RectHorn | `.../1_Result/Design.em` | 8.43 | 3(Vacuum, PEC, copper) | PEC/PMC/ABC/FCBC/**GEN** | 广义波端口 ×1 | FemType **11**, freq=8.43e9 | | **FEM009_Patch_MetalSurface** | FEM009-Patch_MetalSurface | 同上 | 2.80 | 4 | 含 **FCBC**(Groiss SR) | 广义波端口 ×1 | FemType **11** | | **FEM013_MountPatch** | FEM013-MountPatch | 同上 | 2.45 | 3(含 FR4) | 含 **LPO** | 集总波端口 ×1 | FemType **11** + `laspcem.lumped` | | **FEM027_HalfAmygdala_FEIE** | FEM027_HalfAmygdala_FEIE | 同上 | 0.30 | 2 | ABC + **IIEE/MLFMA** | **平面波** Single | FemType **11** + `sbc` 平面波 | | **FEM049_Anisotropic** | FEM049 | 同上 | 3.00 | 5(3 各向异性块) | ABC | **多角度平面波** Multiple | FemType **11** + 各向异性材料 | **完整路径示例(FEM001)**: ``` Z:\home\项目文件\西电-合作\laspcem-case\FEM001_RecHorn\out\FEM001-RectHorn\1_Result\Design.em Z:\home\项目文件\西电-合作\laspcem-case\FEM001_RecHorn\out\FEM001-RectHorn\1_Result\Design.em.mesh ``` **页面设计(PDF)建议暴露字段**: | 页面控件 | 绑定 | |----------|------| | 算例选择下拉 | `CaseId` 五选一 → 自动填充 `EmPath` | | 频率只读 | 解析 `Freq_distribution_info` | | 边界列表 | 解析 `num_boundary_conditions` | | 材料表 | 解析 `num_materials` | | 输出目录 | `OutFile` | | 运行 | 调用 `OpticsFEM_All`,`InputMode=laspcem` | --- ## 8. C++ 实现要点(与思维导图节点对应) ### 8.1 接口层 `FEM_Interface.cpp` ```cpp int OpticsFEM_API::OpticsFEM_All(OpticsFEMData data) { json js = json::parse(data.data); if (js.value("InputMode", "") == "laspcem") { LaspcemAdapter adapter; std::string jsonPath, meshPath; adapter.Convert(js.at("EmPath"), js.value("WorkDir", ""), jsonPath, meshPath); // 将 jsonPath 内容读回 data 或直接传内部结构 return RunFromInternalJson(jsonPath, meshPath); } // 原有 FemType 0–3 逻辑 } ``` ### 8.2 `LaspcemAdapter::Convert` 步骤 1. 解析 `Design.em`(键值 + `{ ... }` 数组块,`#`/`--` 注释行忽略) 2. 校验 `mesh_filename` 存在且为 `Design.em.mesh` 3. `EmMeshImporter::Load(mesh)` → `Mesh_3D` 4. `EmToJson::Build(em, meshMeta)` → `opticsfem_case.json` 5. `Mesh_3D::Export(mesh_3d_converted.dat)` 6. 写 manifest:`case.converted.json`(记录源路径、哈希、转换时间) ### 8.3 与二维思维导图差异 | 二维 | LASPCEM 3D | |------|------------| | 三角网格 + 边 DOF 混合 | 纯四面体 Nedelec | | `Mesh_2D::GetMesh` | `Mesh_3D::GetMeshFromLaspcem`(新增) | | TM/TE `EletricType` | 固定 `EletricType=2`(全矢量) | | 无 IIEE | `iiee_*` 记入 `laspcem`,首版可忽略 | --- ## 9. 错误码与日志 | 代码 | 场景 | |------|------| | E001 | `EmPath` 不存在 | | E002 | `Design.em.mesh` 缺失 | | E003 | `.em` 键缺失(如无 `Freq_distribution_info`) | | E004 | 网格段行数与声明不符 | | E005 | 不支持的 `bound_type` | | E006 | 各向异性材料未实现 | | E007 | `FemType` 3D 求解器未就绪 | 日志:转换阶段写 `WorkDir/adapter.log`;求解阶段沿用 `_SolverPip_0.log` 风格。 --- ## 10. 验收与测试计划 | 步骤 | 内容 | |------|------| | T1 | 五例 `Convert()` 成功,生成 `opticsfem_case.json` + `mesh_3d_converted.dat` | | T2 | 网格守恒:顶点数、四面体数与 LASPCEM 一致 | | T3 | 材料/边界条数与 `Design.em` 一致 | | T4 | FEM001 远场 / S 参数与 LASPCEM `export/*.csv` 对比(容差待定) | | T5 | FEM049 各向异性 ε 张量对角元与 `.em` 一致 | --- ## 11. 版本路线 | 版本 | 内容 | |------|------| | v0.1 | 本文档 + 五例路径与映射表 | | v0.2 | `EmParser` / `EmMeshImporter` 原型,FEM001 网格贯通 | | v0.3 | 边界 GEN/LPO/平面波 + FEM013/FEM027 | | v0.4 | 各向异性 FEM049 + IIEE 忽略说明 | | v1.0 | `OpticsFEM_All` 正式返回码 11,页面联调 | --- ## 12. 附录 A:`Design.em` 键名索引(解析器必支持) ``` physics, basis_functions, variational_unknown, geometrical_order, variational_order, geometry_units, mesh_format, mesh_filename, Freq_distribution_num, Freq_distribution_type, Freq_distribution_info, num_materials, material_name_*, definition_type_*, permittivity_*, permeability_*, electric_loss_type_*, dielectric_loss_tangent_*, electric_conductivity_*, num_boundary_conditions, bound_mark_*, bound_type_*, bound_conduc_*, bound_mur_*, num_interior_excitations, num_exterior_excitations, num_waveport_excitations, general_*, lumped_*, exterior_*, iiee_truncation_method, iiee_truncation_aceleration, iiee_truncation_error ``` ## 13. 附录 B:与 `测试数据集` 命名对照 | 测试数据集 | LASPCEM 五例 | |------------|--------------| | `case1.json` | `Design.em` | | `project_3299_15.dat` | `Design.em.mesh` | | `mesh.json`(辅助) | `MESH/Mesh_Statistics.dat`、`tetmaps.dat`(可选校验) | --- *文档结束。实现时以 `opticsfem-master` 源码与五例实文件为准;若 LASPCEM 升级导致 `.mesh` 增段,须同步修订 §3.3。*