Effortlessly optimize complex photonic devices. Tidy3D integrates automatic differentiation with the efficient adjoint method, allowing you to compute gradients for thousands of parameters with just one extra simulation.
Tidy3D empowers users to perform gradient-based optimization and sensitivity analysis of photonic devices directly within their simulation workflow. This is achieved by making Tidy3D simulations differentiable – meaning we can efficiently compute the derivative (gradient) of a figure of merit (like transmission efficiency) with respect to any number of design parameters (like geometry dimensions or material properties).
This capability relies on two core technologies working together:
autograd): Handles the differentiation of the overall Python code defining your objective function.Let’s break down how these pieces fit together.
Optimizing photonic devices often involves finding the best set of design parameters (e.g., taper shape) that maximize or minimize a specific outcome (e.g., coupling efficiency). Gradient-based optimization methods are highly effective for this, but they require knowing how sensitive the outcome is to small changes in each parameter.
Calculating this gradient for a complex FDTD simulation is challenging. A naive approach (like finite differences) would require running many simulations – one for each parameter – which quickly becomes computationally infeasible for designs with many variables.
autograd and the Adjoint MethodTidy3D leverages the autograd library for automatic differentiation. When you write a Python function that defines your simulation setup, runs tidy3d.web.run, and calculates a final figure of merit, autograd can automatically track all the mathematical operations outside the simulation.

However, autograd doesn’t inherently know how to differentiate through the FDTD simulation node. This is where Tidy3D’s custom integration comes in, using the adjoint method.
We’ve essentially “taught” autograd the derivative rule for the tidy3d.web.run operation. This rule is implemented using the adjoint method, a powerful technique derived from electromagnetic theory.
Key Benefit of the Adjoint Method: It allows us to compute the gradient of the figure of merit with respect to all design parameters using just one additional simulation (the adjoint simulation), regardless of how many parameters there are (hundreds, thousands, or even millions).
When you ask autograd to compute the gradient (e.g., using autograd.grad(objective_function)), here’s a simplified view of what happens under the hood:
td.Structure, td.Box, td.Medium, etc.) are created, potentially using autograd tracked numbers (from autograd.numpy).tidy3d.web.run(simulation) is called. The standard forward FDTD simulation runs.SimulationData) are returned.autograd.numpy operations. autograd builds the computational graph along the way.autograd starts propagating gradient information backward through the computational graph using the chain rule.td.web.run node, Tidy3D’s custom VJP function takes over.autograd.autograd continues the backward pass until it reaches the original input parameters, yielding the final overall gradient.
Different types of parameters require different specific calculations within the adjoint method framework. Tidy3D handles this internally:
Box.center, Box.size, PolySlab.vertices), gradients are typically computed using surface integrals involving the forward and adjoint fields on the boundaries of the shape. Moving a boundary slightly changes the permittivity locally, and the adjoint method quantifies the impact of this change on the objective.CustomMedium), gradients are computed using the forward and adjoint fields within that material region.You don’t need to worry about these formulas – Tidy3D components like td.Box, td.Cylinder, td.Medium, td.CustomMedium, etc., have their differentiation logic built-in.
The beauty of this approach is its simplicity from the user’s perspective:
autograd.numpy for numerical operations.td.web.run() within your function as usual.autograd.grad() (or related functions like value_and_grad) to get the gradient.Tidy3D and autograd handle the complex forward simulation, field storage, adjoint simulation setup, adjoint run, and final gradient calculation automatically behind the scenes. You get the efficiency of the adjoint method without needing to implement it yourself.
Tidy3D’s integration with autograd via the adjoint method provides a powerful, flexible, and efficient platform for inverse design and sensitivity analysis. By defining a custom derivative rule for FDTD simulations, we unlock the ability to use gradient-based optimization on complex photonic design problems, requiring only one forward and one adjoint simulation per optimization step, regardless of the number of design parameters. This dramatically accelerates the design cycle for cutting-edge photonic devices.
Next Steps / Further Reading: