Python FDTD

Tidy3D provides a rich Python interface for defining and running FDTD simulations. Python is used for setting up and analyzing simulation results. The FDTD algorithm runs in the background on Flexcompute's servers, which are highly optimized for solving FDTD efficiently.

If you do not wish to install, please click this button to get started quickly.

Run this Python code

Set up and run your first FDTD simulation

With just a few steps, you can set up and run your first FDTD simulation using the Python user interface. Additionally, you may want to explore other examples and tutorials to create your own simulations.

1. Set up Tidy3D

Install the python library for creating, managing, and postprocessing Tidy3d simulations with

pip install tidy3d

Next, configure your tidy3d package with the API key from your account.
Get your free API key

tidy3d configure

You can also uncomment line 4 below, then copy and paste the API key. For detailed installation instructions, refer to the Tidy3D documentation.

2. Run a simulation

# import the tidy3d package and configure it with your API key
import tidy3d as td
import tidy3d.web as web
import numpy as np

# set up global parameters of simulation ( speed of light / wavelength in micron )
freq0 = td.C_0 / 0.75

# create structure - a box centered at 0, 0, 0 with a size of 1.5 micron and permittivity of 2
square = td.Structure(
    geometry=td.Box(center=(0, 0, 0), size=(1.5, 1.5, 1.5)),
    medium=td.Medium(permittivity=2.0)
)

# create source - A uniform current source with frequency freq0 on the left side of the domain
source = td.UniformCurrentSource(
    center=(-1.5, 0, 0),
    size=(0, 0.4, 0.4),
    source_time=td.GaussianPulse(freq0=freq0, fwidth=freq0 / 10.0),
    polarization="Ey",
)

# create monitor - Measures electromagnetic fields within the entire domain at z=0
monitor = td.FieldMonitor(
    size=(td.inf, td.inf, 0),
    freqs=[freq0],
    name="fields",
    colocate=True,
)

# Initialize simulation - Combine all objects together into a single specification to run
sim = td.Simulation(
    size=(4, 3, 3),
    grid_spec=td.GridSpec.auto(min_steps_per_wvl=25),
    structures=[square],
    sources=[source],
    monitors=[monitor],
    run_time=120/freq0,
)

print(f"simulation grid is shaped {sim.grid.num_cells} for {int(np.prod(sim.grid.num_cells)/1e6)} million cells.")

# run simulation through the cloud and plot the field data computed by the solver and stored in the monitor
data = td.web.run(sim, task_name="quickstart", path="data/data.hdf5", verbose=True)

3. Analyze results

ax = data.plot_field("fields", "Ey", z=0)
3. Analyze results

How well does python FDTD perform

Tidy3D consistently outperforms other conventional FDTD solvers by an order of 100x or more. We achieve this performance improvement through the use of our custom hardware, which is optimized specifically for large scale FDTD simulation. As such, simulations that may take several hours or days on conventional hardware may be done in just minutes using Tidy3D. Furthermore, we can handle simulations with several billions of spatial degrees of freedom, which require too much memory to handle using conventional FDTD solvers.
For more details, see our papers and examples.

1X2 MMI; 6M grid points 58k of time steps 40s
8-channel multiplexer; 120M grid points 98k of time steps 3min 40s
Number of Unknowns in the simulation
Cascaded MZI filter; 1.3B grid points 556k of time steps 57min
Full size metalens; 20B grid points 26.4k of time steps 59min

What features does the python interface of Tidy3D FDTD provide

Tidy3D contains all of the standard features found in FDTD software, as such it is applicable to almost all problems. For the complete list of Tidy3D Python features and how to use them see the documentation.
A few of the main features include:

Compatibility between Python UI and GUI

The Tidy3D Python interface generates JSON files containing all the simulation specifications, including structures, sources, and monitor parameters. These files can be opened in the web-based Graphical User Interface (GUI), where all the components can be visualized in a 3D interface. Simulations built using the GUI can also be loaded using Python script.

Python Script
Python Script
GUI
GUI

How is the python interface of Tidy3D FDTD designed

The Tidy3D package allows users to define their simulation programmatically as a collection of basic components, such as geometries, materials, sources, and monitors. Each of these components is a data structure with a well-defined schema combined with validations that ensure that the contents are properly set up. These validations ensure that if a simulation is set up incorrectly, it is immediately caught before starting the FDTD, which saves time and effort. Here is an example

import tidy3d as td
# try to make a box with negative size in one dimension box = td.Box(size=(-1, 1, 1))
"""
1 validation error for Box
size -> 0
   ensure this value is greater than or equal to 0 (type=value_error.number.not_ge; limit_value=0)
"""

All components are combined into a single Simulation object, which defines an FDTD simulation and can be easily visualized, validated, and exported to a JSON file. We leverage the pydantic python package to define these components. Here is a minimum working example of a Simulation object containing 5 cylinders that are defined programmatically by looping over their positions.

import tidy3d as td
# generate 5 dielectric cylinders by looping over some positions
dielectric = td.Medium(permittivity=4.0)
cylinders = []
for position in [-2, -1, 0, 1, 2]:
    cylinder = td.Cylinder(radius=0.5, center=(position, 0, 0), length=10, axis=2)
    structure = td.Structure(geometry=cylinder, medium=dielectric)
    cylinders.append(structure)

point_dipole = td.PointDipole(
    center=(0, 0, 1),
    source_time=td.GaussianPulse(freq0=2e14, fwidth=3e13),
    polarization='Ex',
)

monitor = td.FieldMonitor(
     size=(td.inf, td.inf, 0),
     freqs=[2e14],
     name='field'
)

# combine everything into a single Simulation object
sim = td.Simulation(
    size=(6, 3, 6),
    structures=cylinders,
    sources=[point_dipole],
    monitors=[monitor],
    run_time=1e-12,
)

Next, the simulation is sent to Flexcompute’s servers through a simple API call from python. The progress of the job is monitored in real time and other functionalities for controlling the job are available directly from python.

import tidy3d.web as web
sim_data = web.run(sim, task_name='my_simulation')
# while the task is running, the status is monitored. # the results are loaded into the `sim_data` object.

Finally, the results are loaded into a SimulationData object, which contains the data for each of the supplied monitors. The data is stored in .hdf5 format and the xarray python package is used to provide a convenient interface for performant plotting, selection, interpolation, and post-processing of the data.

# interpolate the Ex field component at a specific point and frequency
Ex_at_origin = data['field'].Ex.interp(x=0, y=0, z=0, f=2e14)

As the simulation times are typically on the order of seconds to minutes, this whole process is seamlessly performed within the same python session or broken into different sessions if desired. If one wants to run several simulations in parallel, there is an interface for batch processing of jobs.

How do we visualize results in python

If we have a working Simulation defined, one easy way to visualize it is through the .plot method, which accepts spatial coordinates. For example, using the simulation defined earlier.

import matplotlib.pylab as plt
ax = sim.plot(z=0)
ax.set_tile('my simulation')
plt.show()

gives the following plot.

gives the following plot

Data can be plotted in a similar way as the SimulationData object and its contents contain .plot_field() and .plot() methods, respectively. More information on plotting and visualization can be seen in our documentation and in the following examples.

How do I sign up for Tidy3D

Use of Tidy3D requires an account to be able to submit jobs to our sever. You can sign up and try if for FREE.

Sign up for Free