We’re putting the final touches on our new badges platform. Badge issuance remains temporarily paused, but all completions are being recorded and will be fulfilled once the platform is live. Thank you for your patience.
Photonics – Chinese

Photonics – Chinese

Topics related to Lumerical and more, in Chinese language.

“Inverse design of y-branch”问题请教

    • m202373352
      Subscriber

      老师您好,我在官网下载了“Inverse design of y-branch”的案例,并尝试将其修改成我自己的几何结构并进行优化,目前遇到了如下问题,烦请老师进行解答:

      1.再将几何参数等修改为我自己的结构时,运行代码会出现如下报错:WARNING: The monitor "fom" is not aligned with the grid. Its distance to the nearest mesh point is [1.e-08]. This can introduce small phase errors which sometimes result in inaccurate gradients.但是运行案例时就没有这个问题。我也尝试在fom监视器处加一个mesh,以强制让其与网格对齐,但是这又会出现新的报错:D:\Program Files\Lumerical\v241\api\python\lumapi.py:160: UserWarning: Multiple objects named '::model::mesh'. Use of this object may give unexpected results.warnings.warn(message)。因此想请教老师,在形状优化当中,fom监视器处究竟需不需要或者说能不能加mesh以强制对齐网格?如果不能,那上述问题该如何解决?

      2.我在运行仿真时,并没有采用对称边界条件,因为我所选的模式光源关于y轴并不对称。举例说,我想选择TE0模作为输入,输出fom同样也选择TE0模作为监视对象,这种情况当我选择模式的序号,输入光源模式序号为2,输出fom模式序号选择3,但是发现,当直接选择模式序号时,优化会出现问题,发现迭代一直卡在第0代,并且fom值非常小(1e-10的数量级),并且几代就结束了优化,但是感觉并没有真正的优化。请问这个问题是什么原因造成的呢,应该如何解决?因为所涉及到的输入有高阶模式,因为不能直接选择“fundamental mode”。当选择输入光源和输出监视器fom均选择“fundamental mode“时,优化可以进行,但还是会出现WARNING: The monitor "fom" is not aligned with the grid. Its distance to the nearest mesh point is [1.e-08]. This can introduce small phase errors which sometimes result in inaccurate gradients.的警告。

      下面给出了我仿真的代码以及相应的报错等相关截图。以上问题已经困惑了我好久,真诚希望老师能在百忙之中检阅并予以知道,非常感谢!!!!

      import lumapi

      import numpy as np

      from scipy.constants import c

       

      def y_branch_init_(mode):

       

      ## CLEAR SESSION

      mode.switchtolayout()

      mode.selectall()

      mode.delete()

       

      ## SIM PARAMS

      size_x=6e-6;

      size_y=5e-6;

      mesh_x=20e-9;

      mesh_y=20e-9;

      finer_mesh_size_x=5.5e-6;

      finer_mesh_size_y=4.5e-6;

      mesh_accuracy=4;

      lam_c = 1.550e-6;

       

      ## MATERIAL

      opt_material=mode.addmaterial('Dielectric');

      mode.setmaterial(opt_material,'name','Si: non-dispersive');

      n_opt = mode.getindex('Si (Silicon) - Palik',c/lam_c);

      mode.setmaterial('Si: non-dispersive','Refractive Index',n_opt);

       

      sub_material=mode.addmaterial('Dielectric');

      mode.setmaterial(sub_material,'name','SiO2: non-dispersive');

      n_sub = mode.getindex('SiO2 (Glass) - Palik',c/lam_c);

      mode.setmaterial('SiO2: non-dispersive','Refractive Index',n_sub);

      mode.setmaterial('SiO2: non-dispersive',"color", np.array([0, 0, 0, 0]));

       

      ## GEOMETRY

       

      #INPUT WAVEGUIDE

       

      mode.addrect();

      mode.set('name','input wg');

      mode.set('x span',3e-6);

      mode.set('y span',1e-6);

      mode.set('z span',220e-9);

      mode.set('y',0);

      mode.set('x',-4e-6);

      mode.set('z',0);

      mode.set('material','Si: non-dispersive');

       

      #OUTPUT WAVEGUIDES

       

      mode.addrect();

      mode.set('name','output wg top');

      mode.set('x span',3e-6);

      mode.set('y span',1e-6);

      mode.set('z span',220e-9);

      mode.set('y',0.9e-6);

      mode.set('x',4e-6);

      mode.set('z',0);

      mode.set('material','Si: non-dispersive');

       

      mode.addrect();

      mode.set('name','output wg bottom');

      mode.set('x span',3e-6);

      mode.set('y span',1e-6);

      mode.set('z span',220e-9);

      mode.set('y',-0.9e-6);

      mode.set('x',4e-6);

      mode.set('z',0);

      mode.set('material','Si: non-dispersive');

       

      mode.addrect();

      mode.set('name','sub');

      mode.set('x span',11e-6);

      mode.set('y span',11e-6);

      mode.set('z span',10e-6);

      mode.set('y',0);

      mode.set('x',0);

      mode.set('z',0);

      mode.set('material','SiO2: non-dispersive');

      mode.set('override mesh order from material database',1);

      mode.set('mesh order',3);

      mode.set('alpha',0.8);

       

      ## varFDTD

      mode.addvarfdtd();

      mode.set('mesh accuracy',mesh_accuracy);

      mode.set('x min',-size_x/2);

      mode.set('x max',size_x/2);

      mode.set('y min',-size_y/2);

      mode.set('y max',size_y/2);

      #mode.set('force symmetric y mesh',1);

      #mode.set('y min bc','Anti-Symmetric');

      mode.set('z',0);

       

      mode.set('effective index method','variational');

      mode.set('can optimize mesh algorithm for extruded structures',1);

      mode.set('clamp values to physical material properties',1);

       

      mode.set('x0',-2.8e-6);

      mode.set('number of test points',4);

      mode.set('test points',np.array([[0, 0],[2.8e-6, 1e-6], [2.8e-6, -1e-6], [2.8e-6, 0]]));

       

      ## SOURCE

      mode.addmodesource();

      mode.set('direction','Forward');

      mode.set('injection axis','x-axis');

      #mode.set('polarization angle',0);

      mode.set('y',0);

      mode.set("y span",size_y);

      mode.set('x',-2.75e-6);

      mode.set('center wavelength',1550e-9);

      mode.set('wavelength span',0);

      mode.set('mode selection','user select');

      mode.set('selected mode number', 2);

       

       

      ## MESH IN OPTIMIZABLE REGION

      mode.addmesh();

      mode.set('x',0);

      mode.set('x span',finer_mesh_size_x);

      mode.set('y',0);

      mode.set('y span',finer_mesh_size_y);

      mode.set('dx',mesh_x);

      mode.set('dy',mesh_y);

       

      ## OPTIMIZATION FIELDS MONITOR IN OPTIMIZABLE REGION

       

      mode.addpower();

      mode.set('name','opt_fields');

      mode.set('monitor type','2D Z-normal');

      mode.set('x',0);

      mode.set('x span',finer_mesh_size_x - 0.1e-6);

      mode.set('y',0);

      mode.set('y span',finer_mesh_size_y - 0.1e-6);

      mode.set('z',0);

       

      ## FOM FIELDS

       

      mode.addpower();

      mode.set('name','fom');

      mode.set('monitor type','Linear Y');

      mode.set('x',2.75e-6);

      mode.set('y',0);

      mode.set('y span',size_y);

      mode.set('z',0);

       

      #mode.addmesh();

      #mode.set("name","fom_mesh");

      #mode.set("x",2.75e-6);

      #mode.set("x span",2*mesh_x);

      #mode.set("y",0);

      #mode.set("y span",size_y);

      #mode.set("z",0);

      ##set("z span",240e-9);

      #mode.set("override x mesh",1); ##

      #mode.set("override y mesh",0); ##

      #mode.set("override z mesh",0); ##

      #mode.set("dx",mesh_x);

       

       

      #mode.addmodeexpansion();##

      #mode.set("name","mode_expansion");

      #mode.set("monitor type",2); # 1 = linear X, 2 = linear Y

      #mode.set("x", 2.75e-6);

      #mode.set("z",0);

      #mode.set("y", 0);

      #mode.set("y span",size_y);

      #mode.select("mode_expansion");

      #mode.setexpansion("input", "fom");

      #mode.set("mode selection","user select"); # use the 'user select' option

      #mode.seteigensolver("use max index",1); # specify a custom value for 'n'

      #mode.updatemodes(3);

       

       

      if __name__ == "__main__":

      mode = lumapi.MODE(hide = False)

      y_branch_init_(mode)

      input('Press Enter to escape...')

       

      优化代码:

      import os, sys

      import numpy as np

      import scipy as sp

      import lumapi

       

      from lumopt.utilities.wavelengths import Wavelengths

      from lumopt.geometries.polygon import FunctionDefinedPolygon

      from lumopt.utilities.materials import Material

      from lumopt.figures_of_merit.modematch import ModeMatch

      from lumopt.optimizers.generic_optimizers import ScipyOptimizers

      from lumopt.optimization import Optimization

       

      ######## BASE SIMULATION ########

      sys.path.append(os.path.dirname(__file__))

      from varFDTD_y_branch import y_branch_init_

      y_branch_base = y_branch_init_

       

       

      ######## DIRECTORY FOR GDS EXPORT #########

      example_directory = os.getcwd()

       

      ######## SPECTRAL RANGE #########

      wavelengths = Wavelengths(start = 1530e-9, stop = 1565e-9, points = 8)

       

      ######## DEFINE OPTIMIZABLE GEOMETRY ########

      # The class FunctionDefinedPolygon needs a parameterized Polygon (with points ordered

      # in a counter-clockwise direction). Here the geometry is defined by 10 parameters defining

      # the knots of a spline, and the resulting Polygon has 200 edges, making it quite smooth.

       

      # Define the span and number of points

      initial_points_x = np.linspace(-2.5e-6, 2.5e-6, 20)

      initial_points_y = np.linspace(0.5e-6, 1.4e-6, initial_points_x.size)

      def splitter(params):

      ''' Defines a taper where the paramaters are the y coordinates of the nodes of a cubic spline. '''

       

      ## Include two set points based on the initial guess. The should attach the optimizeable geometry to the input and output

      points_x = np.concatenate(([initial_points_x.min() - 0.01e-6], initial_points_x, [initial_points_x.max() + 0.01e-6]))

      points_y = np.concatenate(([initial_points_y.min()], params, [initial_points_y.max()]))

       

      ## Up sample the polygon points for a smoother curve. Some care should be taken with interp1d object. Higher degree fit

      # "cubic", and "quadratic" can vary outside of the footprint of the optimization. The parameters are bounded, but the

      # interpolation points are not. This can be particularly problematic around the set points.

      n_interpolation_points = 200

      polygon_points_x = np.linspace(min(points_x), max(points_x), n_interpolation_points)

      interpolator = sp.interpolate.interp1d(points_x, points_y, kind = 'cubic')

      polygon_points_y = interpolator(polygon_points_x)

       

      ### Zip coordinates into a list of tuples, reflect and reorder. Need to be passed ordered in a CCW sense

      polygon_points_up = [(x, y) for x, y in zip(polygon_points_x, polygon_points_y)]

      polygon_points_down = [(x, -y) for x, y in zip(polygon_points_x, polygon_points_y)]

      polygon_points = np.array(polygon_points_up[::-1] + polygon_points_down)

      return polygon_points

       

      # L-BFGS methods allows the parameters to be bound. These should enforse the optimization footprint defined in the setup

      bounds = [(0.4e-6, 1.8e-6)] * initial_points_y.size

       

      #Load from 2D results if availble

      try:

      prev_results = np.loadtxt('2D_parameters.txt')

      except:

      print("Couldn't find the file containing 2D optimization parameters. Starting with default parameters")

      prev_results = initial_points_y

       

      # Set device and cladding materials, as well as as device layer thickness

      eps_in = Material(name = 'Si: non-dispersive', mesh_order = 2)

      eps_out = Material(name = 'SiO2: non-dispersive', mesh_order = 3)

      depth = 220.0e-9

       

      # Initialize FunctionDefinedPolygon class

      polygon = FunctionDefinedPolygon(func = splitter,

      initial_params = prev_results,

      bounds = bounds,

      z = 0.0,

      depth = depth,

      eps_out = eps_out, eps_in = eps_in,

      edge_precision = 5,

      dx = 1.0e-9)

       

       

      ######## FIGURE OF MERIT ########

      fom = ModeMatch(monitor_name = 'fom',

      mode_number = 3,

      direction = 'Forward',

      target_T_fwd = lambda wl: np.ones(wl.size),

      norm_p = 1)

       

      ######## OPTIMIZATION ALGORITHM ########

      optimizer = ScipyOptimizers(max_iter = 30,

      method = 'L-BFGS-B',

      #scaling_factor = scaling_factor,

      pgtol = 1.0e-5,

      ftol = 1.0e-5,

      #target_fom = 0.0,

      scale_initial_gradient_to = 0.0)

       

      ######## PUT EVERYTHING TOGETHER ########

      opt = Optimization(base_script = y_branch_base,

      wavelengths = wavelengths,

      fom = fom,

      geometry = polygon,

      optimizer = optimizer,

      use_var_fdtd = True,

      hide_fdtd_cad = False,

      use_deps = True,

      plot_history = True,

      store_all_simulations = False)

       

       

      ######## RUN THE OPTIMIZATION ########

      results = opt.run()

       

      ######## SAVE THE BEST PARAMETERS TO FILE ########

      np.savetxt('../2D_parameters.txt', results[1])

       

      ######## EXPORT OPTIMIZED STRUCTURE TO GDS ########

      gds_export_script = str("gds_filename = 'y_branch_2D.gds';" +

      "top_cell = 'model';" +

      "layer_def = [1, {0}, {1}];".format(-depth/2, depth/2) +

      "n_circle = 64;" +

      "n_ring = 64;" +

      "n_custom = 64;" +

      "n_wg = 64;" +

      "round_to_nm = 1;" +

      "grid = 1e-9;" +

      "max_objects = 10000;" +

      "Lumerical_GDS_auto_export;")

       

      with lumapi.MODE(hide = False) as mode:

      mode.cd(example_directory)

      y_branch_init_(mode)

      mode.addpoly(vertices = splitter(results[1]))

      mode.set('x', 0.0)

      mode.set('y', 0.0)

      mode.set('z', 0.0)

      mode.set('z span', depth)

      mode.set('material','Si: non-dispersive')

      mode.save("y_branch_2D_FINAL")

      input('Enter...')

      mode.eval(gds_export_script)

    • m202373352
      Subscriber

      以上问题已经困惑了我好久,真诚希望老师能在百忙之中检阅并予以知道,非常感谢!!!!

    • GuanYo Dong
      Subscriber

      你好

      第一個指出的問題,得讓局部加的mesh name那一欄位不重複,多個編號之類的,不要讓每個都叫做mesh,這在後續select的時候容易出錯選到多個。
      我們試試看比較定義座標的時候, 腳本中避免算了多次A/2,那我們讓軟件先把A/2給成一個代號每次給到軟件的位置,因為多次算可能會造成浮點數最後一個位數計算偏差,就是您看到1e-8。

      第二個除了網格對不齊的問題外,我們選模式在Y-brench 出口端的兩個端口,應該各自放一個monitor去偵測,並且各自選擇模式。這三個位置的monitor也應該要一樣大,且跟結構中心對齊,此時應該選到一樣的模式編號,無論是不是自選的。

      莎益博 董冠佑

    • m202373352
      Subscriber

      您的回复已经收到,非常感谢!请问"我們選模式在Y-brench 出口端的兩個端口,應該各自放一個monitor去偵測,並且各自選擇模式。這三個位置的monitor也應該要一樣大,且跟結構中心對齊"您这句话想表达的是什么意思,不是很理解?您所指的“三个位置”是哪三个位置?在Y-branch两个输出端分别放置一个监视器,还有哪个地方需要放吗?

      还有就是为什么不可以像案例中那样,在输出端放置一个阔度比较大的、覆盖两个输出端口的监视器呢?

      再次感谢您的回复,祝工作顺利,身体健康!

    • GuanYo Dong
      Subscriber

      你好

      不好意思這個案例mode expantion的用法跟一般比較不同,他確實是兩個出口端共用一個mode expantion,並且是此結構的基模,兩個一起看總透過率。
      要分析s參數的時候才一定要一個端口一個mode expantion.

      另外我發現代碼varFDTD_y_branch.py,並沒有在建立基本文件的步驟加入mode expantion,但在優化文件中有 ,那你在這段落加入了,可以在優化中途確認一下是否有多一個?
      如果有多,也要確認軟件抓取哪一個數據?

      案例代碼y_branch_opt_2D.py就可以直接改要分析的模式,我選不是基模,可以有結果但不同的模式最佳的情況不同,這個模式就沒有官網的基模好。
      所以不同模式也可能結果不好。

      莎益博 董冠佑

    • m202373352
      Subscriber

      非常感谢您的回复,但是问题还是没有解决,还要跟您再请教一下。

      首先,我想做一个能同时实现TE0模和TE1模分束的Y-branch结构,因而我在选择光源mode number和fom的“mode_number”时会涉及TE1模的选择,不能只选择“fundamental mode”。因为我也不知道在模式扩展监视器中应具体选择哪个模式序号,因而在fom监视器的位置放置了一个和fom监视器尺寸相同并且将fom监视器作为"Monitors for expansion"输入,用来预先确定要选择的模式序号,但是在后续开始优化的时候,我是将刚才提到的模式扩展监视器注释掉的,因而在生成的仿真文件中只有文件自动生成的“fom_mode_exp”监视器。

      我在原案例代码的基础上进行了参数修改,更改了几何尺寸,即将输入、输出波导宽度改为1微米以便能激发出TE1模式,然后将中间的优化区域增大到大概5.5微米*4.5微米;并在优化python文件中,我也修改了相应的x,y坐标的范围以及bounds的范围;在选择输入模式光源的模式序号和输出fom的模式序号时,对于TE0模式,输入序号为2,输出选择3,对于TE1模式,输入选择4,输出选择8;并且边界条件为默认边界条件,没有采用对称边界条件,因为TE1模式不支持对称边界条件;其余设置均和案例中保持一致(具体代码在之前的提问中已经给出)。现在出现的问题是:当我按照上述设置进行优化时,对于TE0模式,fom的值非常小,在1e-10数量级,仿真在几代后便停止了,查看更新图像,发现参数并没有更新,意味着优化并未进行;对于TE1模式,优化在初始化完之后便停止了。具体截图如下

      对于上述问题,我已经认真检查了代码,并没有发现错误,但为什么会出现这种情况就不是很明白了,还要麻烦老师予以解答,非常感谢!!

    • GuanYo Dong
      Subscriber

      你好 ,
      我測了你說的情況(不設置對稱邊界,輸入輸出都挑非基模),在疊代0就數字不太好的情況下,代表沒有找到較好的優化方向,我的情況也不太好如圖
      所選模式相同,不同次的結果還有些不同代表現在的結構,這可能是初值亂數選的不同了,也不是疊代越多次就一定越好,不過我沒有找到一次都沒疊代的情況。



      我的理解,本就不是所有模式都找的到結構來匹配,
      也看到可能一開始沒有找到好的梯度所以沒有好的結果,
      這邊我感覺幫不到您了,沒有檔案能做的有限,建議您找軟件售後的AE仔細來看檔案

      莎益博 董冠佑

    • m202373352
      Subscriber

      好的,还是非常感谢您的回复!

       

Viewing 7 reply threads
  • You must be logged in to reply to this topic.