Add 3D eigen frequency (FemType=5) and update docs for scatter+eigen workflows.
Support OpticsFEM_3D_EigenFreq assembly with A/B matrix export, add eigen3d.json, and document scat3D/eigen3D build layout alongside FemType=4 scattering. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
54279fe532
commit
db3ea489fe
|
|
@ -1,4 +1,11 @@
|
||||||
build/
|
build/
|
||||||
|
build1/
|
||||||
|
scat3D/
|
||||||
|
eigen3D/
|
||||||
|
3D opticsfem-master/scat3D/
|
||||||
|
3D opticsfem-master/eigen3D/
|
||||||
|
3D opticsfem-master/build/
|
||||||
|
3D opticsfem-master/build1/
|
||||||
*.exe
|
*.exe
|
||||||
*.obj
|
*.obj
|
||||||
*.pdb
|
*.pdb
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,24 @@
|
||||||
################################################################################
|
# CMake / VS 本地构建目录(勿提交)
|
||||||
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
|
/build/
|
||||||
################################################################################
|
/build1/
|
||||||
|
/scat3D/
|
||||||
|
/eigen3D/
|
||||||
|
/out/
|
||||||
|
|
||||||
/.vs
|
/.vs
|
||||||
/out/build/x64-debug
|
/out/build/x64-debug
|
||||||
/build/x64-Debug
|
/build/x64-Debug
|
||||||
|
|
||||||
|
# 编译产物
|
||||||
|
*.exe
|
||||||
|
*.obj
|
||||||
|
*.pdb
|
||||||
|
*.lib
|
||||||
|
*.exp
|
||||||
|
*.ilk
|
||||||
|
*.tlog
|
||||||
|
*.lastbuildstate
|
||||||
|
*.recipe
|
||||||
|
|
||||||
|
# 大型运行输出(本地验证用)
|
||||||
|
**/OutFile/
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,27 @@ int OpticsFEM_API::OpticsFEM_All(OpticsFEMData data)
|
||||||
fem.Post(outFile);
|
fem.Post(outFile);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
else if (FemType == 5)
|
||||||
|
{
|
||||||
|
Mesh_3D mesh3d;
|
||||||
|
OpticsFEM_3D_EigenFreq fem;
|
||||||
|
Solver_EigenFreq solver;
|
||||||
|
Post_3D_EigenFreq post;
|
||||||
|
|
||||||
|
solver.GetSolver(str);
|
||||||
|
mesh3d.GetMesh(meshFile, str);
|
||||||
|
|
||||||
|
fem.GetMaterial(&matLab);
|
||||||
|
fem.GetMesh(&mesh3d);
|
||||||
|
fem.GetPhy(&phy);
|
||||||
|
fem.GetSolver(&solver);
|
||||||
|
fem.GetPost(&post);
|
||||||
|
|
||||||
|
fem.Assemble();
|
||||||
|
string outFile = js.at("OutFile");
|
||||||
|
fem.Test_OutputMatrix(outFile);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "err" << std::endl;
|
std::cout << "err" << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
| 项目 | 说明 |
|
| 项目 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 文档版本 | v2.0 |
|
| 文档版本 | v3.0 |
|
||||||
| 编制日期 | 2026-06-08 |
|
| 编制日期 | 2026-06-09 |
|
||||||
| 适用代码 | **`3D opticsfem-master/`**(三维版,主算例 FemType=4) |
|
| 适用代码 | **`3D opticsfem-master/`**(三维版,主算例 FemType=4 散射 + FemType=5 本征频率) |
|
||||||
| 适用平台 | Windows x64,**Visual Studio 2026(18)**,MSVC |
|
| 适用平台 | Windows x64,**Visual Studio 2026(18)**,MSVC |
|
||||||
| 关联文档 | `compare/README.md`(COMSOL 对比)、上级目录 2D 版 `opticsfem-master/` |
|
| 关联文档 | `compare/README.md`(COMSOL 对比)、上级目录 2D 版 `opticsfem-master/` |
|
||||||
|
|
||||||
|
|
@ -31,17 +31,20 @@
|
||||||
|
|
||||||
**OpticsFEM3D** 是一套基于 C++ 实现的**三维矢量有限元(FEM)光学电磁仿真内核**。程序采用 **一阶 Nedelec 边元** 离散麦克斯韦方程,通过 JSON 配置物理模型、材料与边界条件,通过 `.dat` 文本文件读入四面体网格,计算结果以文本文件输出。
|
**OpticsFEM3D** 是一套基于 C++ 实现的**三维矢量有限元(FEM)光学电磁仿真内核**。程序采用 **一阶 Nedelec 边元** 离散麦克斯韦方程,通过 JSON 配置物理模型、材料与边界条件,通过 `.dat` 文本文件读入四面体网格,计算结果以文本文件输出。
|
||||||
|
|
||||||
> **当前主算例**:`FemType = 4`,三维 SBC 散射,配置文件 `sbc3d.json`,网格 `SBCmesh.dat`。
|
> **当前三维主算例**:
|
||||||
|
> - **FemType = 4**:三维 SBC 散射,`sbc3d.json`,网格 `SBCmesh.dat`,完整求解流程。
|
||||||
|
> - **FemType = 5**:三维本征频率,`eigen3d.json`,同一网格,当前完成 A/B 矩阵组装与导出。
|
||||||
|
|
||||||
### 1.2 支持的问题类型
|
### 1.2 支持的问题类型
|
||||||
|
|
||||||
| FemType | 问题类型 | 驱动类 | 网格 | 求解器 | 后处理 |
|
| FemType | 问题类型 | 驱动类 | 网格 | 求解器 | 后处理 | 状态 |
|
||||||
|---------|----------|--------|------|--------|--------|
|
|---------|----------|--------|------|--------|--------|------|
|
||||||
| 0 | 本征模式(2D 遗留) | `OpticsFEM_2D_EigenMode` | `Mesh_2D` | `Solver_EigenMode` | `Post_2D_EigenMode` |
|
| 0 | 本征模式(2D 遗留) | `OpticsFEM_2D_EigenMode` | `Mesh_2D` | `Solver_EigenMode` | `Post_2D_EigenMode` | 遗留 |
|
||||||
| 1 | 本征频率(2D 遗留) | `OpticsFEM_2D_EigenFreq` | `Mesh_2D` | `Solver_EigenFreq` | `Post_2D_EigenFreq` |
|
| 1 | 本征频率(2D 遗留) | `OpticsFEM_2D_EigenFreq` | `Mesh_2D` | `Solver_EigenFreq` | `Post_2D_EigenFreq` | 遗留 |
|
||||||
| 2 | 2D 散射(按波长 λ) | `OpticsFEM_2D_Scatter` | `Mesh_2D` | `Solver_LdaDom` | `Post_2D_Scatter` |
|
| 2 | 2D 散射(按波长 λ) | `OpticsFEM_2D_Scatter` | `Mesh_2D` | `Solver_LdaDom` | `Post_2D_Scatter` | 遗留 |
|
||||||
| 3 | 2D 散射(按频率 f) | `OpticsFEM_2D_Scatter` | `Mesh_2D` | `Solver_LdaDom` | `Post_2D_Scatter` |
|
| 3 | 2D 散射(按频率 f) | `OpticsFEM_2D_Scatter` | `Mesh_2D` | `Solver_LdaDom` | `Post_2D_Scatter` | 遗留 |
|
||||||
| **4** | **3D 一阶散射(SBC,按 λ)** | **`OpticsFEM_3D_Scatter`** | **`Mesh_3D`** | **`Solver_LdaDom`** | **`Post_3D_Scatter`** |
|
| **4** | **3D 一阶散射(SBC,按 λ)** | **`OpticsFEM_3D_Scatter`** | **`Mesh_3D`** | **`Solver_LdaDom`** | **`Post_3D_Scatter`** | **完整** |
|
||||||
|
| **5** | **3D 一阶本征频率** | **`OpticsFEM_3D_EigenFreq`** | **`Mesh_3D`** | **`Solver_EigenFreq`** | **`Post_3D_EigenFreq`** | **组装+矩阵导出** |
|
||||||
|
|
||||||
### 1.3 设计原则
|
### 1.3 设计原则
|
||||||
|
|
||||||
|
|
@ -62,7 +65,8 @@
|
||||||
|
|
||||||
| FemType | 依赖 | 说明 |
|
| FemType | 依赖 | 说明 |
|
||||||
|---------|------|------|
|
|---------|------|------|
|
||||||
| **4(3D 散射,推荐)** | `complex/complexsolver.exe` | **CMake 会从 `complex/complexsolver.cpp` 自动编译**(Eigen SparseLU),无需 PETSc |
|
| **4(3D 散射)** | `complex/complexsolver.exe` | **CMake 自动编译**(Eigen SparseLU),求解 **A·x=b** |
|
||||||
|
| **5(3D 本征频率)** | 暂无(矩阵导出阶段) | 当前仅 `Assemble` + `Test_OutputMatrix`;完整求解需 `real_solver/`、`complex_solver/` |
|
||||||
| 0–3(2D 遗留) | `complex/complexsolver.exe` 等 | 本征问题另需 `real_solver/`、`complex_solver/` |
|
| 0–3(2D 遗留) | `complex/complexsolver.exe` 等 | 本征问题另需 `real_solver/`、`complex_solver/` |
|
||||||
|
|
||||||
散射求解器通过**临时 `.dat` 文件**与主程序交换 CSR 格式矩阵,由 `system()` 启动。
|
散射求解器通过**临时 `.dat` 文件**与主程序交换 CSR 格式矩阵,由 `system()` 启动。
|
||||||
|
|
@ -75,8 +79,9 @@
|
||||||
3D opticsfem-master/
|
3D opticsfem-master/
|
||||||
├── CMakeLists.txt # CMake:OpticsFEM + complexsolver
|
├── CMakeLists.txt # CMake:OpticsFEM + complexsolver
|
||||||
├── CMakeSettings.json # VS CMake 设置(x64-Release)
|
├── CMakeSettings.json # VS CMake 设置(x64-Release)
|
||||||
├── sbc3d.json # ★ FemType=4 默认算例配置
|
├── sbc3d.json # ★ FemType=4 散射算例配置
|
||||||
├── SBCmesh.dat # ★ 三维四面体网格
|
├── eigen3d.json # ★ FemType=5 本征频率算例配置
|
||||||
|
├── SBCmesh.dat # ★ 三维四面体网格(散射与本征共用)
|
||||||
├── Interface/ # 对外 API(FemType 路由)
|
├── Interface/ # 对外 API(FemType 路由)
|
||||||
├── test/ # Test_Main.cpp 入口、JSON 解析
|
├── test/ # Test_Main.cpp 入口、JSON 解析
|
||||||
├── complex/ # complexsolver 源码(Eigen 稀疏求解)
|
├── complex/ # complexsolver 源码(Eigen 稀疏求解)
|
||||||
|
|
@ -84,18 +89,19 @@
|
||||||
├── phy/ # 物理模型与边界条件
|
├── phy/ # 物理模型与边界条件
|
||||||
├── material/ # 材料库
|
├── material/ # 材料库
|
||||||
├── mesh/ # Mesh_2D + Mesh_3D 读写
|
├── mesh/ # Mesh_2D + Mesh_3D 读写
|
||||||
├── kernel/ # 2D/3D 组装(含 Assemble_Scatter_3D_Boundary)
|
├── kernel/ # 2D/3D 组装(散射 SBC + 本征 A/B)
|
||||||
├── solver/ # 数值求解器接口
|
├── solver/ # 数值求解器接口
|
||||||
├── post/ # Post_3D_Scatter 场重构与输出
|
├── post/ # Post_3D_Scatter / Post_3D_EigenFreq
|
||||||
├── function/ # Nedelec 基函数与高斯积分
|
├── function/ # Nedelec 基函数与高斯积分
|
||||||
├── common/ # 公共常量
|
├── common/ # 公共常量
|
||||||
├── parser/ # 表达式解析器
|
├── parser/ # 表达式解析器
|
||||||
├── nlohmann/ # JSON 库
|
├── nlohmann/ # JSON 库
|
||||||
├── Eigen/ # 线性代数库
|
├── Eigen/ # 线性代数库
|
||||||
└── build/ # CMake 构建产物(本地生成,不上传)
|
├── scat3D/ # 推荐:FemType=4 本地 CMake 构建(不上传)
|
||||||
|
└── eigen3D/ # 推荐:FemType=5 本地 CMake 构建(不上传)
|
||||||
```
|
```
|
||||||
|
|
||||||
**源码统计(不含 build/):**
|
**源码统计(不含 scat3D/、eigen3D/、build/ 等构建目录):**
|
||||||
|
|
||||||
| 类别 | 数量 | 说明 |
|
| 类别 | 数量 | 说明 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
|
|
@ -132,7 +138,7 @@ public:
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
**返回值:** 0 = FemType 无法识别;1 = 本征模式;2 = 本征频率;3 = 2D 散射;**4 = 3D 散射完成**。
|
**返回值:** 0 = FemType 无法识别;1 = 2D 本征模式;2 = 2D 本征频率;3 = 2D 散射;**4 = 3D 散射完成**;**5 = 3D 本征频率矩阵导出完成**。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -140,7 +146,7 @@ public:
|
||||||
|
|
||||||
| 文件 | 说明 |
|
| 文件 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| `Test_Main.cpp` | 进程 `main()` 入口:从 `bele.json` 读取整行 JSON,封装为 `OpticsFEMData`,调用 `OpticsFEM_All()` |
|
| `Test_Main.cpp` | 进程 `main()` 入口:从 JSON 文件(默认 `sbc3d.json`)读取整行 JSON,封装为 `OpticsFEMData`,调用 `OpticsFEM_All()`。本征算例改为 `eigen3d.json` 后须重新编译 |
|
||||||
| `Test_ReadData.cpp` | 实现 `Phy_WaveOpticsModel::Test_ReadData()` 与 `MaterialLib::Test_ReadData()`,将 JSON 字段映射到内存对象 |
|
| `Test_ReadData.cpp` | 实现 `Phy_WaveOpticsModel::Test_ReadData()` 与 `MaterialLib::Test_ReadData()`,将 JSON 字段映射到内存对象 |
|
||||||
| `Test_OutputData.cpp` | 调试用途:将组装后的稀疏矩阵 A/B/P 输出到文本文件 |
|
| `Test_OutputData.cpp` | 调试用途:将组装后的稀疏矩阵 A/B/P 输出到文本文件 |
|
||||||
| `interfaceClass.h` | 遗留的 `FemInput` 结构体,记录预期配置字段(当前 JSON 路径未直接使用) |
|
| `interfaceClass.h` | 遗留的 `FemInput` 结构体,记录预期配置字段(当前 JSON 路径未直接使用) |
|
||||||
|
|
@ -204,7 +210,7 @@ public:
|
||||||
| `Mesh_Interface.cpp` | `Mesh_2D::GetMesh()`:顺序解析 `.dat` 网格文件 |
|
| `Mesh_Interface.cpp` | `Mesh_2D::GetMesh()`:顺序解析 `.dat` 网格文件 |
|
||||||
| `Mesh_Find.cpp` | 域/PBC 索引查找:边/节点所属域、PBC 源/目标映射 |
|
| `Mesh_Find.cpp` | 域/PBC 索引查找:边/节点所属域、PBC 源/目标映射 |
|
||||||
|
|
||||||
**Mesh_3D** 已在头文件中声明,但 `OpticsFEM_All()` 当前未接入 3D 求解分支。
|
**Mesh_3D** 已接入 `FemType=4`(散射)与 `FemType=5`(本征频率),读入 `SBCmesh.dat` 等三维四面体网格。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -350,7 +356,8 @@ FEM_Interface.cpp ──► Phy / Material / Mesh(读入)
|
||||||
├── FemType 0 ──► OpticsFEM_2D_EigenMode ──► Solver_EigenMode ──► Post_2D_EigenMode
|
├── FemType 0 ──► OpticsFEM_2D_EigenMode ──► Solver_EigenMode ──► Post_2D_EigenMode
|
||||||
├── FemType 1 ──► OpticsFEM_2D_EigenFreq ──► Solver_EigenFreq ──► Post_2D_EigenFreq
|
├── FemType 1 ──► OpticsFEM_2D_EigenFreq ──► Solver_EigenFreq ──► Post_2D_EigenFreq
|
||||||
├── FemType 2/3 ► OpticsFEM_2D_Scatter ──► Solver_LdaDom ──► Post_2D_Scatter
|
├── FemType 2/3 ► OpticsFEM_2D_Scatter ──► Solver_LdaDom ──► Post_2D_Scatter
|
||||||
└── FemType 4 ──► OpticsFEM_3D_Scatter ──► Solver_LdaDom ──► Post_3D_Scatter
|
├── FemType 4 ──► OpticsFEM_3D_Scatter ──► Solver_LdaDom ──► Post_3D_Scatter
|
||||||
|
└── FemType 5 ──► OpticsFEM_3D_EigenFreq ──► Solver_EigenFreq ──► Post_3D_EigenFreq
|
||||||
│
|
│
|
||||||
└── Mesh_3D ← SBCmesh.dat
|
└── Mesh_3D ← SBCmesh.dat
|
||||||
│
|
│
|
||||||
|
|
@ -375,6 +382,22 @@ Test_Main.cpp
|
||||||
└─ Post("OutFile") → Ex, Ey, Ez, normE
|
└─ Post("OutFile") → Ex, Ey, Ez, normE
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 4.2b 完整调用序列(FemType=5,三维本征频率)
|
||||||
|
|
||||||
|
```
|
||||||
|
Test_Main.cpp
|
||||||
|
└─ 读取 eigen3d.json
|
||||||
|
└─ OpticsFEM_All(data)
|
||||||
|
└─ [FemType == 5]
|
||||||
|
├─ Phy / Material ← JSON(PMC/PEC/PBC 边界)
|
||||||
|
├─ Mesh_3D::GetMesh("SBCmesh.dat")
|
||||||
|
├─ OpticsFEM_3D_EigenFreq::Assemble()
|
||||||
|
│ ├─ Assemble_WaveEquation() A=curl-curl, B=ε·质量
|
||||||
|
│ └─ Assemble_PEC_PBC() 边界约束矩阵 P
|
||||||
|
└─ Test_OutputMatrix("OutFile") → Ai/Aj/Av, Bi/Bj/Bv
|
||||||
|
(Run/Post 待接入:eigs 求 λ,再重构 Ex/Ey/Ez/freq)
|
||||||
|
```
|
||||||
|
|
||||||
### 4.3 完整调用序列(FemType=2,二维散射,遗留)
|
### 4.3 完整调用序列(FemType=2,二维散射,遗留)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -403,7 +426,7 @@ main()
|
||||||
|
|
||||||
### 4.4 数据流
|
### 4.4 数据流
|
||||||
|
|
||||||
**FemType = 4(当前主算例):**
|
**FemType = 4(三维散射):**
|
||||||
|
|
||||||
```
|
```
|
||||||
sbc3d.json ──► Phy(sbc 边界/入射场)
|
sbc3d.json ──► Phy(sbc 边界/入射场)
|
||||||
|
|
@ -414,6 +437,19 @@ SBCmesh.dat ──► Mesh_3D(四面体 + 三角边界)
|
||||||
──► Post ──► OutFile/Ex, Ey, Ez, normE
|
──► Post ──► OutFile/Ex, Ey, Ez, normE
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**FemType = 5(三维本征频率):**
|
||||||
|
|
||||||
|
```
|
||||||
|
eigen3d.json ──► Phy(PMC/PEC/PBC)
|
||||||
|
──► MaterialLib
|
||||||
|
SBCmesh.dat ──► Mesh_3D
|
||||||
|
──► Assemble ──► 稀疏矩阵 A(刚度), B(质量)
|
||||||
|
──► Test_OutputMatrix ──► OutFile/Ai,Aj,Av,Bi,Bj,Bv
|
||||||
|
(后续 Run: eigs(A,B) → λ=k₀²;Post → freq, Ex/Ey/Ez)
|
||||||
|
```
|
||||||
|
|
||||||
|
**物理对应关系:** 散射体积分 `A_scatter ≈ A_eigen − k₀²·B_eigen`(同一网格与 Nedelec 基函数下)。
|
||||||
|
|
||||||
**FemType = 2(2D 遗留):**
|
**FemType = 2(2D 遗留):**
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -441,26 +477,31 @@ project_3.dat ──► Mesh_2D(网格拓扑)
|
||||||
|
|
||||||
### 5.2 编译步骤
|
### 5.2 编译步骤
|
||||||
|
|
||||||
|
推荐使用**两个独立构建目录**,避免散射与本征互相覆盖 exe 和 OutFile:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# 若 cmake 不在 PATH 中,追加 VS 2026 自带 CMake 路径
|
# 若 cmake 不在 PATH 中,追加 VS 2026 自带 CMake 路径
|
||||||
$env:Path += ";C:\Program Files\Microsoft Visual Studio\18\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin"
|
$env:Path += ";C:\Program Files\Microsoft Visual Studio\18\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin"
|
||||||
|
|
||||||
cd "3D opticsfem-master"
|
cd "3D opticsfem-master"
|
||||||
mkdir build -Force
|
|
||||||
cd build
|
|
||||||
|
|
||||||
cmake .. -G "Visual Studio 18 2026" -A x64
|
# FemType=4 散射
|
||||||
cmake --build . --config Release
|
cmake -B scat3D -G "Visual Studio 18 2026" -A x64
|
||||||
|
cmake --build scat3D --config Release
|
||||||
|
|
||||||
|
# FemType=5 本征频率
|
||||||
|
cmake -B eigen3D -G "Visual Studio 18 2026" -A x64
|
||||||
|
cmake --build eigen3D --config Release
|
||||||
```
|
```
|
||||||
|
|
||||||
**产物路径:** `build/Release/OpticsFEM.exe`
|
|
||||||
|
|
||||||
**产物路径:**
|
**产物路径:**
|
||||||
|
|
||||||
- `build/Release/OpticsFEM.exe`
|
- `scat3D/Release/OpticsFEM.exe` + `scat3D/Release/complex/complexsolver.exe`
|
||||||
- `build/Release/complex/complexsolver.exe`(FemType=4 必需,CMake 自动编译)
|
- `eigen3D/Release/OpticsFEM.exe`
|
||||||
|
|
||||||
### 5.3 运行前准备(FemType = 4,推荐)
|
也可使用单一 `build/` 目录(见 `CMakeSettings.json`),但切换算例时需重新编译并注意 OutFile 覆盖。
|
||||||
|
|
||||||
|
### 5.3 运行前准备(FemType = 4,三维散射)
|
||||||
|
|
||||||
#### 步骤 1:指定 JSON 配置文件
|
#### 步骤 1:指定 JSON 配置文件
|
||||||
|
|
||||||
|
|
@ -470,22 +511,20 @@ cmake --build . --config Release
|
||||||
std::ifstream fd("sbc3d.json");
|
std::ifstream fd("sbc3d.json");
|
||||||
```
|
```
|
||||||
|
|
||||||
更换算例时,修改文件名或把目标 JSON 复制为 `sbc3d.json`。修改后须**重新编译**。
|
更换算例时修改文件名;修改后须**重新编译 scat3D**。
|
||||||
|
|
||||||
#### 步骤 2:部署输入文件
|
#### 步骤 2:部署输入文件
|
||||||
|
|
||||||
将 JSON 及 `MeshFile` 指定的网格文件复制到 **`build/Release/`**(与 exe 同目录):
|
将 JSON 及 `MeshFile` 指定的网格文件复制到 **`scat3D/Release/`**(与 exe 同目录):
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
Copy-Item sbc3d.json, SBCmesh.dat -Destination build\Release\
|
Copy-Item sbc3d.json, SBCmesh.dat -Destination scat3D\Release\
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 步骤 3:确认求解器
|
#### 步骤 3:确认求解器
|
||||||
|
|
||||||
FemType=4 只需:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Release/
|
scat3D/Release/
|
||||||
├── OpticsFEM.exe
|
├── OpticsFEM.exe
|
||||||
├── sbc3d.json
|
├── sbc3d.json
|
||||||
├── SBCmesh.dat
|
├── SBCmesh.dat
|
||||||
|
|
@ -496,7 +535,7 @@ Release/
|
||||||
#### 步骤 4:执行
|
#### 步骤 4:执行
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
cd build/Release
|
cd scat3D/Release
|
||||||
.\OpticsFEM.exe
|
.\OpticsFEM.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -508,6 +547,48 @@ cd build/Release
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 5.3c 运行前准备(FemType = 5,三维本征频率)
|
||||||
|
|
||||||
|
#### 步骤 1:指定 JSON 配置文件
|
||||||
|
|
||||||
|
编辑 `test/Test_Main.cpp`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::ifstream fd("eigen3d.json");
|
||||||
|
```
|
||||||
|
|
||||||
|
修改后须**重新编译 eigen3D**(可与 scat3D 并存,互不干扰)。
|
||||||
|
|
||||||
|
#### 步骤 2:部署输入文件
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Copy-Item eigen3d.json, SBCmesh.dat -Destination eigen3D\Release\
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 步骤 3:执行
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cd eigen3D/Release
|
||||||
|
.\OpticsFEM.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
控制台应打印 `OpticsFEM_All returned 5`。
|
||||||
|
|
||||||
|
#### 步骤 4:查看矩阵输出
|
||||||
|
|
||||||
|
`OutFile/` 下导出 A/B 稀疏矩阵 COO(0-based):
|
||||||
|
|
||||||
|
| 文件 | 含义 |
|
||||||
|
|------|------|
|
||||||
|
| `Ai.txt`, `Aj.txt`, `Av.txt` | 刚度矩阵 A |
|
||||||
|
| `Bi.txt`, `Bj.txt`, `Bv.txt` | 质量矩阵 B(ε 加权) |
|
||||||
|
|
||||||
|
可与 MATLAB `3D一阶本征问题2` 中 `export_ab_matrix.m` 输出对比验证。
|
||||||
|
|
||||||
|
> **当前限制**:`Run()`(广义特征值求解)与 `Post()`(场重构、freq 输出)尚未接入 `FEM_Interface.cpp` 的 FemType=5 分支。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### 5.3b 运行前准备(FemType 0–3,2D 遗留)
|
### 5.3b 运行前准备(FemType 0–3,2D 遗留)
|
||||||
|
|
||||||
#### 步骤 1:指定 JSON 配置文件
|
#### 步骤 1:指定 JSON 配置文件
|
||||||
|
|
@ -560,18 +641,26 @@ cd build/Release
|
||||||
|------|------|
|
|------|------|
|
||||||
| 更换 JSON | 修改 `Test_Main.cpp` 中 `fd.open()` 文件名,或将目标 JSON 复制为当前文件名 |
|
| 更换 JSON | 修改 `Test_Main.cpp` 中 `fd.open()` 文件名,或将目标 JSON 复制为当前文件名 |
|
||||||
| 更换网格 | 确保 JSON 中 `MeshFile` 与实际 `.dat` 文件名一致 |
|
| 更换网格 | 确保 JSON 中 `MeshFile` 与实际 `.dat` 文件名一致 |
|
||||||
| 更换问题类型 | 修改 JSON 中 `FemType`(0/1/2/3/4),程序自动路由 |
|
| 更换问题类型 | 修改 JSON 中 `FemType`(0/1/2/3/4/5),程序自动路由 |
|
||||||
|
|
||||||
### 5.5 快速验证(sbc3d 三维 SBC 算例)
|
### 5.5 快速验证(sbc3d 三维 SBC 散射)
|
||||||
|
|
||||||
1. 编译 Release(见 5.2 节)
|
1. 编译 `scat3D` Release(见 5.2 节)
|
||||||
2. 复制 `sbc3d.json`、`SBCmesh.dat` 到 `build/Release/`
|
2. 确认 `Test_Main.cpp` 读取 `sbc3d.json`,复制 `sbc3d.json`、`SBCmesh.dat` 到 `scat3D/Release/`
|
||||||
3. 确认 `sbc3d.json` 中 `"FemType": 4`
|
3. 确认 `sbc3d.json` 中 `"FemType": 4`
|
||||||
4. 运行 `OpticsFEM.exe`
|
4. 运行 `OpticsFEM.exe`
|
||||||
5. 检查 `OutFile/` 下四个场文件
|
5. 检查 `OutFile/` 下四个场文件
|
||||||
|
|
||||||
与 COMSOL 对比见 `compare/README.md`。
|
与 COMSOL 对比见 `compare/README.md`。
|
||||||
|
|
||||||
|
### 5.5b 快速验证(eigen3d 三维本征频率)
|
||||||
|
|
||||||
|
1. 编译 `eigen3D` Release,`Test_Main.cpp` 改为读取 `eigen3d.json`
|
||||||
|
2. 复制 `eigen3d.json`、`SBCmesh.dat` 到 `eigen3D/Release/`
|
||||||
|
3. 确认 `"FemType": 5`
|
||||||
|
4. 运行 `OpticsFEM.exe`,应返回 5
|
||||||
|
5. 检查 `OutFile/` 下 `Ai/Aj/Av`、`Bi/Bj/Bv` 六个文件
|
||||||
|
|
||||||
### 5.6 快速验证(bele 二维算例,遗留)
|
### 5.6 快速验证(bele 二维算例,遗留)
|
||||||
|
|
||||||
1. 从 `../测试数据集/bele/` 复制 `bele.json` 和 `project_3.dat` 到 `build/Release/`
|
1. 从 `../测试数据集/bele/` 复制 `bele.json` 和 `project_3.dat` 到 `build/Release/`
|
||||||
|
|
@ -602,7 +691,7 @@ data.test2 = 0;
|
||||||
data.data = (char*)jsonStr.data();
|
data.data = (char*)jsonStr.data();
|
||||||
|
|
||||||
int ret = OpticsFEM_API::OpticsFEM_All(data);
|
int ret = OpticsFEM_API::OpticsFEM_All(data);
|
||||||
// ret: 1=本征模式, 2=本征频率, 3=2D散射, 4=3D散射, 0=错误
|
// ret: 1=2D本征模式, 2=2D本征频率, 3=2D散射, 4=3D散射, 5=3D本征矩阵导出, 0=错误
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -618,7 +707,7 @@ int ret = OpticsFEM_API::OpticsFEM_All(data);
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
| 字段 | 类型 | 说明 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| `FemType` | int | 0=本征模式, 1=本征频率, 2=2D散射(λ), 3=2D散射(f), **4=3D散射(λ)** |
|
| `FemType` | int | 0=2D本征模式, 1=2D本征频率, 2=2D散射(λ), 3=2D散射(f), **4=3D散射(λ)**, **5=3D本征频率** |
|
||||||
| `NbrBoundary` | int | 边界数量(3D 为三角面边界条数;2D 为边界面条数) |
|
| `NbrBoundary` | int | 边界数量(3D 为三角面边界条数;2D 为边界面条数) |
|
||||||
| `BoundaryFlag` | int[] | 每条边界的类型编码(见 3.3 节) |
|
| `BoundaryFlag` | int[] | 每条边界的类型编码(见 3.3 节) |
|
||||||
| `NbrDomain` | int | 材料物理域数量 |
|
| `NbrDomain` | int | 材料物理域数量 |
|
||||||
|
|
@ -630,9 +719,10 @@ int ret = OpticsFEM_API::OpticsFEM_All(data);
|
||||||
|
|
||||||
| 字段 | 说明 |
|
| 字段 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| `NbrMode` | 求解模态数量 |
|
| `NbrMode` | 求解模态数量(FemType 0/1/5) |
|
||||||
| `searchValue` | 特征值搜索目标 |
|
| `searchValue` | 特征值搜索目标(FemType 0/1/5) |
|
||||||
| `lambda0` | 真空波长(本征模式 FemType=0) |
|
| `searchType`, `solverType`, `maxIterNum`, `tol`, `tolType` | 特征值求解器参数(FemType 5 JSON 已预留) |
|
||||||
|
| `lambda0` | 参考波长(FemType 0/5) |
|
||||||
|
|
||||||
#### 散射问题专用字段
|
#### 散射问题专用字段
|
||||||
|
|
||||||
|
|
@ -690,6 +780,30 @@ int ret = OpticsFEM_API::OpticsFEM_All(data);
|
||||||
|
|
||||||
**BoundaryFlag 编码(三角面边界):** 0=PMC, 1=PEC, **2=SBC**, 3=ELE, 4=PBC, …
|
**BoundaryFlag 编码(三角面边界):** 0=PMC, 1=PEC, **2=SBC**, 3=ELE, 4=PBC, …
|
||||||
|
|
||||||
|
#### eigen3d 算例 JSON 摘要(FemType = 5)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"FemType": 5,
|
||||||
|
"EletricType": 2,
|
||||||
|
"NbrBoundary": 14,
|
||||||
|
"BoundaryFlag": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"NbrDomain": 2,
|
||||||
|
"matType": [0, 0],
|
||||||
|
"epsilonrR": [1.0, 1.5],
|
||||||
|
"epsilonrI": [0.0, 0.0],
|
||||||
|
"murR": [1.0, 1.0],
|
||||||
|
"MeshFile": "SBCmesh.dat",
|
||||||
|
"OutFile": "./OutFile",
|
||||||
|
"NbrMode": 6,
|
||||||
|
"searchType": 0,
|
||||||
|
"searchValue": 374740572.5,
|
||||||
|
"lambda0": 0.8
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
本算例为全 PMC 边界(`BoundaryFlag` 全 0),与 MATLAB `3D一阶本征问题2` 对齐。方程 **A·x = λ·B·x**,λ = k₀²。
|
||||||
|
|
||||||
#### SBCmesh.dat 网格格式(Mesh_3D)
|
#### SBCmesh.dat 网格格式(Mesh_3D)
|
||||||
|
|
||||||
文本格式,按块顺序读取(1-based 索引,读入后转 0-based):
|
文本格式,按块顺序读取(1-based 索引,读入后转 0-based):
|
||||||
|
|
@ -734,7 +848,7 @@ int ret = OpticsFEM_API::OpticsFEM_All(data);
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 6.2 三维网格 SBCmesh.dat(Mesh_3D,FemType = 4)
|
### 6.2 三维网格 SBCmesh.dat(Mesh_3D,FemType = 4 / 5)
|
||||||
|
|
||||||
见上文 [SBCmesh.dat 网格格式](#sbcmeshdat-网格格式mesh_3d)。
|
见上文 [SBCmesh.dat 网格格式](#sbcmeshdat-网格格式mesh_3d)。
|
||||||
|
|
||||||
|
|
@ -863,16 +977,18 @@ extern "C" {
|
||||||
|
|
||||||
| 序号 | 文件 | 阅读目标 |
|
| 序号 | 文件 | 阅读目标 |
|
||||||
|------|------|----------|
|
|------|------|----------|
|
||||||
| 1 | `test/Test_Main.cpp` | 入口,默认读 `sbc3d.json` |
|
| 1 | `test/Test_Main.cpp` | 入口,默认读 `sbc3d.json`(本征改为 `eigen3d.json`) |
|
||||||
| 2 | `Interface/FEM_Interface.cpp` | FemType 路由(含 **FemType=4 → 3D**) |
|
| 2 | `Interface/FEM_Interface.cpp` | FemType 路由(**4→3D散射**, **5→3D本征**) |
|
||||||
| 3 | `test/Test_ReadData.cpp` | JSON → Phy/Material(含 `sbc` 块) |
|
| 3 | `test/Test_ReadData.cpp` | JSON → Phy/Material(含 `sbc` 块) |
|
||||||
| 4 | `mesh/Mesh_Interface.cpp` | `Mesh_3D::GetMesh` 读 SBCmesh.dat |
|
| 4 | `mesh/Mesh_Interface.cpp` | `Mesh_3D::GetMesh` 读 SBCmesh.dat |
|
||||||
| 5 | `kernel/Assemble_kernel.cpp` | `OpticsFEM_3D_Scatter` 总控 |
|
| 5 | `kernel/Assemble_kernel.cpp` | `OpticsFEM_3D_Scatter` / `OpticsFEM_3D_EigenFreq` 总控 |
|
||||||
| 6 | `kernel/Assemble_Scatter_3D_Boundary.cpp` | 3D SBC 边界积分 |
|
| 6 | `kernel/Assemble_Scatter_3D_Boundary.cpp` | 3D SBC 边界积分(FemType=4) |
|
||||||
| 7 | `kernel/Assemble_Scatter_Equation.cpp` | 四面体体积方程 |
|
| 7 | `kernel/Assemble_Scatter_Equation.cpp` | 散射四面体体积方程(FemType=4) |
|
||||||
| 8 | `complex/complexsolver.cpp` | Eigen 稀疏线性求解 |
|
| 8 | `kernel/Assemble_EigenFreq_Equation.cpp` | 本征 A/B 体积积分(FemType=5) |
|
||||||
| 9 | `post/Post_CalEletric.cpp` | `Post_3D_Scatter::GetElectric` |
|
| 9 | `kernel/Assemble_EigenFreq_Boundary.cpp` | 本征 PEC/PBC(FemType=5) |
|
||||||
| 10 | `post/Post_Output.cpp` | 写入 OutFile |
|
| 10 | `complex/complexsolver.cpp` | Eigen 稀疏线性求解(FemType=4) |
|
||||||
|
| 11 | `post/Post_CalEletric.cpp` | `Post_3D_Scatter::GetElectric` |
|
||||||
|
| 12 | `post/Post_Output.cpp` | 写入 OutFile |
|
||||||
|
|
||||||
### 调试建议
|
### 调试建议
|
||||||
|
|
||||||
|
|
@ -891,7 +1007,7 @@ extern "C" {
|
||||||
| 运行无输出、无 OutFile | 缺少 `complexsolver.exe` 或路径错误 | 检查 `complex/` 目录及工作目录 |
|
| 运行无输出、无 OutFile | 缺少 `complexsolver.exe` 或路径错误 | 检查 `complex/` 目录及工作目录 |
|
||||||
| 无法打开 `sbc3d.json` | 工作目录不含 JSON | 复制到 `Release/` 或在其中运行 |
|
| 无法打开 `sbc3d.json` | 工作目录不含 JSON | 复制到 `Release/` 或在其中运行 |
|
||||||
| 无法打开 `SBCmesh.dat` | `MeshFile` 路径不匹配 | 确保 `.dat` 与 exe 同目录 |
|
| 无法打开 `SBCmesh.dat` | `MeshFile` 路径不匹配 | 确保 `.dat` 与 exe 同目录 |
|
||||||
| 无法打开 `bele.json` | 2D 算例文件缺失 | 从 `测试数据集/bele/` 复制 |
|
| 无法打开 `eigen3d.json` | 本征算例 JSON 缺失 | 复制到 `eigen3D/Release/` 并确认 Test_Main 文件名 |
|
||||||
| 控制台打印 `err` | JSON 缺少或错误 `FemType` | 检查 JSON 完整性 |
|
| 控制台打印 `err` | JSON 缺少或错误 `FemType` | 检查 JSON 完整性 |
|
||||||
| 编译警告 C4819 | Eigen 头文件编码 | 不影响功能,可忽略 |
|
| 编译警告 C4819 | Eigen 头文件编码 | 不影响功能,可忽略 |
|
||||||
| BELE 表达式报错 | 表达式语法错误或变量未定义 | 检查 muparser 支持的函数(如 `sin`, `pi`, `x`) |
|
| BELE 表达式报错 | 表达式语法错误或变量未定义 | 检查 muparser 支持的函数(如 `sin`, `pi`, `x`) |
|
||||||
|
|
@ -904,11 +1020,15 @@ extern "C" {
|
||||||
OpticsFEM_API
|
OpticsFEM_API
|
||||||
├── Phy_WaveOpticsModel ← JSON 边界/激励
|
├── Phy_WaveOpticsModel ← JSON 边界/激励
|
||||||
├── MaterialLib ← JSON 材料
|
├── MaterialLib ← JSON 材料
|
||||||
├── Mesh_3D ← SBCmesh.dat(FemType=4)
|
├── Mesh_3D ← SBCmesh.dat(FemType=4/5)
|
||||||
└── OpticsFEM_3D_Scatter ← 3D 散射驱动
|
├── OpticsFEM_3D_Scatter ← FemType=4:A·x=b
|
||||||
├── Assemble(体积 + SBC 边界)
|
│ ├── Assemble(体积 + SBC)
|
||||||
├── Solver_LdaDom → complexsolver
|
│ ├── Solver_LdaDom → complexsolver
|
||||||
└── Post_3D_Scatter → OutFile
|
│ └── Post_3D_Scatter → Ex/Ey/Ez/normE
|
||||||
|
└── OpticsFEM_3D_EigenFreq ← FemType=5:A·x=λB·x
|
||||||
|
├── Assemble(A 刚度 + B 质量 + PEC/PBC)
|
||||||
|
├── Test_OutputMatrix → Ai/Aj/Av, Bi/Bj/Bv
|
||||||
|
└── (待接)Solver_EigenFreq → Post_3D_EigenFreq
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -922,6 +1042,7 @@ OpticsFEM_API
|
||||||
| 2 | `lambda`, 边界块 | Ex/Ey/Ez/normE |
|
| 2 | `lambda`, 边界块 | Ex/Ey/Ez/normE |
|
||||||
| 3 | `freq`, 边界块 | Ex/Ey/Ez/normE |
|
| 3 | `freq`, 边界块 | Ex/Ey/Ez/normE |
|
||||||
| **4** | **`lambda`, `sbc` 块, `SBCmesh.dat`** | **Ex/Ey/Ez/normE** |
|
| **4** | **`lambda`, `sbc` 块, `SBCmesh.dat`** | **Ex/Ey/Ez/normE** |
|
||||||
|
| **5** | **`NbrMode`, `searchValue`, `lambda0`, `SBCmesh.dat`** | **Ai/Aj/Av, Bi/Bj/Bv**(当前);后续 **freq, Ex/Ey/Ez** |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -929,9 +1050,10 @@ OpticsFEM_API
|
||||||
|
|
||||||
| 版本 | 日期 | 修订内容 |
|
| 版本 | 日期 | 修订内容 |
|
||||||
|------|------|----------|
|
|------|------|----------|
|
||||||
|
| v3.0 | 2026-06-09 | 新增 FemType=5 三维本征频率;scat3D/eigen3D 双构建目录;eigen3d.json;A/B 矩阵导出 |
|
||||||
| v2.0 | 2026-06-08 | 适配 3D 版:FemType=4、sbc3d 算例、SBCmesh 格式、CMake complexsolver |
|
| v2.0 | 2026-06-08 | 适配 3D 版:FemType=4、sbc3d 算例、SBCmesh 格式、CMake complexsolver |
|
||||||
| v1.0 | 2026-06-03 | 初版(2D opticsfem-master) |
|
| v1.0 | 2026-06-03 | 初版(2D opticsfem-master) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*本文档基于 `3D opticsfem-master` 当前代码状态编制。主算例:`sbc3d.json` + `SBCmesh.dat`,FemType=4。*
|
*本文档基于 `3D opticsfem-master` 当前代码状态编制。三维主算例:`sbc3d.json`(散射 FemType=4)+ `eigen3d.json`(本征 FemType=5),共用 `SBCmesh.dat`。*
|
||||||
|
|
|
||||||
|
|
@ -7,60 +7,106 @@
|
||||||
| FemType | 说明 | 网格 | 状态 |
|
| FemType | 说明 | 网格 | 状态 |
|
||||||
|---------|------|------|------|
|
|---------|------|------|------|
|
||||||
| 0–3 | 二维问题(本征/散射) | `Mesh_2D` | 遗留接口,与 2D 版相同 |
|
| 0–3 | 二维问题(本征/散射) | `Mesh_2D` | 遗留接口,与 2D 版相同 |
|
||||||
| **4** | **三维一阶散射(SBC)** | **`Mesh_3D`** | **当前主算例** |
|
| **4** | **三维一阶散射(SBC)** | **`Mesh_3D`** | **完整:组装 → 求解 → 后处理** |
|
||||||
|
| **5** | **三维一阶本征频率** | **`Mesh_3D`** | **组装 + A/B 矩阵导出(Run/Post 待接)** |
|
||||||
|
|
||||||
## 快速开始(FemType = 4)
|
三维主算例共用网格 **`SBCmesh.dat`**,散射与本征分别使用 `sbc3d.json`、`eigen3d.json`。
|
||||||
|
|
||||||
### 环境
|
## 推荐构建目录
|
||||||
|
|
||||||
|
为避免散射与本征互相覆盖 exe 和 OutFile,建议使用**两个独立 CMake 构建目录**:
|
||||||
|
|
||||||
|
| 目录 | 用途 | 配置文件 |
|
||||||
|
|------|------|----------|
|
||||||
|
| `scat3D/` | FemType=4 散射 | `sbc3d.json` |
|
||||||
|
| `eigen3D/` | FemType=5 本征频率 | `eigen3d.json` |
|
||||||
|
|
||||||
|
旧目录 `build/`、`build1/` 为早期本地构建,可保留或删除,**不必上传 Git**。
|
||||||
|
|
||||||
|
## 环境
|
||||||
|
|
||||||
- Windows 10/11 x64
|
- Windows 10/11 x64
|
||||||
- Visual Studio 2026(18),工作负载:使用 C++ 的桌面开发
|
- Visual Studio 2026(18),工作负载:使用 C++ 的桌面开发
|
||||||
- CMake ≥ 3.8(随 VS 安装)
|
- CMake ≥ 3.8(随 VS 安装)
|
||||||
|
|
||||||
### 编译
|
若 `cmake` 不在 PATH 中:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$env:Path += ";C:\Program Files\Microsoft Visual Studio\18\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 编译
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
cd "3D opticsfem-master"
|
cd "3D opticsfem-master"
|
||||||
|
|
||||||
# 若 cmake 不在 PATH 中,追加 VS 2026 自带 CMake
|
# 散射(FemType=4)
|
||||||
$env:Path += ";C:\Program Files\Microsoft Visual Studio\18\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin"
|
cmake -B scat3D -G "Visual Studio 18 2026" -A x64
|
||||||
|
cmake --build scat3D --config Release
|
||||||
|
|
||||||
mkdir build
|
# 本征频率(FemType=5)
|
||||||
cd build
|
cmake -B eigen3D -G "Visual Studio 18 2026" -A x64
|
||||||
cmake .. -G "Visual Studio 18 2026" -A x64
|
cmake --build eigen3D --config Release
|
||||||
cmake --build . --config Release
|
|
||||||
```
|
```
|
||||||
|
|
||||||
产物:
|
产物(每个构建目录各一份):
|
||||||
|
|
||||||
- `build/Release/OpticsFEM.exe`
|
- `scat3D/Release/OpticsFEM.exe` 或 `eigen3D/Release/OpticsFEM.exe`
|
||||||
- `build/Release/complex/complexsolver.exe`(CMake 自动编译)
|
- `*/Release/complex/complexsolver.exe`(FemType=4 散射求解必需,CMake 自动编译)
|
||||||
|
|
||||||
### 运行 sbc3d 算例
|
## 运行散射算例(FemType = 4)
|
||||||
|
|
||||||
|
1. 修改 `test/Test_Main.cpp`,确保读取 `sbc3d.json`(当前默认),重新编译 `scat3D`。
|
||||||
|
2. 部署输入文件:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# 复制输入文件到 exe 同目录
|
Copy-Item sbc3d.json, SBCmesh.dat -Destination scat3D\Release\
|
||||||
Copy-Item ..\sbc3d.json, ..\SBCmesh.dat -Destination Release\
|
cd scat3D\Release
|
||||||
|
|
||||||
cd Release
|
|
||||||
.\OpticsFEM.exe
|
.\OpticsFEM.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
结果输出到 `Release/OutFile/`:`Ex`、`Ey`、`Ez`、`normE`。
|
3. 控制台应打印 `OpticsFEM_All returned 4`。
|
||||||
|
4. 结果在 `OutFile/`:`Ex`、`Ey`、`Ez`、`normE`。
|
||||||
|
|
||||||
### 输入文件
|
## 运行本征频率算例(FemType = 5)
|
||||||
|
|
||||||
| 文件 | 说明 |
|
1. 修改 `test/Test_Main.cpp` 中 JSON 文件名为 `eigen3d.json`,重新编译 `eigen3D`。
|
||||||
|------|------|
|
2. 部署输入文件:
|
||||||
| `sbc3d.json` | 算例配置,`FemType` 必须为 **4** |
|
|
||||||
| `SBCmesh.dat` | 三维四面体网格(顶点、四面体、边、三角边界等) |
|
```powershell
|
||||||
|
Copy-Item eigen3d.json, SBCmesh.dat -Destination eigen3D\Release\
|
||||||
|
cd eigen3D\Release
|
||||||
|
.\OpticsFEM.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 控制台应打印 `OpticsFEM_All returned 5`。
|
||||||
|
4. 当前输出 `OutFile/` 下 A/B 稀疏矩阵 COO:`Ai/Aj/Av`、`Bi/Bj/Bv`(0-based),供与 MATLAB `eigs(A,B)` 对比验证。
|
||||||
|
|
||||||
|
> **说明**:FemType=5 的 `Run()`(特征值求解)与 `Post()`(场重构)尚未接入主流程;矩阵组装与边界处理已完成。
|
||||||
|
|
||||||
|
## 输入文件
|
||||||
|
|
||||||
|
| 文件 | FemType | 说明 |
|
||||||
|
|------|---------|------|
|
||||||
|
| `sbc3d.json` | 4 | 散射配置,含 `sbc` 边界块与 `lambda` |
|
||||||
|
| `eigen3d.json` | 5 | 本征频率配置,含 `NbrMode`、`searchValue` 等 |
|
||||||
|
| `SBCmesh.dat` | 4 / 5 | 三维四面体网格(顶点、四面体、边、三角边界等) |
|
||||||
|
|
||||||
|
## 物理形式简述
|
||||||
|
|
||||||
|
| 问题 | 方程形式 | 矩阵 |
|
||||||
|
|------|----------|------|
|
||||||
|
| 散射 (4) | **A·x = b**(给定 λ/k₀) | A = curl-curl − k₀²ε + SBC;b 来自入射边界 |
|
||||||
|
| 本征 (5) | **A·x = λ·B·x** | A = curl-curl(刚度);B = ε·质量 |
|
||||||
|
|
||||||
|
体积分核函数相同,散射将刚度与质量合并进 A 并加边界激励;本征拆成 A、B 求特征值。
|
||||||
|
|
||||||
## 详细文档
|
## 详细文档
|
||||||
|
|
||||||
- [OpticsFEM_完整使用说明与代码介绍.md](./OpticsFEM_完整使用说明与代码介绍.md) — 模块说明、JSON 字段、FemType=4 专章
|
- [OpticsFEM_完整使用说明与代码介绍.md](./OpticsFEM_完整使用说明与代码介绍.md) — 模块说明、JSON 字段、FemType=4/5 专章
|
||||||
- [compare/README.md](./compare/README.md) — 与 COMSOL 的 normE 切面对比
|
- [compare/README.md](./compare/README.md) — 与 COMSOL 的 normE 切面对比(散射)
|
||||||
|
|
||||||
## 仓库说明
|
## 仓库说明
|
||||||
|
|
||||||
- 只需上传**源码**;`build/` 由 CMake 本地生成,不必提交。
|
- 仅上传**源码**与算例 JSON;`scat3D/`、`eigen3D/`、`build/`、`build1/` 为本地 CMake 产物,不上传。
|
||||||
- 散射算例(FemType=4)的 `complexsolver.exe` 可由 CMake 从 `complex/complexsolver.cpp` 编译,无需单独 PETSc 版求解器。
|
- FemType=4 的 `complexsolver.exe` 由 CMake 从 `complex/complexsolver.cpp` 编译,无需单独 PETSc 版求解器。
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# normE 切面对比(COMSOL vs OpticsFEM)
|
# normE 切面对比(COMSOL vs OpticsFEM)
|
||||||
|
|
||||||
在 **z = 0.5 m** 平面上对比 COMSOL 与 C++ OpticsFEM 的 |E| 热图。
|
在 **z = 0.5 m** 平面上对比 COMSOL 与 C++ OpticsFEM 的 |E| 热图(**散射算例 FemType=4**)。
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
|
|
@ -18,14 +18,14 @@
|
||||||
|
|
||||||
## 使用步骤
|
## 使用步骤
|
||||||
|
|
||||||
### 1. 运行 C++ 求解
|
### 1. 运行 C++ 散射求解
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
cd "3D opticsfem-master\build\Release"
|
cd "3D opticsfem-master\scat3D\Release"
|
||||||
.\OpticsFEM.exe
|
.\OpticsFEM.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
确认生成 `OutFile/normE`。
|
确认生成 `OutFile/normE`(需已部署 `sbc3d.json` 与 `SBCmesh.dat`,见根目录 README)。
|
||||||
|
|
||||||
### 2. 导出 COMSOL 切面
|
### 2. 导出 COMSOL 切面
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"FemType": 5,
|
||||||
|
"EletricType": 2,
|
||||||
|
"NbrBoundary": 14,
|
||||||
|
"BoundaryFlag": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"NbrDomain": 2,
|
||||||
|
"domainType": [2, 2],
|
||||||
|
"domainIndex": [0, 1],
|
||||||
|
"matType": [0, 0],
|
||||||
|
"epsilonrR": [1.0, 1.5],
|
||||||
|
"epsilonrI": [0.0, 0.0],
|
||||||
|
"murR": [1.0, 1.0],
|
||||||
|
"murI": [0.0, 0.0],
|
||||||
|
"chiheR": [0.0, 0.0],
|
||||||
|
"chiehR": [0.0, 0.0],
|
||||||
|
"chiheI": [0.0, 0.0],
|
||||||
|
"chiehI": [0.0, 0.0],
|
||||||
|
"sigma": [0.0, 0.0],
|
||||||
|
"n": [1.0, 1.0],
|
||||||
|
"k": [0.0, 0.0],
|
||||||
|
"MeshFile": "SBCmesh.dat",
|
||||||
|
"OutFile": "./OutFile",
|
||||||
|
"NbrMode": 6,
|
||||||
|
"searchType": 0,
|
||||||
|
"searchValue": 374740572.5,
|
||||||
|
"solverType": 0,
|
||||||
|
"maxIterNum": 40,
|
||||||
|
"tol": 1.0e-6,
|
||||||
|
"tolType": 0,
|
||||||
|
"lambda0": 0.8,
|
||||||
|
"lambda": 0.0,
|
||||||
|
"freq": 0.0
|
||||||
|
}
|
||||||
|
|
@ -165,6 +165,8 @@ public:
|
||||||
|
|
||||||
void Assemble();
|
void Assemble();
|
||||||
|
|
||||||
|
void Test_OutputMatrix(const std::string& outDir = "./OutFile");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Assemble_WaveEquation();
|
void Assemble_WaveEquation();
|
||||||
void Assemble_PEC_PBC();
|
void Assemble_PEC_PBC();
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ void OpticsFEM_3D_EigenFreq::Assemble_WaveEquation()
|
||||||
//material
|
//material
|
||||||
int domain = _mMesh->GetDomainOfTet(n);
|
int domain = _mMesh->GetDomainOfTet(n);
|
||||||
Matrix3cd epsr = _mMatLib->GetEpsr(domain);
|
Matrix3cd epsr = _mMatLib->GetEpsr(domain);
|
||||||
Matrix3cd invMur = _mMatLib->GetEpsr(domain).inverse();
|
Matrix3cd invMur = _mMatLib->GetMur(domain).inverse();
|
||||||
|
|
||||||
//mapping
|
//mapping
|
||||||
VectorXi MappingIndex = VectorXi::Zero(dof);
|
VectorXi MappingIndex = VectorXi::Zero(dof);
|
||||||
|
|
|
||||||
|
|
@ -512,10 +512,16 @@ void OpticsFEM_2D_Scatter::Post(string file)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
3D_EigenFreq
|
3D_EigenFreq - volume assembly_equ → sparse A (curl-curl) and B (eps mass)
|
||||||
*/
|
*/
|
||||||
void OpticsFEM_3D_EigenFreq::Assemble()
|
void OpticsFEM_3D_EigenFreq::Assemble()
|
||||||
{
|
{
|
||||||
|
_mDof = _mMesh->GetNbrEdge();
|
||||||
|
_mTripleA_real.clear();
|
||||||
|
_mTripleB_real.clear();
|
||||||
|
_mTripleA_complex.clear();
|
||||||
|
_mTripleB_complex.clear();
|
||||||
|
|
||||||
_mIsReal = _mMatLib->IsReal();
|
_mIsReal = _mMatLib->IsReal();
|
||||||
if (_mIsReal)
|
if (_mIsReal)
|
||||||
{
|
{
|
||||||
|
|
@ -533,11 +539,15 @@ void OpticsFEM_3D_EigenFreq::Assemble()
|
||||||
|
|
||||||
if (_mIsReal)
|
if (_mIsReal)
|
||||||
{
|
{
|
||||||
|
_mA_real.resize(_mDof, _mDof);
|
||||||
|
_mB_real.resize(_mDof, _mDof);
|
||||||
_mA_real.setFromTriplets(_mTripleA_real.begin(), _mTripleA_real.end());
|
_mA_real.setFromTriplets(_mTripleA_real.begin(), _mTripleA_real.end());
|
||||||
_mB_real.setFromTriplets(_mTripleB_real.begin(), _mTripleB_real.end());
|
_mB_real.setFromTriplets(_mTripleB_real.begin(), _mTripleB_real.end());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
_mA_complex.resize(_mDof, _mDof);
|
||||||
|
_mB_complex.resize(_mDof, _mDof);
|
||||||
_mA_complex.setFromTriplets(_mTripleA_complex.begin(), _mTripleA_complex.end());
|
_mA_complex.setFromTriplets(_mTripleA_complex.begin(), _mTripleA_complex.end());
|
||||||
_mB_complex.setFromTriplets(_mTripleB_complex.begin(), _mTripleB_complex.end());
|
_mB_complex.setFromTriplets(_mTripleB_complex.begin(), _mTripleB_complex.end());
|
||||||
}
|
}
|
||||||
|
|
@ -546,7 +556,24 @@ void OpticsFEM_3D_EigenFreq::Assemble()
|
||||||
{
|
{
|
||||||
this->Assemble_PEC_PBC();
|
this->Assemble_PEC_PBC();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_mIsReal)
|
||||||
|
{
|
||||||
|
_mP_real.resize(_mDof, _mDof);
|
||||||
|
_mP_real.setIdentity();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_mP_complex.resize(_mDof, _mDof);
|
||||||
|
_mP_complex.setIdentity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[OpticsFEM_3D_EigenFreq] Assemble done: DOF=" << _mDof
|
||||||
|
<< " nnz(A)=" << (_mIsReal ? _mA_real.nonZeros() : _mA_complex.nonZeros())
|
||||||
|
<< " nnz(B)=" << (_mIsReal ? _mB_real.nonZeros() : _mB_complex.nonZeros())
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -685,6 +712,53 @@ void OpticsFEM_3D_Scatter::Test_OutputMatrix(const std::string& outDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpticsFEM_3D_EigenFreq::Test_OutputMatrix(const std::string& outDir)
|
||||||
|
{
|
||||||
|
EnsureOutputDir(outDir);
|
||||||
|
const std::string prefix = outDir + "/";
|
||||||
|
|
||||||
|
if (_mIsReal)
|
||||||
|
{
|
||||||
|
std::ofstream outAi(prefix + "Ai.txt"), outAj(prefix + "Aj.txt"), outAv(prefix + "Av.txt");
|
||||||
|
std::ofstream outBi(prefix + "Bi.txt"), outBj(prefix + "Bj.txt"), outBv(prefix + "Bv.txt");
|
||||||
|
for (const auto& t : _mTripleA_real)
|
||||||
|
{
|
||||||
|
outAi << t.row() << '\n';
|
||||||
|
outAj << t.col() << '\n';
|
||||||
|
outAv << t.value() << '\n';
|
||||||
|
}
|
||||||
|
for (const auto& t : _mTripleB_real)
|
||||||
|
{
|
||||||
|
outBi << t.row() << '\n';
|
||||||
|
outBj << t.col() << '\n';
|
||||||
|
outBv << t.value() << '\n';
|
||||||
|
}
|
||||||
|
std::cout << "[OpticsFEM_3D_EigenFreq] exported A/B COO to " << outDir << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ofstream outAi(prefix + "Ai.txt"), outAj(prefix + "Aj.txt");
|
||||||
|
std::ofstream outAv_real(prefix + "Av_real.txt"), outAv_imag(prefix + "Av_imag.txt");
|
||||||
|
std::ofstream outBi(prefix + "Bi.txt"), outBj(prefix + "Bj.txt");
|
||||||
|
std::ofstream outBv_real(prefix + "Bv_real.txt"), outBv_imag(prefix + "Bv_imag.txt");
|
||||||
|
for (const auto& t : _mTripleA_complex)
|
||||||
|
{
|
||||||
|
outAi << t.row() << '\n';
|
||||||
|
outAj << t.col() << '\n';
|
||||||
|
outAv_real << t.value().real() << '\n';
|
||||||
|
outAv_imag << t.value().imag() << '\n';
|
||||||
|
}
|
||||||
|
for (const auto& t : _mTripleB_complex)
|
||||||
|
{
|
||||||
|
outBi << t.row() << '\n';
|
||||||
|
outBj << t.col() << '\n';
|
||||||
|
outBv_real << t.value().real() << '\n';
|
||||||
|
outBv_imag << t.value().imag() << '\n';
|
||||||
|
}
|
||||||
|
std::cout << "[OpticsFEM_3D_EigenFreq] exported A/B COO to " << outDir << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
3D_Scatter2
|
3D_Scatter2
|
||||||
prism
|
prism
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
std::ifstream fd("sbc3d.json");
|
std::ifstream fd("sbc3d.json"); // FemType=4 散射;本征请改为 eigen3d.json 并编译 eigen3D 目录
|
||||||
if (!fd.is_open())
|
if (!fd.is_open())
|
||||||
{
|
{
|
||||||
std::cout << "cannot open sbc3d.json" << std::endl;
|
std::cout << "cannot open sbc3d.json" << std::endl;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue