tidy3d.EMESimulation#
- class EMESimulation[source]#
Bases:
AbstractYeeGridSimulation
EigenMode Expansion (EME) simulation.
- Parameters:
attrs (dict = {}) – Dictionary storing arbitrary metadata for a Tidy3D object. This dictionary can be freely used by the user for storing data without affecting the operation of Tidy3D as it is not used internally. Note that, unlike regular Tidy3D fields,
attrs
are mutable. For example, the following is allowed for setting anattr
obj.attrs['foo'] = bar
. Also note that Tidy3D` will raise aTypeError
ifattrs
contain objects that can not be serialized. One can check ifattrs
are serializable by callingobj.json()
.center (Union[tuple[Union[float, autograd.tracer.Box], Union[float, autograd.tracer.Box], Union[float, autograd.tracer.Box]], Box] = (0.0, 0.0, 0.0)) – [units = um]. Center of object in x, y, and z.
size (Union[tuple[Union[pydantic.v1.types.NonNegativeFloat, autograd.tracer.Box], Union[pydantic.v1.types.NonNegativeFloat, autograd.tracer.Box], Union[pydantic.v1.types.NonNegativeFloat, autograd.tracer.Box]], Box]) – [units = um]. Size in x, y, and z directions.
medium (Union[Medium, AnisotropicMedium, PECMedium, PoleResidue, Sellmeier, Lorentz, Debye, Drude, FullyAnisotropicMedium, CustomMedium, CustomPoleResidue, CustomSellmeier, CustomLorentz, CustomDebye, CustomDrude, CustomAnisotropicMedium, PerturbationMedium, PerturbationPoleResidue] = Medium(attrs={}, name=None, frequency_range=None, allow_gain=False, nonlinear_spec=None, modulation_spec=None, heat_spec=None, type='Medium', permittivity=1.0, conductivity=0.0)) – Background medium of simulation, defaults to vacuum if not specified.
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[Literal[0, -1, 1], Literal[0, -1, 1], Literal[0, -1, 1]] = (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.
sources (Tuple[NoneType, ...] = ()) – Sources in the simulation. NOTE: sources are not currently supported for EME simulations. Instead, the simulation performs full bidirectional propagation in the ‘port_mode’ basis. After running the simulation, use ‘smatrix_in_basis’ to use another set of modes or input field.
boundary_spec (BoundarySpec = BoundarySpec(attrs={}, x=Boundary(attrs={},, plus=PECBoundary(attrs={},, name=None,, type='PECBoundary'),, minus=PECBoundary(attrs={},, name=None,, type='PECBoundary'),, type='Boundary'), y=Boundary(attrs={},, plus=PECBoundary(attrs={},, name=None,, type='PECBoundary'),, minus=PECBoundary(attrs={},, name=None,, type='PECBoundary'),, type='Boundary'), z=Boundary(attrs={},, plus=PECBoundary(attrs={},, name=None,, type='PECBoundary'),, minus=PECBoundary(attrs={},, name=None,, type='PECBoundary'),, type='Boundary'), type='BoundarySpec')) – Specification of boundary conditions along each dimension. If
None
, PML boundary conditions are applied on all sides. NOTE: for EME simulations, this is required to be PECBoundary on all sides. To capture radiative effects, move the boundary farther away from the waveguide in the tangential directions, and increase the number of modes. The ‘ModeSpec’ can also be used to try different boundary conditions.monitors (Tuple[Annotated[Union[tidy3d.components.eme.monitor.EMEModeSolverMonitor, tidy3d.components.eme.monitor.EMEFieldMonitor, tidy3d.components.eme.monitor.EMECoefficientMonitor, tidy3d.components.monitor.ModeSolverMonitor], FieldInfo(default=PydanticUndefined, discriminator='type', extra={})], ...] = ()) – Tuple of monitors in the simulation. Note: monitor names are used to access data after simulation is run.
grid_spec (GridSpec = GridSpec(attrs={}, grid_x=AutoGrid(attrs={},, type='AutoGrid',, min_steps_per_wvl=10.0,, max_scale=1.4,, dl_min=0.0,, mesher=GradedMesher(attrs={},, type='GradedMesher')), grid_y=AutoGrid(attrs={},, type='AutoGrid',, min_steps_per_wvl=10.0,, max_scale=1.4,, dl_min=0.0,, mesher=GradedMesher(attrs={},, type='GradedMesher')), grid_z=AutoGrid(attrs={},, type='AutoGrid',, min_steps_per_wvl=10.0,, max_scale=1.4,, dl_min=0.0,, mesher=GradedMesher(attrs={},, type='GradedMesher')), wavelength=None, override_structures=(), snapping_points=(), type='GridSpec')) – Specifications for the simulation grid along each of the three directions. This is distinct from ‘eme_grid_spec’, which defines the 1D EME grid in the propagation direction.
version (str = 2.7.2) – String specifying the front end version number.
lumped_elements (Tuple[Union[LumpedResistor, CoaxialLumpedResistor], ...] = ()) – Tuple of lumped elements in the simulation. Note: only
tidy3d.LumpedResistor
is supported currently.subpixel (Union[bool, SubpixelSpec] = SubpixelSpec(attrs={}, dielectric=PolarizedAveraging(attrs={},, type='PolarizedAveraging'), metal=Staircasing(attrs={},, type='Staircasing'), pec=PECConformal(attrs={},, type='PECConformal',, timestep_reduction=0.3), type='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 toSubpixelSpec()
, orFalse
to apply staircasing.simulation_type (Optional[Literal['autograd_fwd', 'autograd_bwd', None]] = None) – Tag used internally to distinguish types of simulations for
autograd
gradient processing.freqs (Union[Tuple[float, ...], ArrayLike[dtype=float, ndim=1]]) – Frequencies for the EME simulation. The field is propagated independently at each provided frequency. This can be slow when the number of frequencies is large. In this case, consider using the approximate ‘EMEFreqSweep’ as the ‘sweep_spec’ instead of providing all desired frequencies here.
axis (Literal[0, 1, 2]) – Propagation axis (0, 1, or 2) for the EME simulation.
eme_grid_spec (Union[EMEUniformGrid, EMECompositeGrid, EMEExplicitGrid]) – Specification for the EME propagation grid. The simulation is divided into cells in the propagation direction; this parameter specifies the layout of those cells. Mode solving is performed in each cell, and then propagation between cells is performed to determine the complete solution. This is distinct from ‘grid_spec’, which defines the grid in the two tangential directions, as well as the grid used for field monitors.
store_port_modes (bool = True) – Whether to store the modes associated with the two ports. Required to find scattering matrix in basis besides the computational basis.
normalize (bool = True) – Whether to normalize the port modes to unity flux, thereby normalizing the scattering matrix and expansion coefficients.
port_offsets (Tuple[NonNegativeFloat, NonNegativeFloat] = (0, 0)) – Offsets for the two ports, relative to the simulation bounds along the propagation axis.
sweep_spec (Union[EMELengthSweep, EMEModeSweep, EMEFreqSweep, NoneType] = None) – Specification for a parameter sweep to be performed during the EME propagation step. The results are stored in ‘sim_data.smatrix’. Other simulation monitor data is not included in the sweep.
constraint (Optional[Literal['passive', 'unitary']] = passive) – Constraint for EME propagation, imposed at cell interfaces. A constraint of ‘passive’ means that energy can be dissipated but not created at interfaces. A constraint of ‘unitary’ means that energy is conserved at interfaces (but not necessarily within cells). The option ‘none’ may be faster for a large number of modes. The option ‘passive’ can serve as regularization for the field continuity requirement and give more physical results.
Notes
EME is a frequency-domain method for propagating the electromagnetic field along a specified axis. The method is well-suited for propagation of guided waves. The electromagnetic fields are expanded locally in the basis of eigenmodes of the waveguide; they are then propagated by imposing continuity conditions in this basis.
The EME simulation is performed along the propagation axis
axis
at frequenciesfreqs
. The simulation is divided into cells along the propagation axis, as defined byeme_grid_spec
. Mode solving is performed at cell centers, and boundary conditions are imposed between cells. The EME ports are defined to be the boundaries of the first and last cell in the EME grid. These can be moved usingport_offsets
.An EME simulation always computes the full scattering matrix of the structure. Additional data can be recorded by adding ‘monitors’ to the simulation.
Other Bases
By default, the scattering matrix is expressed in the basis of EME modes at the two ports. It is sometimes useful to use alternative bases. For example, in a waveguide splitter, we might want the scattering matrix in the basis of modes of the individual waveguides. The functions smatrix_in_basis and field_in_basis in
EMESimulationData
can be used for this purpose after the simulation has been run.Frequency Sweeps
Frequency sweeps are supported by including multiple frequencies in the freqs field. However, our EME solver repeats the mode solving for each new frequency, so frequency sweeps involving a large number of frequencies can be slow and expensive. If a large number of frequencies are required, consider using our FDTD solver instead.
Passivity and Unitarity Constraints
Passivity and unitarity constraints can be imposed via the constraint field. These constraints are imposed at interfaces between cells, possibly at the expense of field continuity. Passivity means that the interface can only dissipate energy, and unitarity means the interface will conserve energy (energy may still be dissipated inside cells when the propagation constant is complex). Adding constraints can slow down the simulation significantly, especially for a large number of modes (more than 30 or 40).
Too Many Modes
It is important to use enough modes to capture the physics of the device and to ensure that the results have converged (see below). However, using too many modes can slow down the simulation and result in numerical issues. If too many modes are used, it is common to see a warning about invalid modes in the simulation log. While these modes are not included in the EME propagation, this can indicate some other issue with the setup, especially if the results have not converged. In this case, extending the simulation size in the transverse directions and increasing the grid resolution may help by creating more valid modes that can be used in convergence testing.
Mode Convergence Sweeps
It is a good idea to check that the number of modes is large enough by running a mode convergence sweep. This can be done using
EMEModeSweep
.Example
>>> from tidy3d import Box, Medium, Structure, C_0, inf >>> from tidy3d import EMEModeSpec, EMEUniformGrid, GridSpec >>> from tidy3d import EMEFieldMonitor >>> lambda0 = 1 >>> freq0 = C_0 / lambda0 >>> sim_size = 3*lambda0, 3*lambda0, 3*lambda0 >>> waveguide_size = (lambda0/2, lambda0, inf) >>> waveguide = Structure( ... geometry=Box(center=(0,0,0), size=waveguide_size), ... medium=Medium(permittivity=2) ... ) >>> eme_grid_spec = EMEUniformGrid(num_cells=5, mode_spec=EMEModeSpec(num_modes=10)) >>> grid_spec = GridSpec(wavelength=lambda0) >>> field_monitor = EMEFieldMonitor( ... size=(0, sim_size[1], sim_size[2]), ... name="field_monitor" ... ) >>> sim = EMESimulation( ... size=sim_size, ... monitors=[field_monitor], ... structures=[waveguide], ... axis=2, ... freqs=[freq0], ... eme_grid_spec=eme_grid_spec, ... grid_spec=grid_spec ... )
See also
- Notebooks:
Attributes
The EME grid as defined by 'eme_grid_spec'.
Grid spatial locations and information as defined by grid_spec.
Max number of modes in the simulation.
Max number of modes at the two ports.
A list of mode solver monitors at the cell centers.
Dictionary mapping monitor names to their estimated storage size in bytes.
EME Mode solver monitor for only the port modes.
version
DO NOT EDIT: Modified automatically with .bump2version.cfg
Methods
from_scene
(scene, **kwargs)Create an EME simulation from a :class:.`Scene` instance.
plot
([x, y, z, ax, source_alpha, ...])Plot each of simulation's components on a plane defined by one nonzero x,y,z coordinate.
plot_eme_grid
([x, y, z, ax, hlim, vlim])Plot the EME grid.
plot_eme_ports
([x, y, z, ax, hlim, vlim])Plot the EME ports.
plot_eme_subgrid_boundaries
(eme_grid_spec[, ...])Plot the EME subgrid boundaries.
subsection
(region[, grid_spec, ...])Generate a simulation instance containing only the
region
.Validate the fully initialized EME simulation is ok for upload to our servers.
Inherited Common Usage
- freqs#
- axis#
- eme_grid_spec#
- monitors#
- boundary_spec#
- sources#
- grid_spec#
Specifications for the simulation grid along each of the three directions.
Example
Simple application reference:
Simulation( ... 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) ), ... )
See also
GridSpec
Collective grid specification for all three dimensions.
UniformGrid
Uniform 1D grid.
AutoGrid
Specification for non-uniform grid along a given dimension.
- Notebooks:
- store_port_modes#
- normalize#
- port_offsets#
- sweep_spec#
- constraint#
- plot_eme_ports(x=None, y=None, z=None, ax=None, hlim=None, vlim=None, **kwargs)[source]#
Plot the EME ports.
- plot_eme_subgrid_boundaries(eme_grid_spec, x=None, y=None, z=None, ax=None, hlim=None, vlim=None, **kwargs)[source]#
Plot the EME subgrid boundaries. Does nothing if
eme_grid_spec
is notEMECompositeGrid
. Operates recursively on subgrids.
- plot_eme_grid(x=None, y=None, z=None, ax=None, hlim=None, vlim=None, **kwargs)[source]#
Plot the EME grid.
- plot(x=None, y=None, z=None, ax=None, source_alpha=None, monitor_alpha=None, hlim=None, vlim=None, **patch_kwargs)[source]#
Plot each of simulation’s components on a plane defined by one nonzero x,y,z coordinate.
- Parameters:
x (float = None) – position of plane in x direction, only one of x, y, z must be specified to define plane.
y (float = None) – position of plane in y direction, only one of x, y, z must be specified to define plane.
z (float = None) – position of plane in z direction, only one of x, y, z must be specified to define plane.
source_alpha (float = None) – Opacity of the sources. If
None
, uses Tidy3d default.monitor_alpha (float = None) – Opacity of the monitors. If
None
, uses Tidy3d default.ax (matplotlib.axes._subplots.Axes = None) – Matplotlib axes to plot on, if not specified, one is created.
hlim (Tuple[float, float] = None) – The x range if plotting on xy or xz planes, y range if plotting on yz plane.
vlim (Tuple[float, float] = None) – The z range if plotting on xz or yz planes, y plane if plotting on xy plane.
- Returns:
The supplied or created matplotlib axes.
- Return type:
matplotlib.axes._subplots.Axes
- property eme_grid#
The EME grid as defined by ‘eme_grid_spec’. An EME grid is a 1D grid aligned with the propagation axis, dividing the simulation into cells. Modes and mode coefficients are defined at the central plane of each cell. Typically, cell boundaries are aligned with interfaces between structures in the simulation.
This is distinct from ‘grid’, which is the grid used in the tangential directions as well as the grid used for field monitors.
- classmethod from_scene(scene, **kwargs)[source]#
Create an EME simulation from a :class:.`Scene` instance. Must provide additional parameters to define a valid EME simulation (for example,
size
,grid_spec
, etc).- Parameters:
scene (:class:.`Scene`) – Scene containing structures information.
**kwargs – Other arguments
- property mode_solver_monitors#
A list of mode solver monitors at the cell centers. Each monitor has a mode spec. The cells and mode specs are specified by ‘eme_grid_spec’.
- property port_modes_monitor#
EME Mode solver monitor for only the port modes.
- validate_pre_upload()[source]#
Validate the fully initialized EME simulation is ok for upload to our servers.
- property monitors_data_size#
Dictionary mapping monitor names to their estimated storage size in bytes.
- property max_num_modes#
Max number of modes in the simulation.
- property max_port_modes#
Max number of modes at the two ports.
- property grid#
Grid spatial locations and information as defined by grid_spec. This is the grid used in the tangential directions as well as the grid used for field monitors. This is distinct from ‘eme_grid’, which is the grid used for mode solving and EME propagation.
- subsection(region, grid_spec=None, eme_grid_spec=None, symmetry=None, monitors=None, remove_outside_structures=True, remove_outside_custom_mediums=False, **kwargs)[source]#
Generate a simulation instance containing only the
region
. Same as inAbstractYeeGridSimulation
, except also restricting EME grid.- Parameters:
region (:class:.`Box`) – New simulation domain.
grid_spec (:class:.`GridSpec` = None) – New grid specification. If
None
, then it is inherited from the original simulation. Ifidentical
, then the original grid is transferred directly as a :class:.`CustomGrid`. Note that in the latter case the region of the new simulation is snapped to the original grid lines.eme_grid_spec (
EMEGridSpec
= None) – New EME grid specification. IfNone
, then it is inherited from the original simulation. Ifidentical
, then the original grid is transferred directly as aEMEExplicitGrid
. Noe that in the latter case the region of the new simulation is expanded to contain full EME cells.symmetry (Tuple[Literal[0, -1, 1], Literal[0, -1, 1], Literal[0, -1, 1]] = None) – New simulation symmetry. If
None
, then it is inherited from the original simulation. Note that in this case the size and placement of new simulation domain must be commensurate with the original symmetry.monitors (Tuple[MonitorType, ...] = None) – New list of monitors. If
None
, then the monitors intersecting the new simulation domain are inherited from the original simulation.remove_outside_structures (bool = True) – Remove structures outside of the new simulation domain.
remove_outside_custom_mediums (bool = True) – Remove custom medium data outside of the new simulation domain.
**kwargs – Other arguments passed to new simulation instance.
- __hash__()#
Hash method.