In this lecture, we will describe the basic concepts of EM simulation using FDTD.

- How Maxwell's equations can be solved computationally in the context of a photonic device.

- Discretization of the simulation space using the finite difference method.

- A demonstration on how we solve for the electromagnetic fields radiated by a dipole source.

Additional information:
This Lecture was updated in Apr 15, 2022

This tutorial will walk you through setting up a simple dipole radiation simulation in Tidy3D.

For more details, refer to the Tidy3d documentation.

First we import Tidy3D and the other packages needed. If it is not installed, please perform the installation and account authentication by following the detailed instructions here.

In [1]:

```
# imports
import matplotlib.pylab as plt
import tidy3d as td
import tidy3d.web as web
```

Then, we will define the basic simulation parameters. Note that the length scale is microns.

In [2]:

```
# simulation parameters
side_length = 9.0
grid_size = 50e-3
# apply a PML in all directions
boundary_spec=td.BoundarySpec.all_sides(boundary=td.PML())
# spectrum and resolution parameters
lambda0 = 1.0
freq0 = td.C_0 / lambda0
fwidth = freq0 / 50
run_time = 200 / freq0
```

Next, we define the objects present in our simulation, specifically the source and monitor.

In [3]:

```
# define dipole source at origin pointing in z
dipole_source = td.PointDipole(
center=(0, 0, 0),
source_time=td.GaussianPulse(freq0=freq0, fwidth=fwidth),
polarization='Ez',
name='dipole',
)
```

In [4]:

```
# define monitor to measure fields in xz plane at central frequency
monitor = td.FieldMonitor(
center=(0,0,0),
size=(td.inf, 0, td.inf),
freqs=[freq0],
name='freq_domain',
)
```

And finally, we put everything together in a `Simulation`

object, which contains all of the specs needed to run the simulation.

In [5]:

```
# define simulation
simulation = td.Simulation(
size=(side_length, side_length, side_length),
grid_spec=td.GridSpec.uniform(dl=grid_size),
structures=[],
sources=[dipole_source],
monitors=[monitor],
run_time=run_time,
boundary_spec=boundary_spec,
)
```

To run the simulation, we will call the `web.run()`

function, passing our `Simulation`

and some parameters about the task name and the path to download the data file.

In [6]:

```
# run simulation
sim_data = web.run(simulation, task_name='lecture01_dipole', path='data/data_dipole.hdf5')
```

After the job is done, all of the data is loaded into the `SimulationData`

object called `sim_data`

in this example.

From this, we can plot the results and make sure it looks reasonable.

In [7]:

```
# check that frequency domain fields look good
ax = sim_data.plot_field('freq_domain', 'Ez', y=0, f=freq0)
plt.show()
```

To make things more intereting, let's run the same simulation, but adding a few structures in the mix. For now, let's just add a few dielectric box objects to see how that changes the results.

In [8]:

```
# define the boxes
epsilon_box = 3
center_offset_box = 1.6
size_box = 1.8
medium=td.Medium(permittivity=epsilon_box,name='medium')
box_top = td.Structure(
geometry=td.Box(
center=(0, 0, center_offset_box),
size=(size_box, size_box, size_box),
),
medium=medium,
name='box top',
)
bot_bot_r = td.Structure(
geometry=td.Box(
center=(+center_offset_box, 0, -center_offset_box),
size=(size_box, size_box, size_box),
),
medium=medium,
name='box bottom right',
)
bot_bot_l = td.Structure(
geometry=td.Box(
center=(-center_offset_box, 0, -center_offset_box),
size=(size_box, size_box, size_box),
),
medium=medium,
name='box bottom left',
)
```

In [9]:

```
# make a new simulation with the boxes added
simulation_boxes = td.Simulation(
size=(side_length, side_length, side_length),
grid_spec=td.GridSpec.uniform(dl=grid_size),
structures=[box_top, bot_bot_r, bot_bot_l],
sources=[dipole_source],
monitors=[monitor],
run_time=run_time,
boundary_spec=boundary_spec,
)
# visualize the simulation first, before running
ax = simulation_boxes.plot(y=0.01)
plt.show()
```

In [10]:

```
# run simulation
sim_data_boxes = web.run(simulation_boxes, task_name='lecture01_several_box', path='data/data_several_box.hdf5')
```

In [11]:

```
ax = sim_data_boxes.plot_field('freq_domain', 'Ez', y=0, f=freq0)
plt.show()
```

In [ ]:

```
```

FDTD 101: Lecture 1

Today, I would like to give a short introduction to the finite difference time domain method or with the acronym FDTD. I'm Shanhui Fan from Flexcompute.

The finite difference time domain method or FDTD is a method for simulating interaction of light with structures and materials. It is widely used as a general purpose method for solving Maxwell’s equations and is very widely used in photonics and electromagnetics. It allows you to simulate a white range of phenomena in photonics. So below, I have a few images of some of the structures that people have simulated using FDTD method that range from Photonic Crystal Nanocavity to Grading Coupler in silicon photonics to Ring Resonators to Metasurface.

