先在开篇说一句实在话:DOE和metalens这两类衍射元件,很多搞光学设计的人一听就头大。倒不是因为物理原理有多难,而是光学设计软件里那套“几何光线追踪”的心智模型,碰到衍射元件经常会卡壳——你明明把表面建模出来了,追迹出来的结果却不对,要么效率算不准,要么相位对不上。
这篇文章我用Ansys Zemax OpticStudio来拆一遍,衍射光学元件(DOE)和超透镜(metalens)到底怎么建模、怎么验证。不是堆理论,就是实际工程中能落地的那套流程,包括参数怎么设、采样怎么布、效率怎么看、公差怎么给。无论你是刚接手衍射元件项目的应届生,还是被仿真结果反复折磨的老工程师,这篇都能给你省下不少试错时间。
1. 建模前的思维切换:几何光学与衍射光学的边界在哪
1.1 为什么普通面型建模会失效
OpticStudio里默认的球面、非球面,本质上是让光线按照费马原理走最短光程,适合折射和反射。但DOE和metalens靠的是微结构产生相位突变再通过干涉合成波前,这个逻辑差异极其关键。
举个例子:一束平行光垂直打到普通透镜上,出射的是汇聚球面波。但打到二元衍射面上时,光会同时被分成多个级次(0级、±1级、±2级……),每个级次对应不同的聚焦位置和强度。普通光线追踪只能告诉你“某个局部面法线朝哪”,它没法自己决定“能量分到几级”,更没法给你0级和1级的能量占比。所以把微观锯齿结构一个一个画进CAD再导入,追迹还可能失败,因为OpticStudio需要的是相位信息,不是物理几何本身。
1.2 DOE与metalens:同源但路径不同
DOE通常是连续浮雕或二元台阶结构,特征尺寸从亚微米到几十微米不等,靠台阶高度差产生相位延迟。metalens则是用亚波长纳米柱阵列(常见直径100到500nm)来等效调控相位。在OpticStudio的建模视角里,两者可以用几乎相同的手段处理:把微小结构抽象为一个“相位面”,这个面只知道“在某点给入射光附加多少相位”,不关心底下到底是硅柱子还是台阶。
从工程角度看这个抽象极其重要,它把电磁仿真软件(比如FDTD)和光学设计软件解耦了:微观结构的精确电磁响应交给FDTD去算,整机光路的行为用OpticStudio去追迹。建模时你负责把相位导出成Zemax能识别的格式,验证时再看整机MTF、PSF、衍射效率等指标。
| 维度 | DOE(二元光学) | metalens(超透镜) |
|---|---|---|
| 结构特征尺寸 | 数百纳米到数十微米 | 亚波长(<波长) |
| 相位产生机理 | 台阶高度差 / 浮雕轮廓 | 纳米柱散射共振、相位累积 |
| 软件层面抽象 | 衍射面/相位面均可 | 一般用相位面 |
| 典型设计工具 | 标量衍射理论足够 | 需FDTD先取相位库 |
| Zemax中难点 | 级次处理、台阶离散 | 相位拟合、采样密度 |
1.3 OpticStudio里的三条建模路径
实操中Zemax给出了几种建模方式,要根据项目和精度阶段选:
- 基于面型的Binary Optic(二元面):内置型号比如Binary Optic 2,可以定义台阶数、衍射级次和相位多项式系数,适合DOE的快速评估。
- 用户自定义相位面(User Defined Surface):用DLL或ZPL宏描述相位分布,自由度最高,适合metalens这种没有标准面型的场景。
- 相位掩膜 + 采样数据文件:按网格导入相位值(通常由FDTD或自编脚本导出),适合已经拿到具体结构的仿真结果、想直接验证系统性能的情况。
2. 参数审题:动手前先明确哪些信息决定了成败
2.1 波长与材料:决定相位深度的物理底账
设计DOE和metalens,波长就是“第一宪法”。二元DOE的台阶高度与波长和材料折射率直接挂钩,相位公式为:
[ h = \frac{\lambda}{(n - n_0) \cdot 2^m} ]
其中 ( n ) 为材料折射率,( n_0 ) 是入射介质折射率(通常是空气,取1),( m ) 是二进制台阶位数。2台阶时 ( m=1 ),高度是半波长除以(n-1);4台阶时 ( m=2 ),高度是四分之一波长除以(n-1)。台阶越多,等效相位轮廓越接近理想连续面,衍射效率也越高。
这个公式我建议你在做任何设计前先手算一遍。因为Zemax里输入相位系数时,用户需要把物理高度换算成相位(弧度或波数),换算错一个单位,后面全白搭。
对于metalens,相位分布更直白——只需要满足双曲线相位分布:
[ \varphi(r) = -\frac{2\pi}{\lambda}\left(\sqrt{r^2 + f^2} - f\right) ]
这里 ( r ) 是距离中心的径向距离,( f ) 是设计焦距。公式里没有材料参数,因为它默认每个纳米柱已经被FDTD“调”到恰好提供所需相位延迟了。此时你需要的是一个“单元库”,也就是从FDTD里扫出来的一套“直径→相位”映射表,这张表是否单调、相位覆盖是否满2π,直接决定metalens能不能用。
2.2 口径、F数与NA:决定设计难度的天花板
很多新人上来就设一个2mm口径、F/1的metalens,然后抱怨Zemax跑不动。问题不出在软件,出在参数没审。
口径和焦距决定数值孔径(NA),NA又决定需要多大范围内的相位梯度。金属ens的相位梯度越大,意味着单位周期内相位变化越剧烈,纳米柱的“直径变化率”越陡,工艺容忍度越低。在Zemax中对应的现象是:相位拟合多项式需要很多项,或者网格采样密度要求非常高。
经验上,F数低于2的metalens,设计时就必须考虑相位拟合误差和采样点密度;NA超过0.7时,近似的标量相位方法误差明显,建议在FDTD验证阶段就上全波仿真。F数在2到4之间,用OpticStudio的相位面建模基本够用。
3. 高效建模实操:从相位公式到Zemax模型的完整流程
3.1 用Binary Optic建模表面浮雕DOE
假设我们要设计一个在1064nm下聚焦、焦距50mm、口径20mm的二元DOE。材料用熔石英,折射率1.45。
第一步:计算理想相位分布
焦距50mm,口径20mm,中心到边缘最大径向距离 r=10mm。带入聚焦相位公式,边缘相位(换算成波长数):
[ \varphi_{\text{max}} = \frac{\sqrt{10^2 + 50^2} - 50}{\lambda} \approx \frac{50.99 - 50}{1.064} \approx 0.93 ]
抱歉,这个数算出来不到1个波长,说明这个透镜F数很大(F=2.5),相位变化很小。为了演示二值化的意义,我们把口径扩大到25mm,焦距缩短到30mm:
[ \varphi_{\text{max}} = \frac{\sqrt{12.5^2 + 30^2} - 30}{1.064} \approx \frac{32.5 - 30}{1.064} \approx 2.35 ]
意味着从中心到边缘,去掉整数个波长后还需要提供2.35个波长的相位差。每个波长对应2π弧度,所以Zemax相位面里的最大相位约为14.8弧度。
第二步:把相位连续函数转成二元台阶
取8台阶(即3bit),每个台阶相位步进为 ( 2\pi/8=0.785 ) 弧度。然后用取整函数对理想相位做量化。这里有个容易犯的错误:直接在Zemax面型参数里选Binary Optic 2,然后输入相位系数时,到底要不要自己先量化?
不需要。Zemax内部会根据你设置的台阶数自动做量化处理,你只需要给出连续相位的多项式系数。但必须确认你给的相位多项式形式是幂级数还是Zernike多项式,两者坐标系和归一化半径完全不同。
第三步:在Zemax里建立模型
- 在Surface Type里选择Binary Optic 2。
- Diffraction Order填1(看+1级)。
- Number of Steps填8。
- 在Extra Data Editor里输入相位多项式系数。如果是旋转对称系统,只需要偶次幂项系数。例如用幂级数展开相位分布(单位弧度,半口径归一化): [ \varphi(\rho) = A_2 \rho^2 + A_4 \rho^4 + \cdots ] 其中 ( \rho = r/r_{\text{max}} )。这个系数不是随意给,而是对理论相位做多项式拟合获得的。
这里强烈建议用Zemax自带的优化功能去拟合相位系数,不要手算。方法是建立评价函数,目标函数设置理想的波前相位,或者直接利用ZPL宏循环扫描系数。
3.2 用网格相位面建模metalens
metalens在Zemax里官方推荐的建模方式是Grid Phase面型,或者直接用Zernike Phase面来拟合。区别是:Grid Phase是逐点插值,精度高但数据量大的时候会让文件臃肿;Zernike Phase是模式拟合,平滑但高频成分可能有截断误差。
我的习惯流程:
第一步:从FDTD获得单元库
在Lumerical或FDTD Solutions里按周期边界仿真一个单元,扫描纳米柱直径从100nm到400nm(步长10nm),提取每个直径对应的相位延迟和透过率。确保相位覆盖从-π到+π并且尽量单调递增。透过率在这个阶段就要进行筛选,透过率低于80%的直径点直接剔除。
第二步:计算全局相位分布
根据目标焦距f和工作波长,按公式 ( \varphi(r) = -\frac{2\pi}{\lambda}(\sqrt{r^2+f^2}-f) ) 计算每个坐标点需要的相位。这一步建议在Python或MATLAB里做,离散成跟FDTD仿真相同精度的网格,便于后续映射。
注意,这个公式里r的平方项在口径较大的情况下会产生一个偏置项,不要去手动消掉,直接让Zemax去处理。
第三步:把相位映射到直径
每个坐标点根据相位值反查单元库,找到最匹配的纳米柱直径。注意此时可能出现相位跳变2π的地方需要跨周期处理。做完这个映射,你其实已经知道在物理版图上每个位置放多大直径的柱子了。
第四步:在Zemax里生成Grid Phase文件
用Python脚本把上述相位分布按笛卡尔或极坐标网格导出为Zemax能读的相位图文件。Zemax网格相位的文件格式是:
波长(微米) 尺寸X(mm) 尺寸Y(mm) 像素数X 像素数Y 相位值矩阵(单位:弧度)注意:不同版本对文件格式有细微差异,建议对照Help文档核对。新版本支持有向相位数据,老版本只认标量,推荐先在序列模式下用Grid Phase面型验证,把采样密度控制在128x128或256x256以内,追迹速度才不至于太慢。
4. 验证设计:从点列图到衍射效率全链路校准
4.1 序列模式下的评价函数搭建
对metalen透镜而言,评价函数的设置比传统透镜需要更谨慎。用RMS Wavefront还是RMS Spot Size?焦距、口径、波长定下来后,建议第一步用几何光线追踪算RMS Spot Size来快速判断焦点位置有没有放错。如果几何焦点明显不对,检查相位分布是不是坐标原点没放在透镜中心,或者口径和半口径搞混。
确认焦点位置后,切换到FFT PSF或者Huygens PSF看衍射光斑。需要注意:对于衍射元件,几何光线的行为并不真实反映成像质量,必须用衍射分析去看。Zemax的PSF分析里有个选项是“Use Pupil Sampling”,采样数至少要64x64以上,不然PSF的边缘会出现明显的伪影。
4.2 衍射效率计算:怎么知道能量真的集中在设计级次
衍射效率对DOE就是输出能量中落在设计级次上的比例;对metalens,则要看聚焦光斑能量与总透射能量的比值。Zemax里没有直接给一个数字叫“衍射效率”,但可以用以下变通手段:
- 用探测器面(Detector Rectangle)放在焦平面上,收集焦点附近小区域内的能量,除以透过元件后的总能量。
- 用物理光学传播(Physical Optics Propagation)模块做全链路传播,直接获得焦平面光场分布,然后自己定义积分区域算效率。
第二种方法更靠谱。POP模块里可以设定光束直径、采样网格,衍射元件会被当成相位屏处理,追迹速度比FDTD快若干个量级。注意POP的采样网格要满足奈奎斯特采样条件,网格大小要小于波长/NA。
4.3 真实环境验证:把加工误差和入射角也放进去
设计到软件里完美无缺不算完,DOE和metalens对工艺误差极其敏感。特别是台阶深度误差——8台阶DOE如果深度蚀刻偏5%,一级衍射效率可能从95%掉到85%左右。metalens更夸张,纳米柱直径做偏10nm,相位就可能偏0.2π,焦点强度肉眼可见地下降。
建议在Zemax里用蒙特卡罗公差分析模拟以下三类误差:
- 台阶深度/柱高误差:直接改相位面物理高度或相位系数做灵敏度分析。
- 柱径加工误差:等效为相位噪声,在Grid Phase数据上叠加随机扰动。
- 入射角误差:用倾斜入射光束验证视场表现。
这类公差分析不需要跑全波仿真,用标量模型已经能给出趋势性结论,对工艺参数选择非常有指导意义。
5. 采样、截断与NA的三重矛盾
5.1 为什么网格相位面跑不动
300x300的Grid Phase面与900万个独立数据点,序列追迹时会非常慢;更麻烦的是内存占用。实际上Zemax在追迹时每个光线都要对网格插值,数据点在百万量级时,一条光线可能要微秒级才完成,而一帧会场图需要几十万根光线,时间自然爆炸。
我的经验是:仿真阶段把相位图降到128x128,粗看光斑形态;要精细评估再用256x256。超过512x512除非要出出版级结果图,否则很少需要。
另一种更高效的处理是:用Zernike Phase代替Grid Phase。把相位分布拟合成前15或36项Zernike多项式,追迹速度可以快几十倍。但要注意Zernike拟合对高频相位分量不友好——你如果用Zernike去拟合一个包含2π跳变的相位包裹图,会得到一团乱麻。对策是先对相位做解包裹,得到连续相位,再拟合。
5.2 NA增大后的标量近似失效
当NA超过0.5,金属柱内部的电场分布不完全由局域相位响应决定,还可能存在邻近效应和多模干涉。这时还在Zemax里用纯标量相位面,验证结果和实验的偏差会越来越明显。但这不是Zemax的bug,而是模型边界没划好。
工程上正确划界是:OpticStudio做系统级优化和像差平衡,FDTD做单元级精确标定。两边结合,而不是在一款软件里做完所有事。
6. 常见问题与排查技巧实录
6.1 相位拟合后焦点不在预设位置
新手最常遇到的坑。检查方向依次是:
- 相位公式里的f用的是焦距还是后焦距。Zemax默认从表面顶点到焦点的距离,如果第一面有厚度,别把厚度忘掉。
- 多项式归一化半径有没有设置正确。Zernike系数的归一化半径默认是表面半口径,如果你的有效半口径是12.5mm,但系统口径是25mm,那就差一倍。
- 相位符号反了。聚焦透镜的相位分布是负的二次项,如果你填成正的,出来的就是发散透镜。
6.2 衍射效率算出来不对
如果你用Detector Rectangle去算效率,注意积分区域的尺寸必须包含中心艾里斑能量的大部分,但又不能太大以至于把旁瓣也算进去。建议以理论艾里斑半径为依据,取半径的1.5到2倍做积分。
另一个常见问题是光源类型。用Incoherent Irradiance计算时,能量是按强度叠加的,但衍射元件的设计基于相干光场叠加,两者会有一个明显的偏差。务必用Coherent Irradiance来算。
6.3 POP运行报错:采样网格分辨不足
遇到这个报错先看NA和波长:网格间隔需要小于约 ( \lambda/(2NA) )。比如1.064um波长、NA=0.5,网格间隔要小于约1.064um。如果你默认用了32x32采样,实际物理网格可能有几百微米,肯定不满足。把采样点提高到512或者1024,通常就能通过。
但要注意,采样点增加会让计算时长呈平方上涨,此时先用小口径验证再全口径跑,别一上来就挑战最大阵面。
6.4 公差分析跑不起来
公差分析默认是针对标准面的,你用Grid Phase或Binary Optic 2的时候,很多公差操作数不适用。比如TTHI对衍射面的相位高度没有作用,因为相位面的厚度本质是虚的。
处理方法是:把相位误差等效成波前误差,用TWR或TEXI类操作数代替;或者用自定义变量去扫描相位多项式系数的一阶变化,间接评估深度误差。
7. 案例复盘:完成一个10mm口径metalens的全流程验证
最后把我自己做的一个典型项目流程完整列出来供参考。设计目标:10mm口径、30mm焦距、1550nm工作波长、NA约0.16的metalen透镜。
- 第一步,FDTD扫描单元库:SiO2基底上a-Si纳米柱,高度600nm,周期800nm,柱径从200到500nm,提取相位和透射率曲线,确认相位覆盖超过2π,最大透射率波动小于15%。
- 第二步,Python计算理想相位分布,1mm步长网格,导出Grid Phase文件。
- 第三步,Zemax里建序列系统:准直光源→Grid Phase面→30mm空气→像面。
- 第四步,检查几何焦点:RMS Spot Radius约15um,接近衍射极限。
- 第五步,改用POP分析:采样1024x1024,得到焦面PSF,计算1.5倍艾里斑内能量占比约87%。
- 第六步,做公差分析:柱径误差±20nm时,聚焦效率下降到约78%,判断工艺窗口可接受。
整个流程从拿到相位数据到输出设计报告,一个下午能完成。相比每轮都跑全波仿真,效率提升非常明显。
有了这套流程,你可能会发现:DOE和metalens在OpticStudio里并没有想象中那么玄乎。关键是把物理问题拆成相位面,再用合适的采样和验证手段去把控精度。我个人做下来感触最深的一点是——不要把所有的精度压力都给建模工具,模型的边界划到哪里、用什么精度验证,每一步都要心里有数。这样出来的结果,才对得起工艺线上那几十道工序。