With the release of 2020 R2.3 release, we added two new features to our photonic inverse design toolbox lumopt:

- Support for co-optimization with user defined weights.
- Support for tilted figure-of-merit monitors (and corresponding tilted adjoint sources)

In this post, we demonstrate how to combine those two new features to maximize the coupling efficiency of a grating coupler while simultaneously minimizing the back-reflection into the waveguide.

This example is based on our existing application gallery example “Inverse design of grating couple ”but reverses the excitation and includes the back-reflection into the target figure of merit (FOM). To accomplish this, we will use a four-step approach:

**Step 1: Define base simulation parameters**

The goal of this initial step is to define the setup of the FDTD simulation that will be used for the adjoint optimization. This includes the settings for the source, monitors for field gradient and figure of merit (FOM) calculations. These settings are adjusted in the FDTD file

( pid_grating_coupler_2D_TE_base_tilted.fsp). For co-optimization, we need to define two monitors, one for each figure of merit (coupling efficiency “fom” and back reflection “fom_back”).

The forward simulation has the light coming from the horizontal waveguide as shown below which is different from the original PID GC example.

While in the adjoint simulation for the coupling efficiency fom, the light propagates from the tilted fiber as we no longer use the beam source and use the fiber group instead to model the fiber explicitly.

**Step 2: initialize the optimization geometry**

In the simulation folder, there is a python file (pid_optim_1.json) with the values of 50 parameters representing the starting point of the gratings defined by a polygon (equivalent to step 2 in the existing Inverse design of grating coupler 10 example).

**Step 3: Set up the tilted fiber angle parameters**

In the main python simulation file (pid_grating_coupler_2D_1etch_tilted.py), the *rotation_angle_theta* and *rotation_offset* values are defined in calling ModeMatch class for adjoint calculations of the first figure of merit (coupling efficiency - fom). In our example the rotation_angle_theta is defined identical to the fiber angle theta (*theta0* in the fiber group) in the FDTD base simulation file (with an opposite sign).

fom = ModeMatch(monitor_name = 'fom',

mode_number = 1,

direction = 'Forward',

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

norm_p = 1,

rotation_angle_theta = -5,

rotation_offset = 8.13081e-6)

**Step 4: Formulate the co-optimization problem:**

In our example, we are interested in maximizing the coupling efficiency between the GC (fom) and the tilted fiber and minimizing the back reflection from the gratings (fom_back). Therefore, in the main python file (pid_grating_coupler_2D_1etch_tilted.py), the SuperOptimization class is imported first in the headings.

from lumopt.optimization import Optimization

from lumopt.optimization import SuperOptimization

TWO optimization classes are set-up representing the two figures of merit and called (opt1 and opt2).

opt1 = Optimization(base_script = base_script,

wavelengths = wavelengths1,

fom = fom,

geometry = geometry,

optimizer = optimizer1,

use_var_fdtd = False,

hide_fdtd_cad = False,

use_deps = True,

plot_history = True,

store_all_simulations = True,

save_global_index = False,

label = None)

opt2 = Optimization(base_script = base_script,

wavelengths = wavelengths2,

fom = fom_back,

geometry = geometry,

optimizer = optimizer2,

use_var_fdtd = False,

hide_fdtd_cad = False,

use_deps = True,

plot_history = True,

store_all_simulations = True,

save_global_index = False,

label = None)

Then, the SuperOptimzation is called with a list of the figure of merits [fom1, fom2] and their corresponding list of weights [1, -1] (+ve weights for maximization and -ve for minimization) and finally run the optimizer.

Note: co-optimization weights are selected according to each problem, and their values may impact the convergence speed of the optimizer.

######## RUN THE OPTIMIZER ########

optT=[opt1, opt2]

weights=[1, -1]

opt=SuperOptimization(optimizations = optT,weights = weights)

result = opt.run(working_dir=working_dir) return result

During the optimization step, the total figure of merit which in our case is the difference between the fom (coupling efficiency) and fom_back (back reflection) is plotted against each step and we can notice the improvement in each one of the three plots.

Note: in this simulation, we impose the fabrication feasibility condition of 100 nm as minimum feature size of the grating coupler as activated in the python script.