
做硅光的人十有八九绕不开环形谐振器。不管是要做波分复用滤波器、环形调制器还是传感器第一件事通常都是先把环的透射谱算明白。Lumerical在这种场景下几乎是行业默认工具FDTD算法成熟、脚本化能力强从画版图到出曲线一套流程跑下来结果和流片后的测试往往对得上。这篇就按我自己实际跑过的套路完整走一遍SOI平台、5微米半径环形谐振器的仿真流程顺便把Lumerical FDTD学习路径、脚本调用方法、还有那些藏得很深的界面和报错问题一起说清楚。1. 项目概述与设计思路环形谐振器仿真在做什么1.1 环形谐振器在硅光里为什么这么重要环形谐振器的工作原理不复杂。一束光沿直波导传播通过倏逝波耦合进入旁边的环形波导。只有满足共振条件的光——也就是环的等效周长等于波导模式波长整数倍的那些波长——才能在环内反复干涉、积累增强其余波长直接从直波导通过。于是透射端会看到一系列对应共振波长的凹陷这就是经典的全通型陷波响应。这个结构之所以在硅光里无处不在是因为它天然可以做波长选择。改变环半径、波导截面、耦合间隙就能调整谐振波长、自由光谱范围和Q值。相比马赫-曾德尔干涉仪那种大尺寸结构环形谐振器尺寸小、功耗低、选择性高做滤波器、调制器、开关、延迟线都非常合适。我这次仿真的目标是在SOI标准平台上设计一个5微米半径、500纳米波导宽度、200纳米耦合间隙的全通型环形谐振器用Lumerical FDTD计算它在1500到1600纳米波段的透射谱并从中提取谐振波长、Q值、FSR和消光比。1.2 FDTD仿真在整个设计链条里扮演什么角色硅光器件从想法到流片中间隔着漫长的仿真验证。FDTD方法直接在时域求解麦克斯韦方程组空间上离散成Yee网格时间上逐步推进天然支持任意几何形状和非均匀材料的全波仿真。对环形谐振器这种强耦合、多模干涉的结构FDTD是精度最可靠的工具。但FDTD不是唯一的工具。Lumerical套件里还有MODE求解器专门做波导本征模式和色散分析。实际项目里合理的流程是先用MODE算弯曲波导的等效折射率和损耗快速确定半径和截面参数再用FDTD做全波验证拿到透射谱。两者配合既避免一上来就全波仿真导致的时间浪费又能在最后阶段保证结果可信。我第一次跑环形谐振器就是直接开FDTD网格设得细仿真区域又大结果一个波长扫描跑了十几个小时。后来学聪明了先用MODE做预研FDTD只负责最后验证效率提升了不止一个量级。1.3 Lumerical FDTD学习路径怎么安排最省时间经常有人问Lumerical FDTD怎么学。我的建议是不要一开始就啃大器件。Lumerical官方提供了很多示例工程从直波导、Y分支到微环都有先把这些例子跑通理解几个核心概念再说。FDTD学习最核心的五个概念模式光源、监视器、边界条件、网格精度、收敛性验证。模式光源用来注入特定模式的导波监视器用来记录透射率和场分布PML边界用来吸收向外传播的波网格精度决定了空间离散的粗细收敛性验证则是确认结果不随网格加密而明显变化。学习路径上建议按这样的顺序推进先跑一个直波导仿真理解光源和监视器的设置再跑弯曲波导理解模式匹配和损耗然后上环形谐振器把耦合和透射谱跑通最后才是调制器、滤波器这类完整器件。每一步都试着用脚本而不是纯鼠标操作后面会轻松很多。2. 建模前的关键准备先把参数和边界条件想明白2.1 材料与波导尺寸SOI平台的默认选择环形谐振器的材料体系选择直接影响仿真参数的起点。我用的SOI硅光平台是目前最常见的流片平台底层是硅衬底中间是2微米左右的二氧化硅埋氧层顶层是220纳米厚的单晶硅。硅和二氧化硅的折射率差非常大光被限制在顶层硅波导里弯曲半径可以做到很小而不产生严重辐射损耗。仿真中材料模型直接选Lumerical自带的Palik数据即可。硅在1550纳米附近的折射率约为3.48二氧化硅约为1.44这两种材料的损耗都很低在无源器件波段完全可以忽略吸收。要注意的是Lumerical材料库里有多个硅模型有的包含色散有的是常数折射率。对于宽带仿真最好选带色散的Palik模型窄带仿真用常数折射率影响也不大。波导截面尺寸的选取核心是保证单模传输和低损耗。220纳米厚的顶层硅配合450到500纳米宽的波导在1550纳米波段刚好支持TE基模和TM基模其中TE基模是主要用到的模式。波导太宽会出现高阶模太窄则模场扩散、弯曲损耗增大。500纳米宽是我常用的折中值。2.2 用公式先估算谐振波长、FSR和Q值建模之前先用理论公式估算一遍能避免仿真时漫无目的地扫参。环形谐振器的共振条件很简单光在环内走一圈的相位变化必须是2π的整数倍neff × L m × λ其中L是环的周长即2πR。根据波导截面的有效折射率neff就能估算不同m值对应的谐振波长。自由光谱范围FSR是相邻两个谐振波长之间的间隔近似表达式为FSR ≈ λ² / (ng × L)ng是群折射率对于220纳米×500纳米的SOI波导TE基模在1550纳米附近大约为4.2环半径5微米时周长约31.4微米估算出来的FSR大约在18纳米左右。这个值决定了一个波分复用通道内能放下几个谐振峰。Q值表示谐振的尖锐程度定义为谐振波长除以3dB带宽。它与环的损耗直接相关包括弯曲损耗、波导散射损耗和耦合损耗。损耗越大Q值越低。在FDTD仿真之前可以根据目标耦合系数和损耗水平先估算一个预期的Q值范围方便仿真结束后对照验证。2.3 仿真区域、PML边界和网格精度的取舍Lumerical FDTD中仿真区域的选择是个平衡题。区域太大网格数量爆炸仿真时间成倍增长区域太小边界反射和模式截断会影响结果。环形谐振器仿真区域我认为至少需要满足两个条件一是完全包含环形波导和耦合区域二是PML边界距离器件至少半个波长以上。我用的尺寸是x方向18微米、y方向14微米、z方向4微米。x方向要覆盖输入波导和输出监视器的位置y方向要给直波导和环之间的场分布留出空间z方向要包含足够厚的衬底和上包层。边界条件全部用PML。PML是一种人工吸收边界能在边界处几乎无反射地吸收向外传播的波。如果PML离器件太近倏逝波会被PML吸收掉一部分导致Q值偏低。如果器件本身有辐射损耗PML还需要离得更远一些。网格精度是FDTD仿真最核心的取舍点。Lumerical中有网格精度等级设置等级越高网格越密但计算量和内存需求也指数级增长。对于环形谐振器波长1550纳米硅波导截面只有220纳米×500纳米网格至少要能分辨场分布的主要特征。我用的是全局网格精度3级再配合局部网格覆盖区域在波导附近加密到20纳米以内。3. 核心实操从零搭出可出结果的环形谐振器模型3.1 新工程的基础设置与单位确认打开Lumerical FDTD之后第一件事是确认单位设置。Lumerical默认使用SI单位制长度是米频率是赫兹。很多人仿真结果对不上就是因为把微米当成米输入了。我的习惯是新建工程后先用脚本设置好单位usebrowser; set(length unit, m); set(angle unit, deg);接下来在布局编辑器中确认坐标系。Lumerical中z轴默认是竖直方向硅光波导通常沿着x-y平面布局硅层厚度方向沿z。我把硅层放在z0平面衬底向z负方向延伸空气包层在z正方向。确认这些基础设置之后再开始建模后面就不会出现结构位置对不上的问题。3.2 几何建模直波导、环形波导和耦合间隙的准确放法环形谐振器的几何建模分三部分衬底、直波导、环形波导。衬底是一整块二氧化硅矩形覆盖整个仿真区域的下半部分。直波导是一根硅矩形沿x方向延伸。环形波导是一个硅环用内半径和外半径定义。这里有一个容易搞错的地方耦合间隙的定义。我定义gap为环形波导外壁到直波导侧壁之间的空气缝隙。设环中心线半径R波导宽度w则环外壁在yRw/2处直波导中心线应该放在yRgapw处才能保证缝隙正好是gap。例如R5微米、w500纳米、gap200纳米时直波导中心线位于y5.7微米。几何建模用脚本可以精确定位。先建衬底再建输入直波导最后建环形波导addrect; set(name,substrate); set(x,0); set(x span, 20e-6); set(y,0); set(y span, 16e-6); set(z, -1e-6); set(z span, 1.2e-6); set(material,SiO2 (Glass) - Palik); addrect; set(name,bus_waveguide); set(x,0); set(x span, 20e-6); set(y,5.7e-6); set(y span,0.5e-6); set(z,0); set(z span,0.22e-6); set(material,Si (Silicon) - Palik); addring; set(name,ring_waveguide); set(x,0); set(y,0); set(z,0); set(z span,0.22e-6); set(inner radius,4.75e-6); set(outer radius,5.25e-6); set(material,Si (Silicon) - Palik);注意addring创建的是环形几何体内半径与外半径之差等于波导宽度500纳米。比较严谨的做法是把整个模型建好后在查看器里检查一下物体的相对位置确认耦合间隙没有重叠。3.3 模式光源、监视器和边界条件的配置要点光源选择模式光源这是Lumerical中最适合波导仿真的光源类型。模式光源先在指定的波导横截面求解本征模式然后把选定的模式作为激励源注入能够保证注入的是真正在波导中传输的模式而不是自由空间平面波。模式光源放在输入直波导中x-8微米处y方向对准直波导中心z方向覆盖硅层厚度。方向设为正向也就是沿x传播。模式选择TE基模波长范围设为1500到1600纳米这样一次计算能得到完整的透射谱。监视器我放了两个一个透射功率监视器放在输出波导中x8微米处记录透射光的功率一个场分布监视器放在z0平面用于查看谐振时的场增强效果。透射监视器的截面要完全覆盖波导模式通常设置y方向跨2微米、z方向跨1微米就足够了。FDTD区域设置中边界条件全选PML。我的设置是addfdtd; set(name,fdtd_region); set(x span,18e-6); set(y span,14e-6); set(z span,4e-6); set(boundary conditions, {PML,PML,PML,PML,PML,PML}); set(mesh accuracy, 3);这里有个细节PML层有自己的厚度Lumerical中PML占用的空间在FDTD区域边缘自动计算所以实际有效仿真空间比设置的span略小。设计区域时要把这个余量考虑进去。3.4 网格覆盖区算得准与算得快的平衡点全局网格精度设到3级对Lumerical来说是一个比较常规的选择。但环形谐振器的耦合区域对网格非常敏感纯靠全局网格要么精度不够要么计算量太大。我的做法是加一个局部网格覆盖区域把波导所在的带状区域单独加密。网格覆盖区域设置在z方向上覆盖硅层和部分上包层x-y方向覆盖整个环形波导和耦合区。网格尺寸设为dxdy20纳米、dz10纳米。硅波导截面220纳米厚10纳米的z向网格能给出大约22层网格足以分辨模式场分布。addmesh; set(name,mesh_fine); set(x,0); set(x span,12e-6); set(y,0); set(y span,12e-6); set(z,0); set(z span,0.4e-6); set(dx,20e-9); set(dy,20e-9); set(dz,10e-9);网格加密之后还要检查一下计算量。粗略估算12微米×12微米的平面内20纳米步长约600×600个网格点z方向40层总网格数超过1400万。这个规模在单台工作站上需要的内存大约十几GB跑一次100纳米带宽仿真大概需要一到两小时。如果你用的是老机器可以把加密区域缩小到环带和直波导附近或者把dx、dy放宽到30纳米。4. 脚本自动化把GUI操作变成可复现的仿真流程4.1 为什么强烈建议脚本化操作Lumerical提供了完整的脚本接口所有GUI操作都有对应的脚本命令。刚入门时用鼠标点一点很直观但一旦涉及参数扫描和结果批量处理纯GUI操作会让人崩溃。脚本化最大的好处是可复现性同一套脚本换台电脑跑出来结果一致同一个模型改个参数就能批量扫参流程还能挂在服务器上后台运行。另一个好处是便于记录。仿真参数全部写在脚本里时间久了回头再看也知道当初是怎么设置的。这比翻截图高效太多了。4.2 一版可直接改用的LSF脚本结构下面这份脚本是我跑环形谐振器的基础模板涵盖了从清理环境到设置模型再到保存工程的完整流程# ring_resonator.lsf switchtolayout; deleteall; # 参数区 R 5e-6; # 环中心半径 w 500e-9; # 波导宽度 h_si 220e-9; # 硅层厚度 gap 200e-9; # 耦合间隙 lam0 1550e-9; # 中心波长 lam_span 100e-9; # 扫描范围 y_wg R gap w; # 衬底 addrect; set(name,substrate); set(x,0); set(x span, 20e-6); set(y,0); set(y span, 16e-6); set(z, -1e-6); set(z span, 1.2e-6); set(material,SiO2 (Glass) - Palik); # 直波导 addrect; set(name,bus_waveguide); set(x,0); set(x span, 20e-6); set(y, y_wg); set(y span, w); set(z,0); set(z span, h_si); set(material,Si (Silicon) - Palik); # 环形波导 addring; set(name,ring_waveguide); set(x,0); set(y,0); set(z,0); set(z span, h_si); set(inner radius, R - w/2); set(outer radius, R w/2); set(material,Si (Silicon) - Palik); # 光源 addmode; set(name,mode_source); set(x, -8e-6); set(y, y_wg); set(z, 0); set(direction,Forward); set(mode selection, fundamental TE); set(wavelength center, lam0); set(wavelength span, lam_span); # 透射监视器 addpower; set(name,T_monitor); set(monitor type, Linear X); set(x, 8e-6); set(y, y_wg); set(y span, 2e-6); set(z span, 1e-6); # 场监视器 addmonitor; set(name,field_xy); set(monitor type, 2D Z-normal); set(z, 0); set(x span, 12e-6); set(y span, 12e-6); # FDTD区域 addfdtd; set(name,fdtd_region); set(x span, 18e-6); set(y span, 14e-6); set(z span, 4e-6); set(boundary conditions, {PML,PML,PML,PML,PML,PML}); set(mesh accuracy, 3); # 网格覆盖 addmesh; set(name,mesh_fine); set(x,0); set(x span, 12e-6); set(y,0); set(y span, 12e-6); set(z,0); set(z span, 0.4e-6); set(dx,20e-9); set(dy,20e-9); set(dz,10e-9); save(ring_resonator.fsp);这份脚本的思路是参数集中、对象独立、保存工程。不同版本的Lumerical在个别函数名上可能有差异比如监视器类型设置在新版本里改成了下拉枚举但整体结构是通用的。4.3 命令行、MATLAB和Python调用脚本的方式Lumerical脚本可以在软件内部运行也可以通过外部程序调用。软件内部很简单打开脚本编辑器选中全部内容运行即可。外部调用则常用于批量扫描和自动化流程。命令行方式最直接。假设你的Lumerical安装在默认路径脚本保存在C盘模拟目录下可以这样C:\Program Files\Lumerical\v242\bin\fdtd-solutions.exe -run C:\sim\ring_resonator.lsf这个命令会启动Lumerical软件并自动运行指定脚本。如果需要不打开界面直接在后台跑命令行里加上对应的批处理参数Lumerical会以隐藏窗口方式运行适合挂机批量仿真。MATLAB调用是很多工程师的选择。Lumerical提供了MATLAB接口可以在MATLAB中控制仿真进程h appopen(fdtd-solutions); appevalscript(h, cd(C:/sim);); appevalscript(h, run(ring_resonator.lsf);); appevalscript(h, T transmission(T_monitor);); T_data appeval(h, T);Python调用类似通过安装lumapi模块可以在Jupyter环境中完成建模、仿真和数据分析。这种方式对复杂参数扫描特别友好我现在的硅光器件优化基本都是Python驱动Lumerical跑批量的。5. 仿真结果分析与参数提取看懂透射谱才算闭环5.1 透射谱的解读从峰值到谷值仿真结束后第一步是看透射谱曲线。透射率表示输出功率与输入功率的比值Lumerical中可以从监视器对象上获取。Lumerical的模式光源本身功率归一化所以透射率直接反映器件的插入损耗。理想的环形谐振器透射谱是一系列向下的尖峰每个尖峰对应一个谐振波长。非谐振波长的光几乎无损耗地通过直波导透射率接近1谐振波长的光被耦合进入环内在透射端形成凹陷。凹陷的深度取决于耦合强度与环内损耗的匹配程度当两者相等时出现临界耦合理论上消光比可以达到无穷大。如果在透射谱上看到的是向上的峰而不是向下的谷说明光源或监视器设置可能有问题。常见原因是模式方向反了或者监视器记录了背向反射光。5.2 手动计算Q值、FSR与消光比Lumerical本身有内置的分析函数但自己动手提取参数能更深入理解结果。我一般用脚本从监视器获取透射数据然后在脚本里计算关键指标。核心数据获取代码是f getdata(T_monitor,f); lambda 2.998e8 ./ f; T transmission(T_monitor); TdB 10*log10(T);拿到波长和透射率数组后找局部最小值点就是谐振波长。记录谐振波长lambda0找到谷底上方3dB处的两个波长点其差值就是3dB带宽delta_lambdaQ值等于lambda0除以delta_lambda。FSR的提取更简单在透射谱上找两个相邻的谐振谷波长相减就是FSR。如果仿真波长范围太窄只扫到一个谐振峰就提取不出FSR这就要扩大光源的波长范围重新仿真。消光比是谷底透射率相对于非谐振基线透射率的差值单位是dB。消光比越高说明谐振越深滤波性能越好。下面是提取这些参数的核心逻辑# 找透射谷简化示意 T_min 1; for i 1:length(T) if T(i) T_min T_min T(i); idx_min i; end end lambda_res lambda(idx_min); # 计算3dB带宽在谷底加3dB处找左右交叉点 threshold 10*log10(T_min) 3; ... Q lambda_res / delta_lambda;下表是我经常用的参数定义速查方便对照参数物理含义提取方法谐振波长透射谷对应的波长透射谱极小值3dB带宽谷底上方3dB处的宽度从透射谱交叉点读取Q值谐振锐度lambda_res / delta_lambdaFSR相邻谐振峰间隔相邻两个谷的波长差消光比谷深基线透射率减谷底透射率dB5.3 后续参数优化往哪个方向调仿真跑通只是第一步实际工程中往往需要把透射谱调整到目标规格。耦合间隙是影响耦合强度的第一敏感参数。间隙越窄耦合越强谐振谷越深间隙过窄会进入过耦合状态消光比升高但Q值下降。间隙越大则越接近欠耦合Q值高但消光比变差。环半径主要影响FSR和谐振波长。半径减小FSR增大可以放下更多通道但弯曲损耗增加Q值下降。波导宽度影响有效折射率和色散调宽度可以微调谐振波长的具体位置。我做过一批不同间隙的对比仿真gap从150纳米扫到300纳米配合Q值和消光比两个指标选最优值。这种扫描用脚本批量跑非常方便改一个参数重启一遍模型输出结果汇总成表格半小时就能完成一组对比。6. 常见问题与避坑实录界面、学习路径与脚本报错6.1 打开后窗口界面比例不协调怎么处理这个问题我遇到不止一次。Lumerical的老版本基于传统的Tk图形库在Windows高分屏和系统缩放比例125%或150%的环境下经常出现各个窗口比例失调对象树窗口被压得很窄脚本窗口只剩一条缝布局编辑器占了大半个屏幕按钮显示不全字体模糊。第一次遇到的时候我还以为是安装损坏了重装了一遍也没解决。后来摸出了几条有效方案。首选是在Windows里调整兼容性设置右键Lumerical快捷方式属性兼容性更改高DPI设置勾选“替代高DPI缩放行为”缩放执行选“系统”或“系统(增强)”。这一步能解决大部分字体模糊和窗口错乱的问题。其次是软件内部的布局管理。Lumerical的布局是可以通过拖拽分隔条自由调整的把鼠标放在窗口边缘拖到合适比例即可。调整好之后在View菜单里找Save Layout或类似选项把布局存下来下次打开就不会再乱。新版Ansys Lumerical已经重做过UI这类问题基本消失了所以如果条件允许升级软件版本也是一劳永逸的办法。6.2 新人学习FDTD最容易踩的坑我见过太多刚接触Lumerical的朋友第一个模型就卡了好几天。总结下来主要的坑有这么几个。第一个坑是不理解单位。Lumerical默认用国际单位所有几何尺寸都是米。如果你按微米习惯输入5e-6但忘了这个值是5微米后面看物体尺寸时会一脸懵。更严重的是把500纳米输入成500意味着波导宽度比仿真区域还大。第二个坑是忽略PML边界距离。PML确实能吸收大部分向外传播的光但如果器件离PML太近像环形谐振器这种本身就存在倏逝场的结构结果会明显失真。我通常保证器件最外侧到PML边界至少1到2微米。第三个坑是监视器位置选得不合适。透射监视器必须放在单模波导的横截面上而且要远离耦合区域否则记录到的不仅是透射光还有环内泄漏出来的场。第四个坑是网格精度设置走极端。要么全局精度只有1级算出来曲线毛糙不堪要么全局5级精度跑了一周没结果。正确做法是用中等全局精度加局部网格覆盖把资源花在波导和耦合区上。第五个坑是不做收敛性验证。网格密度直接决定FDTD的精度但网格加密到什么程度结果才算可信没有统一答案。负责任的仿真流程是至少对比两套网格密度下的结果如果差异在可接受范围内说明结果收敛了。下面这个表是我常用的问题自查现象可能原因排查方向透射谱全是毛刺网格太粗或监视器位置不当加密网格检查监视器透射率大于1监视器靠近光源或归一化错误移动监视器位置检查归一化谐振峰漂移材料模型或波导尺寸偏差核对材料色散和几何参数仿真时间过长网格过密或Q值过高降低网格精度缩小扫描范围场分布不对称光源方向或结构不对称检查光源和几何对称性6.3 脚本调用报错时的排查思路脚本调用报错是每个人都会遇到的。常见的报错可以归为几类路径问题、语法问题、对象选择问题。路径问题最容易出在外部调用的场景。Lumerical脚本里的文件路径如果有中文、空格或者特殊字符新版本软件可能直接拒绝访问。我的习惯是工程目录全部用英文路径分隔符用正斜杠避免转义问题。语法问题主要出在脚本函数名和参数名上。Lumerical的脚本语言有自己的函数手册不同版本的函数名偶尔会调整。当你从网上复制一段脚本运行时优先确认函数名大小写和参数的拼写是否正确比如set的参数名用引号括起来字符串值也要用引号。对象选择问题常见于刚切换布局的时候就运行脚本。Lumerical脚本执行时有的命令需要先进入布局模式有的命令需要先选中特定对象。如果你在脚本里用switchtolayout切换到布局模式后再逐条添加对象就不容易出现对象查找失败的问题。还有一类问题是内存不足。FDTD网格过密、仿真区域过大内存不够时Lumerical会直接报错中断。看到这类报错先别急着加内存回头看一下网格覆盖区域有没有铺得过大或者仿真时间步数设置是否合理通常都能找到优化空间。最后再分享一个小技巧。调试脚本时不要一次性跑完整段先把脚本分块执行跑完一块就查看一下对象树和几何结构确认没问题再继续下一块。这样即便出错也能马上定位到具体是哪一步造成的。我用这个方法排掉了不少隐蔽的脚本错误希望对你也有效。