admin管理员组

文章数量:1612837

Getting Started with lumopt - Python API

来自 https://support.lumerical/hc/en-us/articles/360050995394-Getting-Started-with-lumopt-Python-API

可以从 CAD 脚本编辑器、命令行或任何 python IDE 运行使用 lumopt 的逆向设计。在第一小节中,我们将简要介绍如何导入 lumopt 和 lumapi 模块;尽管有经验的 python 用户可能会跳过这部分。作为起点,建议运行 AppGallery 示例并将它们用作您自己项目的模板。在您阅读此页面时跟随这些文件可能会有所帮助,或者您可以在稍后运行示例时简单地参考此页面。在项目初始化部分,我们概述了应包含的项目输入和必要的模拟对象。突出了重要的 lumopt 特定注意事项;然而,有效的模拟设置是必不可少的,因此收敛测试应被视为先决条件。下一个重要的 lumopt 设置类,应更新以反映您的规格,并记录在案。最后,介绍了 scipy 优化器和 lumopt 优化类。形状和拓扑优化的主要区别在于它们如何处理可优化几何图形,这是本系列下一页的主题。

一、安装

从 CAD 脚本编辑器运行的优点是无需设置,并使用 Lumerical 安装程序附带的 Python 3 发行版,因此无需安装单独的 Python。 此方法会自动配置工作区以查找 lumopt 和 lumapi 模块,对于没有使用 python 经验的用户来说,这将是首选方法。 对于更有经验的用户来说,使用您自己的 python 版本并从 IDE 或命令行运行可能更可取。 为此,只需导入 lumopt 和 lumapi ,这将需要指定正确的路径。 使用 importlibutil 传递显式路径,或者更新搜索路径以永久附加 PythonPath 对象。 使用大量库的高级用户可能想要创建 Lumerical 虚拟环境。 有关这些方法和操作系统特定路径的更多信息,请参阅会话管理。

注意:
Lumerical 附带一个 Python 3 版本,包括已经安装的 lumapi 和 lumopt 模块。 要“开箱即用”运行我们的任何示例,只需从 CAD 中的脚本文件编辑器运行脚本。

二、项目启动

需要使用以下选项之一定义基础模拟

预定义的模拟文件 - 初始化一个 python 变量,该变量指定基本文件的路径。 示例光栅耦合器(Grating coupler)。

base_sim = os.path.join(os.path.dirname(__file__), 'grating_base.fsp')

一个 lsf 设置脚本 - 使用 load_from_lsf 函数创建一个 python 变量。 波导交叉示例(
Waveguide crossing)。

from lumopt.utilities.load_lumerical_scripts import load_from_lsf
crossing_base = load_from_lsf('varFDTD_crossing.lsf')

使用 API 进行设置的可调用 python 代码 - 这可以是在同一文件中定义的函数或导入的函数。 示例 Y 分支(Y-branch)。

sys.path.append(os.path.dirname(__file__))  #Add current directory to Python path
from varFDTD_y_branch import y_branch_init_ #Import y_branch_init function from file
y_branch_base = y_branch_init_              #New handle for function

每个方法都会生成一个优化器更新和运行的文件。 由于生成的项目文件应该是等效的; 每个用户采用的方法是偏好或方便的问题。

所需对象

在 varFDTD 和 FDTD 基础模拟中,还需要提供输入/输出几何形状并定义 lumopt 使用的以下模拟对象。


图 1:所需的模拟输入

模式源 - 通常命名为源,但可以在优化类(Optimization class)中设置。
覆盖优化体积的网格覆盖区域 - 这是一个静态对象,像素/体素大小应该是统一的。
优化体积上的频率监视器 - 应命名为 opt_field,这些场值对于伴随方法很重要。
输出波导上的频率监视器 - 用于计算 FOM。此监视器的名称被传递给 ModeMatch 类。

模式源应该有足够大的跨度,并且模式应该与预期进行比较,参见 FDE 收敛( FDE convergence)。这被用作前向源。网格覆盖放置在优化区域上,以确保精细均匀的网格覆盖该空间,并使用 opt_field 监视器提取该区域中的场强。 FOM 监视器应与网格单元的界面对齐,以避免插值错误;因此,最好将网格覆盖与 FOM 监视器放在一起。在伴随模拟中,伴随源将代替 FOM 监视器。将 FOM 监视器的名称传递给 modematch 类,允许在同一个基本文件中定义多个 FOM 监视器,这对 SuperOptimization 很有帮助。

