写这个标题的时候,我正在对着屏幕上一团乱麻的电场模分布发呆。事情是这样的:我想在 COMSOL 里仿真一个径向偏振矢量光束的紧聚焦过程,结果设置了好几次,出来的焦点场要么不对称,要么干脆像被什么东西吸走了一样。折腾了三天,把文档翻了个底朝天,又请教了几位做过类似工作的朋友,才把门路摸清楚。现在回头看,矢量光束在 COMSOL 里的设置并不复杂,难的是你绕不开几个关键概念和坐标系陷阱。这篇东西就是把我的踩坑记录整理出来,给准备入坑电磁光学仿真的朋友一份可以直接抄作业的参考。内容会覆盖从物理模型选择、边界条件设定、表达式书写到网格求解的完整链路,尽量把每一步的“为什么”也讲透。
1. 先把概念拉齐:矢量光束到底在说什么
1.1 不要被“矢量”两个字吓住
很多朋友一看到“矢量光束”就本能地觉得难,其实它在物理上非常直白。普通的高斯光束,我们通常用标量近似描述,电场被当作一个纯量,给定振幅和相位就完了,默认偏振方向恒定。矢量光束则不同,它在光束横截面内各点的偏振方向并不总是指向同一个方向,而是随空间位置变化,最典型的就是径向偏振光束和角向偏振光束。
这种空间变化的偏振状态在紧聚焦、超分辨成像、激光加工等场景里意义重大。因为在高数值孔径透镜聚焦下,标量理论会完全失效,只有完整保留电磁场各个分量的矢量理论才能预测焦点附近的真实场分布。所以在 COMSOL 里做这类仿真,你本质上要解决的是一个三维矢量电磁场问题,而不是简单搬一个解析公式就完事。
1.2 三种常见形态的场上差异
我刚开始时有点混淆,后来用一张表把三种形态的区别和适用场景关系梳理清楚了:
| 光束类型 | 横截面偏振方向 | 焦点处典型特征 | 常见应用 |
|---|---|---|---|
| 线偏振高斯光 | 处处一致(例如 x 方向) | 焦点光斑呈椭圆,长轴沿偏振方向,存在较强的轴向分量 | 传统光学实验、基础教学 |
| 径向偏振光 | 每一点指向径向(从中心向外) | 焦点处轴向电场分量(Ez)很强,横向分量相互抵消,形成小而亮的中心光斑 | 超分辨显微、激光打孔 |
| 角向偏振光 | 每一点垂直于径向(绕中心旋转) | 焦点处形成空心环状暗中心,主要存在横向磁场分量 | 粒子捕获、磁光记录 |
径向和角向这俩名字容易记混。我自己的记忆方法:径向偏振就像磁铁周围的磁感线从中心发散出去,角向偏振就像水流在浴缸里绕圈旋转。搞清楚这点,后面设定表达式就不会晕。
2. 建模前的几个关键决定
2.1 物理场接口到底选哪个
COMSOL 里做这类仿真,正路是选择“电磁波,频域”接口,它属于波动光学模块或 RF 模块的一部分。有人会问:用“电磁波,波束包络”接口行不行?我之前图它网格宽容度好,试过一次,结果发现它对光束的描述依赖你提供的包络函数形式。如果你做的是一个跨尺度、含强聚焦的系统,包络近似很容易失真,还是老老实实求解完整麦克斯韦方程组更稳健。
具体操作路径:模型向导里选择三维或者二维轴对称空间维度,然后添加物理场,选“光学 > 波动光学 > 电磁波,频域”。这个接口求解的是复数电场 E 的频域方程,对材料各向异性、PML、端口、背景场都支持得非常完整,矢量光束设置的所有自由度都在里面。
2.2 轴对称还是全三维,直接影响工作量
这是我在方案上翻过最大的一个车。一开始我用全三维笛卡尔坐标系搭建模型,想着“反正矢量场要各分量都算,三维总是更稳”。结果模型自由度一百多万,跑一次要好几个小时,改一次参数重算,人已经麻了。
后来才发现,对于径向偏振和角向偏振这类具有柱对称性的入射场,如果透镜系统绕光轴旋转对称,那你的仿真模型完全可以用“二维轴对称”来建。这意味着只求解一个 r-z 平面内的场分布,计算量能小一个数量级,而且轴对称公式天然把角向的相位和偏振写进方程里,不需要人为处理。
当然,全三维模型也有它的价值。如果你研究的是偏心入射、多光束干涉、非对称光学系统,那就绕不开三维。问题的关键在于:建立一个空间维度时想清楚,你关注的焦点场是否具备对称性。有对称性却用三维,纯属浪费机时。无明显对称却强行用轴对称,出来的结果肯定是错的。
2.3 初始参数准备
动手建模以前,先把基础参数备好。我以常用的 633 nm 氦氖激光波长举例:
- 波长 λ0 = 633e-9 m
- 频率 f0 = c_const/λ0,其中 c_const 是 COMSOL 内置光速常数
- 光束束腰 w0,根据你要模拟的 NA(数值孔径)换算,一般为 λ 量级
- 透镜焦距 f,在你建立的模型中用于设置边界位置
单位统一用国际单位制,尤其在写表达式时,长度全部用米,电场单位是 V/m。不要出现一处用纳米、一处用毫米的悲剧,我在做模型初期就吃过这个亏,出来的场分布尺度乱得没法看。
材料的设置也别忘了。自由空间传播时折射率设为 1,如果你透镜是玻璃,设置 n = 1.5 左右的折射率材料。高折射率界面的网格要额外注意,不然反射计算会产生错误。
3. 三种矢量光束设置的实操路径
标题既然叫“设置那些事儿”,那必须给足可以直接用的方案。COMSOL 里实现矢量光束入射,我梳理出三条路子,适用场景各不相同。
3.1 路径一:把标量高斯改成简单线偏振(最基础的入口)
如果你只是刚接触这功能,我建议别直接上径向偏振。先从最普通的线偏振高斯光束做起,把流程走通,再逐步升级。
具体的做法:在“电磁波,频域”接口下,给模型添加“散射边界条件”或“端口”边界,把入射场设为高斯光束。对于线偏振,电场只需要指定一个分量,例如:
E_x = E0 * exp(-( (x)^2 + (y)^2 ) / w0^2 ) * exp(-j * k * z)
注意这里使用的是三维笛卡尔坐标。在二维模型中表达式会变为:
E_x = E0 * exp(-x^2 / w0^2) * exp(-j * k * z)
COMSOL 的端口边界里通常预置了“高斯光束”选项,你把偏振设置为 x 方向,填入束腰和波矢就行了。这一步跑通的意义在于,你熟悉了边界条件的使用、监视焦点场的操作、以及如何查看各电场分量。
3.2 路径二:二维轴对称模型下用端口边界注入径向偏振
这就是我最后推荐的主力方案。在二维轴对称模型里,坐标变成了 (r, z),而不是 (x, y, z)。坑就在这儿:你在表达式里写 x 或 y,COMSOL 会直接报错,因为你所在的研究域里根本没有笛卡尔坐标变量。
对于径向偏振光束,我们希望在光束入口处给定一个横向电场的径向分量 Er。数学上,径向偏振高斯光的电场可近似写为:
E_r(r) = E0 * (r / w0) * exp(-(r^2) / w0^2)
这里的 r 在二维轴对称坐标系里是内置变量,直接可用。为了形成沿 z 方向传播的波,还应在表达式中加入相位因子:
E_r(r, z) = E0 * (r / w0) * exp(-(r^2) / w0^2) * exp(-j * k * z)
同时,由于径向偏振光束的横向场并非完全横电磁,它在自由空间传播时存在纵向分量(Ez),严格满足麦克斯韦方程组的径向偏振光束表达式需要包含 Bessel 函数修正。如果你偷懒只给 Er 不给 Ez,COMSOL 的端口边界会默认你提供了一个非物理场,激励出来的结果在近场会比较怪,远场传播后其实也能用,但聚焦焦点的轴向分量(通常是最大的亮点)就缺失了。
我的建议:严格的做法是把常见的径向偏振矢量贝塞尔-高斯光束表达式整组写进去。经典的描述(比如论文经常引用的形式)为:
E_r = E0 * (r / w0) * exp(-(r^2) / w0^2) * exp(-j * k * z) E_z = E0 * (j / k) * ( (2 / w0) * ( (r^2) / w0^2 - 1 ) ) * exp(-(r^2) / w0^2) * exp(-j * k * z)
E_phi = 0
其中 E_z 是纵向分量,来自高斯光束的衍射修正。我在实际建模里会被 COMSOL 表达式解析器报错,常见原因是变量名 w0 定义成了参数,但 k 没定义。先建一个参数列表,k = 2*pi/lambda0,w0 = 5e-6,E0 = 1,再写表达式,就顺了。
入口边界在哪里设置?在二维轴对称模型中,你的模型域通常是一个包括 z 轴的矩形截面,左边界落在 r=0 的对称轴上,下边界或右边界作为光束入射口。在“端口”边界条件里,波形类型选“自定义”,然后把上述三个分量填进去。注意端口边界类型要选“矩形”,端口模式也只有 TE 或 TM 选项,径向偏振里既有 Er 又有 Ez,更像一个 TM 模式,我直接用“自定义模式”绕过了默认限制,实测是更灵活。
3.3 路径三:三维模型下用全局表达式直接定义背景场
三维模型下你必须处理笛卡尔坐标。这时把圆柱坐标转换为直角坐标就躲不掉了。径向偏振光的横向径向单位向量是:
e_r = (x, y, 0) / sqrt(x^2 + y^2)
但要特别注意:如果你直接写成 x/r 和 y/r,在 r=0 处会除以零,COMSOL 在数值求值时会出现奇异点。解决方法是利用 COMSOL 内置的平滑函数,或者人为在分母上加一个小量。我通常用:
Ex = E0 * x / sqrt(x^2 + y^2 + eps^2) * ... Ey = E0 * y / sqrt(x^2 + y^2 + eps^2) * ...
其中 eps 设一个极小的值,比如 1e-12,保证坐标轴上不爆值。
光束在三维里传播的相位项是 exp(-j * k * z),完整表达式为:
Ex = E0 * (x / sqrt(x^2 + y^2 + eps^2)) * (sqrt(x^2 + y^2) / w0) * exp(-(x^2 + y^2) / w0^2) * exp(-j * k * z) Ey = E0 * (y / sqrt(x^2 + y^2 + eps^2)) * (sqrt(x^2 + y^2) / w0) * exp(-(x^2 + y^2) / w0^2) * exp(-j * k * z) Ez = 0
但这样处理出来的纵向分量没有了,所以焦点处亮的只有横向聚焦场,核心轴向场缺位。要彻底解决,推荐用“背景场”加“散射场”的计算模式:在模型里开启“背景场”功能,把上面这个表达式填进去,然后求解散射场,相当于把已知的入射波当成背景,再额外计算由聚焦透镜或纳米结构引起的散射场。这样每步物理场都有明确意义,而且后处理时能分别查看总场、背景场和散射场。
三维全波计算内存开销大,网格需要细化到波长的十分之一甚至二十分之一,3000 万自由度不是梦。如果你机器内存不足,建议还是回到路径二的轴对称模型。机器学习不可硬撑。
4. 网格与求解器配置的细节
4.1 网格尺寸的红线和绿线
COMSOL 默认网格在电磁仿真里经常不够用。频域电磁波的基本要求是最小网格尺寸要远小于波长。我在自由空间传播区域习惯设置为 λ/8 到 λ/12,聚焦区域强制 λ/15 以上。波长 633 nm 时,网格边长就落在 40~80 nm 这个量级。
对于强聚焦问题,光穿过透镜后汇聚到一个极小的焦点,焦点的光强梯度非常大,网格必须局部加密。我通常在焦点位置放置一个小的加密盒或加密圆域,尺寸约为全场的 1/4 波长,然后网格尺寸设为最小。这个操作比全局加密省大量自由度。
边界层也很关键。金属、介质界面、PML 内边界都需要边界层网格去捕捉场突变。尤其是 PML 与传播域的交界面,如果网格不匹配,会出现明显的反射数值伪迹。
4.2 求解器选择与迭代策略
线性求解器方面,首选直接求解器 PARDISO。电磁频域问题矩阵通常高度病态,迭代求解器很容易因为预处理不好而不收敛。PARDISO 吃内存,但鲁棒性最好。我先跑一个波数较低或光束偏移较小的模型做试算,等稳定后再用正确参数继续。
如果模型多自由度逼到几百万量级,算不动,可以考虑用“瞬态”解决思路搭配“频域”的替代方案吗?其实还是建议把模型缩小。别小看二维轴对称降维的效果,同样是算径向偏振聚焦,二维轴对称自由度能少了十几倍,求解时间从天级变成分钟级。
4.3 监视器与后处理技巧
求解完成后,别急着看默认的电场模。矢量光束最重要的信息在分量里。我会在全局计算里分别提取焦点位置 (r=0, z=f) 处的 Ez、Er、Ephi(或者三维下的 Ex、Ey、Ez)数值。比如径向偏振紧聚焦,Ez 应远大过 Ex 和 Ey,如果 Ez 很小,说明你的入口表达式没有把纵向分量写进去。
后处理还可以画二维切片的三分量图。我最常用“二维绘图组”叠加三个子图,分别是 Ex、Ey、Ez 的实部或模分布。通过观察分量图能直接看出模式是否正确、对称性有没有被破坏。
5. 常见问题与排查技巧实录
5.1 焦点场不对称,一半强一半弱
这个问题典型出现在你用了三维模型,而光束入口表达式没有正确区分坐标变换。径向偏振的横向方向必须从光束中心算起,而不是从模型原点算起。如果光束中心在 (x0, y0),你直接写 x 和 y 就会把中心偏移掉,焦点自然一边亮一边暗。修正方式:
Ex = E0 * (x - x0) / sqrt((x - x0)^2 + (y - y0)^2 + eps^2) * ... Ey = E0 * (y - y0) / sqrt((x - x0)^2 + (y - y0)^2 + eps^2) * ...
另一种可能是边界条件设置成了“散射边界”而不是端口,散射边界会把向外传播的场吸收掉,同时也可能让入射波前不完全垂直界面,造成相位畸变。我通常对平面入射用端口,对包裹边界用 PML。
5.2 边界反射导致驻波条纹
如果模型边界处场图出现周期性条纹,十有八九是吸收边界没设置好。端口边界不是吸收边界,只能设定入口波,不能吸收出去的能量。在光束传播的最外层边界必须加 PML(完美匹配层)。PML 的厚度我一般设置为中心波长的 2~4 倍,材料属性保持各向同性默认,但尺度参数要匹配你的波长。如果 PML 太薄或者太接近高 NA 焦场的倏逝波,吸收效果会差,反射回去的成分就会形成驻波。
调 PML 时你可以在后处理里直接看域内总场有没有“回声”。我发现一个旁门左道的验证方法:把一个没有 PML 的模型重算一次,对比两者的焦点场强度,如果差别超过 1%,说明 PML 在影响结果,该加厚或把位置外移。
5.3 表达式报错“未定义变量”
这是最无语但也最常见的报错。COMSOL 的表达式解析器非常严格,里面的变量名区分大小写,内置常数是 c_const、mu0_const、epsilon0_const,不要自己随手写 light_speed。你定义的参数名里尽量别用“lambda”,因为 COMSOL 里有时会把它留作内置变量,你自定义就会冲突。我在参数列表里用 lam0 或者 wl 都顺利,用 lambda 写进去就报错。
另外,二维轴对称模型下请不要试图使用 x、y、z。你只能使用 r 和 z,而且注意 r 在 COMSOL 里代表到轴线的距离,永远非负。如果某个表达式里需要笛卡尔坐标下的 x,你需要到“定义”里手动添加一个变量映射项,比如 X = r*cos(theta),但在轴对称模型中没有 theta 变量,所以径向和角向模式只能通过 r 方向或 phi 方向的场分量来区分。
5.4 角向偏振模式的设置陷阱
角向偏振光的电场只有 phi 分量,在二维轴对称模型里需要设置 E_phi 不为 0。但“电磁波,频域”接口在二维轴对称下默认假设场在方位角方向是均匀的(m=0),对于纯径向偏振这没问题。对于角向偏振,你仍然可以用 m=0 的情况,因为 E_phi 是一个物理分量,电场矢量沿圆周切线方向,其标量大小与 phi 无关。所以要触发角向偏振,你只需要把端口模式设为 E_phi = ...
这里的泄漏点是:在结果后处理中,显示电场模时你可能只看到电场模等于 E_phi,看不到轴向分量。角向偏振光束的聚焦场中心是暗的,这是正常现象,不要以为算错了。
5.5 模型自由度太大,内存崩了
如果你已经把模型降到二维轴对称,还是算不动,就要检查网格数量。看详细的网格统计,如果三角形单元数量高于 50 万,说明你的域设置太大或网格太细。对于自由空间传播的域,没有必要把范围扩展到很大的物理尺寸,域宽度(横向)设置成光束束腰的 3~5 倍就够,纵向只要满足透镜前后工作距离加 PML 缓冲即可。别老想着把整个光路都包进去,计算域越小、越精准,收敛越快。
6. 从标量到矢量:我的工作流与经验补充
我的完整推荐链路是:先扫二维码下载官方文档的“透镜聚焦”案例,但别跑案例,直接在模型向导里自定义域,把入射光束表达式替换成你自己的径向偏振表达式。网格用物理场控制的“细化”起步,然后手动把焦点域加密。求解用“频域”默认研究,PARDISO,求解后立即检查分量分布。
这种流程放在标准办公笔记本上,二维轴对称模型几分钟就能算完。我身边有朋友用三维模型,同样的物理条件,机时从半小时到半天不等,而且网格稍微调整就容易震掉收敛。所以,如果你不是研究偏心结构,强烈建议从二维轴对称入手。
多次踩坑之后我的体会是:矢量光束的仿真功夫不在“向量”而在于“对称性”和“分量一致性”。径向偏振的诀窍是在表达式里同时给出 Er 和 Ez,角向偏振要记得检查暗中心,三维模型则要处理好坐标转换和奇异点。很多人卡了一周,最后发现只是表达式里少了纵向分量或者坐标分母没有加 eps。
最后分享一个小技巧:每次改完表达式,先用极小网格和窄域快速试算一次,只看端口附近的场分布,确认模式形态正确后再全模型计算。矢量光束的边界场特点是识别设置正确与否的最快信号,直线偏振是双瓣(一个方向亮,另一个方向暗),径向偏振是甜甜圈环状分布,角向偏振同样是环但极化方向旋转了 90 度。这个检查做一次,能帮你省下后面排查三天两夜的力气。