4、超表面设计软件入门:主流仿真工具介绍(FDTD、RCWA、CST)

做超表面设计,说白了就是跟光“较劲”。你得先知道光穿过纳米结构后会变成什么样,才能反过来设计结构。这个“知道”的过程,就得靠仿真工具。

我个人习惯把仿真工具分成两类:一类是“全波仿真”,比如FDTD和CST,它们把麦克斯韦方程组从头解到尾,精度高但慢;另一类是“半解析方法”,比如RCWA,它针对周期性结构做了优化,快得多。你想想看,一个超表面动辄几百万个纳米柱,全波仿真根本算不过来,所以实际流程往往是先用RCWA扫参数,再用FDTD验证几个关键点。

4.1 三大主流工具对比

工具 核心算法 适用场景 我踩过的坑
FDTD(Lumerical) 时域有限差分 单个/小阵列纳米结构、近场分析 网格尺寸设太大,共振峰直接消失
RCWA(Reticolo、S4) 严格耦合波分析 周期性超表面、参数扫描 傅里叶阶数设太低,衍射效率算不准
CST Microwave Studio 时域/频域有限积分 太赫兹、微波段超表面 边界条件设成PEC,低频结果全飘了

嗯,这里要注意:FDTD和CST虽然都能算时域,但CST在微波段更顺手,FDTD在光波段更流行。我个人做可见光超表面时,主力是FDTD,偶尔用RCWA做快速筛选。

4.2 软件安装与环境配置

安装这事,说起来简单,但环境配置能卡住不少人。我建议按这个顺序来:

  1. FDTD(Lumerical):去官网下载最新版,安装时选“Custom”,把Python API勾上。为什么?因为后期批量跑仿真要用Python调用。我曾经装完才发现没勾,又重装了一遍,浪费时间。
  2. RCWA(我用的是S4):开源免费,但需要装Lua解释器。下载S4源码后,在Linux或WSL里编译。Windows用户建议直接用Docker镜像,省心。
  3. CST:商业软件,安装时注意license server配置。如果只是学生,可以用教育版,功能受限但够用。
⚠️ 环境变量坑:FDTD安装后,记得把安装路径下的bin目录加到系统PATH里。否则命令行调用fdtd-solutions会报“找不到命令”。我当年在这个问题上折腾了俩小时。

4.3 第一个仿真案例:纳米柱的透射响应

好了,理论说再多不如动手跑一个。咱们做一个最简单的案例:一个圆柱形纳米柱(硅材料),放在玻璃基底上,看它透射率随波长的变化。

为什么选这个?因为这是超表面最基础的单元——你想想看,整个超表面就是由无数个这样的纳米柱组成的。搞懂一个,就搞懂了一半。

4.3.1 在FDTD中建模

# 用Python API创建纳米柱仿真
import lumapi
import numpy as np

# 创建FDTD会话
fdtd = lumapi.FDTD()

# 添加纳米柱(圆柱)
fdtd.addcylinder(
    x=0, y=0, z=0,
    radius=0.1,      # 半径100nm
    z_span=0.6,      # 高度600nm
    material='Si (Silicon) - Palik'
)

# 添加基底
fdtd.addrect(
    x=0, y=0, z=-0.3,
    x_span=2, y_span=2, z_span=0.5,
    material='SiO2 (Glass) - Palik'
)

# 设置光源(平面波,垂直入射)
fdtd.addplane(
    x=0, y=0, z=0.5,
    x_span=1.5, y_span=1.5,
    wavelength_start=0.4e-6,
    wavelength_end=0.8e-6
)

# 添加监视器(透射率)
fdtd.addpower(
    name='transmission',
    x=0, y=0, z=-0.5,
    x_span=1.5, y_span=1.5
)

# 运行仿真
fdtd.run()

# 提取结果
T = fdtd.getresult('transmission', 'T')
wavelength = T['lambda'] * 1e9  # 转nm
transmission = T['T']

