Skip to content
Switch branches/tags

Optical Inverse Design with Automatic Differentiation

This repository contains the code and notebooks for the workshop on the inverse design of optical devices with automatic differentiation. Below is the animation of such an optimization applied to an optical wavelength multiplexer.

Automatic differentiation allows one to flexibly define models for optimizing optical devices. Both parameterizations and objective functions can be easily defined using sequences of composable operations, like the example shown below.



Name NB Viewer Description
01_First_simulation View Covers the basics of setting up a finite difference frequency domain (FDFD) simulation
02_Invdes_intro View Deals with setting up and performing an inverse design optimization of a mode converter
03_Invdes_parameterization View Expands on Notebook 02 to introduce parameterization strategies
04_Invdes_wdm_scheduling View (beta) Explores inverse design applied to a wavelength multiplexer and also demonstrates optimizer scheduling of the binarization parameter

The contents of this repository are organized into several Jupyter notebooks. You can view them by clicking the links in the table above or you can interact with them through the jupyter lab interface, which is a web-based user interface that runs from your local computing environment. Details on setting up Jupyter and other necessary libraries are given below. The notebooks are numbered and can be followed in order if you have very little experience with optical simulation and optimization.

The materials were developed by Ian Williamson and Momchil Minkov, who are both postdocs in Shanhui Fan's research group. Feel free to get in touch or open an issue if you have questions or suggestions for improvements.


Getting started

To get started using these course materials, you can transfer them to your local computing environment either by downloading them or git cloning this repository. To download a zip archive of these materials, simply click the green "Clone or download" button on the top right corner of the GitHub repository page and then selecting "Download ZIP" from the drop down menu.

If you have git installed, you can enter the following command in a terminal to clone the repository:

git clone

You will also need a python environment with the necessary packages installed. There are several ways to setup a python environment, but we recommend using Anaconda, which can be downloaded for your operating system from:

Note: you will want to download the distribution for a 3.X version of Python (e.g. 3.6, 3.7, or something higher).

By default, the Anaconda distribution includes many of the python packages that we require for this workshop. However, there are a few additional packages we will need to install manually, as described in the next sections of this guide.

Installing ceviche

Ceviche is our research group's finite difference frequency domain (FDFD) and time domain (FDTD) package. This is the primary package we will use to simulate and optimize optical devices. In case you are wondering, the word "ceviche" refers to a seafood dish from Peru that Tyler Hughes enjoys.

The source code for ceviche is freely available on GitHub at You can install ceviche by git cloning the repository into your local computing environment and adding its location to your PYTHONPATH environment variable. However, we recommend installing ceviche via pip, by executing the following command:

pip install ceviche

Running this command should also install most of the dependencies for ceviche. However, we briefly describe several key dependencies below and the steps for manually installing them, if necessary.


scikit-image provides some useful utility functions for drawing shapes into 2D arrays. We can utilize these functions to help us define geometry features in our FDFD domains. To install scikit-image, execute the following command in your conda environment:

conda install scikit-image

Note: this does not get installed automatically with ceviche.

HIPS autograd

HIPS autograd is an automatic differentiation framework with a Numpy-like API. We rely on autograd for flexible gradient computation in our inverse design studies. To install autograd, execute the following command in your conda environment:

pip install autograd


pymkl provides an interface to the PARDISO sparse solver which we use to accelerate our simulations. We have observed approximately a 10X speed up in certain cases compared to the standard SciPy sparse linear solver routines. To install pymkl, execute the following command in your conda environment:

pip install pymkl


For more information and further reading on the concepts covered in this workshop, see our group's papers.

  • T. W. Hughes, I. A. D. Williamson, M. Minkov, and S. Fan, "Forward-mode Differentiation of Maxwell’s Equations," ACS Photonics, Oct. 2019. doi:10.1021/acsphotonics.9b01238

  • T. W. Hughes*, M. Minkov*, I. A. D. Williamson, and S. Fan, "Adjoint Method and Inverse Design for Nonlinear Nanophotonic Devices," ACS Photonics, Dec. 2018. doi:10.1021/acsphotonics.8b01522


πŸ“ Workshop material for optical inverse design and automatic differentiation








No releases published


No packages published