三、设置类

应该使用您的参数更新的两个重要的 lumopt 类是波长和模式匹配。 这些用于分别定义 FOM 的光谱和模式数(或极化)。 这里需要注意的是,我们接受的 FOM 是导模的功率耦合(power coupling of guided modes)。 不支持其他品质因数,例如将目标相位或功率优化到指定的光栅阶数。 为了计算宽带品质因数,我们使用 p 范数取目标的平均值减去误差。

其中

•T0 是 target_T_fwd
•λ1 和 λ2 是波长点的下限和上限
•T 为实际模式扩展功率传输
•p 是广义 p 范数( p-norm)的值


Wavelengths

定义模拟带宽和波长分辨率。 定义目标 FOM 频谱是在 modematch 中完成的。

from lumopt.utilities.wavelengths import Wavelengths
class Wavelengths(start,
                  stop,
points)

: start: float

最短波长 [m]
stop: float

最长波长 [m]

points:int

点数,均匀分布,包括端点。

示例

wavelengths = Wavelengths(start = 1260e-9, stop = 1360e-9, points = 11)

ModeMatch

该类用于定义目标模式、传播方向和指定宽带功率耦合。

from lumopt.figures_of_merit.modematch import ModeMatch
class ModeMatch(monitor_name,
                mode_number,
                direction,
                target_T_fwd,
                norm_p,
                target_fom)

: monitor_name: str
文件中 FOM 监视器的名称。

: mode_number : str or int

用于指定模式。

如果使用 varFDTD 求解器:

• ‘fundamental mode’
• int - 用户选择模式号

If the FDTD solver is used:

• ‘fundamental mode’
• ‘fundamental TE mode’
• ‘fundamental TM mode’
• int - user select mode number

: direction : str

方向由FDTD坐标确定; 对于在正方向传播的模式,方向是向前(forward)的。

• ‘Backward’
• ‘Forward’

: multi_freq_source: boolean(布尔值), optional
只能由高级用户启用. See frequency Frequency dependent mode profile for more info. Default = False

: target_T_fwd: float or function
一个函数,它将获取波长点的数量并返回值 [0,1]。 通常作为 lambda 函数(lambda function)或单波长 FOM 的单个浮点值传递。 要指定更高级的频谱,可以定义一个函数,使用 numpy windows作为模板可能会有所帮助。

: norm_p: float
是 FOM 计算中使用的广义 p 范数(generalized p-norm)。 p 范数(p≥1)允许用户增加误差的权重。 由于 p=1 提供了此函数的下限,因此更高的 p 数将增加误差项的权重。 默认 p =1.0

: target_fom: float

品质因数的目标值。 这只会改变打印和绘图的行为。 如果启用此功能,则通过设置 0.0 以外的值,将给出当前 FOM 的距离。 默认 = 0.0

示例

class ModeMatch(monitor_name = 'fom', mode_number = 3, direction = 'Backward', target_T_fwd = lambda wl: np.ones(wl.size), norm_p = 1)

四、优化类

在这里,我们描述了通用的 ScipyOptimizer 包装器,以及用于封装项目的 lumopt 优化类。

ScipyOptimizer

这是通用且强大的 SciPy 优化包的包装器(SciPy optimization package)。

from lumopt.optimizers.generic_optimizers import ScipyOptimizers
Class ScipyOptimizers(max_iter, 
method,
scaling_factor,
pgtol,
ftol,
scale_initial_gradient_to,
penalty_fun, 
penalty_jac)

: max_iter: int
最大迭代次数; 每次迭代都可以进行多次品质因数和梯度评估。 Default = 100

: method: str
选择最小化算法; 只有高级用户才能尝试使用此选项。 Default = ‘L-BFGS-B’

: scaling_factor: none, float, np.array
None、标量或与优化参数长度相同的向量。 这用于缩放优化参数。 从 2021R1.1 开始,形状优化的默认行为是在优化例程中自动映射参数范围 [0,1]; 在拓扑中总是如此。 在几何类中定义的边界( bounds)或 eps_min/eps_max 用于此目的。 Default = None

: pgtol: float
当 max(|proj gi| i = 1, …, n)<=pgtol|时,迭代将停止 其中 gi 是投影梯度的第 i 个分量。 Default = 1.0e-5

