Skip to content

flex_rf.tidy3d.Simulation

Type: class Base(s): AbstractYeeGridSimulation

Custom implementation of Maxwell’s equations which represents the physical model to be solved using the FDTD method.

A Simulation defines a custom implementation of Maxwell’s equations which represents the physical model to be solved using the Finite-Difference Time-Domain (FDTD) method. tidy3d simulations run very quickly in the cloud through GPU parallelization.

FDTD is a method for simulating the interaction of electromagnetic waves with structures and materials. It is the most widely used method in photonics design. The Maxwell’s equations implemented in the Simulation are solved per time-step in the order shown in this image.

The simplified input to FDTD solver consists of the permittivity distribution defined by structures which describe the device and sources of electromagnetic excitation. This information is used to computate the time dynamics of the electric and magnetic fields in this system. From these time-domain results, frequency-domain information of the simulation can also be extracted, and used for device design and optimization.

If you are new to the FDTD method, we recommend you get started with the FDTD 101 Lecture Series

Dimensions Selection

By default, simulations are defined as 3D. To make the simulation 2D, we can just set the simulation size in one of the dimensions to be 0. However, note that we still have to define a grid size (eg. tidy3d.Simulation(size=[size_x, size_y, 0])) and specify a periodic boundary condition in that direction.

.. TODO sort out inheritance problem https://aware-moon.cloudvent.net/tidy3d/examples/notebooks/RingResonator/

See further parameter explanations below.

Practical Advice

Use RunTimeSpec instead of a hardcoded run_time to automatically determine simulation duration based on field decay:

sim = Simulation(..., run_time=td.RunTimeSpec(quality_factor=10))

For grid resolution, use min_steps_per_wvl >= 20 in AutoGrid for standard simulations. The default value of 10 is suitable only for quick sanity checks. See AutoGrid for detailed guidance.

All lengths are in micrometers (μm), times in seconds (s), and frequencies in Hz. Convert wavelength to frequency with freq = td.C_0 / wavelength_um.

from tidy3d import Sphere, Cylinder, PolySlab
from tidy3d import UniformCurrentSource, GaussianPulse
from tidy3d import FieldMonitor, FluxMonitor
from tidy3d import GridSpec, AutoGrid
from tidy3d import BoundarySpec, Boundary
from tidy3d import Medium
sim = Simulation(
size=(3.0, 3.0, 3.0),
grid_spec=GridSpec(
grid_x = AutoGrid(min_steps_per_wvl = 20),
grid_y = AutoGrid(min_steps_per_wvl = 20),
grid_z = AutoGrid(min_steps_per_wvl = 20)
),
run_time=40e-11,
structures=[
Structure(
geometry=Box(size=(1, 1, 1), center=(0, 0, 0)),
medium=Medium(permittivity=2.0),
),
],
sources=[
UniformCurrentSource(
size=(0, 0, 0),
center=(0, 0.5, 0),
polarization="Hx",
current_amplitude_definition='total',
source_time=GaussianPulse(
freq0=2e14,
fwidth=4e13,
),
)
],
monitors=[
FluxMonitor(size=(1, 1, 0), center=(0, 0, 0), freqs=[2e14, 2.5e14], name='flux'),
],
symmetry=(0, 0, 0),
boundary_spec=BoundarySpec(
x = Boundary.pml(num_layers=20),
y = Boundary.pml(num_layers=30),
z = Boundary.periodic(),
),
shutoff=1e-6,
courant=0.8,
subpixel=False,
)
size [TracedSize]

Size in x, y, and z directions.

run_time [PositiveFloat | RunTimeSpec]

Total electromagnetic evolution time in seconds. Note: If simulation ‘shutoff’ is specified, simulation will terminate early when shutoff condition met. Alternatively, user may supply a RunTimeSpec to this field, which will auto-compute the run_time based on the contents of the spec. If this option is used, the evaluated run_time value is available in the Simulation._run_time property.

center [TracedCoordinate] = (0.0, 0.0, 0.0)

Center of object in x, y, and z.

version [str] = __version__

String specifying the front end version number.

plot_length_units [LengthUnit | None] = 'μm'

When set to a supported LengthUnit, plots will be produced with proper scaling of axes and include the desired unit specifier in labels.

structure_priority_mode [PriorityMode] = 'equal'

This field only affects structures of priority=None. If equal, the priority of those structures is set to 0; if conductor, the priority of structures made of LossyMetalMedium is set to 90, PECMedium to 100, and others to 0.

subpixel [bool | SubpixelSpec] = factory: SubpixelSpec

Apply subpixel averaging methods of the permittivity on structure interfaces to result in much higher accuracy for a given grid size. Supply a SubpixelSpec to this field to select subpixel averaging methods separately on dielectric, metal, and PEC material interfaces. Alternatively, user may supply a boolean value: True to apply the default subpixel averaging methods corresponding to SubpixelSpec() , or False to apply staircasing.

simulation_type [Literal['autograd_fwd', 'autograd_bwd', 'tidy3d'] | None] = 'tidy3d'

Tag used internally to distinguish types of simulations for autograd gradient processing.

post_norm [float | FreqDataArray] = 1.0

Factor to multiply the fields by after running, given the adjoint source pipeline used. Note: this is used internally only.

internal_absorbers [tuple[InternalAbsorber, ...]] = ()

Planes with the first order absorbing boundary conditions placed inside the computational domain. Note that internal absorbers are automatically wrapped in a PEC frame with a backing PEC plate on the non-absorbing side.

boundary_spec [BoundarySpec] = factory: BoundarySpec

Specification of boundary conditions along each dimension. If None, PML boundary conditions are applied on all sides.

courant [float] = 0.99

Normalized Courant stability factor that is no larger than 1 when CFL stability condition is met. It controls time step to spatial step ratio. Lower values lead to more stable simulations for dispersive materials, but result in longer simulation times.

relax_courant [bool] = False

Relax the CFL stability condition if possible.

precision [Literal['hybrid', 'double']] = 'hybrid'

Floating point precision to use in the computations.

lumped_elements [tuple[LumpedElementType, ...]] = ()

Tuple of lumped elements in the simulation.

grid_spec [GridSpec] = factory: GridSpec

Specifications for the simulation grid along each of the three directions.

medium [MediumType3D] = factory: Medium

Background medium of simulation, defaults to vacuum if not specified.

normalize_index [NonNegativeInt | None] = 0

Index of the source in the tuple of sources whose spectrum will be used to normalize the frequency-dependent data. If None, the raw field data is returned unnormalized.

monitors [tuple[discriminated_union(MonitorType), ...]] = ()

Tuple of monitors in the simulation. Note: monitor names are used to access data after simulation is run.

sources [tuple[discriminated_union(SourceType), ...]] = ()

Tuple of electric current sources injecting fields into the simulation.

shutoff [NonNegativeFloat] = 1e-05

Ratio of the instantaneous integrated E-field intensity to the maximum value at which the simulation will automatically terminate time stepping. Used to prevent extraneous run time of simulations with fully decayed fields. Set to 0 to disable this feature.

structures [tuple[Structure, ...]] = ()

Tuple of structures present in simulation. Note: Structures defined later in this list override the simulation material properties in regions of spatial overlap.

symmetry [tuple[Symmetry, Symmetry, Symmetry]] = (0, 0, 0)

Tuple of integers defining reflection symmetry across a plane bisecting the simulation domain normal to the x-, y-, and z-axis at the simulation center of each axis, respectively. Each element can be 0 (no symmetry), 1 (even, i.e. PMCBoundary symmetry) or -1 (odd, i.e. PECBoundary symmetry). Note that the vectorial nature of the fields must be taken into account to correctly determine the symmetry value.

low_freq_smoothing [LowFrequencySmoothingSpec | None] = None

The low frequency smoothing parameters for the simulation.

custom_datasets [list[Dataset]]

List of custom datasets for verification purposes. If the list is not empty, then the simulation needs to be exported to hdf5 to store the data.

num_computational_grid_points [int]

Number of cells in the computational domain for this simulation. This is usually different from num_cells due to the boundary conditions. Specifically, all boundary conditions apart from Periodic require an extra pixel at the end of the simulation domain. On the other hand, if a symmetry is present along a given dimension, only half of the grid cells along that dimension will be in the computational domain.

all_structures()

List of all structures in the simulation (including the Simulation.medium).

allow_gain()

True if any of the mediums in the simulation allows gain.

aux_fields()

All aux fields available in the simulation.

background_structure()

Returns structure representing the background of the Simulation.

complex_fields()

