《片上集成光栅的仿真与优化全流程》

第4章 FDTD仿真入门:设置仿真区域、边界条件、光源激励

第4章 FDTD仿真入门:设置仿真区域、边界条件、光源激励

好,到了真正跑仿真的环节了。前几章我们把光栅结构搭好,环境配齐,现在要让它「动」起来。FDTD(时域有限差分法)说白了就是在空间和时间上把麦克斯韦方程组离散化,然后一步步往前推。你想想看,光在波导里怎么传播、怎么从光栅里耦合出来,全看这一步设置得对不对。

我个人习惯把FDTD仿真设置拆成三块:仿真区域、边界条件、光源激励。这三块搞定了,一个仿真基本就立住了。今天咱们一个一个过,中间我会穿插一些我在项目里踩过的坑。

FDTD 仿真三要素 仿真区域 尺寸 · 网格 · 对称性 边界条件 PML · 周期 · 金属 光源激励 模式源 · 高斯束 · 偶极子 三者配合 → 稳定、准确的 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;

跑完仿真,别急着看结果。先检查一下能量是否守恒——入射功率减去反射和透射,应该等于辐射损耗(如果有的话)。如果能量对不上,大概率是边界或网格有问题。

⚠️ 再啰嗦一句: 每次修改结构或光源后,记得重新检查仿真区域是否覆盖了所有重要的场分布。光栅的倏逝场有时候会延伸到你以为「足够远」的地方。我吃过这个亏,后来养成了习惯——每次跑完先看场分布截图,确认场在边界处已经衰减到接近零。