7.7 KiB
Test_Main.cpp 代码理解
文件路径:
opticsfem-master/test/Test_Main.cpp
作用:OpticsFEM 程序的主测试入口,负责读取 JSON 配置文件并调用统一 API 完成有限元全流程。
1. 整体结论
当前版本中,main 函数真正有效的逻辑只有两块:
- 读取 JSON 配置文件(
bele.json) - 调用
OpticsFEM_API::OpticsFEM_All执行完整求解流程
第 17–22 行声明的 phy、matLab、mesh、fem、solver、post 对象在当前代码中未被使用,属于旧版手动分步调用留下的冗余代码。这些对象的创建与使用已在 Interface/FEM_Interface.cpp 的 OpticsFEM_All 函数内部完成。
精简后的核心逻辑等价于:
ifstream fd;
std::string str;
fd.open("bele.json");
getline(fd, str);
OpticsFEMData data;
data.data = (char*)str.data();
OpticsFEM_API::OpticsFEM_All(data);
2. 文件结构概览
| 行号 | 内容 | 是否必要 |
|---|---|---|
| 1–6 | 引入 phy / material / mesh / kernel / solver / post 头文件 | 当前不必需(旧代码遗留) |
| 7 | 引入 FEM_Interface.h |
必要 |
| 9–12 | 标准库:文件流、字符串等 | 必要 |
| 17–22 | 声明物理、材料、网格、FEM、求解器、后处理对象 | 不必需 |
| 24–29 | 读取 bele.json |
必要 |
| 31–37 | 构造 OpticsFEMData 并调用 API |
必要 |
| 39–57 | 注释掉的旧版手动流程 | 历史参考,不参与运行 |
| 59 | return 1 |
程序正常退出 |
3. 头文件说明
3.1 当前实际需要的头文件
../Interface/FEM_Interface.h:定义OpticsFEMData结构体和OpticsFEM_API类<fstream>、<string>:读取 JSON 文件
3.2 遗留头文件(1–6 行)
| 头文件 | 对应模块 |
|---|---|
Phy_Base.h |
波动光学物理模型(边界条件、激励等) |
Material_Base.h |
材料库 |
Mesh_Base.h |
二维网格 |
Assemble_Base.h |
有限元组装 |
Solver_Base.h |
求解器 |
Post_Base.h |
后处理与结果输出 |
这些头文件服务于注释掉的旧代码(第 39–57 行),在现行 API 调用方式下可以移除。
4. 第 17–22 行:遗留对象声明
Phy_WaveOpticsModel phy; // 物理模型(边界、PML、背景场等)
MaterialLib matLab; // 材料库(ε、μ 等)
Mesh_2D mesh; // 二维网格
OpticsFEM_2D_EigenFreq fem; // 本征频率 FEM 内核
Solver_EigenFreq solver; // 本征频率求解器
Post_2D_EigenFreq post; // 本征频率后处理
含义
Phy_WaveOpticsModel是类名(波动光学物理模型),phy是该类的一个对象实例- 其余同理:
MaterialLib matLab表示创建一个名为matLab的材料库对象
为何不需要
OpticsFEM_All 内部会根据 JSON 中的 FemType 自行创建对应类型的对象,例如:
| FemType | FEM 内核 | 求解器 | 后处理 |
|---|---|---|---|
| 0 | OpticsFEM_2D_EigenMode |
Solver_EigenMode |
Post_2D_EigenMode |
| 1 | OpticsFEM_2D_EigenFreq |
Solver_EigenFreq |
Post_2D_EigenFreq |
| 2 / 3 | OpticsFEM_2D_Scatter |
Solver_LdaDom |
Post_2D_Scatter |
因此 main 里写死 EigenFreq 类型的声明既不会被用到,也无法适配其他题型。
5. JSON 读取(第 24–29、35 行)
ifstream fd;
std::string str;
fd.open("bele.json");
getline(fd, str);
data.data = (char*)str.data();
流程
- 打开当前工作目录下的
bele.json - 用
getline将文件内容读入字符串str(项目中的 JSON 为单行格式) - 将
str的指针写入OpticsFEMData.data,传递给 API
bele.json 是什么
总配置文件,包含一次有限元计算所需的全部参数,例如:
| 字段 | 含义 |
|---|---|
FemType |
计算类型(0 本征模 / 1 本征频率 / 2、3 散射) |
MeshFile |
网格文件路径(如 project_3.dat) |
OutFile |
结果输出目录 |
BoundaryFlag、pml、bele |
边界条件、吸收层、背景场 |
epsilonrR、murR 等 |
材料参数 |
solverType、tol 等 |
求解器设置 |
注意
main中不解析 JSON 字段,解析工作在OpticsFEM_All内部完成str必须在 API 调用期间保持有效(当前main满足此条件)- 运行前需确保 exe 工作目录下存在
bele.json,且 JSON 中引用的MeshFile等文件路径可访问
6. femAPI 调用(第 31–37 行)
OpticsFEM_API femAPI;
OpticsFEMData data;
data.test1 = 1;
data.test2 = 2;
data.data = (char*)str.data();
femAPI.OpticsFEM_All(data);
OpticsFEMData:数据包裹
定义于 Interface/FEM_Interface.h:
struct OpticsFEMData
{
double test1;
double test2;
char* data; // 唯一实际使用的字段:JSON 字符串指针
};
设计目的是便于 DLL 对外暴露接口,外部程序(Python、MATLAB 等)只需传入 JSON 指针即可调用,无需直接依赖各模块头文件。test1、test2 为占位字段,当前实现未使用。
OpticsFEM_All:统一全流程入口
定义于 Interface/FEM_Interface.cpp,主要步骤:
收到 JSON 字符串
↓
nlohmann::json 解析,读取 FemType
↓
创建 phy、matLab、mesh,从 JSON 填充
↓
按 FemType 选择 fem / solver / post
↓
GetMaterial / GetMesh / GetPhy / GetSolver / GetPost
↓
Assemble() → Run() → Post(OutFile)
↓
返回状态码(0=错误,1/2/3=不同题型成功)
femAPI 对象是否必要
OpticsFEM_All 是静态成员函数,以下写法等价且更简洁:
OpticsFEM_API::OpticsFEM_All(data);
7. 注释掉的旧版流程(第 39–57 行)
旧写法在 main 中手动完成 API 内部的各步骤:
phy/matLab/solver/mesh 从 JSON 读数据
↓
fem 挂载各模块指针
↓
Assemble → Test_OutputMatrix → Run → Post
缺点:
- 题型写死为本征频率(
OpticsFEM_2D_EigenFreq) - 步骤分散在
main中,不便复用和对外封装
现行 API 方式将上述逻辑收拢到 OpticsFEM_All,main 仅负责读文件和调接口。
8. 执行流程图
Test_Main.cpp (main)
│
├─ 打开 bele.json
├─ 读入 JSON 字符串 str
├─ 填入 OpticsFEMData.data
│
└─ OpticsFEM_All(data) ← Interface/FEM_Interface.cpp
│
├─ 解析 JSON,读 FemType / MeshFile / OutFile
├─ phy.Test_ReadData(str)
├─ matLab.Test_ReadData(str)
├─ mesh.GetMesh(meshFile, str)
│
├─ [FemType 分支] 创建对应 fem / solver / post
├─ 挂载模块 → Assemble() → Run() → Post(outFile)
│
└─ 输出结果到 OutFile 目录
9. 运行前提
- 可执行文件工作目录下存在
bele.json(测试数据位于测试数据集/bele/bele.json) - JSON 中
MeshFile指向的网格文件存在且路径正确 - 输出目录(
OutFile字段)可写
10. 相关源文件
| 文件 | 关系 |
|---|---|
Interface/FEM_Interface.h |
API 与数据结构定义 |
Interface/FEM_Interface.cpp |
OpticsFEM_All 全流程实现 |
test/Test_ReadData.cpp |
phy / matLab 等模块的 JSON 解析实现 |
phy/Phy_Base.h |
物理模型类定义 |
测试数据集/bele/bele.json |
示例配置文件(FemType=2,散射问题) |
11. 一句话总结
Test_Main.cpp 是 OpticsFEM 的薄入口:读 JSON → 调 OpticsFEM_All。物理、材料、网格、组装、求解、后处理均由 API 内部按 FemType 自动完成;第 17–22 行及注释代码为历史遗留,理解架构时可忽略。