Photonics

Photonics

Topics related to Lumerical and more.

Topology optimization of an O-band/C-band wavelength de-multiplexer with 100nm

    • raano1
      Subscriber

      Dear Ansys Support Team,

      I reviewed the example “Topology optimization of an O-band/C-band wavelength de-multiplexer with 100nm feature size constraint” on your Knowledge Base (https://optics.ansys.com/hc/en-us/articles/4403241716371), but could not find the following:

      Full 3D Python script (topology.py)

      Required .lsf simulation files

      GDSII export instructions or script

      Steps to extract and plot the transmission spectrum

      Could you please provide these or direct me to where I can access them?

    • Kirill
      Forum Moderator

      This topic has been moved to the Photonics  forum. Thank you! 

    • raano1
      Subscriber

      Thank you for the update. I’ll follow up in the Photonics forum. Please let me know if the requested files or instructions will be shared there.

    • Kirill
      Forum Moderator

      Dear Subscriber,

      Thank you for reporting this. We’ll look into why the mentioned content is missing.

      In the meantime, I suggest reviewing these two related examples:
      - Topology Optimization of a 4-channel wavelength demultiplexer 2D-TE
      - Inverse Design of a Splitter Using Topology Optimization

      Best regards,
      Kirill

    • raano1
      Subscriber

      Dear Kirill,
      Thank you for the quick response and for sharing the related examples. I’ll review them in the meantime.

      I would appreciate it if you could provide the missing content from the original example as early as possible, as I specifically need that example code for my work.

      Looking forward to your update.

    • raano1
      Subscriber

      Dear Kirill,

      Thanks for your response.

      I’m working on the “Topology Optimization of a 4-channel wavelength demultiplexer 2D-TE” and would like to adapt it for a 100 nm feature size. How can I implement this?

      Also, is there any update on the O-band/C-band demultiplexer example with a 100 nm feature constraint?

    • anna.wirth-singh
      Ansys Employee

      Hello,

      I can answer that question about how to implement the minimum feature size constraint. Please see this reference, towards the bottom of the article, for details on the topology settings: Optimizable Geometry - Python API – Ansys Optics

      The parameter you will need to adjust is 'filter_R'. It is set to 200nm by default. 

      Best,

      Anna

    • raano1
      Subscriber

      Dear Anna,

      Thank you for your previous guidance on minimum feature size in topology optimization.

      Following your advice, I’ve been exploring the filter_R parameter to reliably achieve a 100 nm minimum feature size. I understand there's a trade-off between stability and precision, and I've seen three common approaches:

      • filter_R = 50 nm: targets 100 nm (since min feature ≈ 2×filter_R) 

      • filter_R = 100 nm: matches the feature size and seems commonly used

      • filter_R = 200 nm: a safe default yielding smoother, larger features

      I’m also unclear on best practice for setting min_feature_size in the DFM stage. The documentation states it must satisfy:
      filter_R < min_feature_size < 2×filter_R

      Could you please advise which filter size—50 nm, 100 nm, or 200 nm—is appropriate for achieving a 100 nm feature size?


    • raano1
      Subscriber

       

      Dear Ansys Support Team,

      I hope this message finds you well.

      After completing a 3D TE topology optimization run using Lumerical and adjoint methods, I noticed that the output directory (e.g., 3D_TE_topology_x3000_y_2000_f0100_0) contains multiple subfolders such as opts_0, opts_1, convergence_report, and various .png, .npz, and .vtr files. However, I do not see any .fsp (Lumerical project) file generated.

      Could you please clarify:

       

      1. How can I generate a .fsp file from the optimization results, if it is not automatically produced?

       

      1. How to export the final device contour to GDS format?

       

      1. How to visualize the transmission spectrum from the available output files?

       

      Any guidance or documentation link would be greatly appreciated.

      Also,could you please advise which filter size—50 nm, 100 nm, or 200 nm—is appropriate for achieving a 100 nm feature size?

       

    • anna.wirth-singh
      Ansys Employee

      Hi, thanks for the additional questions, I’ll answer as many as I can.

      1.If you do not see a final .fsp file dropped into the main folder, please look into the subfolder with the highest number (opts_1) and find the ‘forward_n.fsp’ also with the highest number. Each time you initiate the optimization process, it will create a new folder and then inside that folder there will be forward and adjoint simulation files corresponding to that part of the optimization. The most recently produced forward.fsp file will contain the optimized result.
      2. Please see this page for reference on the GDS export process: GDS pattern extraction for inverse designed devices using contours method – Ansys Optics
      3. To visualize the transmission spectrum, you should add a Mode expansion monitor – Simulation object – Ansys Optics over the output waveguide. You should look for the T_forward or T_backward result (depending on which direction your monitor is facing), as described here: Using and understanding Mode Expansion Monitors – Ansys Optics

    • raano1
      Subscriber

       

      Dear Ansys Support Team,

      Thank you for your previous guidance on minimum feature size in topology optimization.

      Following your advice, I’ve been exploring the filter_R parameter to reliably achieve a 100 nm minimum feature size. I understand there’s a trade-off between stability and precision, and I’ve seen three common approaches:

      • filter_R = 50 nm: targets 100 nm (since min feature ≈ 2×filter_R) 

       

      • filter_R = 100 nm: matches the feature size and seems commonly used

       

      • filter_R = 200 nm: a safe default yielding smoother, larger features

       

      I’m also unclear on best practice for setting min_feature_size in the DFM stage. The documentation(Optimizable Geometry – Python API – Ansys Optics) states it must satisfy:

      filter_R < min_feature_size < 2×filter_R

      Could you please advise which filter size—50 nm, 100 nm, or 200 nm—is appropriate for achieving a 100 nm feature size?

      Also,In Lumerical inverse design using Python, if I set up the simulation to observe the transmission spectrum, is it possible to automatically view it when the code finishes running? For example, after the script generates the .fsp file and other outputs, can I add some code to display the transmission spectrum at the end?

       

    • anna.wirth-singh
      Ansys Employee

      Hi,

      I looked into your question about the settings a bit more deeply. Both filter_R and min_feature_size are meant to implement a minimum feature size in designs to ensure manufacturability, but they are implemented at different stages of the optimization process. Even with spatial filtering (filter_R) , the process may create some features that break the rules. To add additional constraints, min_feature_size is additionally used to penalize designs that do not follow the minimum feature size rules. Topology optimization is unique to the setup that you have, so there is not a one-size-fits-all approach, but I think it would be safe to set min_feature_size = 100nm and then the filter_R a bit smaller (perhaps 75nm) if you are using the DFM phase. 

      And yes, it is possible to use the Python API (Python API overview – Ansys Optics) to display a plot in Matplotlib. This page has an example code snippet that may be useful: Script Commands as Methods - Python API – Ansys Optics

       

      Best,

      Anna

    • raano1
      Subscriber

      Dear Ansys Support,

      After the topology optimization, I opened the generated forward_0.fsp file and ran the attached script in the FDTD Script Editor. I’ve also attached the resulting transmission plot.

      I noticed that the transmission between 600 nm and 800 nm is visible in the spectrum, but the transmission below 600 nm is missing.

      Additionally, I’ve attached the optimization_400.png image, where it seems the light is transmitting through Channel 2, not Channel 1. Could you please explain why this is happening?

      Could you please confirm if this is the correct workflow and if the script is valid?

      Thank you for your support.

      import lumapi
      import matplotlib.pyplot as plt

      # Update fsp_path to your new file location
      fsp_path = r”D:\Lumerical_projects\wdm\diamond_2_3D_TE_topology_x3000_y2000_f0075_0\opts_1\forward_0.fsp”

      fdtd = lumapi.FDTD()
      fdtd.load(fsp_path)

      transmission_1 = fdtd.getresult(‘fom_1’, ‘T’)
      transmission_2 = fdtd.getresult(‘fom_2’, ‘T’)

      wavelengths_1 = transmission_1[‘lambda’] * 1e9  # convert to nm
      data_1 = transmission_1[‘T’]

      wavelengths_2 = transmission_2[‘lambda’] * 1e9
      data_2 = transmission_2[‘T’]

      plt.figure(figsize=(8,5))
      plt.plot(wavelengths_1, data_1, label=’Channel 1 (520-540 nm)’)
      plt.plot(wavelengths_2, data_2, label=’Channel 2 (600-800 nm)’)
      plt.xlabel(‘Wavelength (nm)’)
      plt.ylabel(‘Transmission’)
      plt.title(‘Transmission Spectra for Both Channels’)
      plt.legend()
      plt.grid(True)

      # Force x-axis to show 500 nm to 800 nm
      plt.xlim(500, 800)

      plt.show()

      fdtd.close()





       

       



       

       

    • Kirill
      Forum Moderator

      Dear Subscriber,

      This issue is difficult to resolve without access to the details of your simulation. Unfortunately, the format of this forum isn’t well suited for handling such cases.

      However, you may be eligible for support through the Ansys Customer Support Space (ACSS), where we can assist you more effectively.
      For details, please refer to How to register on Ansys Customer Support Space. Please try submitting your request there.

      Best regards,
      Kirill

    • raano1
      Subscriber

      Dear Ansys Support,
      I’m working on a design similar to the O-band/C-band wavelength demultiplexer described in the following article:
       
      However, my transmission goal is to achieve high efficiency over the 520–540 nm and 600–800 nm ranges, with each output channel reaching over 95% transmission in its respective band, as shown in the attached transmission plot.
       
      I’ve already created both the base simulation setup and the Python optimization script. Could you please review them along with my transmission analysis code to confirm if everything is correctly implemented?
       
      Thank you for your support.
       
      base simulation code :

      switchtolayout;
      selectall;
      delete;
       
       
      ## SIMULATION PARAMETERS
       
      # Waveguide and Geometry Parameters
      num_wg = 2;
      wg_width = 0.5e-6;
      wg_height = 0.22e-6;      
      out_wg_dist = 1e-6;
      total_wg_h_span = num_wg*wg_width + (num_wg-1)*out_wg_dist;
       
      # Optimization and Simulation Region Size
      opt_size_x = 3e-6;
      opt_size_y = 2e-6;
      opt_size_z = wg_height;  
       
      size_x = opt_size_x + 1e-6;
      size_y = opt_size_y + 1e-6;
      size_z = 1.2e-6;          
       
      # Material and Mesh Parameters
      wg_index = 2.417;          
      bg_index = 1.46;          
      fine_mesh_size = 20e-9;  
       
       
      ## GEOMETRY SETUP
      # Input Waveguide
      addrect;
      set('name','input wg');
      set('x min',-size_x);
      set('x max',-opt_size_x/2 + 5e-7);
      set('y',0);
      set('y span',wg_width);
      set('z', 0);
      set('z span', wg_height);
      set('index',wg_index);
       
      # Output Waveguides
      for( i=1:num_wg ) {
        addrect;
        set('name','output wg '+num2str(i));
        set('x min',opt_size_x/2 - 5e-7);
        set('x max',size_x);
        set('y',-total_wg_h_span/2 + (wg_width/2) + (i-1)*(out_wg_dist+wg_width));
        set('y span',wg_width);
        set('z', 0);
        set('z span', wg_height);
        set('index',wg_index);
      }
       
       
      ## SOURCE SETUP
       
      addmode;
      set('direction','Forward');
      set('injection axis','x-axis');
      set('x',-size_x/2+0.2e-6);
      set('y',0);
      set('y span',3*wg_width);
      set('z',0);
      set('z span',size_z - 0.2e-6);
      set('center wavelength',500e-9);
      set('wavelength span',0);
      set('mode selection','fundamental TE mode');
       
       
      ## FDTD SIMULATION REGION (FDTD)
      addfdtd;
      set('dimension','3D');
      set('index',bg_index);
      set('mesh accuracy',3);
      set('x min',-size_x/2);
      set('x max',size_x/2);
      set('y min',-size_y/2);
      set('y max',size_y/2);
      set('z min',-size_z/2);
      set('z max',size_z/2);
      set('z min bc','PML');
      set('z max bc','PML');
      set('auto shutoff min',1e-6);
      set('simulation time',5000e-15);
       
       
      ## MESH REFINEMENT FOR 100nm FEATURES
      addmesh;
      set('name','opt_mesh');
      set('x',0);
      set('x span',opt_size_x);
      set('y min',-opt_size_y/2);
      set('y max',opt_size_y/2);
      set('z', 0);
      set('z span', opt_size_z);
      set('override x mesh',true);
      set('dx',fine_mesh_size);
      set('override y mesh',true);
      set('dy',fine_mesh_size);
      set('override z mesh',true);
      set('dz',fine_mesh_size);
       
       
      ## MONITORS
      # Optimization Fields Monitor
      adddftmonitor;
      set('name','opt_fields');
      set('monitor type','3D');
      set('x',0);
      set('x span',opt_size_x);
      set('y min',-opt_size_y/2);
      set('y max',opt_size_y/2);
      set('z', 0);
      set('z span', opt_size_z);
       
      # FOM (Figure of Merit) Monitors
      for( i=1:num_wg ) {
        y_center = -total_wg_h_span/2 + (wg_width/2) + (i-1)*(out_wg_dist+wg_width);
        adddftmonitor;
        set('name','fom_'+num2str(i));
        set('monitor type','2D X-normal');
        set('x', size_x/2-0.2e-6);
        set('y', y_center);
        set('y span', 3*wg_width);
        set('z min', -size_z/2);
        set('z max', size_z/2);
      }  
       
      # Global Index Monitor (for visualization)
      addindex;
      set('name','global_index');
      set('monitor type','3D');
      set('x min',-size_x/2);
      set('x max',size_x/2);
      set('y min',-size_y/2);
      set('y max',size_y/2);
      set('z min',-size_z/2);
      set('z max',size_z/2);
       
       
      ## INITIAL GUESS
      # addstructuregroup;
      # set("name","initial_guess");
      # for( i=1:num_wg ) {
      #   y_out = -total_wg_h_span/2 + (wg_width/2) + (i-1)*(out_wg_dist+wg_width);
      #   addwaveguide;
      #   set("name","bend"+num2str(i));
      #   set("base width", wg_width);
      #   set("base height", wg_height);
      #   set("base angle",90);
      #   poles = [-opt_size_x/2, 0;
      #             0, 0;
      #             0, y_out;
      #             opt_size_x/2, y_out];
      #   set("poles",poles);
      #   set("index",wg_index);
      #   addtogroup("initial_guess");
      # }
       





      python code for optimization:

      ######## IMPORTS ########
      # General purpose imports
      import os
      import sys
      import numpy as np
       
      # Optimization specific imports
      from lumopt import CONFIG
      from lumopt.geometries.topology import TopologyOptimization2D,TopologyOptimization3DLayered
      from lumopt.utilities.load_lumerical_scripts import load_from_lsf
      from lumopt.figures_of_merit.modematch import ModeMatch
      from lumopt.optimization import Optimization
      from lumopt.optimizers.generic_optimizers import ScipyOptimizers
      from lumopt.utilities.wavelengths import Wavelengths
       
      ######## DEFINE BASE SIMULATION ########
       
      def runSim(params, eps_bg, eps_wg, x_pos, y_pos,z_pos, size_x, size_y,size_z, filter_R, min_feature_size, working_dir, beta):
       
          ######## DEFINE GEOMETRY ########
          geometry =TopologyOptimization3DLayered(params=params, eps_min=eps_bg, eps_max=eps_wg, x=x_pos, y=y_pos,z=z_pos, filter_R=filter_R, min_feature_size=min_feature_size, beta=beta)
       
          ######## DEFINE FIGURE OF MERIT FOR EACH OUTPUT WAVEGUIDE ########
          fom1 = ModeMatch(monitor_name = 'fom_1', mode_number = 'Fundamental TE mode', direction = 'Forward', norm_p = 2, target_fom=1)
          fom2 = ModeMatch(monitor_name = 'fom_2', mode_number = 'Fundamental TE mode', direction = 'Forward', norm_p = 2, target_fom=1)
       
          ######## DEFINE OPTIMIZATION ALGORITHM ########
          optimizer = ScipyOptimizers(max_iter=800, method='L-BFGS-B', pgtol=1e-6, ftol=1e-5, scale_initial_gradient_to=0.25)
       
          ######## DEFINE SETUP SCRIPT AND INDIVIDUAL OPTIMIZERS ########
         
          script = load_from_lsf('D:/Lumerical_projects/wdm/base_diamond_2.lsf')
          script = script.replace('opt_size_x=3e-6','opt_size_x={:1.6g}'.format(size_x))
          script = script.replace('opt_size_y=2e-6','opt_size_y={:1.6g}'.format(size_y))
       
          wavelengths1 = Wavelengths(start = 520e-9, stop = 540e-9, points = 11)
          opt1 = Optimization(base_script=script, wavelengths = wavelengths1, fom=fom1, geometry=geometry, optimizer=optimizer, use_deps=False, hide_fdtd_cad=True, plot_history=False, store_all_simulations=False, save_global_index=True)
          wavelengths2 = Wavelengths(start = 600e-9, stop = 800e-9, points = 11)
          opt2 = Optimization(base_script=script, wavelengths = wavelengths2, fom=fom2, geometry=geometry, optimizer=optimizer, use_deps=False, hide_fdtd_cad=True, plot_history=False, store_all_simulations=False, save_global_index=False)
         
       
          ######## PUT EVERYTHING TOGETHER AND RUN ########
          opt = opt1+opt2
          opt.run(working_dir = working_dir)
       
      if __name__ == '__main__':
          size_x = 3000
          size_y = 2000
          size_z = 220
         
          filter_R = 75e-9
          min_feature_size=100e-9
       
          x_points=int(size_x/20)+1
          y_points=int(size_y/20)+1
          z_points=int(size_z/20)+1
         
          eps_wg = 2.417**2
          eps_bg = 1.46**2
          x_pos = np.linspace(-size_x/2*1e-9,size_x/2*1e-9,x_points)
          y_pos = np.linspace(-size_y/2*1e-9,size_y/2*1e-9,y_points)
          z_pos = np.linspace(-size_z/2*1e-9,size_z/2*1e-9,z_points)
       
          ## We need to pick an initial condition. Many different options:
          params = 0.5*np.ones((x_points,y_points))     #< Start with the domain filled with (eps_wg+eps_bg)/2
          #params = np.ones((x_points,y_points))        #< Start with the domain filled with eps_wg
          #params = np.zeros((x_points,y_points))       #< Start with the domain filled with eps_bg    
          #params = None                                #< Use the structure defined in the project file as initial condition
       
          working_dir = 'diamond_2_3D_TE_topology_x{:04d}_y{:04d}_f{:04d}'.format(size_x,size_y,int(filter_R*1e9))
          runSim(params, eps_bg, eps_wg, x_pos, y_pos,z_pos, size_x*1e-9, size_y*1e-9,size_z*1e-9,filter_R, min_feature_size,working_dir=working_dir, beta=1)
       

      After completing the topology optimization, the process generated a forward_0.fsp file and an image (optimization_400.png), which I’ve attached.





      I then opened the forward_0.fsp file and ran the attached FDTD script. I’ve also included the resulting transmission plot.

      I noticed that transmission between 600 nm and 800 nm is visible in the spectrum, but there is no transmission below 600 nm.
      Additionally, in the optimization_400.png image, it appears that light is mainly transmitting through Channel 2, not Channel 1. Could you please explain why this might be happening?

      Could you also confirm whether my workflow and script are correct?




      code for see the transmission:
       
      import lumapi
      import matplotlib.pyplot as plt
       
      # Update fsp_path to your new file location
      fsp_path = r"D:\Lumerical_projects\wdm\diamond_2_3D_TE_topology_x3000_y2000_f0075_0\opts_1\forward_0.fsp"
       
      fdtd = lumapi.FDTD()
      fdtd.load(fsp_path)
       
      transmission_1 = fdtd.getresult('fom_1', 'T')
      transmission_2 = fdtd.getresult('fom_2', 'T')
       
      wavelengths_1 = transmission_1['lambda'] * 1e9  # convert to nm
      data_1 = transmission_1['T']
       
      wavelengths_2 = transmission_2['lambda'] * 1e9
      data_2 = transmission_2['T']
       
      plt.figure(figsize=(8,5))
      plt.plot(wavelengths_1, data_1, label='Channel 1 (520-540 nm)')
      plt.plot(wavelengths_2, data_2, label='Channel 2 (600-800 nm)')
      plt.xlabel('Wavelength (nm)')
      plt.ylabel('Transmission')
      plt.title('Transmission Spectra for Both Channels')
      plt.legend()
      plt.grid(True)
       
      # Force x-axis to show 500 nm to 800 nm
      plt.xlim(500, 800)
       
      plt.show()
       
      fdtd.close()




      Could you please guide me on how to design a wavelength demultiplexer with a 100 nm feature size that achieves over 95% transmission in the 520–540 nm and 600–800 nm ranges for each respective output channel?

    • Taylor Robertson
      Ansys Employee

      Hello,

      I don't believe that the optimization has run to completion, but it looks like the Transmission targets are pretty close to the target. I don't believe that DFM is being allowed to complete. Maybe reduce the max_iterations ~200.

      Because you have two channels and wavelength targets there are multiple simulations being run. The results you are looking at are for the second target 600-800nm. You can look at "opts_0\forward_0.fsp” to see the other wavelength target.

      Alternatively, I would adjust the bandwidth in the final simulation and plot the results for 500-800nm.  

      fdtd.load(fsp_path)
      fdtd.switchtolayout()
      fdtd.setglobalsource('wavelength start',500e-9)
      fdtd.setglobalsource('wavelength stop',800e-9)
      fdtd.setglobalmonitor('frequency points',100)
      fdtd.run()

      Some other things to consider, you are using a single index value of 2.417 for the whole bandwidth, while there is likely dispersion. The filter_R parameter is the radius of the convolution filter used in the grescale and binarization. This isn't guaranteed to to achieve a minimum feature size, but is intended to close out small features in the topology object - box blur. There is no definitive answer here, you can play around to see how this effects performance and minimum feature size. The DFM step, actually penalizes the FOM when minimum features are present, and then optimizes; however, I don't think you have run the DFM step for this device.

      Best Regards,

    • raano1
      Subscriber

      Dear Ansys Support,

      To see the transmission spectrum result, I am using this 

      "

      import lumapi

      import matplotlib.pyplot as plt

       

      # Path to your Lumerical .fsp project file (you can use either opts_0 or opts_1)

      fsp_path = r"D:\Lumerical_projects\wdm\diamond_3_3D_TE_topology_x3000_y2000_f0075_1\opts_1\forward_0.fsp"

       

      # Start Lumerical FDTD session and load the project

      fdtd = lumapi.FDTD()

      fdtd.load(fsp_path)

       

      # --- Start of New Code Block ---

      # This is the advice from the Lumerical support person

       

      print("Modifying simulation settings for a wide bandwidth analysis...")

       

      # Switch to layout mode to allow edits to the simulation objects

      fdtd.switchtolayout()

       

      # Set the new, wider wavelength range for the source

      fdtd.setglobalsource('wavelength start', 500e-9) # 500 nm

      fdtd.setglobalsource('wavelength stop', 800e-9) # 800 nm

       

      # Set the number of frequency points for the monitors to calculate results at

      # This ensures good resolution over the new, wider range.

      fdtd.setglobalmonitor('frequency points', 200) # Increased points for better resolution

       

      print("Running the new simulation...")

      # Run the simulation with these new settings

      fdtd.run()

       

      # --- End of New Code Block ---

       

      print("Simulation complete. Retrieving results...")

      # Now, the getresult commands will work and contain data from 500-800 nm

      trans_1 = fdtd.getresult('fom_1', 'T')

      trans_2 = fdtd.getresult('fom_2', 'T')

       

      # Extract wavelengths in nanometers and transmission values

      # Both trans_1 and trans_2 now cover the full spectrum

      wavelengths_1 = trans_1['lambda'] * 1e9

      transmission_1 = trans_1['T']

       

      wavelengths_2 = trans_2['lambda'] * 1e9

      transmission_2 = trans_2['T']

       

      # --- Updated Plotting Section ---

      # Since both monitors have the full spectrum, we can plot them on one graph

      plt.figure(figsize=(10, 6))

      plt.plot(wavelengths_1, transmission_1, 'b-o', label="Transmission at Monitor 'fom_1'")

      plt.plot(wavelengths_2, transmission_2, 'r-o', label="Transmission at Monitor 'fom_2'")

       

      plt.xlabel('Wavelength (nm)')

      plt.ylabel('Transmission')

      plt.title('Complete Transmission Spectra (500-800 nm)')

      plt.legend()

      plt.grid(True)

      plt.show()

       

      # Close Lumerical session after plotting

      fdtd.close()"






      Python code, and I can already see the result. Do I also need to add a mode expansion monitor?

    • raano1
      Subscriber

      Dear Ansys Support Team,

      To see the transmission spectrum result, I am using this 

      "

      import lumapi

      import matplotlib.pyplot as plt

       

      # Path to your Lumerical .fsp project file (you can use either opts_0 or opts_1)

      fsp_path = r"D:\Lumerical_projects\wdm\diamond_3_3D_TE_topology_x3000_y2000_f0075_1\opts_1\forward_0.fsp"

       

      # Start Lumerical FDTD session and load the project

      fdtd = lumapi.FDTD()

      fdtd.load(fsp_path)

       

      # --- Start of New Code Block ---

      # This is the advice from the Lumerical support person

       

      print("Modifying simulation settings for a wide bandwidth analysis...")

       

      # Switch to layout mode to allow edits to the simulation objects

      fdtd.switchtolayout()

       

      # Set the new, wider wavelength range for the source

      fdtd.setglobalsource('wavelength start', 500e-9) # 500 nm

      fdtd.setglobalsource('wavelength stop', 800e-9) # 800 nm

       

      # Set the number of frequency points for the monitors to calculate results at

      # This ensures good resolution over the new, wider range.

      fdtd.setglobalmonitor('frequency points', 200) # Increased points for better resolution

       

      print("Running the new simulation...")

      # Run the simulation with these new settings

      fdtd.run()

       

      # --- End of New Code Block ---

       

      print("Simulation complete. Retrieving results...")

      # Now, the getresult commands will work and contain data from 500-800 nm

      trans_1 = fdtd.getresult('fom_1', 'T')

      trans_2 = fdtd.getresult('fom_2', 'T')

       

      # Extract wavelengths in nanometers and transmission values

      # Both trans_1 and trans_2 now cover the full spectrum

      wavelengths_1 = trans_1['lambda'] * 1e9

      transmission_1 = trans_1['T']

       

      wavelengths_2 = trans_2['lambda'] * 1e9

      transmission_2 = trans_2['T']

       

      # --- Updated Plotting Section ---

      # Since both monitors have the full spectrum, we can plot them on one graph

      plt.figure(figsize=(10, 6))

      plt.plot(wavelengths_1, transmission_1, 'b-o', label="Transmission at Monitor 'fom_1'")

      plt.plot(wavelengths_2, transmission_2, 'r-o', label="Transmission at Monitor 'fom_2'")

       

      plt.xlabel('Wavelength (nm)')

      plt.ylabel('Transmission')

      plt.title('Complete Transmission Spectra (500-800 nm)')

      plt.legend()

      plt.grid(True)

      plt.show()

       

      # Close Lumerical session after plotting

      fdtd.close()"






      Python code, and I can already see the result. Do I also need to add a mode expansion monitor?

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