3. 仿真工具链与环境搭建

异质集成光子器件的多物理场仿真很少能靠单一软件完成。一个典型的硅光—铌酸锂混合调制器,往往需要 Lumerical 求解光场模式与传输,COMSOL 处理电光耦合与热漂移,Sentaurus 或 Silvaco 提供载流子输运与器件级电学特性,最后由 Python 把各家的输入输出串成可复现的流水线。本节讨论的不是“装好软件”,而是如何让这四类工具在同一套环境里协同工作,并把版本控制与自动化真正落到工程实践中。

工具分工与数据接口

先明确各工具在链路中的位置。Lumerical(FDTD/MODE/CHARGE/HEAT)擅长微纳光子结构的光场求解,输出模式有效折射率、群折射率、损耗、S 参数;COMSOL 的强项是任意几何下的多物理场耦合,尤其是电光、热光、声光同时作用的场景;Sentaurus Device 与 Silvaco Atlas 则面向半导体工艺与器件级 TCAD,能给出掺杂分布、载流子浓度、I-V/C-V 曲线。它们之间的数据交换通常有三条路径:几何与网格文件(GDSII、STL、SAT)、场数据(.mat、.h5、.csv)、以及参数化脚本调用。

实际工程中,最容易被忽视的是坐标系与单位约定。Lumerical 默认使用米制并常以 μm 显示,COMSOL 的几何单位可自定义,Sentaurus 的网格文件以 μm 为单位。若在导入时不做统一,一个 500 nm 波导可能在另一工具里变成 500 μm。建议在项目根目录建立 units.md,明确:长度统一用 μm,时间用 ps,频率用 THz,角度用度,并规定所有导出 CSV 的第一行为单位注释。

Python 脚本接口:把工具变成函数

Lumerical 提供 Python API(lumapi),COMSOL 提供 mph 或 Java API 的 Python 封装,Sentaurus 可通过 sde/sdevice 的命令行与 TCL 脚本驱动,Silvaco 则常用 deckbuild 批处理。把这些调用封装成 Python 函数,是自动化工作流的第一步。下面是一个最小可用的封装示例,用于批量扫描波导宽度并提取有效折射率:

import lumapi, numpy as np, pandas as pd

def run_mode_sweep(widths_um, out_csv="neff_sweep.csv"):
    fdtd = lumapi.MODE(hide=True)
    rows = []
    for w in widths_um:
        fdtd.switchtolayout()
        fdtd.setnamed("waveguide", "width", w*1e-6)
        fdtd.run()
        neff = fdtd.getresult("mode1", "neff")
        rows.append({"width_um": w, "neff": float(np.real(neff))})
    fdtd.close()
    pd.DataFrame(rows).to_csv(out_csv, index=False)
    return out_csv

run_mode_sweep(np.linspace(0.4, 0.8, 9))

这段代码的关键点在于:每次修改几何前必须 switchtolayout(),否则参数不会生效;getresult 返回的是复数,需取实部;结果直接落盘为 CSV,便于后续与 COMSOL 或 TCAD 数据合并。示例中扫描 0.4–0.8 μm 共 9 个点,属于教学假设,实际项目中应结合收敛性测试确定步长。

版本控制:管住脚本、参数与结果

仿真项目的版本控制不能只提交 .py。建议采用如下目录结构:

  • src/:Python 封装、TCL 脚本、COMSOL 方法文件;
  • params/:YAML 或 JSON 参数文件,每个设计变体一个;
  • geom/:GDSII、STL 等几何源文件;
  • results/:只保留汇总 CSV 与关键图,原始场数据用 .gitignore 排除;
  • env/:environment.yml 或 requirements.txt,锁定 Python 与 lumapi 版本。

参数文件是版本控制的核心。把扫描变量、材料参数、网格设置全部外置到 YAML,脚本只读不写,这样任何一次仿真都能通过“脚本 commit + 参数 commit”完整复现。对于二进制场数据,建议用 DVC 或 Git LFS 管理,避免仓库膨胀。

自动化工作流:从参数到报告

把上述环节串起来,可以用一个 Makefile 或 Python 的 snakemake 定义依赖关系。下面给出一个简化的 Makefile 片段,展示“参数→Lumerical→COMSOL→汇总”的链路:

PARAMS := params/design_A.yaml
NEFF   := results/neff_sweep.csv
COMSOL := results/eo_response.csv
REPORT := results/report.md

all: $(REPORT)

$(NEFF): src/run_mode_sweep.py $(PARAMS)
	python src/run_mode_sweep.py --params $(PARAMS) --out $(NEFF)

$(COMSOL): src/run_comsol_eo.py $(NEFF)
	python src/run_comsol_eo.py --neff $(NEFF) --out $(COMSOL)

$(REPORT): src/make_report.py $(COMSOL)
	python src/make_report.py --in $(COMSOL) --out $(REPORT)

这样,只要 params/design_A.yaml 或任一脚本发生变化,make 会自动重跑受影响的下游步骤。配合 CI(如 GitLab CI 或 GitHub Actions),每次 push 都能在无图形界面的服务器上跑一遍轻量级回归,检查关键指标是否漂移。

异质集成光子多物理场仿真工具链与自动化数据流 参数与版本控制 params/*.yaml Git + DVC / LFS Lumerical FDTD / MODE neff, 损耗, S 参数 COMSOL 电光 / 热光耦合 VπL, 温漂 Sentaurus / Silvaco 载流子输运 I-V / C-V / 掺杂 Python 编排层 lumapi / mph Makefile / Snakemake 汇总结果与报告 results/*.csv → report.md → CI 回归检查 参数回写 图例 数据/控制流 参数反馈

图中展示了从参数文件出发,经 Lumerical 光场求解、TCAD 电学求解、COMSOL 多物理场耦合,再由 Python 编排层统一调度,最终汇总为报告并进入 CI 回归的完整数据流。虚线表示参数回写:当 COMSOL 发现某个偏压下的温漂超出阈值时,可以自动调整 YAML 中的热边界条件,触发下一轮迭代。

环境搭建中的常见坑

第一,许可证与并发。Lumerical 和 COMSOL 的 license 通常限制同时运行的实例数,自动化脚本必须加锁或排队,否则批量任务会因 license 争用而失败。第二,无图形界面运行。服务器上跑 COMSOL 需要 -nn 或 -np 参数指定核数,Lumerical 的 hide=True 只是隐藏窗口,仍需 X11 或虚拟显示。第三,路径与大小写。Windows 与 Linux 对路径大小写敏感度不同,脚本中一律使用 pathlib 并统一小写文件名。第四,版本锁定。lumapi 与 Lumerical 主程序版本必须匹配,升级前先在分支上跑回归。

建议在项目初期就建立 env/check_env.py,自动检测各工具版本、license 可用性、Python 包版本,并输出一份环境快照。这份快照随每次仿真结果一起归档,是复现性的第一道保障。

把工具链、版本控制与自动化三者结合,最终目标不是“跑得快”,而是“跑得可复现、可追溯、可回归”。当设计参数变化时,你能在一小时内得到从光场到电光响应的完整更新,并且知道每一个数字来自哪次 commit、哪份参数、哪个工具版本——这才是异质集成光子多物理场仿真环境搭建的真正价值。