Whether complex fields are used in the simulation. Currently this only happens when there are Bloch boundaries.

dt()

Simulation time step (distance).

frequency_range()

Range of frequencies spanning all sources’ frequency dependence.

from_scene(scene: Scene, **kwargs: Any)

Create a simulation from a Scene instance. Must provide additional parameters to define a valid simulation (for example, run_time, grid_spec, etc).

get_refractive_indices(freq: float)

List of refractive indices in the simulation at a given frequency. For anisotropic medium, highest refractive index among the 3 main diagonal components is selected.

intersecting_media(test_object: Box, structures: tuple[Structure, ...])

From a given list of structures, returns a list of AbstractMedium associated with those structures that intersect with the test_object, if it is a surface, or its surfaces, if it is a volume.

intersecting_structures(test_object: Box, structures: tuple[Structure, ...])

From a given list of structures, returns a list of Structure that intersect with the test_object, if it is a surface, or its surfaces, if it is a volume.

medium_map()

Returns dict mapping medium to index in material. medium_map[medium] returns unique global index of AbstractMedium in simulation.

mediums()

Returns set of distinct AbstractMedium in simulation.

monitor_medium(monitor: MonitorType)

Return the medium in which the given monitor resides.

monitors_data_size()

Dictionary mapping monitor names to their estimated storage size in bytes.

n_max()

Maximum refractive index in the Simulation.

num_cells()

Number of cells in the simulation grid.

num_time_steps()

Number of time steps in simulation.

nyquist_step()

Maximum number of discrete time steps to keep sampling below Nyquist limit.

padded_copy(x: tuple[NonNegativeFloat, NonNegativeFloat] | None = None, y: tuple[NonNegativeFloat, NonNegativeFloat] | None = None, z: tuple[NonNegativeFloat, NonNegativeFloat] | None = None)

Created a copy of simulation with padded simulation domain.

perturbed_mediums_copy(temperature: CustomSpatialDataType = None, electron_density: CustomSpatialDataType = None, hole_density: CustomSpatialDataType = None, interp_method: InterpMethod = 'linear')

Return a copy of the simulation with heat and/or charge data applied to all mediums that have perturbation models specified. That is, such mediums will be replaced with spatially dependent custom mediums that reflect perturbation effects. Any of temperature, electron_density, and hole_density can be None. All provided fields must have identical coords.

plot_3d(width: int = 800, height: int = 800)

Render 3D plot of Simulation (in jupyter notebook only). Parameters ---------- width : float = 800 width of the 3d view dom’s size height : float = 800 height of the 3d view dom’s size

scaled_courant()

When conformal mesh is applied, courant number is scaled down depending on conformal_mesh_spec.

self_structure()

The simulation background as a Structure.

tmesh()

FDTD time stepping points.

to_gds(cell: gdstk.Cell, x: float | None = None, y: float | None = None, z: float | None = None, permittivity_threshold: NonNegativeFloat = 1, frequency: PositiveFloat = 0, gds_layer_dtype_map: dict[AbstractMedium, tuple[NonNegativeInt, NonNegativeInt]] | None = None, pixel_exact: bool = False)

Append the simulation structures to a .gds cell.

to_gds_file(fname: PathLike, x: float | None = None, y: float | None = None, z: float | None = None, permittivity_threshold: NonNegativeFloat = 1, frequency: PositiveFloat = 0, gds_layer_dtype_map: dict[AbstractMedium, tuple[NonNegativeInt, NonNegativeInt]] | None = None, gds_cell_name: str = 'MAIN', pixel_exact: bool = False)

Append the simulation structures to a .gds cell.

to_gdstk(x: float | None = None, y: float | None = None, z: float | None = None, permittivity_threshold: NonNegativeFloat = 1, frequency: PositiveFloat = 0, gds_layer_dtype_map: dict[AbstractMedium, tuple[NonNegativeInt, NonNegativeInt]] | None = None, pixel_exact: bool = False)

Convert a simulation’s planar slice to a .gds type polygon list.

uniformly_padded_copy(padding: NonNegativeFloat)

Create copy of simulation with uniformly padded simulation domain.

validate_pre_upload(source_required: bool = True)

Validate the fully initialized simulation is ok for upload to our servers.

validate_rf_type()

Whether the simulation contains RF-classified components.

wvl_mat_min()

Minimum wavelength in the materials present throughout the simulation.