In this example, we demonstrate how to design a 50:50 Y-splitter using topology optimization with lumopt. This example complements the existing Y branch Inverse design example which uses shape optimization.
For more info on the differences between these two flavors of inverse design see Optimizable Geometry - Python API
Introduction to Topology Optimization
Inverse design using Topology Optimization enables automatic generation of devices that are optimized for a user-specified figure of merit (FOM). In this Y-splitter example, we want to maximize T_up, the fraction of the total input energy that is transmitted into the upper arm. Since we will enforce symmetry in the y-direction, the maximal value of the FOM will be 0.5. For visualization, instead of directly plotting T_up, we show the insertion loss, so FOM=0.5 - T_up.
The important difference from shape optimization is that for topology optimization, you only need to specify an optimization area. There is no need to parameterize the geometry. The optimization process will often result in non-intuitive but highly efficient structures.
The main challenge with structures generated via topology optimization is manufacturability. To control the smallest features, the optimizer continuously smooths the structure using a filter with a user-defined radius filter_R. This removes small features and rounds sharp corners and thereby improves manufacturability.
Step 1: Define base simulation project
First, we need to define a base simulation project which contains the general structure of the device. This includes the simulation region with the input and output waveguides as well as the source and monitor positions. In this example, we optimize a 50:50 splitter over the wavelength range from 1450nm to 1650nm. The base simulation project is generated via the script file [[splitter_base_2D_TE_topology.lsf]]. We can inspect the setup by opening and running the script in FDTD:
In this example, the setup script also generates a structure group called ‘initial_guess’ which provides an initial device that can be used as a starting point for the optimization. This structure group is optional and topology optimization will also work without it.
Step 2: Define optimization region
For the next step, we first need to define several optimization parameters:
|Name||Value in the example||Description|
|size_x||3000 [nm]||Length of the device|
|size_y||1800 [nm]||Since we use symmetry along the y-axis, the value is half the height of the device|
|delta_x||20 [nm]||Size of a pixel along the x-axis|
|delta_y||20 [nm]||Size of a pixel along the y-axis|
|filter_R||500 [nm]||Radius of the smoothing filter which removes small features and sharp corners|
|eps_max||2.8^2=7.84||Effective permittivity for a Silicon waveguide with a thickness of 220nm|
|eps_min||1.44^2=2.0736||Permittivity of the SiO2 cladding|
In addition, we need to specify the FOM and additional optimizer settings. This is done in the script file [[splitter_opt_2D_TE_topology.py]]. Here, we also define the initial conditions. As discussed above, the main advantage of topology optimization is that there is no need for a sophisticated starting condition. Instead, we can simply fill the entire optimization region with either eps_max or eps_min.
Step 3: Run topology optimization
Running the script [[splitter_opt_2D_TE_topology.py]] will start the optimization. Topology optimization as implemented here works in two phases. First, during the ‘grayscale phase’, the optimizer is free to use any permittivity value ϵ ∈ [eps_low,eps_high ] for the permittivity. Once the optimizer has reached an optimum, it will start the ‘binarization phase’. Here, the optimizer now tries to convert the continuous permittivity distribution into a binary structure that only uses either eps_low or eps_high, but no intermediate values.
The final plot after around 200 iterations should look like this :
In the above plot, we can observe spikes where the FOM temporarily gets worse. Each spike signifies an increase in the binarization factor with a subsequent optimization to improve the FOM again. Towards the end of the optimization, we observe a slight overall deterioration of the FOM. This is again caused by the fact that the binarized structures perform slightly worse than a smooth structure. However, the FOM is plotted on a semi-logarithmic scale and the absolute deterioration is relatively small.
As of 2020aR7 we now support an optional optimization step that will try and force the device to meet manufacturing constraints.
This new workflow proceeds in the same fashion as before, except a design for the manufacturing (DFM) phase is included at the end.
During DFM an indicator function that is minimal when the min feature size constraint is fulfilled everywhere, is used to penalize the figure of merit FOM. This helps the optimizer remove small holes/pillars, and channels/ridges. We applied a technique developed in  to photonics inverse design.
To implement this feature simply add the "min_feature_size" parameter to the TopologyOptimization class.
geometry = TopologyOptimization2D(params=params, eps_min=eps_min, eps_max=eps_max,
x=x_pos, y=y_pos, z=0, filter_R=filter_R, min_feature_size=filter_R)
The optimization should automatically proceed through a DFM phase once the binarization threshold is reached
The minimum feature size constraint was added to line 23. Both the smoothing filter and minimum feature size constraint is set to 150nm, which is a reasonable design specification for optical lithography.
Furthermore, we increased the number of iterations per binarization step to help produce a more readily manufacturable device. See line 45.
opt.continuation_max_iter = 40 #< How many iterations per binarization step (default is 20)
which proceeds as seen below. This argument changes the number of iterations between spikes during the binarization phase.
To extract the resulting designs for mask layout see GDS pattern extraction for inverse designed devices using contours method
- Zhou, M. et a. “Minimum length scale in topology optimization by geometric constraints”, Comput. Methods in Appl. Mech. Eng 293, 266-282 (2015)