Photonics

Photonics

Lumerical Inverse Design Mesh/Grid issues.

    • rchap
      Subscriber

      Hi,

      I am using Inverse Design to design MMIs with the Python function: TopologicalOptimization2D. However, I am having issues with getting the mesh the right size so that the gradient can be calculated.

      For example, my MMI is 1x2, 20um long and 10um wide. My min_feature_size and filter_R are both set to 500e-9. If I have the mesh size to be 10e-9, then the simulation runs okay - but I would like to have a larger mesh so the simulation runs faster (especially for longer MMIs).

      If I set the mesh size (dx) to 50e-9, 100e-9 or 500e-9, the simulation crashes with the error message:

      Making adjoint solves
      Running solves
      Processing adjoint solves
      FOM = 0.8551266229723924 (1 - 0.1448733770276076)
      FOM = 0.850725706181579 (1 - 0.14927429381842106)
      FOM = 0.8551266215692646 (1 - 0.14487337843073544)
      FOM = 0.850725718049913 (1 - 0.14927428195008696)
      [.......]
        File "C:Program FilesLumericalv211apipythonlumoptoptimization.py", line 290, in process_adjoint_solves
          jac = optimization.calculate_gradients()
        File "C:Program FilesLumericalv211apipythonlumoptoptimization.py", line 910, in calculate_gradients
          grad_name = self.geometry.calculate_gradients_on_cad(self.sim, 'forward_fields', 'adjoint_fields', self.scaling_factor)               
        File "C:Program FilesLumericalv211apipythonlumoptgeometries	opology.py", line 298, in calculate_gradients_on_cad
          'dF_dp = topoparamstogradient(params,topo_rho,dF_dEps);').format(self.eps_min,self.eps_max,self.filter_R,self.beta,self.eta,self.dx,self.dy) )
        File "C:Program FilesLumericalv211apipythonlumapi.py", line 1188, in eval
          evalScript(self.handle, code)
        File "C:Program FilesLumericalv211apipythonlumapi.py", line 251, in evalScript
          raise LumApiError("Failed to evaluate code")
      lumapi.LumApiError: 'Failed to evaluate code'
      
      
      Process finished with exit code 1
      


      I use the same mesh size to define the Optimization mesh (x and y), the figure of merit mesh, and the x, y parameters in the TopologicalOptimization2D.

      Is there a trick with getting the correct mesh to match the size of a MMI and Optimization mesh? Why can I only ever set dx to 10e-9 for the simulation to work ?!


      Snippet of code:

      mmi_max_width = 10e-6
      mmi_lengths = 20e-6
      dx = 100e-9
      
      opt_size_x = int(round(mmi_length * 1e9))  # nm
      opt_size_y = int(round(mmi_max_width * 1e9))   # nm
      delta_x = int(round(dx * 1e9))  # nm
      delta_y = int(round(dx * 1e9))  # nm
      
      x_points = int(opt_size_x / delta_x) + 1
      y_points = int(opt_size_y / delta_y) + 1  # I add 1 to make the mesh fit - it crashes without this as well.
      
      x_pos = np.linspace(-opt_size_x / 2, opt_size_x / 2, x_points) * 1e-9
      y_pos = np.linspace(-opt_size_y / 2, opt_size_y / 2, y_points) * 1e-9
      
      geometry0 = TopologyOptimization2D(params=initial_cond,
                                         eps_min=eps_min,
                                         eps_max=eps_max0,
                                         x=x_pos,
                                         y=y_pos,
                                         z=0,
                                         filter_R=filter_R,
                                         min_feature_size=min_feature_size
                                         )
      
      
      
      
      


    • rchap
      Subscriber
      The full error message:
      Traceback (most recent call last):
      File "C:/Users/chapman/Desktop/Lumerical/Inverse_Design/MMI_Switch/Studies/2_length/run.py", line 241, in
      opt.run File "C:\Program Files\Lumerical\v211\api\python\lumopt\optimization.py", line 460, in run
      self.initialize(working_dir=working_dir)
      File "C:\Program Files\Lumerical\v211\api\python\lumopt\optimization.py", line 354, in initialize
      plotting_function=plotting_function)
      File "C:\Program Files\Lumerical\v211\api\python\lumopt\optimizers\optimizer.py", line 100, in initialize
      self.reset_start_params(start_params, self.scale_initial_gradient_to)
      File "C:\Program Files\Lumerical\v211\api\python\lumopt\optimizers\optimizer.py", line 108, in reset_start_params
      self.auto_detect_scaling(scale_initial_gradient_to)
      File "C:\Program Files\Lumerical\v211\api\python\lumopt\optimizers\optimizer.py", line 115, in auto_detect_scaling
      gradients = self.callable_jac(params)
      File "C:\Program Files\Lumerical\v211\api\python\lumopt\optimizers\minimizer.py", line 34, in callable_jac_local
      fom_gradients = callable_jac(params_over_scaling_factor) / self.scaling_factor
      File "C:\Program Files\Lumerical\v211\api\python\lumopt\optimization.py", line 297, in callable_jac
      jac_list = pool.map(process_adjoint_solves, enumerate(self.optimizations))
      File "C:\Program Files\Lumerical\v211\python-3.6.8-embed-amd64\lib\multiprocessing\pool.py", line 266, in map
      return self._map_async(func, iterable, mapstar, chunksize).get File "C:\Program Files\Lumerical\v211\python-3.6.8-embed-amd64\lib\multiprocessing\pool.py", line 644, in get
      raise self._value
      File "C:\Program Files\Lumerical\v211\python-3.6.8-embed-amd64\lib\multiprocessing\pool.py", line 119, in worker
      result = (True, func(*args, **kwds))
      File "C:\Program Files\Lumerical\v211\python-3.6.8-embed-amd64\lib\multiprocessing\pool.py", line 44, in mapstar
      return list(map(*args))
      File "C:\Program Files\Lumerical\v211\api\python\lumopt\optimization.py", line 290, in process_adjoint_solves
      jac = optimization.calculate_gradients File "C:\Program Files\Lumerical\v211\api\python\lumopt\optimization.py", line 910, in calculate_gradients
      grad_name = self.geometry.calculate_gradients_on_cad(self.sim, 'forward_fields', 'adjoint_fields', self.scaling_factor)
      File "C:\Program Files\Lumerical\v211\api\python\lumopt\geometries\topology.py", line 298, in calculate_gradients_on_cad
      'dF_dp = topoparamstogradient(params,topo_rho,dF_dEps);').format(self.eps_min,self.eps_max,self.filter_R,self.beta,self.eta,self.dx,self.dy) )
      File "C:\Program Files\Lumerical\v211\api\python\lumapi.py", line 1188, in eval
      evalScript(self.handle, code)
      File "C:\Program Files\Lumerical\v211\api\python\lumapi.py", line 251, in evalScript
      raise LumApiError("Failed to evaluate code")
      lumapi.LumApiError: 'Failed to evaluate code'


      Process finished with exit code 1

    • Guilin Sun
      Ansys Employee
      Sorry to reply you late, as our support is short of hands currently.
      I am not very familiar to this, but just give you a suggestion to rule out some causes. From your initial post, it seems the gradient calculation has some issue, which is related to Python algorithm. However, to exclude the pure mesh size cause from the simulation file, I suggest that you use your python script to set up, save the fsp file , and then open that saved simulation file and run it separately. If this runs without a problem, it is not the FDTD issue but Python issue. It shows line 298 and lumapi evaluation. You can modify the FDTD to use smaller simulation region and do some testing faster to diagnose the root cause.


    • Taylor Robertson
      Ansys Employee
      Hello rchap
      It seems the FDTD sims are running, and that the error comes from the gradient calculation. I think the most likely cause of this failure is a discrepancy between the FDTD grid and the position vectors defined in python. See the the Topology - initialization section.
      https://support.lumerical.com/hc/en-us/articles/360052044913-Optimizable-Geometry-Python-API
      It is important the mesh defined in the FDTD simulation precisely matches the optimization parameters defined in Python.To do this make sure a uniform meshis definedover the optimizable footprint. The pythonparameters may be defined as follows.
      Even though you are changing the grid size in python this does not automatically update the FDTD grid size. You need to change the base file, or set-up script to force the mesh to match the new step size in Python. The simplest way to do this to use a "uniform" mesh throughout and change dx, dy, in the FDTD object.
      Alternatively you can use a mesh override, but you should understand that when meshing the simulation takes the smaller mesh. So you cannot really use a mesh override to force a larger mesh size than what is calculated from FDTD mesh settings. Use low mesh accuracy with a large step size, but if the mesh size determined by the auto non-uniform is still smaller then what is defined in the mesh override the former will be used. Make sense?



      Also try and use a step size that divides the opt region an integer number of times. To check this you can look at the x_pos values in python and compare them with the x values from the opt fields monitor.
      I hope this helps.
      Best
Viewing 3 reply threads
  • You must be logged in to reply to this topic.