做纳米光学仿真的人,基本都会遇到一个绕不开的问题:球或者柱子的散射光谱出来了,共振峰也看得见,但客户或者说论文审稿人一句“这到底是哪个模式贡献的”,就能把你问懵。单纯说“这是偶极共振”是不够的,你得给出定量的分解:电偶极贡献多少,磁偶极贡献多少,四极又占多少。这个活儿的标准答案就是Mie散射的多级分解(Multipole Decomposition)。
我自己在COMSOL里把这套流程完整跑通过,从最简单的单纳米球,到带衬底的纳米柱阵列,前后踩了不少坑。这篇就把“COMSOL+纳米球/纳米柱+Mie散射多级分解”这一整套东西掰开揉碎讲清楚,包括理论底子怎么补、模型怎么搭、网格怎么剖、数据怎么提、系数怎么算,以及那些文档里不会告诉你的坑。
1. 先搞明白:为什么要做多级分解
1.1 从“光散射”到“模式语言”
光打到纳米颗粒上,颗粒内部的电荷会在入射电场驱动下做受迫振荡,向外辐射电磁波,这就是散射。但一个颗粒表面激发的响应,是入射光直接散射、颗粒内部位移电流、涡旋磁场等一系列效应的叠加。把这些混在一起看,你只能看到“散射强”或“散射弱”,看不到物理图像。
多级分解做的事情,是把颗粒的散射场按球面波函数展开:电偶极(ED)、磁偶极(MD)、电四极(EQ)、磁四极(MQ),以及更高阶项。每一项的系数就代表这个模式对散射的贡献大小。整套数学基础就是1908年Gustav Mie推出来的那套洛伦兹-米散射解。对规则球体,Mie系数是解析的;对非球体,需要数值求解场的分布,再用积分公式提取多级系数。COMSOL干的活,就是把“数值求解麦克斯韦方程组”这部分做掉,多级系数的提取在外面用后处理或者脚本完成。
1.2 为什么磁偶极响应那么受关注
很多人第一反应是:光只和电荷相互作用,哪来的“磁”响应?这个问题的答案在位移电流。高频下,纳米颗粒内的传导电子不产生宏观磁化,但颗粒内部会形成环状位移电流,等效出一个磁偶极矩。当颗粒尺寸和波长可比拟时,这种等效磁偶极响应会非常强,甚至能和电偶极共振叠加,形成所谓的Kerker效应——前向散射增强、后向散射抑制。
搞超表面、搞纳米天线的人对Kerker效应特别敏感。做硅纳米盘(disk)的时候,调节长径比让电偶极和磁偶极共振在同一个波长重合,前向方向性可以到理论极限的4倍。没有多级分解,你根本没法判断两个模式是不是真的重合了。所以这套技术不是学术上的花架子,是实打实的设计工具。
1.3 球和柱:几何带来模式分裂
纳米球和纳米柱在对称性上有本质差别。球是完美球对称,所有方向等价,每个模式是简并的——电偶极在x、y、z三个方向的激发是对称的。圆柱(disk)虽然旋转对称,但光轴方向有了特殊地位。如果光沿柱轴入射,还是能看到简并的偶极模式;如果光垂直柱轴入射(比如沿x方向),柱体在y和z方向的响应不再对称,偶极模式会分裂成两个极化方向不同的共振,谱线位置一高一低。
这个分裂本身就是信息。圆柱的纵横比(高/直径)直接决定了分裂的程度。做柱状超表面的同学就是靠调这个比值来调控共振位置。COMSOL里要对圆柱做参数化扫描,把高度和半径设成参数,一次性扫完,然后看分解结果里各模式系数随纵横比的变化,这个手法在多级分解场景下是效率最高的。
2. COMSOL模型搭建的关键决策
2.1 模块选择和物理场接口
做Mie散射,COMSOL里有两个接口都能跑:一个是RF模块的电磁波(频域),另一个是波动光学模块的电磁波(频域)。对于三维模型,我个人强烈建议用RF模块的“电磁波,频域”接口。原因很简单:RF模块的散射场公式(Scattered Field)收敛性最好,而波动光学模块默认用全场公式,对于散射问题需要手动设置散射边界条件,容易出数值误差。
在模型向导里,空间维度选三维,物理场选“电磁波,频域(ewfd)”,研究选“频域”。求解频率换成波长更直观的话,直接在全局定义里写lambda0这个参数,频率用c_const/lambda0表达。COMSOL 6.x版本里内置了c_const这个物理常数,不用手写299792458。
2.2 散射场公式和背景场设置
这是整个模型最关键的一步。
先解释一下散射场公式的原理:COMSOL求解的是散射场 ( E_{scat} = E_{total} - E_{background} ),其中背景场是入射场(平面波)。你要做的不是让COMSOL去求解总场,而是告诉它“我已知背景场,请只求解散射场”。这样做的好处是:
- 入射场不参与数值误差,因为它是解析给定的
- 散射场的边界衰减更快,PML的吸收负担更小
- 远场计算直接基于散射场,不需要额外减去背景场
在COMSOL里操作:在“电磁波,频域”节点下,把“电场”改成“散射场”。背景电场类型选“用户定义”,然后填入射方向。例如沿x方向传播、沿y方向极化的平面波,写成 ( E_bg = E0 \cdot exp(-i k0 x) \cdot yhat ),注意相位因子用的是减号还是加号,看你的时谐约定。COMSOL默认的时谐因子是 ( e^{i\omega t} ) 还是 ( e^{-i\omega t} ) 取决于你设置的“频率域求解器”约定,默认是 ( e^{-i\omega t} ),所以背景场写成 ( \exp(-i k0 x) )。这个细节错了,后处理的相位会全乱。
2.3 PML和散射边界条件怎么配
完美的边界条件是不存在的,但可以把边界做得“足够好”。
方案一:散射边界条件(SBC)。这是COMSOL内置的一阶吸波边界,对垂直入射的波吸收效果好,但对掠射波有反射。对于纳米球散射,球体会把光散射到各个方向,掠射分量很大,单靠SBC会反射回来干扰近场,导致提取的多级系数有假峰。
方案二:完美匹配层(PML)。这是主流做法。我建议在散射体外面包一层球壳或者方块壳,厚度设为最大波长的1/4到1/2,PML的缩放因子默认即可。关键点是PML内部必须是均匀介质,不能把散射体包进去。散射体周围先留一段“过渡区”,网格用自由三角形/四面体逐渐粗化,再进入PML。
我自己的经验值是:散射体半径 ( r ) 最大到200nm时,过渡区厚度设 ( \lambda_0/2 ),PML厚度设 ( \lambda_0/2 ),整体模型尺寸大概是 ( 5\lambda_0 ) 级别的方块。如果算的是金球(波长在可见光范围),PML厚度取600nm比较稳。这个参数要随着波长扫描变化,扫描的时候直接把PML厚度也设成表达式 ( \lambda_0/2 ) 就好。
2.4 网格剖分:纳米光学仿真的命门
网格的重要性在COMSOL光学仿真里怎么强调都不过分。Mie散射对网格质量的敏感性,仅次于谐振腔。
我推荐的网格策略:
- 散射体内部:最大单元尺寸 ( \lambda_{eff} / 8 ),其中 ( \lambda_{eff} = \lambda_0 / n )(n是颗粒折射率实部)。金在可见光波段折射率虚部大,趋肤深度浅,趋肤深度内至少要有2层网格。
- 散射体外围至PML内边界:最大单元 ( \lambda_0 / 10 ),这是经验下限。如果内存允许,剖到 ( \lambda_0/12 ) 更好。
- PML区域:扫掠网格或者映射网格,保证各向异性拉伸方向层数为8~10层。
- 圆柱的顶面和底面圆弧处:必须加“角细化”或者“边界层”,因为弧形边界是曲率最大的地方,网格粗糙会导致局域电场增强峰值失真。
网格无关性验证:固定波长(比如取共振峰位置),把网格密度乘1.5倍再算,对比散射截面变化小于0.5%就算收敛。注意要对比复数的近场分布,不仅仅是截面标量,否则有可能碰巧截面一致但场分布不一致。
3. 多级系数的提取:从COMSOL数据到物理参数
3.1 远场和截面:COMSOL自带功能的边界
COMSOL的“远场”特征能直接给出散射远场的分布图,但你要的是多级分解系数,COMSOL在标准模块里没有现成的“输出偶极矩”按钮(射频模块的集总端口、S参数这些是微波电路能力,不适用于光学Mie散射)。所以你需要在后处理里自己算。
多级分解计算的底层是用球谐函数展开散射的角分布。这里有两种路线:
路线一:远场积分法。用COMSOL的“远场计算”得到球坐标系下远场方向图 ( E_{ff}(\theta, \phi) ),然后在MATLAB或者Python里对每个球谐函数 ( Y_{lm}(\theta, \phi) ) 做球面积分,得到展开系数。这个方法的好处是COMSOL只负责提供角分布,剩下的用你最熟悉的数学工具处理。坏处是远场网格采样密度不够的话,高阶多级(l≥3)的提取误差会比较大。
路线二:近场体积分法。直接从COMSOL的近场解里提取诱导电流密度 ( J(r) ),用体积分公式计算偶极矩:
[ \mathbf{p} = \frac{1}{-i\omega}\int \mathbf{J} dV ]
[ \mathbf{m} = \frac{1}{2}\int (\mathbf{r} \times \mathbf{J}) dV ]
然后是电四极矩(Q)和磁四极矩(M_Q)。这个路线在圆柱体上比路线一更稳,因为它不依赖远场的角度采样密度,而是直接用体网格里的电流分布积分。
我实际采用的是“近场积分+MATLAB脚本后处理”的组合拳:COMSOL输出诱导电流密度J的体积分数据,导出为txt或直接通过LiveLink for MATLAB调取,然后在MATLAB里完成多级系数计算。这里有个小技巧:COMSOL的“派生值-体积分”里可以直接算 (\int J_x dV) 这类积分,但如果要算整个张量多级系数,导出体网格上的J数据再用外部脚本算反而更快,而且方便复用。
3.2 偶极矩和四极矩的具体公式
不搞复杂推导,我直接给出可用的工作公式。
在SI单位制下,给定时间谐波 ( e^{-i\omega t} ),诱导电流密度 ( \mathbf{J(r)} ) 的多级展开:
电偶极矩:
[ \mathbf{p} = \frac{i}{\omega}\int \mathbf{J} dV ]
磁偶极矩:
[ \mathbf{m} = \frac{1}{2}\int (\mathbf{r} \times \mathbf{J}) dV ]
电四极矩张量(约化形式):
[ \mathbf{Q}{\alpha\beta} = \frac{1}{i\omega}\int [ 3(r{\alpha}J_{\beta} + r_{\beta}J_{\alpha}) - 2\delta_{\alpha\beta}(\mathbf{r}\cdot\mathbf{J}) ] dV ]
磁四极矩张量近似:
[ \mathbf{M}{\alpha\beta} = \frac{1}{3}\int [ (\mathbf{r}\times\mathbf{J}){\alpha} r_{\beta} + (\mathbf{r}\times\mathbf{J}){\beta} r{\alpha} ] dV ]
散射截面(各通道贡献):
[ \sigma_{scat} = \frac{k_0^4}{6\pi I_0} \left( |\mathbf{p}|^2 + \frac{|\mathbf{m}|^2}{c^2} \right) + \frac{k_0^6}{360\pi I_0} \sum_{\alpha\beta} \left( |Q_{\alpha\beta}|^2 + \frac{|M_{\alpha\beta}|^2}{c^2} \right) ]
其中 ( I_0 = \frac{1}{2} \sqrt{\epsilon_0/\mu_0} |E_0|^2 )。
这里特别提醒:在COMSOL里,诱导电流密度J的提取需要勾选“启用感应电流密度计算”相关的后处理选项,并且要区分总电流密度和传导电流密度。对金属颗粒(金、银),吸收损耗通过体积分 (\frac{1}{2}\omega Im(\epsilon)|E|^2) 计算;对介质颗粒(硅、二氧化钛),位移电流占主导,J的重构要小心,直接用COMSOL内置的“电流密度”变量即可,但遇到色散材料时要确认是在频域下计算的,不是把实频域的电流当直流电流。
3.3 MATLAB控制COMSOL:自动化的正确姿势
做多级分解时,只算一个几何、一个波长太浪费了。通常要扫描波长范围(比如400nm到1000nm)加几何参数(比如圆柱半径),每个采样点都要提取多级系数,这用手点鼠标会累死。
我用的是COMSOL的Java API或者LiveLink for MATLAB来做循环控制。工具箱已经内置了LiveLink,不需要额外装。MATLAB脚本可以这样组织:
- 用
mphopen加载构建好的模型文件 - 修改参数(
model.param.set('r', radius_value)) - 求解(
model.sol('sol1').runAll()) - 提取结果(
model.result.numerical('intop1').getReal()) - 计算多级系数,存储到矩阵
- 循环扫下一组参数
Python用户也可以用MPh这个开源库来控制COMSOL,实现类似功能。如果你用的是COMSOL 6.4,它在Windows、Linux和macOS上对LiveLink的支持都很稳定,我没有踩过特别恶性的兼容问题。
我个人建议把“COMSOL计算场”和“多级分解脚本”分开成两个独立模块。COMSOL的任务只负责算出J分布并导出到文件;MATLAB/Python脚本专注做积分和分解。这样即使COMSOL许可证到期或者版本升级,你的分解脚本依然可以用在别的软件(如Lumerical、FDTD Solutions)导出的数据上,复用性很高。
4. 纳米球与纳米柱:建模差异和扫描策略
4.1 纳米球模型:从几何到网格的完整流程
纳米球是最简单也最适合起步验证的模型。几何上就是一个球体,半径r设为参数,材料可以是金、银、硅等。
我以硅球为例跑一遍流程:
新建模型,选择三维、电磁波频域、频域研究。波长范围设400nm到800nm,硅的折射率用COMSOL材料库内置的“Silicon (Palik)”数据,注意它包含了实部和虚部随波长的变化。如果你用的是自己测的椭偏数据,需要插值函数先定义好。
全局参数:
- lambda0:扫描波长(最终向量)
- r:颗粒半径(100nm起步)
- k0:
2*pi/lambda0 - E0:入射电场幅值(1 V/m,线性光学问题,幅值任意)
球体外面建一个立方体(或球壳)作为空气域,空气域外面再建PML层。PML在COMSOL 6.4里有专门的域特征,在“定义”节点下添加“完美匹配层”,然后选择PML域,指定PML类型为球面或笛卡尔。球面PML适用于包围球体的情况,笛卡尔PML适用于长方体计算域。
边界条件:PML外边界设为“散射边界条件”,或者直接默认的PML吸收即可(PML本身已经足够吸波,外面的SBC只是为了数值稳定性)。
网格:球体用“自由四面体”,内部尺寸按前面说的 (\lambda_{eff}/8) 控制。空气域和PML也剖四面体,但PML设“扫掠”网格更合适(PML特征要求网格各向异性层分布合理。如果不方便扫掠,可以允许四面体配合PML的“各向异性缩放”工作,但效果略差)。
求解后,先看远场方向图。如果是200nm的硅球在600nm入射,前向散射明显强于后向,说明有Kerker效应的雏形。然后再提取多级系数,确认此时MD占主导。
4.2 纳米柱模型:旋转对称性的利用
纳米柱(也叫纳米盘)在COMSOL里建模不复杂,就是圆柱体。但物理上有个关键选择:入射方向是沿着柱轴还是垂直于柱轴。
如果是平面波垂直入射(即波矢垂直于柱轴),你可以选择只建半模型或者四分之一模型来节省内存,前提是入射场和几何满足对称性。这时要设置PEC/PMC对称边界(完美电导体/完美磁导体)。模式分解的时候,要记住对称边界会影响模式的本征偏振。四分之一模型虽然快,但是多极分解的积分域要小心处理,建议新手先用全模型跑通,再考虑对称降维。
如果是波矢沿柱轴,柱体截面是圆,旋转对称(CS)可以用来降维:二维轴对称建模可以极大减少计算量。但是,二维轴对称模型只能计算方位角基模(m=0),对偶极子模式的提取范围有限,所以我不推荐用2D轴对称做多级分解。三维模型虽然贵,但拿到的数据是全的,后面怎么分解都不缺信息。
柱体的长径比是核心参数。比如固定半径120nm,扫描高度从50nm到250nm,你会发现消光光谱上出现两个峰:一个是电偶极主导的(大概是短波长侧),一个是磁偶极主导(长波长侧)。两个峰随着高度增加同时红移,但磁偶极的移动量更大。等高度到约200nm时,两个峰重叠,形成超表面里常说的“偶极-磁偶极简并”。用多级分解可以定量跟踪这个过程:把每次扫描得到的p系数和m系数量值画在同一张图上,重叠点就是你要找的设计参数。
4.3 衬底的影响:必须考虑的现实问题
实验室里的纳米颗粒大概率是沉积在玻璃或ITO衬底上的,悬浮颗粒只存在于胶体溶液。衬底打破对称性,散射场不再是纯净的球面波展开,多级系数的提取要考虑衬底反射的路径修正。
处理方式有两种。
方式一是“严格方法”:把衬底一并建在COMSOL模型里,把散射体的近场数据提取出来做多级分解,但分析时要把衬底的贡献从散射场中分出去。这个做法很麻烦,因为衬底本身会产生菲涅尔反射、波导模式,没有明确球心参考点。
方式二是“有效近似”:先算自由空间的多级分解(不考虑衬底),然后单独算衬底反射场对远场的贡献,在远场级别叠加。这个做法物理上不太严格,但对工程估算是够用的。做超表面设计的仿真文章里,很多是直接扫“自由空间+衬底”的完整模型,然后从完整模型的远场里做方向性分析,而不是严格的多级分解。你如果论文需要严格定量,建议直接参考Lumerical的多层衬底远场投影功能,COMSOL这边要手动处理。
从我实操的角度看,如果你的目标是比较不同形貌的颗粒在同样衬底上的散射方向性,直接跑完整模型(含衬底)看远场,比纠结多级系数的衬底修正确实更省时。只有需要判断模式归属时,才用自由空间近似的多级分解。
5. 参数扫描、数据后处理与画图
5.1 在COMSOL里做参数化扫描
COMSOL的“参数化扫描”在研究中直接支持扫描全局参数。设置好波长扫描范围(例如400:20:1000 nm)后,求解器会自动把每个波长的解存成一组,后处理里可以用“数组”选择具体波长。
这里有个效率提示:扫描波长范围如果比较宽,建议开启“自适应网格”或者使用“辅助扫描”将上一步的解作为初值(连续性扫描)。COMSOL的频域求解器默认是直接求解每个频率,不使用上一步结果做初值;但电场随波长变化比较平滑时,开启“运行参数化扫描时使用上一步解作为初始值”可以把总耗时缩短一半以上。做法是:在“研究设置”里勾选“在参数的先前值处使用解作为初始值”,或者在扫描列表里手动指定“初始值来源”。
5.2 从COMSOL导出多级分解需要的数据
从COMSOL导出J分布数据,推荐方式:
在“派生值”里添加“体最大值/体积分”,选择要积分的变量(如
Jx,Jy,Jz,或者ec.Jx)。注意不同版本中电流密度变量的名称可能会有差异,COMSOL 6.x一般是Jx、Jy、Jz,如果你用的是波动光学接口,是ewfd.Jx。如果是要导出全部体网格数据,右键“导出”——“数据”,格式选“文本”,包含表达式里填
x, y, z, Jx, Jy, Jz。这样导出的文件有点大,200nm球体网格约几十万单元会导出几百MB文本,建议用MATLAB处理时以二进制格式(.dat)导出,或者直接在COMSOL体积分里把p、m、Q、M的积分表达式一次性定义好,直接让COMSOL输出系数值。
表达式定义例子:变量名p_x设为(i/omega)*Jx,然后做体积分。这里i是虚数单位,COMSOL用的是i常数。把六组偶极矩分量定义好后,后处理直接读表,不用手动导大数据。我这个做法是经过多次调试确认的。
5.3 画图的三个关键点
第一,截面谱线画双对数坐标。电偶极和磁偶极在小颗粒区域(半径远小于波长)会呈现不同的斜率:电偶极散射截面正比于 ( a^6 ),磁偶极也类似,但系数不同。对数坐标能清楚看出哪个模式在哪个尺寸区间占主导。
第二,多级分解的相位信息别扔掉。很多论文只画各模式的幅值(散射截面),但模式的相位差才是Kerker效应的来源。在MATLAB里把p和m的复数值存成复数数组,画成Argand图,能直观看到相位关系。这个图审稿人非常喜欢。
第三,远场方向图如果只用COMSOL默认的“远场”绘图,增益色标会让人误判方向性。建议导出角度分布数据,在MATLAB里用polarplot或plot重画,并附上均匀球散射的参考曲线。突出前向增强的时候,减去后向值做个归一化处理。
6. 坑点、经验与几个实用排查技巧
6.1 网格相关:结果“看起来对”,但多级系数乱跳
多级分解对网格的苛刻程度,比单纯看吸收截面高一个量级。体积分是通过网格上的J插值积分出来的,如果网格不够细,J的高频振荡(尤其金属颗粒内部)在积分过程中会被数值抹平。我遇到过的情况:消光截面谱线平滑,但把电偶极矩分出来,画出来全是锯齿状,数值在一定范围内来回跳。根源就是球体内部网格太粗。
解决办法:就算不做网格无关性验证,也要在共振峰位置单独做一次加密网格对比。对比目标不是消光截面,而是MD系数的模值偏差,保证1%以内才算收敛。
6.2 PML厚度不足造成的伪散射
PML厚度不够时,掠射方向的散射波会被PML内边界反射回计算域,在远场方向图上形成干涉条纹。排查方法很简单:把PML厚度翻倍重算,看远场曲线是否变化。如果变化了,说明原模型是伪结果。我在做银圆柱时最惨的一次,远场前向散射峰被PML反射干涉完全抹平,翻倍PML后峰出来了。经验公式:PML厚度 ≥ ( \lambda_0/3 )再加10层网格,比较稳妥。
6.3 材料数据不连续导致的光谱跳变
COMSOL材料库里的折射率数据是离散点插值的,不同库给的数据源密度不同,比如Palik数据在红外波段比较稀疏,插值后导数不连续,会让多级系数的谱线出现非物理的毛刺。处理办法是自己定义折射率的样条插值函数(interp函数),用use_spline选项保证平滑,或者把折射率模型用手工公式拟合后再导入。
6.4 内存溢出来了,先别急着换电脑
三维模型加上细网格,自由度轻松过千万,内存不够时COMSOL会提示“内存不足”。这时候可以先检查PML扫掠是否生成了不必要的密集网格,或者把球体对称性用起来(沿入射方向剖半)。实际上,只用自由四面体剖球体内部,外部用扫掠网格(划分成六面体)大幅减少自由度。我已经用这个方法把1200万自由度的问题降到了400万,普通16G内存的机器也能跑。COMSOL 6.4在内存管理上有改进(支持更激进的多核并行),把直接求解器的“内存保存”模式打开,能压得更低。
6.5 暗坑:时谐约定和相位符号
这个坑最防不胜防。COMSOL的频域求解器默认时谐因子是e^{-i\omega t}(在变量omega的定义中有说明),而很多光学论文习惯用e^{+i\omega t}。多级系数公式里带了i,如果把两者的符号搞混,你发现偶极矩的实部虚部对调,p和m的相对相位差 180° 或 90°,Kerker效应完全反了。建议在模型开始前,先用一个已知解析解的标准球验证公式(用Mie系列理论算出来的截面作为基准),确保多级分解脚本正确。
6.6 COMSOL与外部脚本的协同,自动化提效
如果你经常做多级分解,不要每次从COMSOL界面手动导数据算系数,那样既容易错又会消磨耐心。一次性把脚本写好,用LiveLink或者MPh从外部驱动COMSOL结果来做后处理。
用Python做后处理的时候,可以用jcmwave、scipy做球谐函数积分,用单精度读COMSOL导出的数据文件,比用MATLAB更轻便。我个人的工作流是:COMSOL的Job定义好扫描和导出任务,MATLAB脚本做调用与计算结果汇聚,画图用Python的matplotlib统一出图,这个组合在效率和可维护性上是最优的。
7. 一个实操案例:硅纳米盘的多级分解全流程
7.1 建模参数和边界设置
取硅纳米盘,半径120nm,高度160nm,放在玻璃衬底(折射率1.45)上,周围空气。入射平面波沿z方向(垂直于衬底)。分析波长扫描范围700nm到1100nm。
建模:
- 圆柱体:底面半径120nm,高度160nm
- 玻璃衬底:长方体 2x2 um 或者建模时用半无限空间代替,厚度500nm,注意PML要截断厚膜
- 入射场:
E0*exp(-i*k0*z)*xhat,因为波沿z方向
边界条件:PML必须设置在z方向两侧和xy平面四周,底部在衬底下方。否则衬底会无限延伸,数值模型爆掉。
这个模型在本文前几节的原则下运行,网格采用默认物理场控制网格再加密一级。
7.2 结果解读:从多级系数到物理趋势
先看消光光谱。在800nm附近出现一个清晰峰。此时如果只看消光,你说不清它来自哪里。
接着看多级系数。提取电偶极矩p_x和磁偶极矩m_y(这两个在沿z方向入射、x极化条件下是被激发的横向分量)。绘制它们的散射截面贡献曲线。你会发现:800nm峰主要来自磁偶极矩m_y;电偶极矩p_x在约780nm处有一个小峰,而且它的相位和磁偶极矩有大约90°的相位差。这种相位关系导致前向散射增强。用分解的截面叠加,几乎完美复现总消光光谱,这证明分解的物理意义正确。
如果是增大半径到140nm,会出现第三个峰(约900nm),这是电四极矩EQ贡献增强。这时如果你只看到消光上多了一个峰而不做多级分解,可能误判为某个偶极高阶模。分解结果会告诉你它实际上是四极子的贡献。
7.3 参数扫描实现自动追踪共振模式
让半径从100nm扫到160nm(步长5nm),高度固定160nm,波长从700到1100nm扫100步,你会得到一个“半径-波长”复合参数化扫描的消光图谱。对应每个半径,记录磁偶极共振峰的位置。
把共振波长随半径的变化画成曲线,你会发现一条近似线性的红移线。这条“模式轨迹线”对超表面设计特别有用:如果你想要特定波长的磁偶极共振,直接从轨迹线上读半径值即可。COMSOL的“参数化扫描”任务里用“扫描类型:所有组合”可以实现这个双重扫描。
8. 一些经验之谈
做COMSOL光学模型这五六年,我渐渐觉得“多级分解”与其说是一套算法,不如说是一套思考方式。物理场的数值解只是中间产物,把解转化为模式语言,才能从“看到现象”走向“理解机制”。纳米球和纳米柱的散射问题,用多级分解做一次完整的归因分析,往往比闷头扫一百组参数更有价值。
我给新人的建议是:第一,先用Mie理论的解析解验证你的数值分解工具。这一步花一晚上,换来的是剩下所有结果的可靠基础。第二,多级分解的脚本一定要模块化,独立通用化,因为你会反复用到它。第三,不要忽略相位信息,模值和相位一起看,Kerker效应、Fano共振这类现象才讲得清。
最后分享一个小技巧:COMSOL里把所有要提取的多级系数表达式,预先定义成变量列表,然后用后处理的“表格”功能一次性输出,再配合参数化扫描把每个case的记录追加到全局表格里。这样最终得到的表格就是一份清爽的“模式系数—波长—几何参数”数据集,可以直接导入任何绘图软件出论文图。
这套流程跑熟之后,你再看别人的散射光谱论文,会下意识想追问一句:每个峰到底是哪一级的贡献?这种看问题的角度,才是多级分解真正宝贵的地方。