一、设计和优化3D光栅耦合器
1.1 代码讲解
通过预定义的环形间距参数(distances数组),在FDTD中生成椭圆光栅结构,并通过用户交互确认几何正确性后,可进一步执行参数扫描优化。
# os:用于操作系统相关功能(如文件路径操作)
import os
import sys
# lumapi:Lumerical 的 Python API,用于控制 FDTD 仿真
import lumapi
# math:数学计算(如三角函数)
import math
# numpy (np):数值计算(如数组操作)
import numpy as np
# scipy (sp) 和 scipy.interpolate:科学计算(如插值)
import scipy as sp
import scipy.interpolate
# json:处理 JSON 文件
import json
# LumEncoder 和 LumDecoder:自定义 JSON 编码/解码器,用于处理 Lumerical 的特殊数据类型
from lumjson import LumEncoder, LumDecoder
# OrderedDict:保持键值对顺序的字典
from collections import OrderedDict
# 定这是一个光栅耦合器(Grating Coupler)的类,用于存储和优化光栅耦合器的参数
class GratingCoupler:
"""Holds basic parameters of the grating coupler to optimize"""
# __init__ 初始化方法 theta_fib_mat:光纤在材料中的入射角(单位:度,默认 8°) initial_theta_taper:初始锥角(单位:度,默认 30°) optim:是否启用优化模式(默认 False)
def __init__(self, lambda0, n_trenches, n_bg=1.44401, mat_bg="<Object defined dielectric>", n_wg=3.47668,
mat_wg="<Object defined dielectric>", bandwidth=0, wg_height=220e-9, etch_depth=70e-9, wg_width=450e-9,
theta_fib_mat=8, dx=30e-9, dzFactor=3, dim=2, polarization='TE', initial_theta_taper=30, optim=False):
# 存储输入的中心波长、带宽和光栅槽数
self.lambda0 = lambda0
self.bandwidth = bandwidth
# n_trences:光栅槽的数量
self.n_trenches = n_trenches
# 存储波导和背景的几何与材料参数
self.wg_height = wg_height
self.etch_depth = etch_depth
self.wg_width = wg_width # < Only matters for 3D simulation
self.material_name = mat_wg
self.index_wg = n_wg
self.n_bg = n_bg # background refractive index
self.mat_bg = mat_bg
# 定义光纤的位置和模式尺寸
self.x_fib = 18e-6 # 光纤位置(x 方向)
self.x_fib_span = 26e-6 # < Roughly 2.5 * mode diameter 光纤模式直径的 2.5 倍
self.z_fib = 0.5e-6 # 光纤位置(z 方向)
# 定义模式监视器的位置和尺寸(用于计算耦合效率)
self.mode_pos_x = self.x_fib - self.x_fib_span / 2 - 1e-6 if dim == 2 else -1e-6
self.mode_span_y = 3e-6 # 模式监视器的 y 方向跨度
self.mode_span_z = 3e-6 # 模式监视器的 z 方向跨度
# 定义光源的位置(稍微偏移以避免数值问题)
self.bksrc_pos_x = self.mode_pos_x + 100e-9
# 定义仿真网格的尺寸
self.dzFactor = dzFactor # z 方向网格细化因子(默认 3)
self.dx = dx # x 方向网格尺寸
self.dy = dx # y 方向网格尺寸(与 dx 相同)
self.dz = etch_depth / dzFactor # z 方向网格尺寸
## Dimension of the simulation region
# 定义仿真区域的边界(x/y/z 方向的最小/最大值)
self.x_min = self.mode_pos_x - 5 * self.dx
self.x_max = self.x_fib + self.x_fib_span / 2 + 1e-6
self.y_min = -self.x_fib_span / 2
self.y_max = self.x_fib_span / 2
self.z_min = -2.05e-6
self.z_max = 1.5e-6
# 定义优化区域的起始位置(仅优化光栅部分)
self.x_min_opt_region = self.x_fib - self.x_fib_span / 2. if dim == 2 else self.mode_pos_x + 5 * dx
# theta_fib_air = 10
# theta_fib_mat = math.degrees(math.asin(math.sin(math.radians(theta_fib_air))/n_bg))
# 计算光纤在空气中的角度(基于 Snell 定律)
self.theta_fib_mat = theta_fib_mat # math.degrees(math.asin(math.sin(math.radians(theta_fib_air))/n_bg))
self.theta_fib_air = math.degrees(math.asin(math.sin(math.radians(self.theta_fib_mat)) * self.n_bg))
# 填充因子(光栅槽宽度与周期的比例)
self.F0 = 0.95 # < Starting value for the filling factor. Could be up to 1 but that would lead to very narrow trenches which can't be manufactured.
# 定义连接波导和光栅的过渡区域(插值点用于平滑过渡)
self.x_connector_start = -0.5e-6 # 连接器起始位置
self.x_connector_end = 4.0e-6 # 连接器结束位置
self.n_connector_pts = 28 # 连接器插值点数
self.initial_points_x = np.linspace(self.x_connector_start, self.x_connector_end,
self.n_connector_pts + 2) # < x-range for the connector region
# 设置偏振模式和初始锥角
self.pol_angle = 90 if polarization == 'TE' else 0 # TE: 90°, TM: 0°
self.initial_theta_taper = initial_theta_taper # 初始锥角
self.optim = optim # 是否启用优化模式
# 优化模式(optim=True):启用高精度网格设置,用于最终参数优化,确保结果准确,但计算成本高。
# 普通模式(optim=False):使用较粗网格,用于快速验证或初步分析,节省计算资源。
# 设置3D FDTD仿真项目的方法,包括仿真区域、光源、监视器等
def setup_gratingcoupler_3d_base_project(self, fdtd):
# """
# Setup the basic 3D FDTD project with the simulation region, source, monitors, etc.
# """
## CLEAR SESSION
# fdtd.clear()
# 创建新的 FDTD 仿真项目
fdtd.newproject()
# fdtd = lumapi.FDTD(hide=False) # 创建FDTD实例,下载新版本还会出现之前的报错的话把这行注释掉
## Start adding base components
# 禁用图形界面刷新,提升脚本执行速度 禁用图形界面渲染功能,避免仿真过程中实时更新可视化结果,可降低系统资源消耗提升计算效率
fdtd.redrawoff()
## Set FDTD properties
# anti-symmetric:适用于 TE 偏振的边界条件(电场垂直于边界)
# conformal variant 0:标准共形网格细化方法(适合一般结构)
props = OrderedDict([
("dimension", "3D"),
("x min", self.x_min),
("x max", self.x_max),
("y min", self.y_min),
("y max", self.y_max),
("z min", self.z_min),
("z max", self.z_max),
("background material", self.mat_bg),
("y min bc", "anti-symmetric"), # y 下边界条件(反对称)
("simulation time", 5000e-15),
("auto shutoff min", 1e-6), # 自动停止阈值(场能量衰减到 1e-6 时停止)
("mesh refinement", "conformal variant 0"), # 网格细化方法
("meshing tolerance", 1.2e-15), # 网格容差(控制网格密度)控制网格生成精度阈值,数值越小网格越密集(1.2e-15为极高精度)
("use legacy conformal interface detection", False) # 禁用旧版界面检测,采用新版接口识别方法提升网格生成效率和准确性
])
# 处理背景材料和优化模式
if self.mat_bg == "<Object defined dielectric>":
props["index"] = self.n_bg # 自定义背景材料的折射率
if self.optim:
props["mesh refinement"] = "precise volume average" # 优化模式使用精确体积平均法
props["meshing refinement"] = 11 # 网格细化级别(最高为 11)
if self.pol_angle == 0:
props["y min bc"] = "symmetric" # TM 偏振时使用对称边界条件
# 根据属性创建 FDTD 仿真区域
fdtd.addfdtd(properties=props)
# 添加高斯光源
fdtd.addgaussian(name="source", injection_axis="z-axis", direction="backward",
polarization_angle=self.pol_angle, # 偏振角度(TE:90°, TM:0°)
x=self.x_fib, # 光源 x 位置(与光纤对齐)
x_span=self.x_fib_span, # x 方向跨度(覆盖光纤模式)
y_min=self.y_min, y_max=self.y_max, z=self.z_fib, # z 位置(光纤高度)
beam_parameters="Waist size and position", # 高斯光束参数模式
waist_radius_w0=5.2e-6, # 束腰半径 5.2 μm
distance_from_waist=0.0, # 束腰位置与光源重合
angle_theta=self.theta_fib_mat, # 光在材料中的入射角度(例如 8°)
center_wavelength=self.lambda0, wavelength_span=0.1e-6, # 波长范围(100 nm)
optimize_for_short_pulse=False) # 禁用短脉冲优化
# 设置全局光源和监视器参数
fdtd.setglobalsource("center wavelength", self.lambda0) # 全局光源中心波长
fdtd.setglobalsource("wavelength span", 0.1e-6) # 全局波长范围
fdtd.setglobalsource("optimize for short pulse", False) # 禁用短脉冲优化
fdtd.setglobalmonitor("frequency points", 11) # 监视器频率点数,在波长范围内均匀采样 11 个点
fdtd.setglobalmonitor("use wavelength spacing", True) # 使用波长间距(非频率间距)
# 添加光源区域网格 在光源区域设置更细的 z 方向网格,提高仿真精度(但默认不启用)
fdtd.addmesh(name="source_mesh", x=self.x_fib, x_span=24e-6, y_min=self.y_min, y_max=self.y_max, z=self.z_fib,
z_span=2 * self.dz, override_x_mesh=False, override_y_mesh=False, override_z_mesh=True, dz=self.dz)
fdtd.setnamed("source_mesh", "enabled", False) # < Disable by default but need to check the effect
# 添加基底(Substrate)
if self.material_name == "<Object defined dielectric>":
fdtd.addrect(name="substrate", x_min=(self.x_min - 2e-6), x_max=(self.x_max + 2e-6), # 基底 x 范围(超出仿真区域)
y_min=(self.y_min - 2e-6), y_max=(self.y_max + 2e-6), z_min=-4e-6, z_max=-2e-6, # z 范围(位于波导下方)
material=self.material_name, index=self.index_wg, alpha=0.1) # 透明度(可视化用)
else:
# 预定义材料基底
fdtd.addrect(name="substrate", x_min=(self.x_min - 2e-6), x_max=(self.x_max + 2e-6),
y_min=(self.y_min - 2e-6), y_max=(self.y_max + 2e-6), z_min=-4e-6, z_max=-2e-6,
material=self.material_name, alpha=0.1)
# 添加模式监视器 FOM 监视器:测量光栅耦合器的耦合效率(传输到波导的光功率)
fdtd.addpower(name="fom", monitor_type="2D X-normal", x=self.mode_pos_x, y=0, y_span=self.mode_span_y, z=0,
z_span=self.mode_span_z)
fdtd.addmesh(name="fom_mesh", x=self.mode_pos_x, x_span=2 * self.dx, y=0, y_span=self.mode_span_y, z=0,
z_span=self.mode_span_z, override_x_mesh=True, dx=self.dx, override_y_mesh=False,
override_z_mesh=False)
# 添加优化区域监视器 记录光栅区域的电场分布,用于后续优化算法分析
fdtd.addpower(name="opt_fields", monitor_type="3D", x_min=self.x_min_opt_region, x_max=self.x_max,
y_min=self.y_min, y_max=self.y_max, z_min=self.wg_height - self.etch_depth, z_max=self.wg_height,
# z 最小值(刻蚀深度)z 最大值(波导高度)
output_Hx=False, output_Hy=False, output_Hz=False, output_power=False) # 禁用磁场输出 禁用功率输出(仅保存电场)
fdtd.addmesh(name="opt_fields_mesh", x_min=self.x_min_opt_region, x_max=self.x_max, y_min=self.y_min,
y_max=self.y_max, z_min=self.wg_height - self.etch_depth, z_max=self.wg_height, dx=self.dx,
dy=self.dy, dz=self.dz)
# 添加折射率监视器
fdtd.addindex(name="index_xy", monitor_type="2D Z-normal", x_min=self.x_min, x_max=self.x_max, y_min=self.y_min,
y_max=self.y_max, z=self.wg_height - (self.etch_depth / 2.), # z 位置(刻蚀深度中点)
spatial_interpolation='none', enabled=False) # 禁用空间插值 默认禁用
fdtd.addindex(name="index_xz", monitor_type="2D Y-normal", x_min=self.x_min, x_max=self.x_max, y=0,
z_min=self.z_min, z_max=self.z_max, spatial_interpolation='none', enabled=False)
# 添加波导(Waveguide) 波导作用:连接光栅耦合器和芯片其他部分
if self.material_name == "<Object defined dielectric>":
fdtd.addrect(name='wg', x_min=(self.x_min - 2e-6), x_max=2e-6, y=0, y_span=self.wg_width, z_min=0,
z_max=self.wg_height,
material=self.material_name, index=self.index_wg)
else:
fdtd.addrect(name='wg', x_min=(self.x_min - 2e-6), x_max=2e-6, y=0, y_span=self.wg_width, z_min=0,
z_max=self.wg_height, material=self.material_name)
# 添加光栅环形结构 光栅结构:通过环形结构定义光栅的周期性刻蚀
theta_start = self.initial_theta_taper
theta_stop = 360.0 - theta_start # 环形角度范围(对称)
# if self.material_name == "<Object defined dielectric>":
# fdtd.addring(name='silicon', x=0, y=0, z_min=0, z_max=self.wg_height, inner_radius=0, outer_radius=60e-6,
# theta_start=theta_stop, theta_stop=theta_start, material=self.material_name,
# index=self.index_wg)
# else: # 预定义材料光栅
# fdtd.addring(name='silicon', x=0, y=0, z_min=0, z_max=self.wg_height, inner_radius=0, outer_radius=60e-6,
# theta_start=theta_stop, theta_stop=theta_start, material=self.material_name)
if self.material_name == "<Object defined dielectric>":
fdtd.addring(name='silicon', x=0, y=0, z_min=0, z_max=self.wg_height, inner_radius=0, outer_radius=60e-6, make_ellipsoid=True, outer_radius_2=60e-6, theta_start=theta_stop, theta_stop=theta_start, material=self.material_name, index=self.index_wg)
else:
fdtd.addring(name='silicon', x=0, y=0, z_min=0, z_max=self.wg_height, inner_radius=0, outer_radius=60e-6, make_ellipsoid=True, outer_radius_2=60e-6, theta_start=theta_stop, theta_stop=theta_start, material=self.mate