792 lines
29 KiB
Markdown
792 lines
29 KiB
Markdown
# OpticsFEM 完整使用说明与代码介绍
|
||
|
||
| 项目 | 说明 |
|
||
|------|------|
|
||
| 文档版本 | v1.0 |
|
||
| 编制日期 | 2026-06-03 |
|
||
| 适用代码 | `opticsfem-master/` |
|
||
| 适用平台 | Windows x64,Visual Studio 2022/2026,MSVC |
|
||
| 关联文档 | 上级目录 `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` 中完成。注释块(第 39–58 行)保留了手动分步调用的旧版写法。
|
||
|
||
---
|
||
|
||
### 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 与 Nedelec(1 阶)基函数及 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
|
||
│
|
||
├── kernel(Assemble:体积 + 边界积分)
|
||
├── function(BF + 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` | 频率 GHz(FemType=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 y,z 读入时置 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_* ← 问题驱动
|
||
├── Assemble(kernel + function + parser)
|
||
├── Solver_* ← 外部求解器
|
||
└── Post_2D_* ← 场重构与输出
|
||
```
|
||
|
||
---
|
||
|
||
## 附录 B:FemType 与 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 或求解器路径发生变更,请同步更新相应章节。*
|