In this example, a photonic inverse design workflow is introduced for the optimization of 2D polarization splitting grating couplers (2D PSGC). The 2D PSGC is used in photonic integrated circuits (PIC) to achieve polarization diversity, enabling efficient coupling of both P- and S-polarization. This example shows how we can optimize 2D PSGC to reduce peak insertion loss, increase bandwidth, and minimize polarization dependent loss (PDL). This example can only be run with Lumerical release 2025 R2.1 or later. Also, it is recommended to use GPU. We used two H100 GPU cards (95 GB RAM/card) for optimization.
Overview
Understand the simulation workflow and key results
This example will demonstrate how to use the inverse design method to generate the 2D PSGC.
This example draws extensively from the LumOpt framework:
- Photonic Inverse Design Overview - Python API
- Getting Started with lumopt - Python API
- Optimizable Geometry - Python API
Step 1: Pre-optimization
In this step,the 2D PSGC structure can be modified in the pre-optimization project file to set up the initial design. Next, a preparation script is executed to configure a copy of this project file to be used as input for LumOpt. The script also generates the required additional input data files for LumOpt, as explained in Run and Results . This step is optional, as the preparation script has been already run for the pre-optimization file provided in the example.
Step 2: Diamond optimization
Using the files generated in Step 1, we run the inverse design optimization of the 2D PSGC. After the optimization, a script is run to prepare the input files for Step 3 (star optimization). This step can be also skipped to test Step 3 directly. However, the diamond optimization is strongly recommended as the first stage for a new design since it is significantly faster.
Step 3: Star optimization
Using the best solution obtained from Step 2, we run a second inverse design optimization to reduce the polarization dependent loss (PDL).
Run and Results
Instructions for running the model and discussion of key results
Step 1: Pre-optimization
This step is not necessary if you want to run the example as it is; however, the pre-optimization is required for modification of the initial design based on your needs.
- Open the file GenO-Si2-dia-Ppol_pre-opt.fsp and GenO-Si2-dia-Spol_pre-opt.fsp in FDTD.
- Modify the structure group as necessary and run the script prepare-input-files_stage2.lsf .
The parameterization of the PSGC shown below is based on ref. [1] and [2] , while the layer thickness and general geometry parameters (e.g., waveguide width) were taken from ref. [3] .
The PSGC is formed by a 2D array of scatterers with two tapers, each of them connected to a waveguide (WG1 and WG2). The angle between the waveguides (\( \alpha_{WG} \)) is \( \frac{\pi}{2} \) and the whole structure is symmetric with respect to the fiber’s plane of incidence. The scatterers are arranged on a grid formed by the intersection of two sets of confocal ellipses, with the waveguide tips at the far focal point, as shown above. The initial design can be modified by adjusting the variables defined within the structure group (psgc-star-fast) such as \( d_{spot},\ \; L_{taper},\ \text{and}\ \alpha_{taper} \). For more information about the structure group, see
Important Model settings
.
After modifying the
GenO-Si2-dia-Ppol_pre-opt.fsp
and
GenO-Si2-dia-Spol_pre-opt.fsp
file, run the
prepare-input-files_stage2.lsf
file, which prepares the simulation files for each polarization (P and S). The script starts by loading the pre-optimization files (*pre-opt.fsp) for both polarizations and saves new versions for optimization. In this process, the script also enables the structure group to save key configuration data, such as parameters, scatterer indices, and center positions in .txt files
Step 2: Diamond optimization
- Open the file GenO-Si2-dia-Ppol.py in the FDTD Script File Editor.
- Modify the optimization configuration (parameter limits, range and weight of wavelengths in the figure of merit, etc.) as necessary and run the Python script. See Important Model Settings for more information on the optimization configuration.
Here we load the initial design and parameters from Step 1 and run the optimization for multiple wavelengths centered at 1310 nm, with a span of 55 nm and 5 sampling points.
The figure of merit (FOM) is defined as the minimum coupling efficiency between S- and P-polarization, with a polarization-dependent loss (PDL) penalty term disabled (difference_weight=0).
The design parameters in this case are the distances \( p_1, \; q_1, \; p_2, \; \text{and} \; q_2 \) for each diamond-shaped scatterer as illustrated in the figure below.
There are 406 independent scatterers for optimization, which correspond to the upper half of the structure (positive y axis), due to symmetry. Each scatterer has 4 parameters \( (p_1, \; q_1, \; p_2, \; q_2) \) but the scatterers along the bisection line (symmetry plane) have only 2. Therefore, there is a total of 1568 independent parameters that will be optimized.
Here, the optimization was stopped after 44 iterations in about 22 hours, with a total figure of merit around 0.52.
Step 3: Star optimization
- Open the prepare-input-files_stage3.lsf and update the pre_opt_file_fullname and pre_coopt_file_fullname for Step 3 if using a different iteration for best design from Step 2.
- Open the GenO-Si2-star-Ppol.py in the FDTD Script File Editor.
- Modify the optimization configuration as necessary and run the Python script.
- After optimization, run the best_design_analysis.lsf file in the best_design folder to compare the coupling efficiency spectrum for the start, best diamond-shaped and best star-shaped designs. This script also generates GDS files for the three designs.
Here, the FOM is the same as in Step 2 but with the PDL penalty term enabled (difference_weight = 0.1). In addition to the design parameters \( p_1, \; q_1, \; p_2, \; \text{and} \; q_2 \) from Step 2 (diamond optimization), here we introduce the parameter \( r_1, \; s_1, \; r_2, \; \text{and} \; s_2 \) to generate star-shaped scatterers, as shown in the figure below.
Due to the additional four parameters per scatterer in this case, there are 3136 independent parameters for optimization (with the same symmetry considerations as for the diamond-shaped scatterers). Here, the optimization was stopped after 18 iterations in about 14 hours, with a total figure of merit around 0.52. Note that due to the PDL penalty term the FOM in this case starts at 0.28, which is lower than the FOM (without penalty term) from stage 2.
After completing all the optimization steps, we compared the total coupling efficiency and PDL between the start design and the best designs from Step2 (diamond shape) and Step3 (star shape), as shown in the graphs and table below. For convenience, copies of the project files for these designs are provided in the best_design folder so that the plots and table below can be reproduced by running the script file best_design_analysis.lsf in the same folder. Note that in the original project files, only half of the scatterers are drawn; therefore, the script creates new versions of the files (identified by the suffix “_analysis”) with the full structure for GDS extraction.
| Start diamond | Best diamond | Best star | ||
| S polarization | Peak CE (dB) | -5.8 | -1.6 | -1.6 |
| Peak λ (nm) | 1319 | 1315 | 1315 | |
| 1dB BW (nm) | 29 | 31 | 30 | |
| P polarization | Peak CE (dB) | -5.1 | -1.7 | -1.6 |
| Peak λ (nm) | 1312 | 1313 | 1314 | |
| 1dB BW (nm) | 23 | 30 | 30 |
Important Model Settings
Description of important objects and settings used in this model
Structure Group - Modes operation
Since the structure group is updated for each parameter in every iteration, the performance of its setup script is important to speed up the mesh gradient calculation.
The structure group operates in two different modes:
- "Construction" (full_reset=1): The structure group regenerates all scatterers. This mode is required when the set of ellipse indices \( (N_1, \; N_2) \) or any scatterers properties other than vertex position are changed. The user properties 9-38 of the structure group (see Appendix ) define the scatterer configurations in this mode. It is recommended for initial setup and pre-optimization.
-
"Update" (full_reset=0): The structure group only updates the vertex positions of the scatterers, significantly reducing the time to execute the setup script. Therefore, the optimization in this example is configured to use base FDTD files in this mode. Only two user properties of the structure group are used in this mode:
- params: A 1D array (total number of parameters for all scatterers x 1) updated by LumOpt.
- Config: A 2D array (number of scatterers x 10) with \( (N_1, \; N_2) \) and vertex map for all scatterers.
Other simulation objects
If the structure is symmetric, use Symmetric and Antisymmetric boundary conditions for P and S polarization, respectively. Also, the ‘opt_fields’ monitor must extend into the symmetry/anti symmetry region.
LumOpt settings - Bounding box and params limits
To define the location and size of each bounding box, a Bounds class is used as input to ParameterizedGeometry class.
The
get_bounds()
function accesses the current parameters (
current_params
) used by LumOpt, enabling the bounding boxes to be updated dynamically throughout the optimization process.
In the current setup, however, the bounding boxes are static with initial locations of each scatterer and bounds set 500 nm away from the center of each scatterer.
Optionally, [zmin, zmax] can be included in the returned values if the vertical dimension of the bounding boxes is not the same as the opt_fields monitor.
The range of allowed values in params is specified by bounds list passed to ParameterizedGeometry.
LumOpt settings - Figure of Merit (FOM)
The FOM used in this example is based on ref.
[3]
, combining a soft minimum with a PDL penalty term. It is implemented in the Python script using the
SuperOptimization
class with
use_advanced_fom=True
.
The FOM
[3]
is defined as:
$$
\mathrm{FOM}
= \sum_{i=1}^{N_\lambda}
\left[
w_i \cdot
\frac{-2 \cdot \log\left(e^{-100 T_{p_i}} + e^{-100 T_{s_i}}\right)}{100}
- \alpha \cdot (100 T_{p_i} - 100 T_{s_i})^2
\right]
$$
where:
- \( T_{s,i} \) and \( T_{p,i} \) are the coupling efficiencies at wavelength i for S and P polarization, respectively.
- \( w_i \) is the weight of each wavelength, set by target_T_fwd.
- \( \alpha \) is the PDL penalty term set by difference_weight in the SuperOptimization arguments.
- \( N_{\lambda} \) is the total number of wavelengths.
Additional Resources
Additional documentation, examples and training material
Related Publications
- A. Mekis et al., "A Grating-Coupler-Enabled CMOS Photonics Platform," in IEEE Journal of Selected Topics in Quantum Electronics, vol. 17, no. 3, pp. 597-608, May-June 2011
- F.Van Laere, W. Bogaerts, P. Dumon, G. Roelkens, D. Van Thourhout and R. Baets, "Focusing Polarization Diversity Grating Couplers in Silicon-on-Insulator," in Journal of Lightwave Technology, vol. 27, no. 5, pp. 612-618, March1, 2009
- Peng Sun, Thomas Van Vaerenbergh, Sean Hooten, and Raymond Beausoleil, "Adjoint optimization of polarization-splitting grating couplers," Opt. Express 31, 4884-4898 (2023)
See Also
Related Ansys Innovation Courses
Appendix
Additional background information and theory
2D PSGC Geometry: Grid of Scatterers
The geometry of the PSGC is controlled by the parameters in the structure group (psgc-star-fast) in the simulation file.
A confocal ellipse-based coordinate system is used to guide the placement of scatterers based on the phase matching condition between the grating and optical fiber modes [1, 2] . Confocal ellipses are defined by the equation:
$$
r = \frac{N \Lambda}{1 - e \cos \phi}
$$
where:
- r: radial distance
- \( \phi \): polar angle
- N : Ellipse index
- \( \Lambda = \frac{\lambda_0}{n_e} \): Grating pitch factor
- \( e = \frac{n_c \sin \theta_f \sin \left( \frac{\alpha_{WG}}{2} \right)}{n_e} \): Ellipse eccentricity
The ellipse index \( N \) spans the range:
$$
N \in [N_{\min},\, N_{\max}]
$$
with \(N_{\min} \) and \(N_{\max} \) determined by the taper length \( L_{taper} \) and the beam spot diameter \( d_{spot} \).
The effective indices of the grating and the fiber are denoted by \( n_{e} \) and \( n_{c} \) respectively. The vacuum wavelength and the fiber’s angle of incidence are denoted by \( \lambda_{0} \) and \( \theta_{f} \).
To facilitate placement of scatterers, a two-dimensional curvilinear coordinate system is introduced based on the intersection of confocal ellipses. Each point in this space is defined by a pair \( (N_1,\, N_2) \), where both indices fall within the range \( N_{\min},\, N_{\max} \) . In general, \( (N_1,\, N_2) \) can be a pair of real positive numbers, but only integer values satisfy the phase matching condition. Therefore, all scatterers are located at integer-valued coordinates.
2D PSGC Geometry: Scatterer shape
Scatterers (see the image in
Run and Results
) are constructed as polygons with vertices defined by parameters \( (p_1,\, q_1,\, p_2,\, q_2,\, r_1,\, s_1,\, r_2,\, s_2) \), which are normalized relative to the curvilinear grid of integer values \( (N_1,\, N_2) \).
To avoid overlap between scatterers, we constrain the vertices to lie between integer and half integer positions in the curvilinear grid, as shown in
Run and Results
. Therefore, the normalized parameters, which represent locations relative to the integer coordinates \( (N_1,\, N_2) \) are within the range:
$$
0 < p_1,\, q_1,\, p_2,\, q_2,\, r_1,\, s_1,\, r_2,\, s_2 < 1
$$
A diamond-shaped scatterer corresponds to a specific configuration in which the second set of vertices mirrors the first:
$$
r_1 = p_1,\; s_1 = q_1,\; r_2 = p_2,\; s_2 = q_2
$$
For structures with mirror symmetry along the bisection line which corresponds to the fiber’s plane of incidence the symmetry is enforced by:
$$
p_2 = p_1,\; q_2 = q_1,\; r_2 = r_1,\; s_2 = s_1
$$
This is a simple way to ensure that the upper and lower halves of the scatterer are symmetric with respect to the fiber’s plane of incidence.
Structure group settings
We recommend using the structure group psgc-star-fast provided in the example base files. This group offers the following capabilities:
- Support 8-vertex scatterers, which can be configured either as diamond or star shapes.
- Analytical conversion from curvilinear coordinates \( (N_1,\, N_2) \) to Cartesian coordinates is performed for precise vertex placement.
The different types of user properties in the structure group are described in the tables below.
| No. | Keys | Description |
| 1 | full_reset | Number. Flag (0 or 1) to switch between “construction” (1) and “update” (0) modes of operation. See Modes of operation . |
| 2 | save_data | Number. Flag (0 or 1) to enable (1) or disable (0) saving .txt files described below. |
| 3 | params_filename | String. Base name (no extension) of .txt file with values of params user property. |
| 4 | config_filename | String. Base name (no extension) of .txt file with values of config user property . |
| 5 | log_filename | String. Base name (no extension) of .txt file with script output of setup script . |
| 6 | scattindex_filename | String. Base name (no extension) of .txt file with the index of the scatterer that corresponds to each element in the params array. See LumOpt settings-Bounding box and params limit . |
| 7 | centerx_filename | String. Base name (no extension) of .txt file with x location of scatterer centroids . |
| 8 | centery_filename | String. Base name (no extension) of .txt file with y location of scatterer centroids . |
Structure Group - Layout and layer data
| No. | Keys | Description |
| 9 | scatt_type | String. Options are “diamond” and “star”. Only necessary when full_reset = 1. |
| 10 | enclosure_row | Number. Defines the limits of the grating enclosure by a distance equivalent to a given number of additional rows |
| 11 | symmetric | Number. Flag (0 or 1) to draw all scatterers (0) or only unique ones when assuming symmetry (1). Also enforces scatterers along the fiber's plane of incident to be symmetric. |
| 12 | etch_depth | Length [μm]. Depth of etch used for scatterers. Measured from top of SOI layer. |
| 13 | Full_thickness | Length [μm]. Thickness of SOI layer. |
| 14 | slab_material | Material. SOI layer material. |
| 15 | cladding_material | Material. Material used for scatterers, which should be the same as cladding material. |
| 16 | w_wg | Length [μm]. Width of waveguides WG1 and WG2 after grating region is tapered down. |
| 17 | l_wg | Length [μm]. Length of waveguides WG1 and WG2 after taper. Must extend through PML region . |
| 18 | d_spot | Length [μm]. Fiber spot size. |
| 19 | L_taper | Length [μm]. Taper length. |
| 20 | alpha_wg_deg | Number. Angle between waveguide WG1 and WG2 in degrees. |
| 21 | alpha_taper_deg | Number. Full angle of tapers in degrees. |
Structure Group - Scatterer data
| No. | Keys | Description |
| 22 | wavelength | Length [μm]. Vacuum wavelength used to calculate a pitch factor as described in Grid of Scatterers . |
| 23 | theta_fiber_deg | Number. Fiber angle of incidence in degrees. used to calculate eccentricity as described in Grid of Scatterers . |
| 24 | N_min | Number. Minimum value of \( N_1 \) and \( N_2 \) , which determines the first row of the grating. See Grid of Scatterers . Set N_min = 0 to auto-calculate based on L_taper [recommended] . |
| 25 | N_grating | Number. Number of rows, such that \( N_2 = N_1 + N_{grating} \). See Grid of Scatterers . Set N_min = 0 to auto-calculate based on L_taper and d_spot [recommended] . |
| 26 | eccentricity | Number. Parameter to specify eccentricity of ellipses directly. Set to -1 to ignore [recommended] . |
| 27 | grating_pitch | Length [μm]. Parameter to specify pitch factor of ellipses directly. Set to -1 to ignore [recommended] . |
| 28 | n_fiber | Number. Effective index of fiber used to calculate eccentricity as described in Grid of Scatterers . |
| 29 | n_eff | Number. Effective index of grating used to calculate eccentricity and pitch factor as described in Grid of Scatterers . |
| 30 | far_focus | Number. Flag (0 or 1) to use far focal point (0) [recommended] or near focal point (1). |
| 31-38 |
\( p_1,\, q_1,\, p_2,\, q_2 \)
\( r_1,\, s_1,\, r_2,\, s_2 \) |
Numbers. Parameters to define the 8 vertices of the scatterers. Same parameters are applied to all scatterers. Only used when full_reset = 1 . |
| 39 | params | Matrix. 1-D array with the parameters for all scatterers. Only used when full_reset = 0 . See Modes of operation . |
| 40 | config | Matrix. 2-D array with \( (N_1,\, N_2) \) and vertex map for all scatterers. See Modes of operation . |