XIAN-FEM-2026June/opticsfem-master/OpticsFEM_完整使用说明与代码介绍.md

792 lines
29 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OpticsFEM 完整使用说明与代码介绍
| 项目 | 说明 |
|------|------|
| 文档版本 | v1.0 |
| 编制日期 | 2026-06-03 |
| 适用代码 | `opticsfem-master/` |
| 适用平台 | Windows x64Visual Studio 2022/2026MSVC |
| 关联文档 | 上级目录 `OpticsFEM_开发与使用手册.md`、`OpticsFEM_LASPCEM_接口规范.md` |
---
## 目录
1. [程序概述](#1-程序概述)
2. [目录与文件总览](#2-目录与文件总览)
3. [各模块代码详解](#3-各模块代码详解)
4. [软件架构与执行流程](#4-软件架构与执行流程)
5. [完整使用说明](#5-完整使用说明)
6. [输入输出文件规范](#6-输入输出文件规范)
7. [对外 API 与集成方式](#7-对外-api-与集成方式)
8. [测试算例与数据集](#8-测试算例与数据集)
9. [代码阅读路径](#9-代码阅读路径)
10. [常见问题排查](#10-常见问题排查)
---
## 1. 程序概述
### 1.1 程序定位
**OpticsFEM** 是一套基于 C++ 实现的**二维矢量有限元FEM光学电磁仿真内核**。程序采用 **Nedelec 边元** 离散麦克斯韦方程,通过 JSON 配置物理模型、材料与边界条件,通过 `.dat` 文本文件读入三角网格,计算结果以文本文件输出。
### 1.2 支持的问题类型
| FemType | 问题类型 | 驱动类 | 求解器 | 后处理 |
|---------|----------|--------|--------|--------|
| 0 | 本征模式EigenMode | `OpticsFEM_2D_EigenMode` | `Solver_EigenMode` | `Post_2D_EigenMode` |
| 1 | 本征频率EigenFreq | `OpticsFEM_2D_EigenFreq` | `Solver_EigenFreq` | `Post_2D_EigenFreq` |
| 2 | 散射(按波长 λ) | `OpticsFEM_2D_Scatter` | `Solver_LdaDom` | `Post_2D_Scatter` |
| 3 | 散射(按频率 f | `OpticsFEM_2D_Scatter` | `Solver_LdaDom` | `Post_2D_Scatter` |
### 1.3 设计原则
- **单一 API 入口**:外部只需调用 `OpticsFEM_All()`,无需感知内部分支。
- **JSON 为配置语言**:物理、材料、边界、求解参数均通过 JSON 传递。
- **前后端解耦**`Test_Main.cpp` 可替换为 GUI、脚本或 DLL 宿主,接口不变。
- **模块化分层**:网格 → 物理/材料 → 组装 → 求解 → 后处理,各层独立。
### 1.4 第三方依赖(源码内嵌)
| 依赖 | 路径 | 用途 |
|------|------|------|
| Eigen | `Eigen/` | 稠密/稀疏矩阵运算337 个头文件header-only |
| nlohmann/json | `nlohmann/` | JSON 解析 |
| muparserX 派生库 | `parser/` | BELE、SBC、端口等边界表达式求值 |
### 1.5 运行时外部依赖(不在源码树中)
| 路径 | 用途 |
|------|------|
| `complex/complexsolver.exe` | 复数线性方程组求解(散射问题) |
| `real/realsolver.exe` | 实数线性方程组求解 |
| `real_solver/real` | 实数广义特征值求解(本征问题) |
| `complex_solver/complex` | 复数广义特征值求解 |
外部求解器通过**临时 `.dat` 文件**与主程序交换 CSR 格式矩阵,由 `system()` 启动。
---
## 2. 目录与文件总览
```
opticsfem-master/
├── CMakeLists.txt # CMake 构建配置
├── CMakeSettings.json # Visual Studio CMake 设置
├── Interface/ # 对外 API 层2 文件)
├── test/ # 入口与 JSON 解析4 文件)
├── phy/ # 物理模型与边界条件3 文件)
├── material/ # 材料库3 文件)
├── mesh/ # 网格读写与拓扑查询4 文件)
├── kernel/ # FEM 方程与边界组装10 文件)
├── solver/ # 数值求解器接口8 文件)
├── post/ # 后处理与结果输出6 文件)
├── function/ # Nedelec 基函数与高斯积分14 文件)
├── common/ # 公共常量与工具3 文件)
├── parser/ # 数学表达式解析器(约 89 文件)
├── nlohmann/ # JSON 库2 文件)
├── Eigen/ # 线性代数库337 文件)
└── build/ # CMake 构建产物(可忽略)
```
**源码统计(不含 build/**
| 类别 | 数量 | 说明 |
|------|------|------|
| 业务源文件 `.cpp` | 约 35 个 | 组装、求解、后处理等核心逻辑 |
| 业务头文件 `.h` | 约 20 个 | 类声明与接口 |
| parser 模块 | 约 89 个 | muparserX 表达式引擎 |
| Eigen 第三方 | 337 个 | 仅头文件,不参与业务修改 |
| **合计参与编译** | 约 70+ `.cpp` | 链接为单一 `OpticsFEM.exe` |
---
## 3. 各模块代码详解
### 3.1 Interface/ — 对外 API
| 文件 | 说明 |
|------|------|
| `FEM_Interface.h` | 定义 `OpticsFEMData` 结构体与 `OpticsFEM_API` 类;预留 `extern "C"` DLL 导出注释 |
| `FEM_Interface.cpp` | **核心调度器**:解析 JSON 中 `FemType`,创建对应 FEM 驱动/求解器/后处理对象,执行 Assemble → Run → Post 全流程 |
**关键函数:**
```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); // 连通性测试
};
```
**返回值:** 0 = FemType 无法识别1 = 本征模式完成2 = 本征频率完成3 = 散射完成。
---
### 3.2 test/ — 入口与数据解析
| 文件 | 说明 |
|------|------|
| `Test_Main.cpp` | 进程 `main()` 入口:从 `bele.json` 读取整行 JSON封装为 `OpticsFEMData`,调用 `OpticsFEM_All()` |
| `Test_ReadData.cpp` | 实现 `Phy_WaveOpticsModel::Test_ReadData()``MaterialLib::Test_ReadData()`,将 JSON 字段映射到内存对象 |
| `Test_OutputData.cpp` | 调试用途:将组装后的稀疏矩阵 A/B/P 输出到文本文件 |
| `interfaceClass.h` | 遗留的 `FemInput` 结构体,记录预期配置字段(当前 JSON 路径未直接使用) |
**注意:** `Test_Main.cpp` 中声明的 `Phy_WaveOpticsModel`、`MaterialLib` 等对象在 `main()` 内未被直接使用;实际实例化在 `FEM_Interface.cpp` 中完成。注释块(第 3958 行)保留了手动分步调用的旧版写法。
---
### 3.3 phy/ — 物理模型与边界条件
| 文件 | 说明 |
|------|------|
| `Phy_Base.h` | `Phy_WaveOpticsModel` 类声明:存储 PMC/PEC/PBC/PML/SBC/ELE/MAG/SCD/MPD/EPD/BELE/端口/高斯光束等边界数据及访问接口 |
| `Phy_Base.cpp` | 构造函数与各边界查询 getter 实现 |
| `Phy_Interface.cpp` | `GetPhy()` 占位桩 |
**BoundaryFlag 编码(`Test_ReadData.cpp`**
| 值 | 边界类型 |
|----|----------|
| 0 | PMC理想磁导体 |
| 1 | PEC理想电导体 |
| 2 | SBC散射边界条件 |
| 3 | ELE电场 Dirichlet 边界) |
| 4 | PBC周期边界成对计数 |
| 8 | MAG磁场边界 |
| 9 | SCD面电流密度 |
**支持的 JSON 边界扩展块:** `sbc`、`ef`、`mag`、`scd`、`pbc`、`mpd`、`epd`、`bele`、`pml`、`port`、`beam`(均为可选,按 `js.contains()` 判定是否解析)。
---
### 3.4 material/ — 材料库
| 文件 | 说明 |
|------|------|
| `Material_Base.h` | `Material`(单材料张量属性)与 `MaterialLib`(按物理域索引的材料库) |
| `Material_Base.cpp` | 材料属性 setter/getter |
| `Material_Interface.cpp` | `MaterialLib::SetMat()`、`SetNumberMat()`,材料类型分发(各向同性 ε/μ 或 n,k 折射率) |
**材料 JSON 字段:**
| 字段 | 类型 | 说明 |
|------|------|------|
| `NbrDomain` | int | 物理域数量 |
| `matType` | int[] | 0 = ε/μ 张量1 = n,k 折射率 |
| `epsilonrR/I` | double[] | 相对介电常数实部/虚部 |
| `murR/I` | double[] | 相对磁导率 |
| `sigma` | double[] | 电导率 |
| `chiheR/I`, `chiehR/I` | double[] | 磁电耦合张量 |
| `n`, `k` | double[] | 折射率matType=1 时,ε = (n+ik)²) |
---
### 3.5 mesh/ — 网格
| 文件 | 说明 |
|------|------|
| `Mesh_Base.h` | `Mesh_2D`(三角形、边、边界域)与 `Mesh_3D`(四面体、棱柱,部分实现)数据结构及查询 API |
| `Mesh_Base.cpp` | 顶点、边、单元、域编号等基本访问器 |
| `Mesh_Interface.cpp` | `Mesh_2D::GetMesh()`:顺序解析 `.dat` 网格文件 |
| `Mesh_Find.cpp` | 域/PBC 索引查找:边/节点所属域、PBC 源/目标映射 |
**Mesh_3D** 已在头文件中声明,但 `OpticsFEM_All()` 当前未接入 3D 求解分支。
---
### 3.6 kernel/ — FEM 组装
| 文件 | 说明 |
|------|------|
| `Assemble_Base.h` | 声明全部 `OpticsFEM_*` 驱动类2D 本征模式/频率/散射3D 本征频率/散射) |
| `Assemble_Base.cpp` | 依赖注入(`GetMaterial`、`GetMesh` 等),各驱动的 `Run()`/`Post()` 实现 |
| `Assemble_kernel.cpp` | 各问题类型顶层 `Assemble()`:实/复矩阵选择、DOF 规模、边界分发 |
| `Assemble_EigenMode_Equation.cpp` | 2D 本征模式体积积分curl-curl + 质量矩阵) |
| `Assemble_EigenMode_Boundary.cpp` | 本征模式 PEC/PBC 约束 |
| `Assemble_EigenFreq_Equation.cpp` | 2D/3D 本征频率体积积分 |
| `Assemble_EigenFreq_Boundary.cpp` | 本征频率 PEC/PBC |
| `Assemble_Scatter_Equation.cpp` | 散射问题驱动麦克斯韦弱形式体积积分 |
| `Assemble_Scatter_2D_Boundary.cpp` | 2D 边界项SBC、BELE、PML、PEC/ELE、PBC、端口、MPD/EPD、MAG、SCD |
| `Assemble_Scatter_3D_Boundary.cpp` | 3D 边界组装SBC、PEC/ELE部分实现 |
**Assemble 阶段输出:** 稀疏矩阵 **A**、右端向量 **b**、预处理矩阵 **P**(实数或复数,由 PML/SBC/复材料等条件自动判定)。
---
### 3.7 solver/ — 数值求解
| 文件 | 说明 |
|------|------|
| `Solver_Base.h` | `Solver_EigenMode`、`Solver_EigenFreq`、`Solver_LdaDom` 类及稀疏矩阵参数结构 |
| `Solver_Base.cpp` | 简单 getter`GetNbrMode`、`GetLda0`、`GetElectricType` 等) |
| `Solver_Interface.cpp` | JSON 求解参数解析,`SetParam`/`Run` 实现,调用特征值或线性求解器 |
| `eigen_solver.h` | 广义特征值求解 C API 声明(实/复 CSR 格式) |
| `eigen_solver.cpp` | 将矩阵写入 `./real_solver/``./complex_solver/` 临时文件,启动外部特征值求解器,读回结果 |
| `interface.h` | `solveRealLinearEqu`、`solveComplexLinearEqu` 声明 |
| `interface.cpp` | 通过临时 `.dat` 文件调用 `complex/complexsolver.exe` 等外部线性求解器 |
| `framework.h` | Windows DLL 风格求解器接口头 |
**求解器分层:**
| 层级 | 模块 | 适用问题 | 运行时依赖 |
|------|------|----------|------------|
| 特征值 | `eigen_solver.cpp` | FemType 0, 1 | `real_solver/real`, `complex_solver/complex` |
| 线性(实) | `interface.cpp` | 实散射 | `real/realsolver.exe` |
| 线性(复) | `interface.cpp` | 复散射 | `complex/complexsolver.exe` |
当前工程通过宏 `EIGENSOLVER_STATIC``eigen_solver.cpp` 静态编入可执行文件,**不再依赖** `lib/eigensolver.lib`
---
### 3.8 post/ — 后处理
| 文件 | 说明 |
|------|------|
| `Post_Base.h` | `Post_2D_EigenMode`、`Post_2D_EigenFreq`、`Post_2D_Scatter` 及 3D 后处理类声明 |
| `Post_Base.cpp` | `GetMesh`/`GetSolver`/`GetResult`/`GetPhy` 接线 |
| `Post_CalEletric.cpp` | 利用 Nedelec 基函数将边/顶点 DOF 重构为顶点 Ex/Ey/Ez |
| `Post_GetEb.cpp` | 在网格顶点处用 muparser 求值 BELE 解析背景场 |
| `Post_Output.cpp` | 写入 `neff`/`freq`/`Ex`/`Ey`/`Ez`/`normE` 文本文件 |
| `Post_Power.cpp` | `GetPower()` 占位(本征模式返回 0 |
---
### 3.9 function/ — 基函数与高斯积分
| 文件 | 说明 |
|------|------|
| `BF.h` / `BF.cpp` | `BF` 分发类:按单元类型选择并求值基函数 |
| `BF_Line.cpp` | 一维 Lagrange 基函数及梯度/curl |
| `BF_Triangle.cpp` | 二维三角形 Lagrange 与 Nedelec1 阶)基函数及 curl |
| `BF_Quadrangle.cpp` | 二维四边形 Lagrange/Nedelec 基函数 |
| `BF_Tetrahedron.cpp` | 三维四面体 Nedelec 基函数及 curl |
| `BF_Prism.cpp` | 三维棱柱 Nedelec 基函数及 curl |
| `Gauss.h` / `Gauss.cpp` | `Gauss` 类:按单元类型与阶次选择积分规则 |
| `Gauss_Line.h` | 线段高斯点/权重 |
| `Gauss_Triangle.h` | 三角形高斯点/权重 |
| `Gauss_Quadrangle.h` | 四边形高斯点/权重 |
| `Gauss_Tetrahedron.h` | 四面体高斯点/权重 |
| `Gauss_Prism.h` | 棱柱高斯点/权重 |
---
### 3.10 common/ — 公共定义
| 文件 | 说明 |
|------|------|
| `define.h` | 几何/网格/基函数/材料/物理常量(`c_const`、`Pi`、单元类型、边界标志等) |
| `util.h` / `util.cpp` | 数值 clamp、快速排序、唯一索引等网格/组装辅助工具 |
---
### 3.11 parser/ — 数学表达式解析器muparserX
共约 **89 个** `.cpp`/`.h` 文件,为 vendored **muparserX** 分支,用于求值 BELE、SBC、端口等边界上的字符串表达式`"sin(2*pi*x)"`)。
| 分组 | 代表文件 | 作用 |
|------|----------|------|
| 核心引擎 | `mpParser.*`, `mpParserBase.*`, `mpRPN.*`, `mpTokenReader.*`, `mpScriptTokens.*` | 表达式 → RPN → 求值 |
| 值系统 | `mpValue.*`, `mpValueCache.*`, `mpVariable.*`, `mpValReader.*` | 类型化值存储、变量、缓存 |
| 函数库 | `mpFuncCommon/Cmplx/NonCmplx/Matrix/Str.*` | 内置数学/字符串/矩阵函数 |
| 运算符 | `mpOprtBinCommon/Assign/Shortcut/Cmplx/NonCmplx/Matrix/Index/PostfixCommon.*` | 二元/一元/后缀运算符 |
| 注册包 | `mpPackageCommon/Cmplx/NonCmplx/Matrix/Str/Unit.*` | 函数与运算符注册 |
| 插件接口 | `mpICallback.*`, `mpIOprt.*`, `mpIPackage.*`, `mpIValue.*`, `mpIToken.*`, `mpIValReader.*` | 扩展接口 |
| 辅助 | `mpError.*`, `mpIfThenElse.*`, `mpMatrix.*`, `mpTest.*`, `mpDefines.h`, `mpCompat.h`, `mpFwdDecl.h`, `mpTypes.h`, `mpStack.h`, `suSortPred.h`, `suStringTokens.h`, `utGeneric.h` | 错误处理、条件分支、矩阵类型、诊断 |
**一般用户无需修改此模块。**
---
### 3.12 nlohmann/ — JSON 库
| 文件 | 说明 |
|------|------|
| `json.hpp` | nlohmann JSON 单头文件完整实现 |
| `json_fwd.hpp` | 前向声明,加速编译 |
---
### 3.13 Eigen/ — 线性代数库
337 个头文件header-only 第三方库。主要模块:`Core`、`Dense`、`Sparse`、`SparseCore`、`Eigenvalues`、`LU`、`QR`、`SVD`、`Geometry` 等。全项目矩阵运算与稀疏组装均依赖 Eigen。
**一般用户无需修改此模块。**
---
### 3.14 根目录构建文件
| 文件 | 说明 |
|------|------|
| `CMakeLists.txt` | 定义 `OpticsFEM` 可执行目标列出全部源文件分组PARSER/COMMON/GAUSS/BF/MESH/MATERIAL/PHY/SOLVER/POST/KERNEL/TEST/INTERFACE设置 C++17 与 `EIGENSOLVER_STATIC` |
| `CMakeSettings.json` | Visual Studio 中 CMake 配置(生成器、架构等) |
---
## 4. 软件架构与执行流程
### 4.1 模块依赖关系
```
Test_Main.cpp
FEM_Interface.cpp ──► Phy / Material / Mesh读入
├── FemType 0 ──► OpticsFEM_2D_EigenMode ──► Solver_EigenMode ──► Post_2D_EigenMode
├── FemType 1 ──► OpticsFEM_2D_EigenFreq ──► Solver_EigenFreq ──► Post_2D_EigenFreq
└── FemType 2/3 ► OpticsFEM_2D_Scatter ──► Solver_LdaDom ──► Post_2D_Scatter
├── kernelAssemble体积 + 边界积分)
├── functionBF + Gauss 数值积分)
└── parser边界表达式求值
```
### 4.2 完整调用序列(以 FemType=2 散射为例)
```
main()
└─ OpticsFEM_API::OpticsFEM_All(data)
├─ json::parse(data.data)
├─ Phy_WaveOpticsModel::Test_ReadData(str)
├─ MaterialLib::Test_ReadData(str)
├─ Mesh_2D::GetMesh(meshFile, str)
└─ [FemType == 2]
├─ Solver_LdaDom::GetSolver(str)
├─ OpticsFEM_2D_Scatter::GetMaterial / GetMesh / GetPhy / GetSolver / GetPost
├─ OpticsFEM_2D_Scatter::Assemble()
│ ├─ Assemble_WaveEquation() 体积积分
│ ├─ Assemble_PEC_ELE() 理想导体/电边界
│ ├─ Assemble_PBC() 周期边界
│ ├─ Assemble_BELE() 边界等效源
│ ├─ Assemble_PML() 完美匹配层
│ └─ Assemble_Port() 等 端口激励
├─ OpticsFEM_2D_Scatter::Run()
│ └─ Solver_LdaDom::Run() → solveComplexLinearEqu()
└─ OpticsFEM_2D_Scatter::Post(outFile)
├─ GetElectric() DOF → 顶点 Ex/Ey/Ez
└─ OutputData() 写入 OutFile/
```
### 4.3 数据流
```
bele.json ──► Phy_WaveOpticsModel边界/激励)
──► MaterialLib材料参数
──► MeshFile 路径
project_3.dat ──► Mesh_2D网格拓扑
──► Assemble ──► 稀疏矩阵 A, 向量 b
──► Solver ──► 解向量 x
──► Post ──► OutFile/Ex, Ey, Ez, normE
```
---
## 5. 完整使用说明
### 5.1 环境要求
| 组件 | 要求 |
|------|------|
| 操作系统 | Windows 10/11 x64 |
| 编译器 | Visual Studio 2022 或 2026工作负载「使用 C++ 的桌面开发」 |
| 构建工具 | CMake ≥ 3.8 |
| C++ 标准 | C++17 |
### 5.2 编译步骤
```powershell
# 若 cmake 不在 PATH 中,追加 VS 自带 CMake 路径
$env:Path += ";C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin"
cd opticsfem-master
mkdir build -Force
cd build
# VS 2022
cmake .. -G "Visual Studio 17 2022" -A x64
# 或 VS 2026
cmake .. -G "Visual Studio 18 2026" -A x64
cmake --build . --config Release
```
**产物路径:** `build/Release/OpticsFEM.exe`
### 5.3 运行前准备
#### 步骤 1指定 JSON 配置文件
编辑 `test/Test_Main.cpp` 第 28 行:
```cpp
fd.open("bele.json"); // 改为目标算例 JSON 文件名
```
修改后须**重新编译**。
#### 步骤 2部署输入文件
将 JSON 及 JSON 中 `MeshFile` 指定的 `.dat` 网格文件复制到 `build/Release/` 目录(与 `OpticsFEM.exe` 同目录)。
#### 步骤 3部署外部求解器
**散射算例FemType 2/3最小目录**
```
Release/
├── OpticsFEM.exe
├── bele.json
├── project_3.dat
└── complex/
└── complexsolver.exe
```
**本征算例FemType 0/1另需**
```
Release/
├── real_solver/real # 实数特征值求解器
└── complex_solver/complex # 复数特征值求解器
```
#### 步骤 4执行
```powershell
cd build/Release
.\OpticsFEM.exe
```
#### 步骤 5查看结果
检查 JSON 中 `OutFile` 指定目录(默认 `./OutFile`)是否生成:
- 散射:`Ex`、`Ey`、`Ez`、`normE`
- 本征模式:上述文件 + `neff`
- 本征频率:上述文件 + `freq`
### 5.4 切换算例
| 操作 | 方法 |
|------|------|
| 更换 JSON | 修改 `Test_Main.cpp``fd.open()` 文件名,或将目标 JSON 复制为当前文件名 |
| 更换网格 | 确保 JSON 中 `MeshFile` 与实际 `.dat` 文件名一致 |
| 更换问题类型 | 修改 JSON 中 `FemType`0/1/2/3程序自动路由 |
### 5.5 快速验证bele 算例)
1.`../测试数据集/bele/` 复制 `bele.json``project_3.dat``build/Release/`
2. 确认 `Test_Main.cpp``fd.open("bele.json")`
3. 部署 `complex/complexsolver.exe`
4. 运行 `OpticsFEM.exe`
5. 检查 `OutFile/` 下四个场文件
### 5.6 集成到其他程序
**方式 A — 独立可执行文件(当前模式)**
从文件读取 JSON调用 API适合本地验证。
**方式 B — 动态库(预留)**
取消 `FEM_Interface.h` 底部 `extern "C"` 注释,将 CMakeLists 中 `add_library(OpticsFEM SHARED ...)` 启用,编译为 DLL 供 C#/Python 等调用。
**方式 C — 直接调用 API**
```cpp
#include "Interface/FEM_Interface.h"
std::string jsonStr = "..."; // 紧凑 JSON 字符串
OpticsFEMData data;
data.test1 = 0;
data.test2 = 0;
data.data = (char*)jsonStr.data();
int ret = OpticsFEM_API::OpticsFEM_All(data);
// ret: 1=本征模式, 2=本征频率, 3=散射, 0=错误
```
---
## 6. 输入输出文件规范
### 6.1 JSON 配置文件
- **格式**:单行 UTF-8 紧凑 JSON`getline()` 读整行)
- **必填公共字段**`FemType`, `NbrBoundary`, `BoundaryFlag`, `NbrDomain`, `MeshFile`, `OutFile`
#### 公共字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| `FemType` | int | 0=本征模式, 1=本征频率, 2=散射(λ), 3=散射(f) |
| `NbrBoundary` | int | 边界边数量 |
| `BoundaryFlag` | int[] | 每条边界的类型编码(见 3.3 节) |
| `NbrDomain` | int | 材料物理域数量 |
| `MeshFile` | string | 网格 `.dat` 文件路径 |
| `OutFile` | string | 结果输出目录 |
| `EletricType` | int | 0=Et, 1=Ez, 2=完整 E散射/本征频率) |
#### 本征问题专用字段
| 字段 | 说明 |
|------|------|
| `NbrMode` | 求解模态数量 |
| `searchValue` | 特征值搜索目标 |
| `lambda0` | 真空波长(本征模式 FemType=0 |
#### 散射问题专用字段
| 字段 | 说明 |
|------|------|
| `lambda` | 真空波长FemType=2 |
| `freq` | 频率 GHzFemType=3内部换算 λ = 0.299792458/freq |
#### 边界扩展块(可选)
| 块名 | 主要字段 | 用途 |
|------|----------|------|
| `bele` | `index`, `Ebx/y/z`, `curlEbx/y/z`(字符串表达式) | 背景等效场边界 |
| `ef` | `index`, `E0x/y/z` | 电场 Dirichlet 激励 |
| `pml` | `index`, `lambda`, `PMLType`, `PMLData`, `PMLBoundaryIndex` | 完美匹配层 |
| `sbc` | `SBCType`, `Index`, `E0x/y/z`, `kx/y/z` | 散射边界 |
| `pbc` | `srcIndex`, `dstIndex`, `phiR`, `phiI` | 周期边界 |
| `mag` | `index`, `H0x/y/z` | 磁场边界 |
| `scd` | `index`, `J0x/y/z` | 面电流密度 |
| `mpd` | `index`, `mx/y/z` | 磁偶极子源 |
| `epd` | `index`, `px/y/z` | 电偶极子源 |
| `port` | `PORTinc`, `PORTout`, `Einc`, `Eout`, `EincCurl`, `EoutCurl` | 波导端口 |
| `beam` | `type`, `kx`, `ky` | 高斯光束 |
#### bele 算例 JSON 摘要
```json
{
"FemType": 2,
"EletricType": 2,
"lambda": 1,
"NbrBoundary": 13,
"BoundaryFlag": [0, 0, 3, 0, ...],
"bele": {
"index": [4],
"Eby": "sin(2*pi*x)",
"Ebz": "cos(2*pi*x)"
},
"ef": { "index": [1], "E0y": ["0.5"], "E0z": ["0.3"] },
"pml": { "index": [1,2,3,5], "PMLType": [1,1,1,1], ... },
"NbrDomain": 5,
"matType": [0,0,0,0,0],
"epsilonrR": [1.0, 1.0, 1.0, 1.0, 1.0],
"MeshFile": "project_3.dat",
"OutFile": "./OutFile"
}
```
详细字段定义参见上级目录 `OpticsFEM_LASPCEM_接口规范.md`
---
### 6.2 二维网格 `.dat` 文件
`Mesh_2D::GetMesh()` 顺序解析,字段顺序固定:
```
NbrVertex
Vertex (每行 x yz 读入时置 0
NbrEdge
Edge (每行 顶点索引0 顶点索引1
NbrTri
Tri (每行 顶点索引0 1 2
EdgeOfTri (每三角形 3 条边索引)
DomainOfTri (每三角形物理域编号,文件内 0-based读入后 +1
NbrEdges
CoonOfEdges (边界边连接信息)
DomainOfEdges (边界边所属域)
normal (边界法向,块大小由 JSON 中 NbrBoundary 决定)
NbrCopyOfEdges
CopyOfEdges
NbrCopyOfVertexs
CopyOfVertexs
```
---
### 6.3 输出文件格式
#### 散射问题(`Post_2D_Scatter::OutputData`
| 文件名 | 格式 | 内容 |
|--------|------|------|
| `Ex` | 首行 `//`,随后每行 `实部 虚部` | 各顶点 Ex |
| `Ey` | 同上 | 各顶点 Ey |
| `Ez` | 同上 | 各顶点 Ez |
| `normE` | 首行 `//`,随后每行一个浮点数 | 各顶点 \|E\| |
#### 本征模式
额外输出 `neff`:每行 `实部 虚部`(有效折射率)。多模态时 `Ex/Ey/Ez/normE``//` 分隔各模态块。
#### 本征频率
额外输出 `freq`:每行 `实部 虚部`(特征频率)。
---
## 7. 对外 API 与集成方式
### 7.1 数据结构
```cpp
struct OpticsFEMData {
double test1; // 保留
double test2; // 保留
char* data; // 指向 UTF-8 JSON 字符串(需保证生命周期覆盖调用期间)
};
```
### 7.2 接口函数
| 函数 | 说明 | 返回值 |
|------|------|--------|
| `OpticsFEM_All(data)` | 读配置 → 组装 → 求解 → 后处理 | 0/1/2/3 |
| `OpticsFEM_Test(data)` | 向 `OutFile + "test"` 写入 `"test success"` | 1 |
### 7.3 DLL 导出(预留)
`FEM_Interface.h` 底部注释代码可在编译为 SHARED 库时启用:
```cpp
extern "C" {
_declspec(dllexport) int OpticsFEM_ALL(OpticsFEMData data) {
return OpticsFEM_API::OpticsFEM_All(data);
}
}
```
---
## 8. 测试算例与数据集
测试数据位于上级目录 **`测试数据集/`**,源码树内**不包含**算例文件。
### 8.1 散射边界条件算例
| 文件夹 | JSON | 网格 | 测试内容 |
|--------|------|------|----------|
| `bele/` | `bele.json` | `project_3.dat` | 背景等效场边界 + PML |
| `pml_xy/` | `pml_xy.json` | `project_1.dat` | XY 方向 PML |
| `epd/` | `epd.json` | `project_4.dat` | 电偶极子源 |
| `mpd/` | `mpd.json` | `project_4.dat` | 磁偶极子源 |
| `mag/` | `mag.json` | `project_4.dat` | 磁场边界 |
| `scd/` | `scd.json` | `project_4.dat` | 面电流密度 |
| `port/` | `port.json` | `meshData_Port.txt` | 波导端口 |
### 8.2 波导/光纤本征模算例
| 文件夹 | 说明 |
|--------|------|
| `条形波导/case1` | 条形波导本征模 |
| `脊波导/case2` | 脊波导 |
| `槽波导/case3` | 槽波导 |
| `SPP波导/case4` | 表面等离激元波导 |
| `光子晶体波导/case5` | 光子晶体波导 |
| `阶跃折射率光纤/case6` | 阶跃折射率光纤 |
| `空芯光纤/case7` | 空芯光纤 |
| `多模光纤/case8` | 多模光纤 |
| `多芯光纤/case9` | 多芯光纤 |
| `光子晶体光纤/case10` | 光子晶体光纤 |
| `一维光子晶体/case11` | 一维光子晶体 |
| `方格光子晶体/case12` | 方格光子晶体 |
| `衍射光栅/case13` | 衍射光栅 |
| `表面等离激元线光栅/case14` | SPP 线光栅 |
| `scatter_modal/` | 散射模态 |
每个本征算例通常包含:`caseN.json`(或 `mesh.json`)、`project_*.dat` 网格,部分含 `.brep` 几何源文件。
---
## 9. 代码阅读路径
建议按以下顺序阅读,建立从入口到输出的完整认知:
| 序号 | 文件 | 阅读目标 |
|------|------|----------|
| 1 | `test/Test_Main.cpp` | 进程入口、JSON 文件读取 |
| 2 | `Interface/FEM_Interface.cpp` | FemType 路由、三阶段调度 |
| 3 | `test/Test_ReadData.cpp` | JSON 字段 → Phy/Material 映射 |
| 4 | `mesh/Mesh_Interface.cpp` | `.dat` 网格格式与读入 |
| 5 | `kernel/Assemble_kernel.cpp` | Assemble / Run / Post 总控 |
| 6 | `kernel/Assemble_Scatter_2D_Boundary.cpp` | BELE / PML / EF 等边界组装 |
| 7 | `kernel/Assemble_Scatter_Equation.cpp` | 体积方程组装 |
| 8 | `solver/Solver_Interface.cpp` | 求解器参数与 Run |
| 9 | `solver/interface.cpp` | 外部线性求解器调用 |
| 10 | `post/Post_Output.cpp` | 结果文件格式 |
### 调试建议
-`FEM_Interface.cpp``FemType` 分支入口设断点,确认路由正确。
- 散射分支已调用 `Test_OutputMatrix()`,可在 Assemble 后检查矩阵非零元。
- Post 完成后检查 `OutFile/` 目录内容。
---
## 10. 常见问题排查
| 现象 | 可能原因 | 处理措施 |
|------|----------|----------|
| `cmake` 无法识别 | CMake 未加入 PATH | 使用 VS 自带 CMake 完整路径 |
| `LNK1181: eigensolver.lib` | 旧版仍链接外部库 | 确认 `EIGENSOLVER_STATIC` 已启用 |
| 运行无输出、无 OutFile | 缺少 `complexsolver.exe` 或路径错误 | 检查 `complex/` 目录及工作目录 |
| 无法打开 `bele.json` | 工作目录不含 JSON | 在 `Release/` 下运行,或复制输入文件 |
| 无法打开 `project_3.dat` | `MeshFile` 路径不匹配 | 确保 `.dat` 与 exe 同目录 |
| 控制台打印 `err` | JSON 缺少或错误 `FemType` | 检查 JSON 完整性 |
| 编译警告 C4819 | Eigen 头文件编码 | 不影响功能,可忽略 |
| BELE 表达式报错 | 表达式语法错误或变量未定义 | 检查 muparser 支持的函数(如 `sin`, `pi`, `x` |
---
## 附录 A核心类关系图
```
OpticsFEM_API
├── Phy_WaveOpticsModel ← JSON 边界/激励
├── MaterialLib ← JSON 材料(含 Material[]
├── Mesh_2D ← .dat 网格
└── OpticsFEM_2D_* ← 问题驱动
├── Assemblekernel + function + parser
├── Solver_* ← 外部求解器
└── Post_2D_* ← 场重构与输出
```
---
## 附录 BFemType 与 JSON 关键参数对照
| FemType | 关键 JSON 参数 | 输出特征量 |
|---------|----------------|------------|
| 0 | `lambda0`, `NbrMode`, `searchValue` | `neff`, Ex/Ey/Ez |
| 1 | `lambda0`, `NbrMode`, `searchValue`, `EletricType` | `freq`, Ex/Ey/Ez |
| 2 | `lambda`, 边界块 | Ex/Ey/Ez/normE |
| 3 | `freq`, 边界块 | Ex/Ey/Ez/normE |
---
## 附录 C文档修订记录
| 版本 | 日期 | 修订内容 |
|------|------|----------|
| v1.0 | 2026-06-03 | 初版全文件目录、模块说明、使用指南、I/O 规范、算例索引 |
---
*本文档基于 `opticsfem-master` 当前代码状态编制。若 CMakeLists、API 或求解器路径发生变更,请同步更新相应章节。*