Lumerical FDTD 脚本开发综合技术指南 (v3)
适用范围:本指南适用于使用 Lumerical LSF 脚本语言为 FDTD 求解器编写自动化仿真代码的全部场景,涵盖从基础物理原理、语言语法、工程代码规范到结构建模、参数扫描、结果提取与 Python 后处理的完整链路。核心目标是让 AI 生成的代码一次性通过编译并正确执行,避免因语法混淆、求解器命令越界、属性依赖顺序错误等导致的运行时故障。
1. FDTD 求解器核心物理原理
1.1 Maxwell 方程与 Yee 网格离散
FDTD 方法在非磁性材料中求解 Maxwell 旋度方程,控制方程为:
- ∂D /∂t = ∇ × H
- D (ω) = ε₀εᵣ(ω)E(ω)
- ∂H /∂t = −(1/μ₀)∇ × E
其中 εᵣ(ω) = n² 为复相对介电常数。2D 情形下,Maxwell 方程分裂为两组独立模式:TE 模式 (Ex, Ey, Hz)和 TM 模式(Hx, Hy, Ez)。
FDTD 采用 Yee 元胞 离散,每个电磁场分量在网格单元内处于略有偏移的位置。Lumerical FDTD 自动将数据插值到网格原点,用户在分析中无需直接处理 Yee 偏移。
Courant 稳定性条件 自动由求解器处理,用户通过 dt stability factor(<1)间接控制时间步长。
1.2 网格系统
- 默认使用 自动非均匀网格 (
mesh type="auto non-uniform") mesh accuracy(1--8)控制每波长网格点数:1→6 ppw,每级增加 4 ppw- 高折射率材料自动获得更细网格
- 网格覆盖区 (
addmesh)在关键区域强制细化 - 共形网格(conformal mesh)技术允许较粗网格仍保持高精度
1.3 边界条件
| 边界类型 | 字符串值 | 物理含义 |
|---|---|---|
| PML | "PML" |
完美匹配层,吸收出射波,模拟开放边界 |
| Metal (PEC) | "Metal" |
理想电导体,E_平行=0,全反射 |
| PMC | "PMC" |
理想磁导体,H_平行=0 |
| Periodic | "Periodic" |
周期性,无相位差 |
| Bloch | "Bloch" |
周期性带相位差,用于倾斜入射 |
| Symmetric | "Symmetric" |
电场镜像、磁场反对称,可缩减 4x 计算量 |
| Anti-Symmetric | "Anti-Symmetric" |
电场反对称、磁场镜像 |
边界条件通过在 FDTD 仿真区域对象 上设置属性实现,不存在独立的 addpml/addperiodic 等命令(那些是 DGTD 等求解器的命令)。
1.4 材料模型
| 模型 | 说明 | 关键属性 |
|---|---|---|
| Dielectric | 恒定实折射率 | index |
| (n,k) | 单频指定 n,k | refractive index, imaginary refractive index |
| Conductive 3D | 欧姆导电 | permittivity, conductivity |
| Plasma (Drude) | 自由电子金属 | permittivity, plasma resonance, collision |
| Debye | 弛豫型色散 | permittivity, Debye permittivity, collision |
| Lorentz | 共振型色散 | permittivity, Lorentz permittivity, resonance, linewidth |
| Sellmeier | 玻璃常用 | 系数 A, B, C |
| Sampled 3D data | 实验数据拟合 MCM | tolerance, max coefficients |
| PEC | 理想电导体 | 无参数 |
| Multi-coefficient (MCM) | 通用色散拟合 | 从 Sampled 3D data 自动生成 |
2. LSF 语言语法精要
2.1 与 MATLAB / Python 的关键差异
| 特性 | LSF | MATLAB | Python |
|---|---|---|---|
| 数组索引 | 1-based | 1-based | 0-based |
| 元素级乘法 | A * B |
A .* B |
A * B (numpy) |
| 矩阵乘法 | mult(A,B) |
A * B |
A @ B |
| 矩阵纵向拼接 | [A; B] |
[A; B] |
np.vstack |
| 矩阵横向拼接 | [A, B] |
[A, B] |
np.hstack |
| 逻辑与 | & 或 and |
&& 或 & |
and |
| 逻辑或 | ` | 或or` |
` |
| 不等于 | != |
~= |
!= |
| 注释 | # |
% |
# |
| 字符串拼接 | + |
strcat 或 + |
+ 或 f-string |
| 字符串定界符 | " 或 ' |
" 或 ' |
" 或 ' |
| 虚数单位 | i |
1i 或 1j |
1j |
| 块结束 | } |
end |
缩进 |
| 函数定义 | function name(){...} |
function out = name() |
def name(): |
| 打印输出 | ?expr; 或 print(expr); |
disp(expr) |
print(expr) |
2.2 变量与命名
lsf
# 变量赋值 --- 无需声明类型
x = 5; # 标量
A = [1, 2; 3, 4]; # 2x2 矩阵(分号=新行,逗号=新列)
v = 1:10; # 行向量 [1, 2, ..., 10]
v2 = 1:0.5:10; # 步长 0.5
v3 = linspace(1, 10, 100); # 100 个线性间隔点
# 变量名可包含空格(% 语法)
"my variable"% = 10;
?"my variable"%; # 输出 10
命名规则:
| 规则 | 说明 | 示例 |
|---|---|---|
| 允许字符 | 字母、数字、下划线 | my_var, x_span_val |
| 区分大小写 | X 与 x 不同 |
--- |
| 避开保留命令名 | 不可与命令冲突 | 不用 set 作变量名 |
| 变量名空格 | 用下划线或 % 语法 | x_span 或 %x span% |
| 预定义常量 | pi, c, eps0, mu0, h, hbar, true, false, e, i, endl | 不可覆盖 |
⚠️ 致命混淆:变量名 vs 属性名
lsf
# 变量(存储值)--- 用下划线,无引号
x_span_fdtd = 10e-6; # ✅ 合法变量名
# 属性(set/get 参数)--- 用 GUI 原名(含空格),双引号包裹
set("x span", 10e-6); # ✅ 合法属性名
set("x_span", 10e-6); # ❌ 错误 --- 属性名是 "x span" 不是 "x_span"
set(x_span_fdtd, 10e-6); # ❌ 错误 --- 把变量当属性名传了
set("x span", x_span_fdtd); # ✅ 正确 --- 变量值赋给属性
2.3 预定义常量
| 常量 | 值 | 说明 |
|---|---|---|
pi |
3.14159265... | 圆周率 |
c |
2.99792458e8 | 真空光速 (m/s) |
eps0 |
8.854187817e-12 | 真空介电常数 (F/m) |
mu0 |
1.2566370614e-6 | 真空磁导率 (H/m) |
h |
6.62606896e-34 | 普朗克常数 (J·s) |
hbar |
1.054571628e-34 | 约化普朗克常数 (J·s) |
true |
1 | 逻辑真 |
false |
0 | 逻辑假 |
e |
1.602176487e-19 | 元电荷 © |
i |
sqrt(-1) | 虚数单位 |
endl |
--- | 换行符,用于字符串拼接 |
2.4 数据类型
| 类型 | 创建 | 访问 |
|---|---|---|
| 实数/标量 | x = 5; |
直接 |
| 复数 | z = 1 + 2i; |
real(z), imag(z), abs(z), angle(z) |
| 矩阵 | A = matrix(3,4); 或 A = [1,2;3,4]; |
A(i,j) --- 1-based |
| 元胞数组 | C = cell(3); C{1} = "str"; |
C{i} --- 花括号 |
| 结构体 | S = struct; S.field = value; |
S.field --- 点号 |
| 数据集 | D = rectilineardataset; |
D.attribute, D.parameter --- 点号 |
| 字符串 | str = "hello"; |
str + " world" 拼接 |
矩阵操作:
lsf
# 元素访问(1-based)
val = A(2,3); # 第2行第3列
row = A(2,:); # 整行
col = A(:,3); # 整列
sub = A(1:3, 2:4); # 子矩阵
last = A(end); # 最后一个元素(MATLAB-style)
# 创建辅助函数
I = eye(3); # 3x3 单位阵
Z = zeros(3,4); # 3x4 零矩阵
O = ones(2,2); # 2x2 全1阵
R = randmatrix(3,3); # [0,1] 均匀随机
Rn = randnmatrix(3,3); # 标准正态随机
# 维度与变形
s = size(A); # [行数, 列数]
n = length(A); # 总元素数
A = pinch(A); # 去除单例维度
B = transpose(A); # 转置
B = ctranspose(A); # 共轭转置
C = inv(A); # 矩阵求逆
D = mult(A,B); # 矩阵乘法
E = A \ B; # 解线性方程组
G = eig(A); # 特征值
数据集操作:
lsf
# 从监视器获取数据集
E = getresult("monitor", "E"); # 返回数据集
?E; # 显示: "E vs x, y, z, lambda/f"
# 用点号提取数据
Ex = E.Ex; # Ex 分量
x = E.x; # x 位置向量
lambda = E.lambda; # 波长向量
# 构造数据集
D = rectilineardataset;
D.addparameter("x", x_vec);
D.addparameter("y", y_vec);
D.addattribute("E", Ex_data, Ey_data, Ez_data); # 矢量属性
D.addattribute("T", T_data); # 标量属性
⚠️ 数据集不可直接参与数学运算,必须先提取矩阵。
2.5 控制流
if-else:
lsf
if (x < 5) {
y = x^2;
} else if (x > 10) {
y = 2*x;
} else {
y = x;
}
# 逻辑组合
if ((a == 1) & (b == 2) | (c != 3)) { ... }
for 循环:
lsf
# 单参数 --- 遍历向量
for (x = 1:100) { ?x; }
# 三参数 --- 初始化; 条件; 增量
for (i = 1; i <= 100; i = i + 1) { ... }
# while 等价写法(无 while 关键字)
x = 1;
for (0; x < 10; 0) { # "0" 为占位符
?x;
x = x + 1;
}
# 嵌套循环
for (i = 1:10) {
for (j = 1:10) {
A(i,j) = i*j;
}
}
LSF 没有 break 和 continue。如需提前退出,需用条件控制循环条件。
try-catch 错误处理:
lsf
try {
run;
} catch (errMsg) {
print(errMsg);
}
2.6 函数定义
lsf
# 函数必须在全局作用域定义
function even_floor(a) {
return floor(a) - mod(floor(a), 2);
}
# 多输入单输出
function add(a, b) {
return a + b;
}
# 带参数校验的函数
function create_structure(params) {
if (params.wg_width <= 0) {
?'Error: wg_width must be positive';
return -1;
}
# 函数体...
return result;
}
函数规则: 全局作用域定义;函数内不能嵌套定义函数;函数文件命名不能与函数名相同。
2.7 字符串操作
lsf
# 创建与拼接
str = "hello world";
full = "hello" + " " + "world"; # 用 + 拼接
# 转换
num = str2num("3.14"); # 字符串转数字
s = num2str(3.14159); # 数字转字符串
s = num2str(3.14159, 2); # 保留2位小数
# 查找与提取
pos = findstring("hello world", "world"); # 返回 7
sub = substring("hello world", 7, 5); # 返回 "world"
s = replace("hello world", 7, "WORLD"); # 返回 "hello WORLD"
s = replacestring("a,b,c", ",", ";"); # 返回 "a;b;c"
parts = splitstring("a,b,c", ","); # 返回元胞数组
s = upper("hello"); # "HELLO"
s = lower("HELLO"); # "hello"
2.8 文件 I/O
lsf
# 仿真文件
save("my_simulation.fsp"); # 保存 .fsp
load("my_simulation.fsp"); # 加载 .fsp
newproject; # 新建项目
# 数据文件
savedata("data.ldf", var1, var2); # 保存 .ldf
loaddata("data.ldf"); # 加载 .ldf
# 文本文件
write("output.txt", "hello world"); # 写入文本
data = readdata("input.txt"); # 读取文本
# JSON(自动加 .json 扩展名)
jsonsave("result", struct_var); # 生成 result.json
# MATLAB(自动加 .mat 扩展名)
matlabsave("fields", fd); # 生成 fields.mat
# ⚠️ 不要重复写扩展名:matlabsave("fields.mat", fd) → fields.mat.mat
# CSV
exportcsvresults("results.csv");
# 加载外部脚本
feval('materials.lsf'); # 执行 .lsf 文件
# ⚠️ feval 参数用 .lsf,不是 .txt
3. 工程代码规范与工作流
3.1 多文件组织
FDTD 仿真项目应按功能拆分为多个文件:
| 文件类型 | 命名示例 | 职责 |
|---|---|---|
| 材料库 | materials.lsf |
材料初始化函数 |
| 结构库 | deep_etched_waveguide.lsf, grating.lsf |
结构建模函数 |
| FDTD 设置 | fdtd_setup.lsf |
仿真区域、端口、监视器配置 |
| 运行文件 | run_sweep.lsf |
参数定义、扫描循环、结果收集 |
| Python 可视化 | visualize_sweep.py |
后处理与 HTML 报告生成 |
运行文件顶部加载库:
lsf
# ============================================================
# 扫描运行文件
# ============================================================
feval('materials.lsf');
feval('deep_etched_waveguide.lsf');
feval('grating.lsf');
feval('fdtd_setup.lsf');
3.2 注释风格
lsf
# ============================================================
# 文件头部 --- 用 = 分隔线
# 物理参数与坐标约定
# ============================================================
# ------------------------------------------------------------
# 子节分隔 --- 用 - 分隔线
# ------------------------------------------------------------
# 行内注释 --- 独立一行,中文描述物理含义
z_offset = bottom_clad_thickness + core_thickness / 2;
# 1. 步骤标记 --- 数字编号描述构建顺序
# 2. 创建下包层 (InP)
# 3. 创建稀释波导芯层
3.3 命名约定
| 类别 | 风格 | 示例 |
|---|---|---|
| 函数名 | snake_case,动词开头 | create_, init_, get_, generate_, setup_ |
| 对象名 | snake_case,描述物理部件 | input_core, top_cladding, grating_tooth_1 |
| 参数结构体 | params 为主结构体 |
params.wg_length, params.core_thickness |
| 物理尺寸 | SI 单位(米),科学记数法 | 200e-9, 1e-6, 10e-6 |
| 材料名 | 数据库原名或描述标签 | 'Si (Silicon) - Palik', core_n3370 |
| 维度后缀 | y→width, z→thickness, x→length | wg_width, core_thickness |
3.4 Z 坐标偏移约定
使用 z 偏移将波导芯层中心置于 z=0:
lsf
z_offset = bottom_clad_thickness + core_thickness / 2;
# 所有 z_min/z_max 值都相对于此偏移量表达
# 实际设置时: 物理高度 - z_offset
3.5 材料初始化模式
始终先检查存在性再创建:
lsf
# 动态命名材料(折射率编码到名称中)
core_mat_name = 'core_n' + num2str(round(n_core * 1000));
if (materialexists(core_mat_name) != 1) {
core_mat = addmaterial('Sampled 3D data');
setmaterial(core_mat, 'name', core_mat_name);
}
setmaterial(core_mat_name, 'max coefficients', 2);
setmaterial(core_mat_name, 'sampled data', core_data);
setmaterial(core_mat_name, 'color', [0.5, 1, 0.2, 1]);
Sampled 3D data 格式: [frequency(Hz), permittivity],其中 permittivity = (n + i*k)²,frequency = c / lambda。
lsf
params.core_data = [c/1.5e-6, (3.380 + 0i)^2;
c/1.55e-6, (3.370 + 0i)^2;
c/1.6e-6, (3.360 + 0i)^2];
3.6 结构构建模式(多边形法)
标准 addpoly 流程:
lsf
# 1. 定义顶点矩阵(相对于中心)
vertex = [
-L/2, width/2;
L/2, width/2;
L/2, -width/2;
-L/2, -width/2
];
# 2. 创建多边形并设置属性
addpoly;
set('name', 'object_name');
set('alpha', 0.9); # 透明度: core=0.9, clad=0.4, sub=0.3
set('vertices', vertex);
set('material', 'MaterialName');
# 3. 添加到组
addtogroup('group_name');
# 4. 选择并设置空间位置(必须在 addtogroup 之后)
select('group_name::object_name');
set('x', x_position);
set('y', y_position);
set('z min', z_bottom);
set('z max', z_top);
set('override mesh order from material database', 1);
set('mesh order', 2); # core=2, clad/sub/fill=3
常用 alpha 值: core 层 0.9,cladding 0.4,substrate 0.3,fill 层 0.5-0.55。
常用 mesh order: core 2,cladding/substrate/fill 3。
3.7 参数扫描框架
lsf
# ------------------------------------------------------------
# 扫描配置
# ------------------------------------------------------------
scan_param_name = 'grating_ridge_length';
scan_start = 200e-9;
scan_stop = 800e-9;
scan_step = 50e-9;
n_scan = round((scan_stop - scan_start) / scan_step) + 1;
# 输出目录保护
if (!exist('mat_output_dir')) {
mat_output_dir = 'result_mats';
}
# ------------------------------------------------------------
# 扫描循环
# ------------------------------------------------------------
all_results = cell(n_scan);
for (i = 1:n_scan) {
current_value = scan_start + (i - 1) * scan_step;
# 复制并修改参数
params = base_params;
if (scan_param_name == 'grating_ridge_length') {
params.grating_ridge_length = current_value;
params.grating_period = params.grating_ridge_length + base_params.grating_slot_length;
params.grating_duty_cycle = params.grating_ridge_length / params.grating_period;
} else if (scan_param_name == 'n_periods') {
params.n_periods = round(current_value);
}
# ... 其他参数分支 ...
# 派生参数在运行时计算
params.derived_param = params.some_field / 2 - params.other_field;
# 文件名生成规则
if (scan_param_name == 'n_periods' | scan_param_name == 'mesh_accuracy') {
value_str = num2str(round(current_value));
} else if (current_value >= 1) {
value_str = num2str(round(current_value * 1000)) + 'um';
} else {
value_str = num2str(round(current_value * 1e9)) + 'nm';
}
# 重置环境
switchtolayout;
deleteall;
# 构建与仿真
create_structure(params);
save('prefix_' + scan_param_name + '_' + value_str); # ⚠️ 先 save
run; # 后 run
# 结果提取
port_result = getresult('FDTD::ports::output_port', 'expansion for port monitor');
T_net_value = port_result.T_net; # 矢量:每频点一个值
# 保存 .mat 场数据
fd = struct;
fd.Ex = getdata('monitor_xz', 'Ex');
fd.x = getdata('monitor_xz', 'x');
fd.z = getdata('monitor_xz', 'z');
matlabsave('fields_' + scan_param_name + '_' + value_str, fd);
# 保存 .json 结果
result = struct;
result.scan_index = i;
result.transmission = T_net_value;
jsonsave('result_' + scan_param_name + '_' + value_str, result);
all_results{i} = result;
switchtolayout;
}
# 保存汇总
summary = struct;
summary.scan_param_name = scan_param_name;
summary.results = all_results;
jsonsave('scan_summary_' + scan_param_name, summary);
4. FDTD 对象完整属性参考
4.1 属性发现与依赖机制
发现属性的方法: 创建对象后执行 ?get; 列出所有可用属性。
lsf
addfdtd; ?get; # 列出 FDTD 区域所有属性
addrect; ?get; # 列出矩形所有属性
addport; ?get; # 列出端口所有属性
属性名必须与 GUI 完全一致 (含空格、大小写、特殊字符),用双引号包裹传给 set()/get()。
Active vs Inactive 属性: 许多属性是条件激活的------当某个"主控"属性具有特定值时,依赖属性才可用。试图设置未激活属性会报错:"the requested property 'xxx' is inactive"。
设置顺序原则:先设主控属性,再设依赖属性。
4.2 FDTD 仿真区域(addfdtd)
General Tab:
| 属性 | 类型 | 说明 |
|---|---|---|
dimension |
Integer | 1=2D, 2=3D |
background index |
Float | 背景介质折射率 |
background material |
String | 背景材料名称(如 'SiO2 (Glass) - Palik') |
simulation time |
Float | 最大仿真时长(秒) |
simulation temperature |
Float | 温度(K) |
Geometry Tab:
| 属性 | 类型 | 说明 |
|---|---|---|
x, y, z |
Float | 中心位置 |
x min, x max |
Float | X 边界 |
y min, y max |
Float | Y 边界 |
z min, z max |
Float | Z 边界 |
x span, y span, z span |
Float | 各方向跨度 |
Mesh Settings Tab:
| 属性 | 类型 | 说明 |
|---|---|---|
mesh type |
String | "auto non-uniform", "custom non-uniform", "uniform" |
mesh accuracy |
Integer | 1--8(仅 auto non-uniform 有效) |
mesh cells x/y/z |
Integer | 网格单元数(仅 custom/uniform 有效) |
grading factor |
Float | 网格渐变率 1--2(默认 sqrt(2)) |
mesh refinement |
String | "conformal variant 0/1/2", "staircase" |
dt stability factor |
Float | Courant 限制分数(<1) |
min mesh step |
Float | 绝对最小网格步长 |
Boundary Conditions Tab:
| 属性 | 类型 | 说明 |
|---|---|---|
x min bc ~ z max bc |
String | 边界条件字符串(见第1.3节) |
allow symmetry on all boundaries |
Boolean | 允许上下边界对称 |
set based on source angle |
Boolean | 从光源角度自动设置 Bloch 矢量 |
kx, ky, kz |
Float | Bloch 波矢分量 |
extend structure through pml |
Boolean | 结构延伸穿过 PML(默认开) |
pml profile |
Integer/Array | 1=standard, 2=stabilized, 3=steep angle, 4=custom |
Advanced Options(嵌套语法 ::):
| 属性 | 类型 | 说明 |
|---|---|---|
pml settings::type |
String | "stretched coordinate" 或 "uniaxial anisotropic" |
pml settings::kappa |
Float | 归一化虚电导率 |
pml settings::sigma |
Float | 最大归一化电导率 |
pml settings::layers |
Integer | PML 层数 |
pml settings::polynomial |
Integer | 电导率增长幂次 |
use early shutoff |
Boolean | 自动关闭(能量衰减时) |
auto shutoff min |
Float | 自动关闭阈值 |
use divergence checking |
Boolean | 发散检测 |
auto shutoff max |
Float | 发散判定阈值 |
express mode |
Boolean | GPU 仿真必须设为 1 |
4.3 矩形结构(addrect)
| 属性 | 类型 | 说明 |
|---|---|---|
x, y, z |
Float | 中心位置 |
x span, y span, z span |
Float | 跨度 |
material |
String | 材料名或 "<Object defined dielectric>" |
index |
Float/String | 折射率(仅 object-defined dielectric 时激活)。各向异性用分号:"1;1.5;1" |
index units |
String | "m", "um", "nm"(空间变化折射率) |
override mesh order from material database |
Boolean | 覆盖材料默认 mesh order |
mesh order |
Integer | mesh order(需先设 override=1) |
alpha |
Float | 渲染透明度 0--1 |
color opacity |
Float | 颜色透明度 |
render type |
String | "wireframe", "surface", "detailed" |
属性依赖链:
lsf
# 正确使用 object-defined dielectric
set('material', '<Object defined dielectric>'); # 主控属性
set('index', 1.5); # 依赖属性 --- 现在可用
set('override mesh order from material database', 1); # 主控属性
set('mesh order', 2); # 依赖属性 --- 现在可用
4.4 模式光源(addmodesource)
Modal Properties:
| 属性 | 类型 | 说明 |
|---|---|---|
injection axis |
String | "x-axis", "y-axis", "z-axis"(必须先设,决定可用几何参数) |
direction |
String | "forward" 或 "backward" |
amplitude |
Float | 振幅 |
phase |
Float | 相位(度) |
mode selection |
String | "fundamental mode", "fundamental TE mode", "fundamental TM mode", "user select" |
selected mode numbers |
Vector | 模式编号,如 (1:20) |
number of field profile samples |
Integer | 模式计算的频点数 |
bent waveguide |
Boolean | 弯曲波导(默认 false) |
bend radius |
Float | 弯曲半径(需 bent waveguide=1) |
bend orientation |
Integer | 弯曲取向 1--3 |
multifrequency mode injection |
Boolean | 多频模式注入 |
Advanced:
| 属性 | 类型 | 说明 |
|---|---|---|
eliminate discontinuity |
Boolean | 平滑时间信号过渡 |
optimize for short pulse |
Boolean | 最短脉冲(FDTD 默认开) |
4.5 高斯光源(addgaussian)
| 属性 | 类型 | 说明 |
|---|---|---|
injection axis |
String | "x-axis", "y-axis", "z-axis" |
direction |
String | "forward" 或 "backward" |
waist radius w0 |
Float | 束腰半径(m) |
distance from waist |
Float | 束腰到注入面距离(m) |
use scalar approximation |
Boolean | 标量近似(默认开) |
polarization angle |
Float | 偏振角(度) |
4.6 平面波光源(addplane)
| 属性 | 类型 | 说明 |
|---|---|---|
injection axis |
String | "x-axis", "y-axis", "z-axis" |
direction |
String | "forward" 或 "backward" |
angle theta |
Float | 入射角(度) |
angle phi |
Float | 方位角(度) |
polarization angle |
Float | 偏振角(度) |
4.7 DFT 监视器(adddftmonitor / addpower)
⚠️ 版本兼容性: 新版 Lumerical 使用 adddftmonitor,旧版使用 addpower/addprofile。若 adddftmonitor 报错不存在,回退到 addpower;。
| 属性 | 类型 | 说明 |
|---|---|---|
monitor type |
String | "2D X-normal", "2D Y-normal", "2D Z-normal", "3D", "Point", "Linear X/Y/Z" |
override global monitor settings |
Boolean | 主控:设为 true 才能设置以下频率属性 |
sample spacing |
String | "uniform", "chebyshev", "custom" |
use wavelength spacing |
Boolean | 按波长间隔(需 override=1) |
use source limits |
Boolean | 使用光源频率范围(需 override=1) |
frequency points |
Integer | 频点数(需 override=1) |
wavelength start |
Float | 起始波长(需 use source limits=0) |
wavelength stop |
Float | 终止波长(需 use source limits=0) |
x, y, z |
Float | 中心位置 |
x span, y span, z span |
Float | 跨度 |
down sample x/y/z |
Integer | 空间降采样 |
正确设置顺序:
lsf
adddftmonitor; # 或 addpower(旧版)
set('name', 'transmission_monitor');
set('monitor type', '2D Y-normal');
set('x', 0); set('x span', 2e-6);
set('y', 5e-6); set('y span', 0); # 2D Y-normal: y span = 0
set('z', 0); set('z span', 1e-6);
# 必须先开启 override
set('override global monitor settings', true);
set('use source limits', true);
set('use wavelength spacing', true);
set('frequency points', 101);
4.8 折射率监视器(addindex)
属性与 DFT 监视器类似,主要属性:monitor type, override global monitor settings, use wavelength spacing, use source limits, frequency points, 以及几何属性。
4.9 模式扩展监视器(addmodeexpansion)
| 属性 | 类型 | 说明 |
|---|---|---|
monitor type |
String | "2D X-normal", "2D Y-normal", "2D Z-normal" |
injection axis |
String | "x-axis", "y-axis", "z-axis" |
mode selection |
String | "fundamental mode", "user select" 等 |
override global monitor settings |
Boolean | 覆盖全局设置 |
auto update before analysis |
Boolean | 分析前自动更新模式 |
必须与 DFT 监视器关联:
lsf
adddftmonitor; set('name', 'dft');
# ... 设置 DFT 属性 ...
addmodeexpansion; set('name', 'mode_exp');
set('monitor type', '2D Y-normal');
setexpansion('mode_exp', 'dft'); # 关联 DFT 与模式扩展
4.10 端口(addport)--- FDTD 专属
Modal Properties:
| 属性 | 类型 | 说明 |
|---|---|---|
injection axis |
String | "x-axis", "y-axis", "z-axis"(先设) |
direction |
String | "forward" 或 "backward" |
amplitude |
Float | 振幅 |
phase |
Float | 相位(度) |
mode selection |
String | "fundamental mode", "user select" 等 |
selected mode numbers |
Vector | 如 (1:20) |
number of field profile samples |
Integer | 模式计算频点数 |
bent waveguide |
Boolean | 弯曲波导 |
bend radius |
Float | 弯曲半径(需 bent=1) |
frequency dependent profile |
Boolean | GPU 仿真必须设为 0 |
multifrequency mode injection |
Boolean | 多频模式注入 |
number of trial modes |
Integer | 搜索模式数 |
Impedance Tab:
| 属性 | 类型 | 说明 |
|---|---|---|
calculate characteristic impedance |
Boolean | 计算特征阻抗 Z0 |
integration shape |
String | "circular" 或 "rectangular" |
端口结果访问:
lsf
# 仿真后提取
S = getresult('port_1', 'S'); # S 参数
T = getresult('port_1', 'T'); # 透射率
neff = getresult('port_1', 'neff'); # 有效折射率
port_E = getresult('port_1', 'E'); # 模式场分布
# 注意:名称必须与 set('name', 'port_1') 完全一致
4.11 网格覆盖(addmesh)
| 属性 | 类型 | 说明 |
|---|---|---|
override x mesh |
Boolean | 启用 X 网格覆盖(主控) |
override y mesh |
Boolean | 启用 Y 网格覆盖(主控) |
override z mesh |
Boolean | 启用 Z 网格覆盖(主控) |
dx |
Float | X 方向最大步长(需 override x mesh=1) |
dy |
Float | Y 方向最大步长(需 override y mesh=1) |
dz |
Float | Z 方向最大步长(需 override z mesh=1) |
equivalent x index |
Float | 等效折射率(dx 的替代) |
based on a structure |
Boolean | 基于结构定位 |
structure |
String | 关联结构名(需 based on=1) |
buffer |
Integer | 结构周围缓冲单元数 |
x, y, z |
Float | 中心位置(非 based on 时) |
x span, y span, z span |
Float | 跨度 |
4.12 电影监视器(addmovie)
| 属性 | 类型 | 说明 |
|---|---|---|
monitor type |
String | "2D X-normal", "2D Y-normal", "2D Z-normal" |
x, y, z |
Float | 中心位置 |
x span, y span, z span |
Float | 跨度 |
down sample time |
Integer | 时间降采样 |
5. 执行顺序与稳定性保障
5.1 黄金执行顺序
FDTD 仿真脚本必须遵循以下执行顺序,任何偏差都可能导致数据丢失或仿真失败:
lsf
# ============================================================
# 标准执行顺序 --- 不可更改
# ============================================================
# 步骤 1: 新建项目(或加载已有)
newproject;
# 或: load("existing_project.fsp");
# 步骤 2: 初始化材料
feval('materials.lsf');
# 步骤 3: 构建结构
feval('structure.lsf');
# 步骤 4: 设置 FDTD 仿真区域
addfdtd;
set('dimension', 2);
set('x span', 10e-6); set('y span', 5e-6); set('z span', 2e-6);
set('mesh accuracy', 3);
set('simulation time', 1000e-15);
set('x min bc', 'PML'); set('x max bc', 'PML');
set('y min bc', 'PML'); set('y max bc', 'PML');
set('z min bc', 'PML'); set('z max bc', 'PML');
# GPU 必备:
set('express mode', 1);
# 步骤 5: 添加光源
addmodesource;
set('name', 'source');
set('injection axis', 'x-axis');
set('direction', 'forward');
set('x', -4e-6); set('y', 0); set('y span', 3e-6);
set('z', 0); set('z span', 1e-6);
# 步骤 6: 添加监视器
adddftmonitor;
set('name', 'monitor');
set('monitor type', '2D Y-normal');
set('override global monitor settings', true);
set('use source limits', true);
set('frequency points', 101);
# 步骤 7: 添加端口(如需要 S 参数)
addport;
set('name', 'input_port');
set('injection axis', 'x-axis');
set('direction', 'forward');
set('x', -3e-6); set('y', 0); set('y span', 8e-6);
set('z', 0); set('z span', 5e-6);
set('mode selection', 'user select');
set('selected mode numbers', (1:20));
# GPU 必备:
set('frequency dependent profile', 0);
# 步骤 8: 设置全局光源波长
setglobalsource('wavelength start', 1500e-9);
setglobalsource('wavelength stop', 1600e-9);
# 步骤 9: 【必须】保存项目
save("project_name"); # ⚠️ 必须先 save
# 步骤 10: 运行仿真
run; # 后 run
# 步骤 11: 提取结果
T = transmission("monitor");
port_result = getresult('FDTD::ports::input_port', 'expansion for port monitor');
T_net = port_result.T_net;
# 步骤 12: 保存结果
savedata("results.ldf", T);
jsonsave("result", result_struct);
# 步骤 13: 【如需修改】切换回布局模式
switchtolayout; # 之后才能修改对象
5.2 GPU 仿真三要素
使用 GPU 加速时必须同时满足以下三个条件,缺一不可:
| 要素 | 设置位置 | 命令 |
|---|---|---|
| Express Mode | FDTD 区域 | set('express mode', 1); |
| 关闭频变模式 | 每个端口 | set('frequency dependent profile', 0); |
| 先 save 再 run | 全局 | save('project_name'); 在 run; 之前 |
GPU 错误码 10: "there was an unknown parallel error. The error code is 10" 几乎总是以上三者之一未满足。
5.3 参数扫描执行流程
lsf
for (i = 1:n_scan) {
# 1. 切换布局并清空
switchtolayout;
deleteall;
# 2. 重新构建结构
create_structure(params);
# 3. 设置 FDTD、光源、监视器、端口
setup_fdtd(params);
setup_ports(params);
setup_monitors(params);
# 4. 设置全局波长
setglobalsource('wavelength start', params.lambda_min);
setglobalsource('wavelength stop', params.lambda_max);
# 5. 【必须】保存
save('project_' + num2str(i));
# 6. 运行
run;
# 7. 提取并保存结果
extract_and_save_results(i);
# 8. 准备下一次迭代
switchtolayout;
}
5.4 稳定性检查清单
每次生成脚本后,对照以下清单检查:
-
save("name");在run;之前 - GPU 时
set('express mode', 1);已设置 - GPU 时每个端口
set('frequency dependent profile', 0);已设置 -
addfdtd;后边界条件已设置(PML/Periodic 等) - 光源
injection axis在几何属性之前设置 - 端口
injection axis在几何属性之前设置 - 监视器
override global monitor settings= true 在频率属性之前 - 网格覆盖
override x/y/z mesh= true 在dx/dy/dz之前 - 对象
material="<Object defined dielectric>"在index之前 -
switchtolayout;在修改对象前(如果已运行过仿真) -
run;后使用getresult/getdata而非直接访问对象属性
6. 常见错误根因分析与修复
6.1 "syntax error"
| 根因 | 错误示例 | 正确写法 |
|---|---|---|
使用 endfor/endif |
endfor; |
用 } 关闭块 |
使用 end 关块 |
end; |
用 } |
使用 Python def |
def myfunc(): |
function myfunc() { ... } |
| 使用 MATLAB 函数语法 | function out = myfunc() |
function myfunc() { return out; } |
使用 && / ` |
` | |
使用 ~= |
if (x ~= 5) |
if (x != 5) |
使用 % 注释 |
% comment |
# comment |
使用 .* 元素乘法 |
A .* B |
A * B(同尺寸时元素级) |
使用 % 变量 |
%var%(正确但易混淆) |
推荐用下划线:my_var |
使用 += 等复合赋值 |
x += 1; |
x = x + 1; |
| 使用三元运算符 | x = (a>b) ? c : d; |
用 if-else |
使用 clc |
clc; |
LSF 无此命令 |
| 缺少分号 | x = 5 |
x = 5; |
使用 j 作虚数 |
1+2j |
1+2i |
6.2 "xxx is not a valid function or variable name"
| 根因 | 错误示例 | 正确写法 |
|---|---|---|
| 变量名与命令冲突 | set = 5; |
my_set = 5; |
| 属性名当作变量 | x span = 10e-6; |
x_span = 10e-6; 或 %x span% = 10e-6; |
| 版本不支持命令 | adddftmonitor;(旧版) |
addpower;(旧版回退) |
| 属性名用下划线 | set("x_span", 10e-6); |
set("x span", 10e-6); |
6.3 "argument list for set command is incorrect"
| 根因 | 错误示例 | 正确写法 |
|---|---|---|
| 属性名未加引号 | set(x span, 10e-6); |
set("x span", 10e-6); |
| 变量当属性名 | set(x_span_fdtd, 10e-6); |
set("x span", x_span_fdtd); |
| 参数数量不对 | set("x span"); |
set("x span", 10e-6); |
用 = 代替 , |
set("x span" = 10e-6); |
set("x span", 10e-6); |
6.4 "the requested property 'xxx' is inactive"
这是最常见的运行时错误,根因是属性依赖链未按顺序设置。
监视器频率属性依赖链:
override global monitor settings = true
→ use source limits [激活]
→ use wavelength spacing [激活]
→ frequency points [激活]
→ wavelength start/stop [激活,需 use source limits = false]
网格覆盖依赖链:
override x mesh = true → dx [激活]
override y mesh = true → dy [激活]
override z mesh = true → dz [激活]
结构材料依赖链:
material = "<Object defined dielectric>" → index [激活]
override mesh order from material database = 1 → mesh order [激活]
模式光源/端口依赖链:
injection axis = "x-axis" → x, x span 可用(y, z 相关几何属性)
bent waveguide = 1 → bend radius [激活]
6.5 "index of A was out of range"
| 根因 | 错误示例 | 正确写法 |
|---|---|---|
| 0-based 索引 | A(0) = 1; |
A(1) = 1;(LSF 是 1-based) |
| 超界访问 | A(5) = 1;(A 只有 4 个元素) |
先预分配:A = zeros(1,10); |
| 循环越界 | for(i=1:100) A(i)=i;(A 只有 50) |
预分配或动态增长 |
| 维度错误 | A(i,j) 但 A 是 1D |
size(A); 检查维度 |
6.6 "d-card named xxx was not found"
| 根因 | 解决方案 |
|---|---|
| 对象名不匹配 | 检查 set('name', 'xxx') 与 getresult('xxx', ...) 是否一致 |
| 仿真未运行 | run; 必须在 getresult 之前 |
| 未先 save 再 run | save('name'); 必须在 run; 之前 |
| layout 模式访问数据 | switchtolayout; 会清除数据,需先保存 |
| 结果名错误 | 用 ?getresult('monitor_name'); 查看可用结果 |
| 端口路径错误 | 端口结果路径:FDTD::ports::port_name |
6.7 求解器命令混淆
| ❌ 错误命令(其他求解器) | ✅ FDTD 正确做法 |
|---|---|
addperiodic; (DGTD) |
set('x min bc', 'Periodic'); 在 FDTD 区域上 |
addvoltagebc; (CHARGE) |
FDTD 不适用 |
addelectricalcontact; (CHARGE) |
FDTD 不适用 |
addemeport; (EME) |
addport;(FDTD 端口) |
addmode; (MODE/FDE) |
addmodesource; 或 addport; |
addvarfdtd; (MODE) |
addfdtd; |
addfde; (MODE) |
FDTD 不适用 |
adddgtdsolver; (DGTD) |
FDTD 不适用 |
6.8 GPU 相关错误
| 错误信息 | 根因 | 修复 |
|---|---|---|
Error GPU simulation cannot run without FDTD property 'express mode' |
未开启 Express Mode | set('express mode', 1); |
Error GPU simulation does not support the frequency dependent profile option for ports |
端口频变模式未关闭 | set('frequency dependent profile', 0); |
Error: there was an unknown parallel error. The error code is 10 |
以上任一 + 可能未 save | 检查 express mode、frequency dependent profile、save |
7. 结构构建模式速查
7.1 深刻蚀波导
层叠结构(自下而上):衬底 (InP) → 下包层 (InP) → 芯层 (动态材料) → 上包层 (InP),刻蚀区用 SiO2/Si3N4/BCB 填充。
lsf
# Z 偏移计算
total_thickness = bottom_clad_thickness + core_thickness + top_clad_thickness;
z_offset = bottom_clad_thickness + core_thickness / 2;
z_etch_bottom = total_thickness - etch_thickness;
# 外侧分离逻辑(每层的刻蚀边界)
z_bottom_clad_outer_top = min([bottom_clad_thickness, max([z_etch_bottom, 0])]);
if (z_bottom_clad_outer_top > 0) {
create_outer_block(group_name, 'bottom_clad_outer', ...);
}
7.2 光栅耦合器
光栅周期参数(互斥配置):
方案 1 --- ridge + slot 长度:
lsf
params.grating_period = params.grating_ridge_length + base_params.grating_slot_length;
params.grating_duty_cycle = params.grating_ridge_length / params.grating_period;
方案 2 --- period + duty_cycle 直接:
lsf
base_params.grating_period = 700e-9;
base_params.grating_duty_cycle = 0.99;
光栅实际长度:grating_actual_length = n_periods * grating_period + grating_period * grating_duty_cycle;
7.3 矩形多边形辅助函数
lsf
function create_rect_poly(group_name, obj_name, x, y, z_min, z_max, width, x_length, material, mesh_order, alpha){
vertex = [-x_length/2, width/2; x_length/2, width/2;
x_length/2, -width/2; -x_length/2, -width/2];
addpoly;
set('name', obj_name);
set('alpha', alpha);
set('vertices', vertex);
set('material', material);
addtogroup(group_name);
select(group_name + '::' + obj_name);
set('x', x); set('y', y);
set('z min', z_min); set('z max', z_max);
set('override mesh order from material database', 1);
set('mesh order', mesh_order);
}
7.4 渐变顶点生成
lsf
function sine_profile(t) {
return 0.5 * (1 - cos(pi * t));
}
function generate_taper_vertices(L, W_start, W_end, n_points) {
vertices = matrix(n_points * 2, 2);
for (i = 1:n_points) {
t = (i - 1) / (n_points - 1);
x = t * L;
w = W_start * (1 - sine_profile(t)) + W_end * sine_profile(t);
vertices(i, 1) = x;
vertices(i, 2) = w / 2;
}
for (i = 1:n_points) {
t = (n_points - i) / (n_points - 1);
x = t * L;
w = W_start * (1 - sine_profile(t)) + W_end * sine_profile(t);
vertices(n_points + i, 1) = x;
vertices(n_points + i, 2) = -w / 2;
}
return vertices;
}
8. Python 后处理规范
8.1 依赖包
python
import json, sys, os, glob, re
from pathlib import Path
from datetime import datetime
from collections import OrderedDict
import numpy as np
from scipy.io import loadmat # .mat v7 格式
import h5py # .mat v7.3 HDF5 格式
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.colors as pc
8.2 Lumerical JSON 解包
Lumerical 的 jsonsave() 生成嵌套结构,需解包:
python
def _unwrap_lumerical_value(val):
if isinstance(val, dict) and "_data" in val:
data_arr = val["_data"]
size = val.get("_size", [len(data_arr)])
arr = np.asarray(data_arr, dtype=float)
if len(size) > 1 and size[1] > 1:
arr = arr.reshape(size, order='F')
elif len(size) == 2 and size[1] == 1:
arr = arr.reshape(size, order='F').flatten()
return arr
return val
def _unwrap_lumerical_results(data):
if "summary" in data and isinstance(data["summary"], dict):
data = data["summary"]
results = data.get("results")
if isinstance(results, dict) and "_data" in results:
data = dict(data)
data["results"] = results["_data"]
return data
8.3 T_net 透射率提取
T_net 可能是 [n_freq, n_modes] 矩阵,默认取第一列(基模):
python
def _extract_transmission_vector(trans):
arr = np.asarray(trans, dtype=float)
if arr.ndim == 2 and arr.shape[1] > 1:
return arr[:, 0] # 基模
elif arr.ndim == 2 and arr.shape[1] == 1:
return arr.flatten()
return arr
8.4 .mat 文件多格式加载
python
def load_field_mat(mat_path):
# 先尝试 scipy (v7 格式)
try:
mat = loadmat(mat_path)
if 'fd' in mat:
fd = mat['fd']
while isinstance(fd, np.ndarray) and fd.shape == (1, 1):
fd = fd[0, 0]
# 从 struct 提取字段
Ex = _to_array(fd['Ex']) if 'Ex' in fd.dtype.names else None
return {"Ex": Ex, ...}
except (NotImplementedError, ImportError):
pass
# 回退到 h5py (v7.3 HDF5)
with h5py.File(mat_path, 'r') as f:
if 'fd' in f:
fd = f['fd']
# 读取数据集...
9. 快速参考表
9.1 边界条件字符串
| 类型 | 值 |
|---|---|
| PML | "PML" |
| Metal (PEC) | "Metal" |
| PMC | "PMC" |
| Periodic | "Periodic" |
| Bloch | "Bloch" |
| Symmetric | "Symmetric" |
| Anti-Symmetric | "Anti-Symmetric" |
9.2 注入轴字符串
| 轴 | 值 |
|---|---|
| X | "x-axis" |
| Y | "y-axis" |
| Z | "z-axis" |
9.3 方向字符串
| 方向 | 值 |
|---|---|
| 正向 | "forward" |
| 反向 | "backward" |
9.4 监视器类型字符串
| 类型 | 值 |
|---|---|
| 2D X-法向 | "2D X-normal" |
| 2D Y-法向 | "2D Y-normal" |
| 2D Z-法向 | "2D Z-normal" |
| 3D | "3D" |
| 点 | "Point" |
| 线性 X | "Linear X" |
| 线性 Y | "Linear Y" |
| 线性 Z | "Linear Z" |
9.5 模式选择字符串
| 选择 | 值 |
|---|---|
| 基模 | "fundamental mode" |
| 基模 TE | "fundamental TE mode" |
| 基模 TM | "fundamental TM mode" |
| 用户选择 | "user select" |
9.6 PML 配置文件
| 类型 | 整数值 |
|---|---|
| Standard | 1 |
| Stabilized | 2 |
| Steep angle | 3 |
| Custom | 4 |
9.7 常用材料名
lsf
"Si (Silicon) - Palik"
"SiO2 (Glass) - Palik"
"Si3N4 (Silicon Nitride) - Luke"
"Au (Gold) - CRC"
"Ag (Silver) - CRC"
"Al (Aluminum) - CRC"
"InP (Indium Phosphide) - Palik"
"GaAs (Gallium Arsenide) - Palik"
"TiO2 (Titanium Dioxide) - Siefke"
"<Object defined dielectric>" # 用户自定义折射率
9.8 求解器兼容性矩阵
| 命令 | FDTD | MODE | DGTD | CHARGE | HEAT | FEEM | INTERCONNECT |
|---|---|---|---|---|---|---|---|
addfdtd |
✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
addport |
✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
addmodesource |
✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
adddftmonitor |
✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
addindex |
✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
addmodeexpansion |
✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
addmesh |
✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
getfdtdindex |
✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
transmission |
✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
farfield2d |
✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
grating |
✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
addperiodic |
❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
addemeport |
❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
addvoltagebc |
❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
10. AI 代码生成铁律(25 条)
-
只用 LSF 语法 ,绝不混用 MATLAB 或 Python 语法。禁止
.*、&&、||、endfor、end、def、import、+=。 -
每条语句以
;结尾 。用?expr;仅在需要显式输出时。 -
数组索引 1-based 。第一个元素是
A(1),永远不是A(0)。 -
属性名用 GUI 原名(含空格),双引号包裹 。如
set("x span", 10e-6);。属性名 ≠ 变量名。 -
变量名用下划线,不用空格 。如
x_span_value = 10e-6;。不要把变量名和属性名搞混。 -
先设主控属性,再设依赖属性 。如
override global monitor settings= true 在use source limits之前。 -
创建对象后用
?get;查看全部属性,确认属性名拼写和依赖关系。 -
save("name");必须在run;之前。否则仿真数据可能无法写入。 -
GPU 三要素缺一不可 :
express mode= 1、端口frequency dependent profile= 0、save在run前。 -
修改对象前调用
switchtolayout;(如果已经运行过仿真)。 -
复数用
i(1+2i),不用j。 -
字符串用双引号
"str"(单引号也可,双引号优先)。 -
LSF 无
break和continue。用条件控制循环条件代替。 -
错误处理用
try { ... } catch (err) { ... }。 -
矩阵纵向拼接
[A; B],横向拼接[A, B]。 -
数据集不可直接数学运算,先用点号提取矩阵。
-
adddftmonitor不存在时回退到addpower(旧版 Lumerical)。 -
端口结果访问用
FDTD::ports::port_name路径 ,名称必须与set('name', ...)完全一致。 -
光源波长通常全局设置
setglobalsource('wavelength start', ...),非单光源设置。 -
feval('file.lsf')参数用.lsf,不用.txt。 -
jsonsave('filename', data)和matlabsave('filename', data)自动加扩展名 ,不要在参数里写.json或.mat。 -
max([a, b])和min([a, b])必须用方括号包裹多参数 。max(a, b)是错的。 -
T_net是矢量/矩阵(每频点一个值),不是标量。提取时注意维度。 -
exist('varname')返回 0(不存在)或 1(存在) 。用于变量保护:if (!exist('var')) { var = default; }。 -
无
round(value, n)语法 。保留 n 位小数用round(value * 10^n) / 10^n。