: ftol: float
当 ((fk−fk+1)/max(|fk| , |fk+1| , 1))<=ftol. 时,迭代停止。 Default = 1.0e-5

: scale_initial_gradient_to: float
强制重新调整梯度以将优化参数改变至少这么多; 默认值零禁用自动缩放。 Default = 0.0

: penalty_fun: function, optional
将惩罚功能添加到品质因数中; 它必须是一个函数,它接受一个带有优化参数的向量并返回一个值。 高级功能。 Default = None

:penalty_jac: function, optional
惩罚函数的梯度; 必须是一个函数,它接受一个带有优化参数的向量并返回一个相同长度的向量。 如果有一个惩罚_fun 而没有惩罚_jac,lumopt 将逼近导数。 高级功能。Default = None

示例

optimizer = ScipyOptimizers(max_iter = 200,
method = 'L-BFGS-B',
scaling_factor = 1.0,
pgtol = 1.0e-5,
ftol = 1.0e-5,
scale_initial_gradient_to = 0.0,
penalty_fun = penalty_fun,
penalty_jac = None)

Optimization

封装和编排所有优化部分和例程。 调用 opt.run 方法将执行优化。

from lumopt.optimization import Optimization
class Optimization(base_script, 
wavelengths, 
fom,
geometry,
optimizer,
use_var_fdtd,
hide_fdtd_cad,
use_deps,
plot_history,
store_all_simulations,
save_global_index, 
label,
source_name)

: base_script: callable, or str

基础模拟 - 见 项目启动部分
• 工作区中的 Python 函数
• 指向基本文件的字符串
• 从 lsf 脚本加载的变量

: wavelengths: float or class Wavelengths
提供优化带宽。 单波长优化和波长类的浮点值为所有模拟提供了宽带光谱范围。

: fom: class ModeMatch
品质因数 FOM, see ModeMatch

: geometry: Lumopt geometry class
这定义了可优化的几何,请参阅Optimizeable Geometry

: optimizer: class ScipyOptimizers
见 ScipyOptimizer f以获取更多信息.

: hide_fdtd_cad: bool
标记以在后台运行 FDTD CAD。Default = False

: use_deps: bool
标记以使用直接从 FDTD 计算的数值导数。 Default = True

: plot_history: bool
绘制所有参数(和梯度)的历史。Default = True

: store_all_simulations: bool
指示是否应存储每次迭代的项目文件。 Default = True

: save_global_index: bool
标记以在每次迭代后将来自全局折射率监视器的结果保存到文件(用于可视化目的)。Default = False

: label: str, optional
如果优化是超优化的一部分,则此字符串用于相应 FOM 图的图例。 Default = None

: source_name: str, optional
模拟项目中源对象的名称。 Default = “source”

示例

 opt_2d = Optimization(base_script = base_sim_2d,
wavelengths = wavelengths,
fom = fom,
geometry = geometry,
optimizer = optimizer,
use_var_fdtd = False,
hide_fdtd_cad = True,
use_deps = True,
plot_history = True,
store_all_simulations = True,
save_global_index = False,
label = None)

注意(高级):对于 2020R2,我们公开了一个原型用户请求的调试功能,允许用户执行梯度计算的检查。 这是优化类的方法,可以如下调用。

opt.check_gradient(intitial_guess, dx=1e-3)

其中 initial_guess 是一个 numpy 数组,它指定应检查梯度的优化参数。 标量参数 dx 用于中心有限差分逼近

有两个限制;一个是检查执行不必要的伴随模拟。 二是 check_gradient 仅可用于常规优化,不能用于多个 FOM 的超优化。

五、超优化

  • 运算符已在优化类中重载,因此同时优化很简单:

•不同的输出波导和/或波长带 CWDM
•确保平衡的 TE\TM 性能或抑制其中一个
•通过同时优化underetch\overtech\nominal 变化来实现稳健的制造。
•ETC …

只需将各种优化类添加在一起即可创建一个新的 SuperOptimization 对象。 然后,您将在此对象上调用 run 以共同优化各种优化定义。 每次 FOM 计算需要 1 个优化对象,因此每次迭代的模拟次数为 Nsim=2×NFOM。

示例

 opt = opt_TE + opt_TM
opt.run(working_dir = working_dir)

本文标签: 入门PythonLumericallumoptAPI