306 lines
11 KiB
Markdown
306 lines
11 KiB
Markdown
---
|
||
name: 3D光学FEM完整实现
|
||
overview: 基于现有2D C++ OpticsFEM代码框架和MATLAB 3D参考实现,修复已有3D代码bug并补全所有缺失模块,输出一个商用级别的三维C++光学有限元程序(含本征频率、本征模式、散射三大问题类型),同时产出完整的API定义文档和示例JSON文件。
|
||
todos:
|
||
- id: fix-3d-bugs
|
||
content: 修复3D Jacobian矩阵、材料域查询、invMur等关键Bug
|
||
status: pending
|
||
- id: mesh-3d-reader
|
||
content: 实现Mesh_3D::GetMesh() JSON格式3D网格读取器
|
||
status: pending
|
||
- id: eigenfreq-3d
|
||
content: 完善3D本征频率:PEC/PBC边界处理、Run()、Post()
|
||
status: pending
|
||
- id: eigenmode-3d
|
||
content: 新增3D本征模式类(OpticsFEM_3D_EigenMode)完整实现
|
||
status: pending
|
||
- id: scatter-3d-sbc
|
||
content: 实现3D SBC散射边界积分(参考MATLAB assembly_out/inc)
|
||
status: pending
|
||
- id: scatter-3d-bc
|
||
content: 实现3D PEC/PBC/PML/BELE/MAG/SCD/MPD/EPD边界和激励
|
||
status: pending
|
||
- id: scatter-3d-run-post
|
||
content: 实现3D Scatter的Run()和Post()(电场插值+输出)
|
||
status: pending
|
||
- id: api-3d-routing
|
||
content: 扩展FEM_Interface增加3D路由和JSON参数解析
|
||
status: pending
|
||
- id: post-3d
|
||
content: 实现3D后处理:边DOF到顶点电场插值、功率计算、文件输出
|
||
status: pending
|
||
- id: second-order
|
||
content: 实现二阶Nedelec基函数(20 DOF/四面体)和对应组装
|
||
status: pending
|
||
- id: api-doc-json
|
||
content: 编写API定义文档和3个问题类型的示例JSON文件
|
||
status: pending
|
||
- id: validation
|
||
content: 与MATLAB 3D结果对比验证,修正数值问题
|
||
status: pending
|
||
isProject: false
|
||
---
|
||
|
||
# 三维C++光学有限元完整实现方案
|
||
|
||
## 一、现状分析
|
||
|
||
### 已有基础(可复用)
|
||
|
||
- 2D完整程序:EigenMode / EigenFreq / Scatter,含完整API、JSON输入、后处理输出
|
||
- 3D类骨架已定义:`OpticsFEM_3D_EigenFreq`、`OpticsFEM_3D_Scatter`、`OpticsFEM_3D_Scatter2`([Assemble_Base.h](opticsfem-master/kernel/Assemble_Base.h) L157-261)
|
||
- 3D网格数据结构:`Mesh_3D` 支持四面体+棱柱([Mesh_Base.h](opticsfem-master/mesh/Mesh_Base.h) L61-128)
|
||
- 3D基函数:一阶Nedelec四面体(6 DOF)和棱柱(9 DOF)已实现([BF_Tetrahedron.cpp](opticsfem-master/function/BF_Tetrahedron.cpp)、[BF_Prism.cpp](opticsfem-master/function/BF_Prism.cpp))
|
||
- 3D体积方程组装:EigenFreq和Scatter的WaveEquation已实现([Assemble_EigenFreq_Equation.cpp](opticsfem-master/kernel/Assemble_EigenFreq_Equation.cpp) L229-345、[Assemble_Scatter_Equation.cpp](opticsfem-master/kernel/Assemble_Scatter_Equation.cpp) L284-573)
|
||
- 3D高斯积分:四面体和棱柱积分点已有
|
||
|
||
### 必须修复的Bug
|
||
|
||
1. **Jacobian矩阵错误**:3D EigenFreq/Scatter的Jac计算用了2D模式(z分量硬编码0/1),应为完整3x3:
|
||
|
||
```cpp
|
||
// 当前错误写法 (Assemble_EigenFreq_Equation.cpp L269-271):
|
||
Jac(0, 2) = 0.; Jac(1, 2) = 0.; Jac(2, 2) = 1.;
|
||
|
||
// 正确写法(参考MATLAB):
|
||
Jac(0, 0) = vertex[0](0)-vertex[3](0); Jac(0, 1) = vertex[0](1)-vertex[3](1); Jac(0, 2) = vertex[0](2)-vertex[3](2);
|
||
Jac(1, 0) = vertex[1](0)-vertex[3](0); Jac(1, 1) = vertex[1](1)-vertex[3](1); Jac(1, 2) = vertex[1](2)-vertex[3](2);
|
||
Jac(2, 0) = vertex[2](0)-vertex[3](0); Jac(2, 1) = vertex[2](1)-vertex[3](1); Jac(2, 2) = vertex[2](2)-vertex[3](2);
|
||
```
|
||
|
||
1. **材料域查询错误**:3D组装中调用 `GetDomainOfTri(n)` 应改为 `GetDomainOfTet(n)`
|
||
2. **EigenFreq中 `GetEpsr` 误用为 `invMur`**:L291 `invMur = GetEpsr(domain).inverse()` 应为 `GetMur(domain).inverse()`
|
||
|
||
### 需要新增的模块
|
||
|
||
- 3D网格文件读取器(JSON格式)
|
||
- 3D EigenMode(本征模式/有效折射率)
|
||
- 3D SBC散射边界组装
|
||
- 3D PEC/PBC/PML边界条件
|
||
- 3D BELE/MAG/SCD/MPD/EPD激励源
|
||
- 3D Port端口边界
|
||
- 3D求解器集成(Run方法)
|
||
- 3D后处理(电场插值、输出)
|
||
- 3D API路由和JSON接口
|
||
- 二阶Nedelec基函数(可选增强)
|
||
|
||
---
|
||
|
||
## 二、架构设计
|
||
|
||
### 整体架构(对标2D,扩展到3D)
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph API [API层]
|
||
APIEntry["OpticsFEM_API::OpticsFEM_All()"]
|
||
JSONParser["JSON解析"]
|
||
end
|
||
|
||
subgraph FEM3D [3D FEM核心]
|
||
EM3D["OpticsFEM_3D_EigenMode"]
|
||
EF3D["OpticsFEM_3D_EigenFreq"]
|
||
SC3D["OpticsFEM_3D_Scatter"]
|
||
end
|
||
|
||
subgraph Modules [功能模块]
|
||
Mesh3D["Mesh_3D\n四面体+棱柱"]
|
||
Mat["MaterialLib\n各向同性/n-k/各向异性"]
|
||
Phy["Phy_WaveOpticsModel\nPEC/PMC/PBC/SBC/PML/Port"]
|
||
BF["BF 基函数\n一阶/二阶Nedelec"]
|
||
Gauss["Gauss积分\n四面体/三角形/棱柱"]
|
||
end
|
||
|
||
subgraph Solver [求解器]
|
||
EigenSolver["Solver_EigenMode\nSolver_EigenFreq"]
|
||
LinearSolver["Solver_LdaDom"]
|
||
end
|
||
|
||
subgraph Post [后处理]
|
||
Post3DEF["Post_3D_EigenFreq"]
|
||
Post3DEM["Post_3D_EigenMode"]
|
||
Post3DSC["Post_3D_Scatter"]
|
||
end
|
||
|
||
APIEntry --> JSONParser
|
||
JSONParser --> FEM3D
|
||
FEM3D --> Modules
|
||
FEM3D --> Solver
|
||
FEM3D --> Post
|
||
```
|
||
|
||
|
||
|
||
### 3D DOF编号方案
|
||
|
||
- **一阶Nedelec**:DOF = NbrEdge(每条边1个DOF)
|
||
- **二阶Nedelec**(后续扩展):DOF = 2*NbrEdge + 2*NbrFace
|
||
- 无顶点DOF(纯矢量FEM,区别于2D的Lagrange+Nedelec混合)
|
||
|
||
### 3D网格JSON格式设计
|
||
|
||
```json
|
||
{
|
||
"NbrVertex": 100,
|
||
"Vertex": [[x1,y1,z1], [x2,y2,z2], ...],
|
||
"NbrEdge": 500,
|
||
"Edge": [[v1,v2], ...],
|
||
"NbrTet": 300,
|
||
"Tet": [[v1,v2,v3,v4], ...],
|
||
"EdgeOfTet": [[e1,e2,e3,e4,e5,e6], ...],
|
||
"DomainOfTet": [1, 2, ...],
|
||
"NbrTri": 200,
|
||
"Tri": [[v1,v2,v3], ...],
|
||
"DomainOfTri": [1, 2, ...],
|
||
"ConnOfTri": [[meshType, tetIdx, faceIdx], ...],
|
||
"NormOfFace": [[nx,ny,nz], ...],
|
||
"CopyOfEdges": [[src, dst], ...],
|
||
"FaceOfTet": [[f1,f2,f3,f4], ...]
|
||
}
|
||
```
|
||
|
||
### 3D FEM设置JSON格式设计
|
||
|
||
```json
|
||
{
|
||
"FemType": 4,
|
||
"Dimension": 3,
|
||
"NbrDomain": 3,
|
||
"matType": [0, 0, 1],
|
||
"epsilonrR": [1.0, 2.25, 0], "epsilonrI": [0, 0, 0],
|
||
"murR": [1.0, 1.0, 0], "murI": [0, 0, 0],
|
||
"n": [0, 0, 1.5], "k": [0, 0, 0],
|
||
"sigma": [0, 0, 0],
|
||
"NbrBoundary": 3,
|
||
"BoundaryFlag": [1, 0, 2],
|
||
"lambda": 1.55e-6,
|
||
"MeshFile": "mesh_3d.json",
|
||
"OutFile": "result/",
|
||
"NbrMode": 5,
|
||
"searchType": 0,
|
||
"searchValue": 1.45,
|
||
"solverType": 0,
|
||
"ElementOrder": 1,
|
||
"sbc": { "SBCType": 0, "Index": [2], "E0x": "1", "E0y": "0", "E0z": "0", "kx": "0", "ky": "0", "kz": "k0" },
|
||
"pbc": { "srcIndex": [3], "dstIndex": [4], "phiR": [1.0], "phiI": [0.0] },
|
||
"pml": { "index": [5], "PMLType": 0, "PMLData": [0,1e-6,0,1e-6,0,1e-6] }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 三、分阶段实施计划
|
||
|
||
### 阶段1:修复Bug + 基础设施(1-2天)
|
||
|
||
- 修复3D Jacobian矩阵(EigenFreq和Scatter的WaveEquation)
|
||
- 修复材料域查询(`GetDomainOfTri` -> `GetDomainOfTet`)
|
||
- 修复 `invMur = GetEpsr().inverse()` -> `GetMur().inverse()`
|
||
- 实现 `Mesh_3D::GetMesh()` 从JSON读取3D网格
|
||
- 补全3D EigenFreq稀疏矩阵尺寸初始化
|
||
|
||
### 阶段2:3D本征频率完善(2-3天)
|
||
|
||
- 完善 `OpticsFEM_3D_EigenFreq::Assemble()` -- PEC/PBC约束矩阵P构建
|
||
- 实现 `OpticsFEM_3D_EigenFreq::Run()` -- 调用本征值求解器
|
||
- 实现 `Post_3D_EigenFreq` -- 3D电场插值(边DOF到顶点)、输出
|
||
|
||
### 阶段3:3D本征模式新增(2-3天)
|
||
|
||
- 新增 `OpticsFEM_3D_EigenMode` 类(类比2D EigenMode,但纯矢量FEM)
|
||
- 实现3D本征模式方程组装(A-lambda*B形式)
|
||
- 实现Run和Post
|
||
- 支持搜索有效折射率
|
||
|
||
### 阶段4:3D散射问题完善(3-5天)
|
||
|
||
- 实现 `OpticsFEM_3D_Scatter::Assemble_SBC()` -- 参考MATLAB的 `assembly_out.m` 和 `assembly_inc.m`
|
||
- 三角面上的边界积分:`ik0*n * N_i . (n_hat x (n_hat x N_j))`
|
||
- 入射场右端向量
|
||
- 实现 `OpticsFEM_3D_Scatter::Assemble_PEC_ELE()` -- 构建约束矩阵P
|
||
- 实现 `OpticsFEM_3D_Scatter::Assemble_PBC()` -- 参考MATLAB的 `assembly_pbc_double.m`
|
||
- 实现BELE/MAG/SCD/MPD/EPD激励
|
||
- 实现PML(3D各向异性坐标拉伸)
|
||
- 实现 `Run()` 和 `Post()`
|
||
|
||
### 阶段5:API接口+JSON(1-2天)
|
||
|
||
- 扩展 `FEM_Interface.cpp` 增加3D路由(FemType=4/5/6 对应3D EigenMode/EigenFreq/Scatter,或用 Dimension 字段区分)
|
||
- 扩展 `Test_ReadData.cpp` 支持3D特有参数(ElementOrder、3D PML数据等)
|
||
- 编写3D网格JSON格式规范
|
||
- 编写3D FEM设置JSON格式规范
|
||
- 提供3D示例JSON(本征频率、本征模式、散射各一个)
|
||
|
||
### 阶段6:商用增强(3-5天)
|
||
|
||
- 二阶Nedelec基函数实现(20 DOF/四面体:12边+8面)
|
||
- Port端口边界条件(2D本征模式 + 3D耦合)
|
||
- 性能优化:稀疏矩阵预分配、OpenMP并行组装
|
||
- 错误处理与日志
|
||
- 内存管理改进(替换裸指针为智能指针/RAII)
|
||
- 波长扫描支持
|
||
|
||
### 阶段7:验证与文档(2-3天)
|
||
|
||
- 与MATLAB结果对比验证(本征频率、散射场)
|
||
- API定义文档输出(Markdown格式)
|
||
- 示例JSON文件(覆盖全部问题类型和边界条件组合)
|
||
- README更新
|
||
|
||
---
|
||
|
||
## 四、关键技术要点
|
||
|
||
### 3D SBC边界积分(参考MATLAB assembly_out.m)
|
||
|
||
- 在三角面上积分,使用2D Gauss积分点
|
||
- 基函数需要从四面体边DOF映射到三角面上
|
||
- 通过 `ConnOfTri` 找到所属四面体和面号
|
||
- 面上的Nedelec基函数通过参考坐标映射
|
||
|
||
### 3D PBC周期边界(参考MATLAB assembly_pbc_double.m)
|
||
|
||
- 匹配源/目标面上的边
|
||
- 约束矩阵P:`P(dst_edge, src_edge) = exp(i*k*d)`
|
||
- 删除目标面的DOF列
|
||
- 角域边的特殊处理
|
||
|
||
### 3D电场后处理(参考MATLAB get_ele.m)
|
||
|
||
- 对每个边界三角面,通过 `ConnOfTri` 定位到四面体
|
||
- 在四面体顶点处用参考坐标计算Nedelec基函数值
|
||
- E = sum(N_j * x_j),其中x_j为边DOF解向量
|
||
|
||
---
|
||
|
||
## 五、文件修改/新增清单
|
||
|
||
### 修改文件
|
||
|
||
- [Assemble_EigenFreq_Equation.cpp](opticsfem-master/kernel/Assemble_EigenFreq_Equation.cpp) -- 修Jacobian和材料bug
|
||
- [Assemble_Scatter_Equation.cpp](opticsfem-master/kernel/Assemble_Scatter_Equation.cpp) -- 修Jacobian和材料bug
|
||
- [Assemble_kernel.cpp](opticsfem-master/kernel/Assemble_kernel.cpp) -- 补全3D EigenFreq/Scatter的Run/Post
|
||
- [Assemble_Scatter_3D_Boundary.cpp](opticsfem-master/kernel/Assemble_Scatter_3D_Boundary.cpp) -- 实现SBC/PEC_ELE
|
||
- [Assemble_Base.h](opticsfem-master/kernel/Assemble_Base.h) -- 新增3D EigenMode类
|
||
- [FEM_Interface.cpp](opticsfem-master/Interface/FEM_Interface.cpp) -- 3D路由
|
||
- [Mesh_Base.h](opticsfem-master/mesh/Mesh_Base.h) -- 补全Mesh_3D的GetMesh声明
|
||
- [Post_Base.h](opticsfem-master/post/Post_Base.h) -- 补全3D后处理类
|
||
- [Test_ReadData.cpp](opticsfem-master/test/Test_ReadData.cpp) -- 3D参数解析
|
||
- [CMakeLists.txt](opticsfem-master/CMakeLists.txt) -- 新增源文件
|
||
|
||
### 新增文件
|
||
|
||
- `opticsfem-master/mesh/Mesh_3D_Interface.cpp` -- 3D JSON网格读取
|
||
- `opticsfem-master/kernel/Assemble_EigenMode_3D_Equation.cpp` -- 3D本征模式体积组装
|
||
- `opticsfem-master/kernel/Assemble_EigenMode_3D_Boundary.cpp` -- 3D本征模式边界
|
||
- `opticsfem-master/kernel/Assemble_EigenFreq_3D_Boundary.cpp` -- 3D本征频率边界
|
||
- `opticsfem-master/post/Post_3D_CalElectric.cpp` -- 3D电场计算
|
||
- `opticsfem-master/post/Post_3D_Output.cpp` -- 3D结果输出
|
||
- `opticsfem-master/function/BF_Tetrahedron_2nd.cpp` -- 二阶基函数(阶段6)
|
||
- `docs/API_3D_FEM.md` -- API定义文档
|
||
- `examples/eigenfreq_3d.json` -- 本征频率示例
|
||
- `examples/eigenmode_3d.json` -- 本征模式示例
|
||
- `examples/scatter_3d.json` -- 散射示例
|
||
- `examples/mesh_3d.json` -- 3D网格示例
|
||
|