做超表面仿真的人应该都有过这种体验:反射谱里突然冒出一个极窄的峰,宽度只有几纳米甚至更小。第一反应通常是检查是不是FDTD网格没收敛、光源设置有问题、监视器出了bug。排除掉这些之后才发现,它很可能是一个准BIC——连续谱中的束缚态被某种对称性破缺“放”出来以后形成的可辐射暗模式。我最近刚好把一个和“磁偶极子贡献准BIC与多极子分析:斜入射反射相位计算”相关的仿真项目完整推了一遍,从模型搭建到多极子分解,再到斜入射反射相位的提取,中间踩了不少坑。这里把整个思路和操作过程整理出来,尽量写成可以直接照着复现的样子。
这个方向目前的关注度很高。准BIC能把光场局域能力推得很高,又比严格BIC更容易被外部光激发;磁偶极子分量让介质纳米颗粒在光学频段获得了很强的“磁响应”;两者叠加之后,反射相位的控制范围可以做得很宽。这篇文章适合刚接触超表面和纳米光子学仿真的人读,也适合已经会跑反射谱、但想把“模式来源”和“相位行为”讲清楚的研究生和工程师参考。我会把结构选取、FDTD设置、多极子分解、相位提取这些关键环节都按可复现的方式写出来,同时把我实际调试中遇到的坑同步标注上。
1. 先把三个概念拆开:准BIC、磁偶极子和多极子展开为什么放一起
1.1 从BIC到准BIC:一个“被推了一把”的暗模式
BIC,直译是连续谱中的束缚态。它落在辐射连续谱里,却不向外辐射,也不和外部入射场耦合。理解它有个很直观的类比:一个放在屋顶边缘的球,理论上可以在那里保持平衡不掉下来,但任何微小的扰动都会把它推落。在超表面和光栅结构里,这种状态通常出现在结构对称性比较高的参数位置,由对称性保护,表现为Q因子趋近无穷大、谱线上消失。
斜入射正是那个“微小扰动”。入射角偏离特殊角度后,结构对模式的耦合条件发生变化,严格BIC退化成准BIC:模式开始向外辐射,Q因子从无穷大掉到有限值,但通常仍然很高。这个“被推了一把”的暗模式,在反射谱里体现为窄峰或窄谷,在相位谱里体现为剧烈变化。
准BIC的Q因子对对称破缺参数非常敏感,常见的是反平方依赖关系。入射角本身就是一个天然的对称破缺旋钮。我实测下来,从正入射到几度角,峰宽就有数量级的变化。合理选择入射角可以按需控制Q因子,这是直接改结构几何参数时没有的便利,也是这个项目选择斜入射作为激发手段的核心原因。
1.2 磁偶极子:介质颗粒在光学频段的“磁响应”
很多人对光与物质作用的第一反应是电场驱动电子振荡。但介质纳米颗粒内部还有一种很特殊的响应:位移电流形成环形分布后,会表现出等效的磁偶极子行为。简单说,当入射光的磁场分量在颗粒里激励出一个闭合位移电流环,这个环就像一个微型磁偶极子,散射行为与常见的电偶极子完全不同。
这个磁偶极子在暗模式里往往是主导项。尤其是对称破缺后的准BIC,模式内部的电流分布经常呈环形,远场辐射特性接近磁偶极子。如果不做多极子分解,反射谱只能告诉你“这里有个峰”,回答不了这个峰是电主导还是磁主导,更解释不了反射相位为什么在共振附近出现快速变化。模式属性直接决定器件功能,所以磁偶极子要单独拎出来分析。
1.3 多极子展开:给共振做“体检”
多极子分解本质上是一个数学投影:把颗粒内部、或者超表面元胞内的实际感应电流分布,投影到一组基本辐射模式上。这些基本模式包括电偶极子、磁偶极子、电四极子、磁四极子、环形偶极子等等。任何一个复杂电流分布都可以看成这些基础模式的叠加,就像把一段复杂波形拆成不同频率的正弦波。
分解结果直接回答三个问题:散射谱上的峰由哪个极子贡献;这个极子的相对强度怎么变化;模式随入射角如何演变。对这个项目来说,多极子分解是连接“准BIC模式”和“反射相位行为”的桥梁。后面会用分解谱判断准BIC是否磁偶极子主导,再把磁偶极子共振峰位置和反射相位跳变点对照。这个对照就是超表面波前调控设计的核心依据。
2. 结构怎么搭:模型参数、对称性设计与FDTD仿真设置
2.1 结构选取:硅纳米盘和对称性破缺
我用的基础结构没有选太复杂的东西:熔融石英衬底上放一个圆柱形硅纳米盘。直径约500nm,高度220nm,衬底折射率取1.45,硅在近红外取3.5。工作波段放在1300到1500nm,这个范围里硅的虚部很小,可以先忽略吸收。周期取800nm,理由是后面要算反射相位,周期性超表面能给出明确的反射级次;在这个波长和角度范围里,800nm周期可以保证高阶衍射级次基本不出现,反射能干净地定义成0阶反射。
正入射下,圆盘结构对称性很高,某些模式与自由空间连续谱解耦,形成严格BIC。但严格BIC在谱里是看不见的,它不辐射、不响应外部入射。为了把它变成准BIC,需要破坏对称性。破坏方式通常有两种:改结构几何(比如圆盘变椭圆),或者改入射角度。我这个项目选的是保持结构完全对称、只改变入射角。
这个选择有明确理由。扫描几何参数会同时改变共振波长和Q因子,还得重新跑网格收敛和多极子积分,变量之间会纠缠;只扫入射角是纯物理变量,数值格式保持一致,方便后续做多极子分解的对照。想快速验证思路的时候,先动入射角永远是成本最低的方案。
2.2 FDTD里的斜入射设置
斜入射平面波在商业或开源FDTD工具里都不难实现,但有几个细节直接影响结果准确性。
边界条件是最容易错的第一步。周期方向必须用布洛赫边界,不能用普通周期边界,因为平面波斜入射时跨周期边界存在相位梯度;用普通periodic边界相当于把入射角强行拉回正入射,结果会完全错掉。z方向要设置足够厚的PML,光源上方多留一点空间,让散射场充分衰减。
光源设置要明确入射角和偏振状态。反射相位对偏振非常敏感,斜入射下s偏振和p偏振的散射行为差异很大。我做的主要是s偏振,因为磁场分量在结构平面内更容易形成环形位移电流,磁偶极子激发更强;p偏振作为对照也跑了一组,两者谱形差别非常明显。
监视器方面,结构上方放平面监视器记录反射光,结构内放体积监视器记录近场复电场,供多极子分解使用。平面监视器的高度要固定,因为反射相位和参考面相关,后面单独说这个问题。网格方面,我习惯先粗跑确认共振范围,再用最大网格步长5nm以内细扫。500nm量级的硅盘,5nm大约是直径的1%,足够解析准BIC模式的高阶空间分量。再细化到2nm会显著增加内存和时间,但Q因子和相位曲线变化很小,说明已经收敛。
2.3 前期验证:先在正入射下找暗模式,再切斜入射
不要一上来就跑斜入射。先在正入射条件下跑一版,把反射谱、透射谱整体看一遍,结合结构内部近场确认候选暗模式的位置。正入射下真正的BIC不出现响应,但它的邻近区域往往还有其他共振峰可以参考。开始加角度之后,准BIC峰会从某个波长附近“长”出来。
我习惯用两步走:先在正入射宽带扫描,比如1300到1500nm,找候选模式;然后固定候选波长,扫描入射角0到15度,观察峰值是否出现、线宽如何变化;确认模式之后,再把入射角调到目标值,做一个窄带高分辨仿真,把Q因子定量提取出来。
有个识别经验非常关键:如果某个峰在正入射谱里本来就有,加角度只是移动,那它其实不是准BIC;真正的准BIC在正入射下应该是消失的,角度一加才出现。识别错了,后面多极子分解和相位对照都会对不上。
3. 多极子分解怎么做:从近场数据算出磁偶极子贡献
3.1 多极子矩的计算公式与物理意义
多极子分解的出发点是颗粒内部被入射场感应出来的极化电流。频域下,感应电流密度与局域电场的关系是 J(r) = -iω(ε(r) - ε_bg)E(r),其中ε是颗粒材料介电常数,ε_bg是背景介电常数。这个电流只在颗粒体积内不为零,所以体积分的积分域只需要覆盖整个颗粒。
常用的几阶极子矩可以用笛卡尔坐标表示,系数细节在不同文献里有差异,但相对谱形是一致的。这里整理成一张速查表:
| 极子阶数 | 表达式 | 物理含义 |
|---|---|---|
| 电偶极子 p | p = (i/ω)∫ J dV | 电荷分离振荡 |
| 磁偶极子 m | m = (1/(2c))∫ r×J dV | 环形位移电流效应 |
| 电四极子 Q_e | 与 rJ + Jr 相关 | 非对称电荷分布 |
| 磁四极子 Q_m | 与 r(r×J) 相关 | 高阶磁响应 |
| 环形偶极子 T | 与 (r·J)r - 2r²J 相关 | 首尾相接的环形电流场 |
对于单个介质颗粒,散射功率可以近似由这些极子矩的强度叠加描述。磁偶极子的辐射功率正比于|m|²,电偶极子正比于|p|²,四极子项带高阶波矢因子。实际操作中,我不太纠结绝对系数,而是把所有极子贡献按同一归一化标准画在一起,看相对大小。
提示:单颗粒模型里,多极子分解在大球谐展开下是一致的。周期阵列里严格说还受晶格耦合影响,但作为模式判别的第一层近似,直接对元胞内单颗粒做分解已经足够。想更严格的话,需要在k空间做晶格与极子耦合的联合分析。
3.2 从FDTD导出近场数据并计算多极子矩(Python示例)
FDTD里的操作流程一般这样走:
- 在纳米盘内部设置一个长方体体积监视器,覆盖整个颗粒,稍微包含一点边界;
- 监视器属性中勾选要输出的场分量Ex、Ey、Ez,频域范围覆盖共振峰附近的离散频率点;
- 导出复振幅数据,坐标按网格排序;
- 在Python脚本中重新构造三维网格,做体积分。
计算磁偶极子矩和电偶极子矩的核心代码可以写成下面这样:
import numpy as np def calc_p_and_m(x, y, z, Ex, Ey, Ez, omega, eps, eps_bg, dV): """ 输入: x, y, z : 一维坐标(需要先构建网格) Ex, Ey, Ez: 频域复电场分量(三维数组) omega : 角频率 eps : 颗粒介电常数 eps_bg : 背景介电常数 dV : 单位体积 dx*dy*dz 输出: p : 电偶极子矩(复数三维矢量) m : 磁偶极子矩(复数三维矢量) """ # 感应电流密度 Jx = -1j * omega * (eps - eps_bg) * Ex Jy = -1j * omega * (eps - eps_bg) * Ey Jz = -1j * omega * (eps - eps_bg) * Ez c = 299792458.0 # 积分用三维网格 X, Y, Z = np.meshgrid(x, y, z, indexing='ij') # 电偶极子 p_x = (1j / omega) * np.sum(Jx * dV) p_y = (1j / omega) * np.sum(Jy * dV) p_z = (1j / omega) * np.sum(Jz * dV) p = np.array([p_x, p_y, p_z]) # 磁偶极子 m_x = (1.0 / (2.0 * c)) * np.sum((Y * Jz - Z * Jy) * dV) m_y = (1.0 / (2.0 * c)) * np.sum((Z * Jx - X * Jz) * dV) m_z = (1.0 / (2.0 * c)) * np.sum((X * Jy - Y * Jx) * dV) m = np.array([m_x, m_y, m_z]) return p, m这个代码有几个容易出错的地方。第一,dV是常数还是逐点变化取决于网格是否均匀,FDTD导出时网格基本均匀,可以直接取dxdydz;如果局部加密区域存在渐变网格,要逐点计算体积元。第二,体积监视器不要包含大块衬底区域,衬底也是介质,同样会有极化电流;如果只想算纳米盘本身的贡献,让监视器边界刚好落在颗粒表面以内一点最干净。第三,频率点要足够密,否则多极子频谱会漏掉准BIC的窄峰。我习惯在共振区域单独设置窄带、高频分辨率的监视器。
3.3 如何读多极子谱:判断磁偶极子的主导地位
有了p和m在每个频率点的值,就可以算多极子散射贡献。频率扫描后画出|m|²和|p|²随波长的曲线,再把总散射谱叠上去,通常能看到准BIC共振位置处|m|²出现尖峰,而|p|²相对平坦,这就是磁偶极子主导的典型特征。
读图时有两种情况要警惕。第一,颗粒半径偏大的时候,四极子可能在邻近波长也有贡献,谱峰重叠;此时不能只看偶极子项,至少要把电四极子分量也算出来,才能判断谁主导。第二,斜入射角度很小时,准BIC峰极窄,频率分辨率不够的话|m|²峰会变矮、展宽、位置漂移;这种情况必须细化频率采样。
我习惯把|m|²峰位和反射谱峰位放在同一个图上对比。两者波长差小于1nm,就可以认为反射共振就是磁偶极子准BIC贡献的。后续反射相位计算就围绕这个共振展开。
4. 斜入射反射相位计算:从FDTD里提取相位并看懂相位曲线
4.1 反射相位的定义与参考面问题
反射相位不是读软件输出里的某个角度就完事了。它的定义是复反射系数的幅角:r(ω,θ) = E_ref(ω) / E_in(ω),其中所有量都是复电场。在斜入射周期结构中,通常只关心0阶反射。FDTD软件可以直接记录反射平面监视器的复频域场,但斜入射情况下,监视器平面上的入射场相位本身呈线性变化,反射场方向也变了,做比值时要特别注意入射场的参考位置。
参考面是个极容易忽略的坑。同一组仿真,把监视器从结构上方100nm挪到500nm,相位会差出常数项甚至线性项。这不是软件bug,也不是结果错了,而是相位本质上依赖空间参考点。开始扫角度之前就要确定统一的参考面。我一般把参考面取在纳米盘顶面所在平面,所有监视器原始相位都减去对应高度差的传播相位,即 φ_corrected = φ_raw - k0 * 2 * Δh,Δh是监视器到参考面的距离。这样不同入射角、不同波长之间的相位才有可比性。
4.2 提取反射相位的详细步骤(含FDTD操作与后处理)
具体操作流程可以按下面这几步走:
光源设置。使用斜入射平面波,入射角设为θ,偏振设为s或p,入射功率归一化方式选择单光源归一化,保证反射系数直接和自由空间入射平面波比较。
监视器设置。结构上方设点监视器或平面监视器。平面监视器可以通过空间傅里叶变换提取0阶反射;点监视器要手动确认它收集的是0阶分量。周期结构用平面监视器更稳,因为可以明确选择衍射级次。
频域变换。监视器自动做时域到频域变换,得到复电场幅度和相位。导出数据时一定记录复数谱,不要只看幅度。
后处理。用反射场复分量除以入射场复分量,减去参考面传播相位,再用相位解包处理跳变。
代码示意:
import numpy as np # e_ref, e_inc: 复反射场和参考入射场(频域复数数组) r = e_ref / e_inc phase = np.angle(r) # 对频率轴做相位解包 phase_unwrapped = np.unwrap(phase) # 减去参考面修正 phase_corrected = phase_unwrapped - k0 * 2 * delta_h- 参数扫描。每个入射角跑一次完整仿真,波长范围集中在共振附近即可,不需要宽带扫描。只关注准BIC附近的相位突变时,宽带扫描反而会因为远离共振的弱反射信号引入数值噪声。
这个流程跑下来,反射相位曲线在共振频率附近通常是平滑的S形,跨度接近2π或者略大于2π。S形中心波长位置,和前面多极子分解得到的磁偶极子峰位几乎重合。
4.3 相位曲线与准BIC共振的对照解读
S形相位变化不是随机出现的,它直接反映谐振散射对背景反射的干涉。反射光里有一部分是结构顶部和衬底界面的直接反射,也就是背景项;另一部分是准BIC共振激发的再辐射场,也就是共振项。两个复振幅叠加时,共振项在共振附近相位快速旋转,合成反射系数的幅角就会从一端扫到另一端,形成相位跳变。
跳变越陡峭,说明共振Q因子越高、辐射耦合越强。从仿真结果看,入射角从5度变到15度,准BIC的Q因子从一万多降到两千多,相位曲线斜率也随之变缓。这个现象对设计很有用:需要快速相位变化用于波前控制,就选小角度、窄共振;更在意相位曲线线性度和稳定性,就适当加大入射角。
还有个细节值得注意:斜入射下s偏振和p偏振的相位曲线并不对称。s偏振下磁偶极子分量更容易被激发,相位突变点清晰;p偏振下有更多电偶极子和四极子混入,相位曲线不那么干净。做相位计算时,要明确目标应用需要哪个偏振。
5. 实操中的坑:排查清单与避坑技巧
5.1 多极子分解结果不合理的常见原因
遇到最多的情况是,算出来的|m|²谱和散射谱对不上,甚至在正常结构里出现莫名其妙的负值或者峰位偏移。排查顺序一般是:
积分域问题。体积监视器覆盖范围过大,把衬底上表面的网格也算进去了,极化电流多出衬底贡献,极子矩数值漂移。解决方法是把监视器严格限制在颗粒几何边界内,或者导出后手动选取坐标范围。
介电常数差符号问题。J = -iω(ε - ε_bg)E,这里把ε和ε_bg写反,或者忘了减背景介电常数,|m|²谱会整个变形。频率色散材料尤其容易出错,建议先拿一个已知纯电偶极子共振的简单模型验证代码。
频率点不够密。宽带监视器默认输出几百个频率点,在准BIC这种线宽不到1nm的共振上经常漏峰或削峰。我后来改成先宽扫定位、再窄扫细化的策略,共振区域单独加一个高分辨率频域监视器,效果立竿见影。
5.2 反射相位曲线毛刺与跳变
相位曲线出现毛刺,十有八九是信号太弱。远离共振时反射场幅度很小,相位角对数值噪声非常敏感,相位谱上会出现大量随机跳点。正确处理方式是先看反射幅度谱,把幅度低于某个阈值的频率点剔除;如果这些点必须保留,就增加仿真时间让时域信号充分衰减,或者改用窄带光源提高信噪比。
另一种跳变是“真实”跳变。反射系数在某个波长处穿过零振幅点,幅角从π跳到-π,这是数学上的正常现象。用相位解包时,要依据共振区间相邻点跳变小于π的原则选择分段参数;否则解包算法会把真实跳变强行拉平,结果反而更怪。
斜入射下反射监视器如果离结构太近,可能采集到不消散的倏逝场成分,引起相位偏移。我一般让监视器距离结构表面至少λ/2以上,同时保证PML足够远,避免反射场和结构自身二次散射混叠。
5.3 其他容易被忽略的细节
网格方向性。斜入射条件下,入射面内和垂直于入射面的场行为不对称。如果x、y方向网格一样密,问题不大;但为了提速把y方向网格放宽,斜入射的相位曲线可能被拉歪。至少在结构区域内保持各向同性网格。
材料色散吸收。准BIC的Q因子极高时,材料很小的虚部也会限制实际Q值。仿真用非色散无耗模型时,得到的Q因子会乐观到离谱,相位跳变也会过于陡峭。项目早期可以用无耗模型定结构,但要出物理结论时,务必加上材料吸收。
模式漂移。扫描入射角时共振波长通常会有几纳米到几十纳米的移动。如果每个角度都固定同一个观察波长,相位曲线会显得模式消失了。正确做法是每个入射角先找共振峰,再在该峰邻域提取相位;最后把相位作为波长和入射角的二维数据来呈现。
5.4 一个推荐的调试顺序
最后分享一个调试顺序,可以省下很多时间:
- 先把反射谱跑通,在正入射下找候选模式;
- 固定结构,扫入射角,看准BIC峰出现和Q因子变化;
- 打开多极子分解,确认主导极子是磁偶极子;
- 最后做反射相位提取,并和前两步结果对照。
四个环节分开调试,每步数据都确认无误,再合并到一起。前几次我就是图省事直接一步到位,结果多极子分解和相位曲线对不上,回头排查花的时间反而更多。
5.5 一个最值的检查操作:把磁偶极子谱和相位叠在一张图
还有一个我觉得非常值得做的习惯:把|m|²随波长的曲线和反射相位曲线画在同一张图里,横轴统一对齐。相位S形跳变的中心点,几乎正好落在|m|²峰的顶点附近。这个重合意味着什么?意味着相位突变的物理根源就是磁偶极子准BIC共振。
就我个人的实操体验来说,这种“一图双轴”的检查方式比单独看任何一条曲线都要直观。你不需要反复切换窗口就能判断一个结构参数调整之后,共振波长移动、Q因子变化、相位跳变斜率改变三者是否同步。只要三者不同步,大概率是某个仿真环节出了问题:要么多极子分解的监视器域设置错了,要么相位参考面没统一,要么频率采样不够密。这个交叉验证步骤,基本可以作为整套流程的“最终验收”。
如果后面想把项目扩展应用,可以考虑在这个磁偶极子准BIC超表面上做二维相位梯度设计,或者用一组不同半径的纳米盘实现相位离散化。核心思路不变,但仿真流程里要额外注意单元间近场耦合对多极子分解带来的修正,这部分会比单颗粒复杂不少。