《片上集成光栅的仿真与优化全流程》
第4章 FDTD仿真入门:设置仿真区域、边界条件、光源激励
第4章 FDTD仿真入门:设置仿真区域、边界条件、光源激励
好,到了真正跑仿真的环节了。前几章我们把光栅结构搭好,环境配齐,现在要让它「动」起来。FDTD(时域有限差分法)说白了就是在空间和时间上把麦克斯韦方程组离散化,然后一步步往前推。你想想看,光在波导里怎么传播、怎么从光栅里耦合出来,全看这一步设置得对不对。
我个人习惯把FDTD仿真设置拆成三块:仿真区域、边界条件、光源激励。这三块搞定了,一个仿真基本就立住了。今天咱们一个一个过,中间我会穿插一些我在项目里踩过的坑。
4.1 仿真区域:多大才够?
仿真区域就是你的计算「盒子」。光栅结构放进去,周围得留够空间。太小了,倏逝波会被截断;太大了,网格一多,内存直接爆炸。我刚开始做光栅仿真时,总想把盒子设得大一点求安心,结果8GB内存的机器直接卡死。后来学乖了——贴着结构走。
经验尺寸参考(针对1550nm波段):
- 波导方向(x轴):光栅长度 + 两侧各 2~3 μm
- 垂直方向(y轴):衬底下方 1~2 μm,上方空气 2~3 μm
- 厚度方向(z轴,2D仿真忽略):波导厚度 + 上下各 1 μm
网格大小也很关键。FDTD里默认网格一般设成 λ/(10n) 左右,对于硅波导(n≈3.5),1550nm波长下网格大约 44nm。但如果你结构里有尖锐拐角或者薄层,我建议局部加密到 10~20nm。别全局加密,否则计算量翻好几倍。
# 以 Lumerical FDTD 脚本为例
addfdtd;
set("x", 0); set("x span", 12e-6); # 仿真区域 x 方向 12 μm
set("y", 0); set("y span", 8e-6); # y 方向 8 μm
set("z", 0); set("z span", 0.5e-6); # z 方向 0.5 μm (2D仿真可忽略)
set("mesh accuracy", 3); # 默认网格精度 3 (约 λ/12)
# 局部网格覆盖
addmesh;
set("x", 0); set("x span", 6e-6);
set("y", 0); set("y span", 2e-6);
set("dx", 20e-9); set("dy", 20e-9); # 局部加密到 20 nm
💡 我的小技巧: 先用粗网格跑一次快速验证,看场分布大概在什么范围。确认没问题了,再加密网格做精确仿真。这叫「先粗后精」,能省下大量试错时间。
4.2 边界条件:PML 不是万能的
边界条件决定了电磁波跑到仿真区域边缘时会发生什么。最常见的是PML(完美匹配层)——它像一块海绵,把入射波吸收掉,几乎没有反射。但PML也有脾气。
我曾经在一个高Q值微环仿真里,PML设得太薄,结果反射波在腔里来回振荡,Q值怎么算都不对。后来把PML层数从8层加到16层,问题立刻解决。所以我的建议是:PML层数至少12层,靠近波导方向最好16~20层。
| 边界类型 | 适用场景 | 注意事项 |
|---|---|---|
| PML | 开放边界,波导/光栅仿真 | 层数≥12,距离结构≥λ/2 |
| 周期边界 | 周期性光栅阵列 | 需与布洛赫条件配合 |
| 金属边界 (PEC) | 理想导体壁,极少用 | 会全反射,慎用 |
| 对称/反对称 | 结构对称时加速仿真 | 模式对称性必须匹配 |
⚠️ 避坑指南: 我曾经在光栅耦合器仿真里偷懒,把PML设成8层,结果耦合效率算出来比实测高了3dB。后来发现是PML反射回来的能量干扰了光栅的辐射场。记住:PML不是「吸得越干净越好」,而是「够厚、够远」。
4.3 光源激励:模式源 vs 高斯束
光源是仿真的「起搏器」。选对了,结果才真实。在光栅仿真里,最常用的两种光源是模式源和高斯束。
模式源:直接注入波导的基模(或高阶模)。适合研究光栅把波导模式耦合到自由空间的情况。我一般用模式源来扫光栅的耦合效率,因为它能精确控制入射模式。
高斯束:模拟光纤或自由空间光束。适合研究从空间光到波导的耦合,或者光栅的远场分布。高斯束的束腰半径和位置要仔细设,否则耦合效率会偏低。
# 模式源设置 (Lumerical 脚本)
addmode;
set("direction", "Forward"); # 正向传播
set("mode selection", "Fundamental TE"); # 选择 TE 基模
set("x", -5e-6); set("y", 0); # 光源位置
set("wavelength start", 1.5e-6);
set("wavelength stop", 1.6e-6);
# 高斯束设置
addgaussian;
set("direction", "Backward"); # 从上方入射
set("waist radius", 3e-6); # 束腰半径 3 μm
set("angle", 10); # 入射角 10°
set("x", 0); set("y", 5e-6);
选型建议:
- 研究光栅的波导-空间耦合效率 → 用模式源
- 研究光纤到光栅的对准容差 → 用高斯束
- 需要同时看近场和远场 → 两种光源都跑一遍,对比结果
嗯,这里要注意:光源的偏振方向一定要和你的光栅设计匹配。TE模式电场主要在水平方向,TM在垂直方向。搞反了,耦合效率直接掉到接近零。我见过不止一个新手在这个问题上浪费了一整天。
4.4 仿真时间与自动关断
FDTD是时域仿真,你得让电磁波在结构里充分传播、衰减,才能得到稳定的频域结果。仿真时间太短,能量还没衰减完,频谱会有振铃;太长,浪费时间。
大多数商业软件都有「自动关断」功能——当仿真区域内的总能量降到某个阈值(比如1e-5)时,自动停止。我一般设成1e-6,保证精度又不浪费算力。对于高Q结构,可能需要手动延长仿真时间。
set("simulation time", 5000e-15); # 5 ps 仿真时间
set("auto shutoff min", 1e-6); # 能量阈值
💡 经验之谈: 如果你发现仿真结果里频谱有奇怪的波动,先检查仿真时间是不是太短。把时间加倍,如果波动消失,那就是时间不够。如果波动还在,那可能是边界反射或者网格问题。
4.5 完整仿真流程示例
把上面所有东西串起来,一个典型的光栅耦合器FDTD仿真脚本大概长这样。我习惯把设置分成几个块,方便调试。
# ===== 1. 仿真区域 =====
addfdtd;
set("x", 0); set("x span", 14e-6);
set("y", 0); set("y span", 10e-6);
set("mesh accuracy", 3);
addmesh;
set("x", 0); set("x span", 8e-6);
set("y", 0); set("y span", 4e-6);
set("dx", 20e-9); set("dy", 20e-9);
# ===== 2. 边界条件 =====
set("x min bc", "PML"); set("x max bc", "PML");
set("y min bc", "PML"); set("y max bc", "PML");
set("pml layers", 16);
# ===== 3. 光源 =====
addmode;
set("direction", "Forward");
set("mode selection", "Fundamental TE");
set("x", -5.5e-6); set("y", 0);
set("wavelength start", 1.5e-6);
set("wavelength stop", 1.6e-6);
# ===== 4. 监视器 =====
addpower;
set("name", "transmission");
set("monitor type", "2D Z-normal");
set("x", 5.5e-6); set("y", 0);
# ===== 5. 运行 =====
set("simulation time", 5000e-15);
set("auto shutoff min", 1e-6);
run;
跑完仿真,别急着看结果。先检查一下能量是否守恒——入射功率减去反射和透射,应该等于辐射损耗(如果有的话)。如果能量对不上,大概率是边界或网格有问题。
⚠️ 再啰嗦一句: 每次修改结构或光源后,记得重新检查仿真区域是否覆盖了所有重要的场分布。光栅的倏逝场有时候会延伸到你以为「足够远」的地方。我吃过这个亏,后来养成了习惯——每次跑完先看场分布截图,确认场在边界处已经衰减到接近零。