606 lines
22 KiB
Markdown
606 lines
22 KiB
Markdown
# OpticsFEM 二维光学有限元程序 — 开发与使用手册
|
||
|
||
| 项目 | 说明 |
|
||
|------|------|
|
||
| 文档版本 | v1.0 |
|
||
| 编制日期 | 2026-06-03 |
|
||
| 适用代码 | `opticsfem-master/` |
|
||
| 适用平台 | Windows x64,Visual Studio 2026(18)/ MSVC |
|
||
| 关联文档 | `OpticsFEM_LASPCEM_接口规范.md` |
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [概述](#1-概述)
|
||
2. [从源代码到可执行文件](#2-从源代码到可执行文件)
|
||
3. [软件架构与模块划分](#3-软件架构与模块划分)
|
||
4. [程序执行流程](#4-程序执行流程)
|
||
5. [数据流与对象模型](#5-数据流与对象模型)
|
||
6. [对外 API 规范](#6-对外-api-规范)
|
||
7. [输入与输出文件规范](#7-输入与输出文件规范)
|
||
8. [构建与部署](#8-构建与部署)
|
||
9. [算例运行指南](#9-算例运行指南)
|
||
10. [代码阅读路径](#10-代码阅读路径)
|
||
11. [求解器依赖说明](#11-求解器依赖说明)
|
||
12. [常见问题与排查](#12-常见问题与排查)
|
||
|
||
---
|
||
|
||
## 1. 概述
|
||
|
||
### 1.1 程序定位
|
||
|
||
OpticsFEM 是一套基于 C++ 实现的**二维矢量有限元(FEM)光学电磁仿真内核**,采用 Nedelec 边元离散麦克斯韦方程,支持以下三类问题:
|
||
|
||
| FemType | 问题类型 | 核心类 |
|
||
|---------|----------|--------|
|
||
| 0 | 本征模式(EigenMode) | `OpticsFEM_2D_EigenMode` |
|
||
| 1 | 本征频率(EigenFreq) | `OpticsFEM_2D_EigenFreq` |
|
||
| 2 | 散射(Scatter,按波长) | `OpticsFEM_2D_Scatter` |
|
||
| 3 | 散射(Scatter,按频率) | `OpticsFEM_2D_Scatter` |
|
||
|
||
程序通过 **JSON 字符串** 描述物理模型、材料参数、边界条件及求解配置;通过 **`.dat` 文本文件** 描述三角网格。计算结果以文本文件形式输出至指定目录。
|
||
|
||
### 1.2 入口程序与可执行文件的关系
|
||
|
||
`test/Test_Main.cpp` 并非完整程序,而是**可执行文件的入口模块**。其职责限于:
|
||
|
||
1. 从本地文件系统读取 JSON 配置文件;
|
||
2. 构造 `OpticsFEMData` 结构体;
|
||
3. 调用统一 API `OpticsFEM_API::OpticsFEM_All()` 触发完整求解流程。
|
||
|
||
可执行文件 `OpticsFEM.exe` 由 CMake 将 `Test_Main.cpp` 与项目中全部业务源文件(约 70 余个 `.cpp` 单元)**编译并链接**为单一二进制产物。操作系统启动进程时,自 `main()` 函数开始执行;后续全部计算逻辑由 `FEM_Interface.cpp` 及其调用的各功能模块完成。
|
||
|
||
### 1.3 设计原则
|
||
|
||
| 原则 | 说明 |
|
||
|------|------|
|
||
| 单一 API 入口 | 外部调用方仅需调用 `OpticsFEM_All()`,无需感知内部分支 |
|
||
| JSON 为配置语言 | 物理、材料、边界、求解参数均通过 JSON 字段传递 |
|
||
| 前后端解耦 | `Test_Main.cpp` 可替换为 GUI、脚本或 DLL 宿主,接口不变 |
|
||
| 模块化组装 | 网格、物理、材料、组装、求解、后处理分层实现 |
|
||
|
||
---
|
||
|
||
## 2. 从源代码到可执行文件
|
||
|
||
### 2.1 构建系统
|
||
|
||
项目采用 **CMake** 管理构建,配置文件为 `opticsfem-master/CMakeLists.txt`。目标产物定义如下:
|
||
|
||
```cmake
|
||
add_executable(OpticsFEM
|
||
"test/Test_Main.cpp"
|
||
${PARSER} ${COMMON} ${GAUSS} ${BF}
|
||
${MESH} ${MATERIAL} ${PHY}
|
||
${SOLVER} ${POST} ${KERNEL}
|
||
${TEST} ${INTERFACE}
|
||
"post/Post_GetEb.cpp"
|
||
)
|
||
target_compile_definitions(OpticsFEM PRIVATE EIGENSOLVER_STATIC)
|
||
set(CMAKE_CXX_STANDARD 17)
|
||
```
|
||
|
||
### 2.2 编译链接流程
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ 源文件层 │
|
||
│ Test_Main.cpp, FEM_Interface.cpp, Mesh_Interface.cpp, ... │
|
||
└────────────────────────────┬─────────────────────────────────────┘
|
||
│ cmake .. -G "Visual Studio 18 2026" -A x64
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ 工程生成层 │
|
||
│ build/OpticsFEM.vcxproj, build/Project.slnx │
|
||
└────────────────────────────┬─────────────────────────────────────┘
|
||
│ cmake --build . --config Release
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ 编译层(Translation) │
|
||
│ 每个 .cpp → 对应 .obj 目标文件 │
|
||
└────────────────────────────┬─────────────────────────────────────┘
|
||
│ 链接(Linking)
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ 产物层 │
|
||
│ build/Release/OpticsFEM.exe │
|
||
└──────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**编译(Compile)**:将各翻译单元(`.cpp`)独立转换为目标文件(`.obj`)。`#include` 头文件仅提供声明,不参与链接。
|
||
|
||
**链接(Link)**:合并全部 `.obj`,解析跨文件符号引用,以 `Test_Main.cpp` 中的 `main()` 作为进程入口,生成最终 `.exe`。
|
||
|
||
### 2.3 第三方依赖
|
||
|
||
| 依赖 | 位置 | 用途 |
|
||
|------|------|------|
|
||
| Eigen | `opticsfem-master/Eigen/` | 稠密/稀疏矩阵运算 |
|
||
| nlohmann/json | `opticsfem-master/nlohmann/` | JSON 解析 |
|
||
| muparser 派生库 | `opticsfem-master/parser/` | BELE 等边界表达式求值 |
|
||
|
||
### 2.4 关于 Test_Main.cpp 中未使用的变量
|
||
|
||
`Test_Main.cpp` 中声明的 `Phy_WaveOpticsModel`、`MaterialLib`、`Mesh_2D` 等对象在 `main()` 内**未被直接使用**。实际对象实例化与数据注入在 `FEM_Interface.cpp::OpticsFEM_All()` 中完成。上述声明为历史遗留或调试用途;注释块(第 39–58 行)保留了手动分步调用流程的旧版写法,现行标准路径为 `OpticsFEM_All()` 一站式调用。
|
||
|
||
---
|
||
|
||
## 3. 软件架构与模块划分
|
||
|
||
### 3.1 目录结构与职责
|
||
|
||
```
|
||
opticsfem-master/
|
||
├── test/
|
||
│ ├── Test_Main.cpp # 进程入口;读取 JSON 文件
|
||
│ ├── Test_ReadData.cpp # JSON → Phy / Material 解析实现
|
||
│ └── Test_OutputData.cpp # 调试输出
|
||
├── Interface/
|
||
│ ├── FEM_Interface.h # 对外 API 声明
|
||
│ └── FEM_Interface.cpp # FemType 路由与全流程调度
|
||
├── phy/ # 物理模型:边界条件、激励
|
||
├── material/ # 材料库:ε、μ、σ、n、k
|
||
├── mesh/ # 网格:.dat 读取与拓扑查询
|
||
├── kernel/ # FEM 组装:方程与边界积分
|
||
├── solver/ # 数值求解:线性方程组 / 特征值
|
||
├── post/ # 后处理:DOF → 顶点场 → 文件输出
|
||
├── function/ # Nedelec 基函数、高斯积分
|
||
├── parser/ # 数学表达式解析器
|
||
└── Eigen/ # 线性代数库(第三方)
|
||
```
|
||
|
||
### 3.2 模块依赖关系
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph entry [入口层]
|
||
TM[Test_Main.cpp]
|
||
API[FEM_Interface.cpp]
|
||
end
|
||
|
||
subgraph io [数据读入层]
|
||
PHY[phy]
|
||
MAT[material]
|
||
MSH[mesh]
|
||
end
|
||
|
||
subgraph core [计算核心层]
|
||
KRN[kernel]
|
||
SLV[solver]
|
||
end
|
||
|
||
subgraph output [输出层]
|
||
PST[post]
|
||
end
|
||
|
||
TM --> API
|
||
API --> PHY
|
||
API --> MAT
|
||
API --> MSH
|
||
API --> KRN
|
||
KRN --> SLV
|
||
KRN --> PST
|
||
SLV --> PST
|
||
PHY --> KRN
|
||
MAT --> KRN
|
||
MSH --> KRN
|
||
MSH --> PST
|
||
PHY --> PST
|
||
```
|
||
|
||
### 3.3 核心类层次(二维)
|
||
|
||
| 类名 | 职责 |
|
||
|------|------|
|
||
| `Phy_WaveOpticsModel` | 存储边界类型、BELE/PML/EF/SBC 等边界数据 |
|
||
| `MaterialLib` | 存储各物理域材料参数 |
|
||
| `Mesh_2D` | 存储顶点、边、三角形及域编号 |
|
||
| `OpticsFEM_2D_Scatter` | 散射问题组装、求解、后处理调度 |
|
||
| `Solver_LdaDom` | 散射线性方程组求解接口 |
|
||
| `Post_2D_Scatter` | 散射结果电场插值与输出 |
|
||
|
||
---
|
||
|
||
## 4. 程序执行流程
|
||
|
||
### 4.1 顶层调用序列
|
||
|
||
以 `FemType = 2`(散射,bele 算例)为例,完整调用序列为:
|
||
|
||
```
|
||
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()
|
||
├─ OpticsFEM_2D_Scatter::Run()
|
||
└─ OpticsFEM_2D_Scatter::Post(outFile)
|
||
```
|
||
|
||
### 4.2 Assemble 阶段内部流程
|
||
|
||
`OpticsFEM_2D_Scatter::Assemble()`(`kernel/Assemble_kernel.cpp`)执行以下步骤:
|
||
|
||
1. **确定矩阵类型**:根据 PML、SBC、复材料等条件判定采用实数或复数稀疏矩阵;
|
||
2. **体积积分**:`Assemble_WaveEquation()` — 在各三角形单元上积分麦克斯韦弱形式;
|
||
3. **边界积分**(按 JSON 配置条件触发):
|
||
- `Assemble_PEC_ELE()` — 理想导体 / 电边界
|
||
- `Assemble_PBC()` — 周期边界
|
||
- `Assemble_BELE()` — 边界等效源(bele 算例)
|
||
- `Assemble_PML()` — 完美匹配层
|
||
- `Assemble_Port()` — 端口激励
|
||
- 等
|
||
4. **约束处理**:对 Dirichlet 型边界自由度施加罚函数或消元。
|
||
|
||
输出:稀疏矩阵 **A**、右端向量 **b**、预处理矩阵 **P**。
|
||
|
||
### 4.3 Run 阶段
|
||
|
||
```cpp
|
||
void OpticsFEM_2D_Scatter::Run()
|
||
{
|
||
_mSolver->SetParam(&_mA_complex, &_mB_complex, &_mP_complex);
|
||
_mSolver->Run(&_mX);
|
||
}
|
||
```
|
||
|
||
`Solver_LdaDom::Run()` 调用 `solveComplexLinearEqu()`(`solver/interface.cpp`),将 CSR 格式矩阵写入临时文件,并启动外部求解器 `complex/complexsolver.exe` 完成迭代求解。解向量经预处理矩阵变换后存入 `_mX`。
|
||
|
||
### 4.4 Post 阶段
|
||
|
||
```cpp
|
||
void OpticsFEM_2D_Scatter::Post(string file)
|
||
{
|
||
_mPost->GetMesh(_mMesh);
|
||
_mPost->GetSolver(_mSolver);
|
||
_mPost->GetPhy(_mPhy);
|
||
_mPost->GetResult(&_mX);
|
||
_mPost->GetElectric(); // 边 DOF → 顶点 Ex/Ey/Ez
|
||
_mPost->OutputData(file); // 写入 OutFile/
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 数据流与对象模型
|
||
|
||
### 5.1 端到端数据流
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph inputs [外部输入]
|
||
J["bele.json\n(JSON 字符串)"]
|
||
D["project_3.dat\n(网格文件)"]
|
||
end
|
||
|
||
subgraph parsed [内存对象]
|
||
P["Phy_WaveOpticsModel\n边界/激励"]
|
||
M["MaterialLib\n材料参数"]
|
||
G["Mesh_2D\n网格拓扑"]
|
||
end
|
||
|
||
subgraph linear [离散方程]
|
||
A["稀疏矩阵 A"]
|
||
B["右端向量 b"]
|
||
X["解向量 x"]
|
||
end
|
||
|
||
subgraph files [文件输出]
|
||
O["OutFile/Ex, Ey, Ez, normE"]
|
||
end
|
||
|
||
J -->|Test_ReadData| P
|
||
J -->|Test_ReadData| M
|
||
J -->|MeshFile 字段| D
|
||
D -->|GetMesh| G
|
||
P --> A
|
||
M --> A
|
||
G --> A
|
||
P --> B
|
||
A --> X
|
||
B --> X
|
||
X --> O
|
||
G --> O
|
||
```
|
||
|
||
### 5.2 JSON 字段到内存对象的映射
|
||
|
||
| JSON 字段组 | 目标对象 | 解析函数 |
|
||
|-------------|----------|----------|
|
||
| `FemType`, `EletricType`, `BoundaryFlag`, `bele`, `ef`, `pml`, `sbc`, … | `Phy_WaveOpticsModel` | `Phy_WaveOpticsModel::Test_ReadData()` |
|
||
| `NbrDomain`, `epsilonrR/I`, `murR/I`, `n`, `k`, `sigma`, … | `MaterialLib` | `MaterialLib::Test_ReadData()` |
|
||
| `MeshFile` | 网格文件路径 | `Mesh_2D::GetMesh()` |
|
||
| `lambda` / `freq`, `NbrMode`, `searchValue`, … | 求解器参数 | `Solver_*::GetSolver()` |
|
||
|
||
### 5.3 bele 算例配置摘要
|
||
|
||
| 配置项 | 值 | 含义 |
|
||
|--------|-----|------|
|
||
| `FemType` | 2 | 散射问题 |
|
||
| `EletricType` | 2 | 求解完整电场 E |
|
||
| `lambda` | 1 | 真空波长 |
|
||
| `bele.index` | [4] | 边界域 4 施加 BELE |
|
||
| `bele.Eby` | `sin(2*pi*x)` | 边界切向电场解析表达式 |
|
||
| `ef` | 边界 1 电场激励 | 等效 Dirichlet 激励 |
|
||
| `pml` | 4 个吸收层 | PML 参数 |
|
||
| `MeshFile` | `project_3.dat` | 网格文件 |
|
||
| `OutFile` | `./OutFile` | 输出目录 |
|
||
|
||
---
|
||
|
||
## 6. 对外 API 规范
|
||
|
||
### 6.1 数据结构
|
||
|
||
```cpp
|
||
struct OpticsFEMData {
|
||
double test1; // 保留字段
|
||
double test2; // 保留字段
|
||
char* data; // UTF-8 JSON 字符串(单行或紧凑格式)
|
||
};
|
||
```
|
||
|
||
### 6.2 接口函数
|
||
|
||
```cpp
|
||
class OpticsFEM_API {
|
||
public:
|
||
// 完整求解流程:读配置 → 组装 → 求解 → 后处理
|
||
static int OpticsFEM_All(OpticsFEMData data);
|
||
|
||
// 连通性测试:向 OutFile 写入 "test success"
|
||
int OpticsFEM_Test(OpticsFEMData data);
|
||
};
|
||
```
|
||
|
||
### 6.3 返回值
|
||
|
||
| 返回值 | 含义 |
|
||
|--------|------|
|
||
| 0 | `FemType` 无法识别 |
|
||
| 1 | 本征模式完成 |
|
||
| 2 | 本征频率完成 |
|
||
| 3 | 散射完成 |
|
||
|
||
### 6.4 集成方式
|
||
|
||
**方式 A — 独立可执行文件(当前 `Test_Main.cpp` 模式)**
|
||
|
||
从文件读取 JSON,调用 API,适用于本地验证与回归测试。
|
||
|
||
**方式 B — 动态库宿主(注释代码预留)**
|
||
|
||
`FEM_Interface.h` 底部预留 `extern "C"` 导出声明,可将内核编译为 DLL 供前端或其他语言调用。
|
||
|
||
---
|
||
|
||
## 7. 输入与输出文件规范
|
||
|
||
### 7.1 JSON 配置文件
|
||
|
||
- **格式**:单行 UTF-8 JSON 或紧凑 JSON;
|
||
- **读取方式**:`Test_Main.cpp` 使用 `getline()` 读取整行;
|
||
- **必填公共字段**:`FemType`, `NbrBoundary`, `BoundaryFlag`, `NbrDomain`, `MeshFile`, `OutFile`;
|
||
- **边界扩展字段**(可选,按 `js.contains` 判定):`bele`, `ef`, `pml`, `sbc`, `mag`, `scd`, `pbc`, `mpd`, `epd`, `port`, `beam`。
|
||
|
||
详细字段定义参见 `OpticsFEM_LASPCEM_接口规范.md` 第 2.3 节。
|
||
|
||
### 7.2 二维网格 `.dat` 文件
|
||
|
||
由 `Mesh_2D::GetMesh()`(`mesh/Mesh_Interface.cpp`)顺序解析,字段顺序为:
|
||
|
||
```
|
||
NbrVertex → Vertex → NbrEdge → Edge → NbrTri → Tri
|
||
→ EdgeOfTri → DomainOfTri → NbrEdges → CoonOfEdges
|
||
→ DomainOfEdges → normal → CopyOfEdges → ...
|
||
```
|
||
|
||
顶点坐标为二维 `(x, y)`,第三分量在读取时置零。
|
||
|
||
### 7.3 输出文件
|
||
|
||
散射问题(`Post_2D_Scatter::OutputData`)在 `OutFile` 目录下生成:
|
||
|
||
| 文件名 | 内容 |
|
||
|--------|------|
|
||
| `Ex` | 各顶点 Ex 分量(实部 虚部,逐行) |
|
||
| `Ey` | 各顶点 Ey 分量 |
|
||
| `Ez` | 各顶点 Ez 分量 |
|
||
| `normE` | 各顶点电场模 |
|
||
|
||
本征问题额外输出 `neff` 或 `freq` 文件。
|
||
|
||
---
|
||
|
||
## 8. 构建与部署
|
||
|
||
### 8.1 环境要求
|
||
|
||
| 组件 | 要求 |
|
||
|------|------|
|
||
| 操作系统 | Windows 10/11 x64 |
|
||
| 编译器 | Visual Studio 2026(18)Community,工作负载「使用 C++ 的桌面开发」 |
|
||
| 构建工具 | CMake ≥ 3.8(VS 自带或独立安装) |
|
||
| C++ 标准 | C++17 |
|
||
|
||
### 8.2 构建命令
|
||
|
||
```powershell
|
||
# 配置 CMake 路径(若未加入系统 PATH)
|
||
$env:Path += ";C:\Program Files\Microsoft Visual Studio\18\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin"
|
||
|
||
cd opticsfem-master
|
||
mkdir build -Force
|
||
cd build
|
||
|
||
cmake .. -G "Visual Studio 18 2026" -A x64
|
||
cmake --build . --config Release
|
||
```
|
||
|
||
产物路径:`build/Release/OpticsFEM.exe`
|
||
|
||
### 8.3 运行时目录结构
|
||
|
||
散射算例(bele)最小部署结构:
|
||
|
||
```
|
||
Release/
|
||
├── OpticsFEM.exe
|
||
├── bele.json # 输入配置(文件名与 Test_Main.cpp 中 fd.open 一致)
|
||
├── project_3.dat # 网格(与 JSON 中 MeshFile 一致)
|
||
└── complex/
|
||
└── complexsolver.exe # 外部线性求解器(运行时必需)
|
||
```
|
||
|
||
本征算例另需:
|
||
|
||
```
|
||
real_solver/real # 或 real_solver 目录下对应可执行文件
|
||
complex_solver/complex
|
||
```
|
||
|
||
### 8.4 关于 eigen_solver 静态链接
|
||
|
||
当前工程已将 `solver/eigen_solver.cpp` 编入可执行文件,并通过宏 `EIGENSOLVER_STATIC` 取消 DLL 导入/导出修饰,**不再依赖** `lib/eigensolver.lib`。该模块服务于本征模式/本征频率问题(`realEigenSolver` / `complexEigenSolver`),运行时仍依赖 `real_solver/` 与 `complex_solver/` 目录下的外部可执行文件。
|
||
|
||
---
|
||
|
||
## 9. 算例运行指南
|
||
|
||
### 9.1 标准运行步骤
|
||
|
||
**步骤 1 — 编译**
|
||
|
||
执行第 8.2 节构建命令,确认生成 `OpticsFEM.exe`。
|
||
|
||
**步骤 2 — 配置入口 JSON 文件名**
|
||
|
||
编辑 `test/Test_Main.cpp` 第 28 行:
|
||
|
||
```cpp
|
||
fd.open("bele.json"); // 改为目标算例 JSON 文件名
|
||
```
|
||
|
||
修改后须重新编译。
|
||
|
||
**步骤 3 — 部署输入文件**
|
||
|
||
将 JSON 及 `MeshFile` 指定的 `.dat` 文件复制至 `build/Release/` 目录。
|
||
|
||
**步骤 4 — 部署外部求解器**
|
||
|
||
将 `complex/complexsolver.exe` 置于 `Release/complex/` 目录(路径相对于工作目录)。
|
||
|
||
**步骤 5 — 执行**
|
||
|
||
```powershell
|
||
cd build/Release
|
||
.\OpticsFEM.exe
|
||
```
|
||
|
||
**步骤 6 — 验证输出**
|
||
|
||
检查 `OutFile/` 目录是否生成 `Ex`、`Ey`、`Ez`、`normE`。
|
||
|
||
### 9.2 切换算例
|
||
|
||
| 操作 | 说明 |
|
||
|------|------|
|
||
| 更换 JSON | 修改 `Test_Main.cpp` 中 `fd.open()` 文件名,或使用同名复制 |
|
||
| 更换网格 | 确保 JSON 中 `MeshFile` 字段与实际 `.dat` 文件名一致 |
|
||
| 更换问题类型 | 修改 JSON 中 `FemType`;程序自动路由至对应求解分支 |
|
||
|
||
测试数据集位于 `测试数据集/`, subdirectory 名称即边界/物理类型(如 `bele/`、`scd/`、`pml_xy/`)。
|
||
|
||
---
|
||
|
||
## 10. 代码阅读路径
|
||
|
||
建议按以下顺序阅读,以建立自入口至输出的完整认知:
|
||
|
||
| 序号 | 文件 | 阅读目标 |
|
||
|------|------|----------|
|
||
| 1 | `test/Test_Main.cpp` | 进程入口、JSON 文件读取 |
|
||
| 2 | `Interface/FEM_Interface.cpp` | FemType 路由、三阶段调度 |
|
||
| 3 | `test/Test_ReadData.cpp` | JSON 字段解析逻辑 |
|
||
| 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` 分支入口设置断点,确认路由正确;
|
||
- 在 `Assemble()` 返回后检查矩阵非零元数量(`Test_OutputMatrix()` 已在散射分支调用);
|
||
- 在 `Post()` 返回后检查 `OutFile/` 目录。
|
||
|
||
---
|
||
|
||
## 11. 求解器依赖说明
|
||
|
||
### 11.1 求解器分层
|
||
|
||
| 层级 | 模块 | 适用问题 | 运行时依赖 |
|
||
|------|------|----------|------------|
|
||
| 特征值求解 | `eigen_solver.cpp` | FemType 0, 1 | `real_solver/real`, `complex_solver/complex` |
|
||
| 线性方程组(实) | `interface.cpp::solveRealLinearEqu` | 实散射 | `real/realsolver.exe` |
|
||
| 线性方程组(复) | `interface.cpp::solveComplexLinearEqu` | 复散射(bele) | `complex/complexsolver.exe` |
|
||
|
||
### 11.2 外部求解器调用机制
|
||
|
||
`interface.cpp` 采用**文件交换**方式与外部求解器通信:
|
||
|
||
1. 将 CSR 格式矩阵、右端项写入当前目录临时文件;
|
||
2. 通过 `system()` 调用外部 `.exe`;
|
||
3. 读取解向量临时文件;
|
||
4. 清理临时文件。
|
||
|
||
因此,外部求解器必须与 `OpticsFEM.exe` **工作目录相对路径**正确对应,且具备可执行权限。
|
||
|
||
---
|
||
|
||
## 12. 常见问题与排查
|
||
|
||
| 现象 | 可能原因 | 处理措施 |
|
||
|------|----------|----------|
|
||
| `cmake` 无法识别 | CMake 未加入 PATH | 使用 VS 自带 CMake 完整路径,或配置环境变量 |
|
||
| `LNK1181: eigensolver.lib` | 旧版 CMakeLists 仍链接外部库 | 确认已启用 `EIGENSOLVER_STATIC` 并编入 `eigen_solver.cpp` |
|
||
| 运行无输出、无 OutFile | 缺少 `complexsolver.exe` 或路径错误 | 检查 `complex/` 目录及工作目录 |
|
||
| 无法打开 `bele.json` | 工作目录不含 JSON | 在 `Release/` 目录下运行,或复制输入文件 |
|
||
| 无法打开 `project_3.dat` | `MeshFile` 路径不匹配 | 确保 `.dat` 与 exe 同目录,或修正 JSON |
|
||
| 编译警告 C4819 | Eigen 头文件编码 | 不影响功能,可忽略 |
|
||
| `FemType` 返回 0 打印 err | JSON 缺少或错误 `FemType` 字段 | 检查 JSON 完整性 |
|
||
|
||
---
|
||
|
||
## 附录 A:FemType 路由对照表
|
||
|
||
| FemType | 求解器类 | 后处理类 | 关键 JSON 参数 |
|
||
|---------|----------|----------|----------------|
|
||
| 0 | `Solver_EigenMode` | `Post_2D_EigenMode` | `lambda0`, `NbrMode`, `searchValue` |
|
||
| 1 | `Solver_EigenFreq` | `Post_2D_EigenFreq` | `lambda0`, `NbrMode`, `searchValue` |
|
||
| 2 | `Solver_LdaDom` | `Post_2D_Scatter` | `lambda`, 边界字段 |
|
||
| 3 | `Solver_LdaDom` | `Post_2D_Scatter` | `freq`, 边界字段 |
|
||
|
||
---
|
||
|
||
## 附录 B:文档修订记录
|
||
|
||
| 版本 | 日期 | 修订内容 |
|
||
|------|------|----------|
|
||
| v1.0 | 2026-06-03 | 初版:构建流程、架构、数据流、部署与算例指南 |
|
||
|
||
---
|
||
|
||
*本文档基于 `opticsfem-master` 当前代码状态编制,若 CMakeLists 或 API 发生变更,请同步更新相应章节。*
|