FDTD 101: Introduction to Finite- Difference Time-Domain Method
Lecture 1: Introduction to FDTD Simulation
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.
For Python setup used in this lecture, please see related FDTD Python Tutorial below.
Tutorial 1: Intro to FDTD¶
This tutorial will walk you through setting up a simple dipole radiation simulation in Tidy3D.
For more details, refer to the Tidy3d documentation.
Setup¶
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.
# 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.
# 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.
# 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',
)
# 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.
# 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,
)
Running Simulation¶
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.
# run simulation
sim_data = web.run(simulation, task_name='lecture01_dipole', path='data/data_dipole.hdf5')
Post Run Analysis¶
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.
# check that frequency domain fields look good
ax = sim_data.plot_field('freq_domain', 'Ez', y=0, f=freq0)
plt.show()
Adding Complexity¶
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.
# 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',
)
# 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()
# run simulation
sim_data_boxes = web.run(simulation_boxes, task_name='lecture01_several_box', path='data/data_several_box.hdf5')
ax = sim_data_boxes.plot_field('freq_domain', 'Ez', y=0, f=freq0)
plt.show()