print("波长(nm)  透射率")
for i in range(len(wavelength)):
    print(f"{wavelength[i]:.1f}    {transmission[i]:.3f}")
💡 小技巧:第一次跑仿真时,网格精度设成2(默认是1-6)。精度2能保证结果定性正确,跑得快。等参数调优时再提精度。

4.3.2 结果解读

跑完后你会看到透射率随波长变化。正常情况下,在600nm附近会有一个透射谷——那是纳米柱的Mie共振导致的。说白了,就是光被“困”在柱子里转了一圈才出来。

我曾经遇到过一个问题:透射率曲线特别平,没有共振峰。检查了半天,发现是纳米柱的半径设成了1μm而不是100nm。嗯,单位搞错了。FDTD默认单位是米,你输入0.1就是0.1米,不是0.1微米。这个坑,我替你们踩过了。

4.3.3 用RCWA快速验证

同样的结构,用RCWA(S4)算起来快得多。代码长这样:

-- S4 Lua脚本:纳米柱透射率
S4 = require 'S4'

-- 设置仿真参数
sim = S4.NewSimulation()
sim:SetGrid(128, 128)  -- 傅里叶网格
sim:SetWavelength(0.6) -- 单位μm

-- 定义材料
sim:AddMaterial('Si', {3.5, 0})  -- 折射率实部虚部
sim:AddMaterial('SiO2', {1.45, 0})
sim:AddMaterial('Air', {1, 0})

-- 定义层
sim:AddLayer('AirTop', 0.5, 'Air')
sim:AddLayer('NanoPillar', 0.6, 'Air')
sim:SetLayerPatternCircle('NanoPillar', 'Si', 0, 0, 0.1)
sim:AddLayer('Substrate', 0.5, 'SiO2')

-- 设置光源
sim:SetExcitationPlanewave(
    {0, 0},  -- 入射方向(垂直)
    1, 0,    -- 振幅、相位
    0, 0     -- 偏振(TE)
)

-- 计算透射率
for wl = 0.4, 0.8, 0.02 do
    sim:SetWavelength(wl)
    result = sim:GetPowerFlux('Substrate', 1)  -- 向下透射
    print(string.format("%.2f %.4f", wl, result))
end

你看,RCWA的代码更简洁,跑一个波长点只要几毫秒。FDTD跑同样的东西要几十秒。但RCWA只能算周期性结构,而且对非均匀网格支持不好。所以我的工作流是:RCWA扫参数空间,FDTD验证最终设计。

核心要点总结

  • FDTD精度高但慢,适合验证;RCWA快但有限制,适合扫描
  • 安装时一定勾选Python API,环境变量配好
  • 第一个案例跑通后,试着改半径、高度,观察共振峰怎么移动
  • 单位!单位!单位!重要的事说三遍
超表面仿真工作流 1. 定义目标 波长、偏振、相位 2. RCWA参数扫描 半径、周期、高度 3. FDTD验证 近场、远场、效率 OK? 不满足要求?调整参数重新扫描 案例:纳米柱透射响应 Si SiO₂基底 入射光 透射光 半径 r = 100 nm 高度 h = 600 nm 周期 p = 500 nm 波长 λ = 400-800 nm

这张图就是我平时做超表面设计的标准流程。先定目标,再用RCWA快速扫参数,最后用FDTD精算验证。如果结果不理想,就回到RCWA重新扫。循环几次,总能找到最优解。

📌 我的个人习惯:每次跑仿真前,先在纸上画一下结构草图,标清楚尺寸和材料。别小看这一步,能避免很多低级错误。我曾经直接上手建模,结果把纳米柱和基底的顺序搞反了,透射率算出来是负的——嗯,光从基底往上打,能不怪吗?

好了,第一个案例就到这里。你跟着跑一遍,应该能感受到FDTD和RCWA的区别。下一节我们会深入纳米柱的几何参数怎么影响相位响应——那是设计超表面透镜的核心。


专注资料整理