1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Python + Ansys Lumerical FDTD] Si/SiO₂ 多層膜構造を自動生成するpythonスクリプトを作ってみた

Last updated at Posted at 2025-12-08

はじめに

Lumerical FDTD では GUI で構造を描くことができますが、多層膜のように層数が多い構造では手作業が大変です。

この記事では、
材料ファイル
多層膜パラメータファイル
構造生成クラス
FDTD プロジェクト生成スクリプト

を Python で分離し、
Si / SiO₂ の多層膜構造を自動生成して .fsp として保存する方法を紹介します。

📁 ファイル構成

project_folder/

├─ user_dielectric_materials.py ← 材料定義
├─ user_multilayer_parameters.py ← 多層膜パラメータ
├─ multilayer_core.py ← 構造生成クラス
└─ build_multilayer_fdtd.py ← 実行スクリプト

1. 材料定義ファイル

user_dielectric_materials.py

Si_material   = "Si (Silicon) - Palik"
SiO2_material = "SiO2 (Glass) - Palik"

material_list = [Si_material, SiO2_material]

unique_material_list = []
for m in material_list:
    if m not in unique_material_list:
        unique_material_list.append(m)

2. 多層膜パラメータ

user_multilayer_parameters.py

import numpy as np

simulation_span_x = 2.0e-6
simulation_span_y = 2.0e-6

substrate_thickness = 1.0e-6
substrate_width     = simulation_span_x
substrate_length    = simulation_span_y

num_pairs = 5        # 1ペア = SiO2 + Si

t_SiO2 = 100e-9
t_Si   = 80e-9

layer_width  = substrate_width
layer_length = substrate_length

stack_total_thickness = num_pairs * (t_SiO2 + t_Si)

air_buffer_above = 0.5e-6
air_buffer_below = 0.5e-6

fdtd_span_x = simulation_span_x
fdtd_span_y = simulation_span_y
fdtd_span_z = substrate_thickness + stack_total_thickness + air_buffer_above + air_buffer_below

3. 多層膜構造生成クラス

multilayer_core.py

import lumapi
from user_multilayer_parameters import *
from user_dielectric_materials import *

class DielectricMultilayer:
    def __init__(self, num_pairs):
        self.num_pairs = num_pairs

    def add_fdtd_multilayer(self, fdtd, create_fdtd_region=True):

        # --- 1. FDTDリージョン ---
        if create_fdtd_region:
            fdtd.addfdtd()
            fdtd.setnamed("FDTD", "x span", fdtd_span_x)
            fdtd.setnamed("FDTD", "y span", fdtd_span_y)
            fdtd.setnamed("FDTD", "z span", fdtd_span_z)

        # --- 2. 基板 ---
        fdtd.addrect(name="Substrate")
        fdtd.setnamed("Substrate", "x span", substrate_width)
        fdtd.setnamed("Substrate", "y span", substrate_length)
        fdtd.setnamed("Substrate", "z span", substrate_thickness)
        fdtd.setnamed("Substrate", "material", Si_material)

        current_z = substrate_thickness / 2

        # --- 3. 多層膜 ---
        fdtd.addstructuregroup()
        fdtd.setnamed("structure group", "name", "MULTILAYER")

        for i in range(self.num_pairs):

            # SiO2 層
            name_sio2 = f"SiO2_layer_{i+1}"
            fdtd.addrect(name=name_sio2)
            fdtd.setnamed(name_sio2, "z", current_z + t_SiO2/2)
            fdtd.setnamed(name_sio2, "x span", layer_width)
            fdtd.setnamed(name_sio2, "y span", layer_length)
            fdtd.setnamed(name_sio2, "z span", t_SiO2)
            fdtd.setnamed(name_sio2, "material", SiO2_material)
            fdtd.addtogroup("MULTILAYER")

            current_z += t_SiO2

            # Si 層
            name_si = f"Si_layer_{i+1}"
            fdtd.addrect(name=name_si)
            fdtd.setnamed(name_si, "z", current_z + t_Si/2)
            fdtd.setnamed(name_si, "x span", layer_width)
            fdtd.setnamed(name_si, "y span", layer_length)
            fdtd.setnamed(name_si, "z span", t_Si)
            fdtd.setnamed(name_si, "material", Si_material)
            fdtd.addtogroup("MULTILAYER")

            current_z += t_Si

4. FDTD プロジェクト生成スクリプト

build_multilayer_fdtd.py

import os
import lumapi

from user_multilayer_parameters import num_pairs
from multilayer_core import DielectricMultilayer

SAVE_DIR = "./multilayer_projects"
os.makedirs(SAVE_DIR, exist_ok=True)

def main():
    stack = DielectricMultilayer(num_pairs)

    with lumapi.FDTD(hide=False) as fdtd:
        fdtd.switchtolayout()
        fdtd.redrawoff()

        stack.add_fdtd_multilayer(fdtd)

        fdtd.redrawon()
        save_path = os.path.join(SAVE_DIR, "dielectric_multilayer.fsp")
        fdtd.save(save_path)

        print("Saved:", save_path)

if __name__ == "__main__":
    main()

multilayer_core.pyファイルでDielectricMultilayerをクラスとして定義し、多層膜のペアの層数num_pairsを外から制御できるパラメータとしています(def init(self, num_pairs):の箇所)。

そうしておくとbuild_multilayer_fdtd.pyのstack = DielectricMultilayer(num_pairs)でnum_pairs=10とすれば、ペアの層数が10層の多層膜が生成できるようになります。

num_pairs以外のパラメータも同じ要領で追加すれば、外から制御できるパラメータとして扱えるので便利です。

実行結果

build_multilayer_fdtd.pyの実行結果がこちらになります。
substrate上にSi/SiO2の多層膜が形成されていることが確認できます。スクリーンショット 2025-12-05 112318.jpg

まとめ

この記事では、
Python + Lumerical FDTD で多層膜構造を自動生成する仕組み
材料ファイル・パラメータファイル・構造クラス・実行スクリプトの分離方法

について紹介しました。

後はプロジェクトファイル上で条件を追加すれば多層膜のFDTDシミュレーションができるようになるでしょう。

※本記事は筆者個人の見解であり、所属組織の公式見解を示すものではありません。

問い合わせ

光学シミュレーションソフトの導入や技術相談、
設計解析委託をお考えの方はサイバネットシステムにお問合せください。

光学ソリューションサイトについては以下の公式サイトを参照:
👉 光学ソリューションサイト(サイバネット)

光学分野のエンジニアリングサービスについては以下の公式サイトを参照:
👉 光学エンジニアリングサービス(サイバネット)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?