The purpose of this course is to give you a broad understanding of the finite difference time domain method (FDTD). What it is used for even though we're not going to go into great details of the algorithm itself. We would like to give you a sense of how it works, what the algorithm looks like at a high conceptual level and the ultimate goal is to get you to start to use it. So the course would go through a number of examples in increasing complexity, so that you will get a sense of how to use this method. And all these examples are implemented using Flexcompute Tidy3D FDTD solver and will provide links with the input files for each of these examples so you can try them out yourself.

If you are using FDTD, you are solving Maxwell’s Equations and therefore I assume that you know something about Maxwell’s Equations already. But just as a very brief overview, Maxwell’s Equations describe the dynamics of electrical the E field and magnetic field, the H field. These are how the equations look like, and the dynamics of the E and H field in a structure is described by a primitivity distribution epsilon here. The structure is then excited by a current source, usually a time oscillating current. This equation is a time domain equation that describes the evolution of electric and magnetic fields as a function of time.

In FDTD method, the TD stands for time domain. It's exactly a time domain method that allows you to directly compute such time evolution. In the FDTD method the input to the solver is the primitivity distribution and that describes how the device looks as well as the source of the excitation. These information are then provided to a FDTD solver that allows you to determine the time dynamics of the electric and magnetic field and from these time dynamics one extracts information that is important for physics study and device design.

As the first illustration of the FDTD method, we're going to solve an example that you probably have all learned in your electromagnetic class. And that is to simulate the emission pattern of a dipole in a vacuum. We would like to compute the electric field that's generated out of an oscillating dipole. In this setup, we're going to set up so that the relative permittivity is one everywhere. So it's vacuum and we choose the dipole source to be oscillating harmonically as a function of time and the oscillation frequency corresponds to a free space wavelength of one micron. So in setting up the FDTD method, one of the first things that you need to do is to choose the computational domain. In our case it turned out that the dipole source would go through as you move away from the dipole source. The field will go from the near field zone to the far field zone and we would like to set up that will capture this transition. And therefore we choose a relatively large computational cell computational domain with a cube with a side length of nine micron corresponding to nine wavelengths and perhaps as a general comment. All these computational setups are closely related to the physics or the device characteristic that you are interested in understanding and so in this case the choice of the computational domain size definitely reflects that.

The finite difference time domain method, the first two words are “finite difference”. And that means that you would take the computational domain and then discretize it by a little cube and then so that you would describe the fields on a discrete lattice formed by this cube. In the FDTD method the cube is called the Yee Cell. So a little cube inside the computational domain when you blow it up will look something like this. The electric fields are distributed on the edge of the Yee cell and the magnetic fields are distributed on the surface of the Yee cell. And the way this distribution is set up, in fact very closely reflects the underlying geometry of Maxwell’s equations. An important parameter is the discretization. So a typical rule of thumb is to choose the discretization to be about wavelengths over 20. Given that we're using a one micron wavelength this corresponds to a 50 nanometer digitization in the examples that I'm going to show you. However, in order to generate perhaps a nicer looking movie we have chosen a finer discretization with a dedication of 20 nanometers. And with 9 micron computational domain size this translates already to be about half a billion unknowns. So it is really the magic of more computing power -- that one in fact is able to do these kinds of problems with billions of unknowns.

The other aspect of the simulation is the boundary condition. So we have a computational domain setup like this, but we would like the field emitted from the dipole to go out of the computational domain without coming back to interfere with it. We can generate the radiating pattern of a dipole radiating industry space. For this purpose in FDTD it is very common to surround the computational domain by a specially designed absorber called the perfectly matched layer. The thickness of these layers is about the typical 10’s of the Yee cells.

So with this now we can put the whole thing together. And as I mentioned this is the computational domain. This is where the dipole sources and we're going to generate the movie showing how the Z component of the electric field varies on the plant as highlighted by gray here. And that's the movie on the right. You see the dipole oscillating in the middle and you can see that the wavelength is about one micron. The red and blue here correspond to large positive and negative fields. And also you see that in the far field zone when you are sufficiently far from the dipole, there's very little emission in the vertical direction. And that's a very characteristic of the far fields of a dipole radiation. In this example, I've shown you something that you probably have seen in your textbook of a dipole radiation pattern. And this is something that you can compute analytically. One of the key strengths of FDTD, however, is that we’ve shown you can simulate vacuum, but you can also simulate complex structure that you put in with essentially the same setup.

So as the last example of this tutorial, we will put a dipole source again, the same computational cell, but we'll also put 3 dielectric blocks. And here is the movie of the electric field distribution and you can see how the fields now are very strongly perturbed by the presence of these blocks. To summarize this first video, what we’ve shown here is the general concept of FDTD, and show you a virtual example that you can generate a nice-looking movie associated with the variation of the field as a function of time. In the next lecture, we are going to build upon this and show you how you can use this capability to get useful information about real devices.