Python API map#
The top-level fdtdx namespace re-exports the principal public API. This page emphasizes the paths exercised by the current examples; specialized parameter transforms, GDS helpers, and field-projection detectors are also available from the top level.
Setup and execution#
- fdtdx.auto_grid(wavelength, domain_size, *, ppw=20.0, dl=None, max_voxels=40000000, max_refractive_index=1.0, min_feature_size=None, min_cells_per_feature=3.0, budget_behavior='raise')[source]#
Build a grid for
domain_sizeatwavelength / ppwresolution.Each axis gets an integer cell count (
ceil(length / dl)with a small roundoff guard) and the per-axis spacing is adjusted tolength / n— the same adjustment Tidy3D’s uniform grid performs, so a domain of e.g. 0.22um at 40nm becomes 6 cells of 0.0367um instead of a fractional 5.5 cells.- Parameters:
wavelength (float) – Free-space wavelength in metres. Used only when
dlis not given.domain_size (tuple[float, float, float]) – Physical
(Lx, Ly, Lz)extent in metres.ppw (float) – Points per wavelength inside the highest-index material when
max_refractive_indexis supplied. Defaults to 20.dl (float | None) – Explicit target cell width in metres. Overrides
ppw.max_voxels (int) – Voxel budget. Raises when exceeded (instead of an OOM crash later) unless
budget_behavior="coarsen".max_refractive_index (float) – Largest refractive index relevant to the scene. The wavelength-derived target spacing is
wavelength / (ppw * max_refractive_index). Defaults to 1 so existing free-space behavior is preserved.min_feature_size (float | None) – Optional smallest geometrical feature that must be represented. At least
min_cells_per_featurecells are targeted.min_cells_per_feature (float) – Target cells across
min_feature_size. Defaults to 3.budget_behavior (Literal['raise', 'coarsen']) –
"raise"preserves the requested accuracy and fails before allocation."coarsen"chooses the finest global spacing that fitsmax_voxelsand emits a warning. This explicit warning is important because global coarsening may under-resolve a requested material wavelength or feature.
- Returns:
A
QuasiUniformGridwith per-axis spacings adjusted so every axis has an integer cell count.- Raises:
ValueError – If the voxel count exceeds
max_voxels.- Return type:
- fdtdx.auto_boundary_config(pml_layers=10, boundary_types=None, structures=None, domain_size=None, wavelength=None, stabilize_evanescent=False, pml_alpha_fraction=0.2)[source]#
Uniform PML boundary config with per-face overrides and inference.
Defaults to PML on every face — the Tidy3D default. Pass
boundary_typesto override individual faces, e.g.{"min_x": "periodic", "max_x": "periodic"}.When
structuresanddomain_sizeare given, any axis whose extent is completely filled by a structure is inferred as PEC on both faces — the convention the Tidy3D goldens use (z-extent = slab thickness with the slab filling it). Explicitboundary_typesalways win over inference.- Parameters:
pml_layers (int) – PML thickness in cells on every PML face.
boundary_types (dict[str, BoundaryType] | None) – Per-face boundary type overrides keyed by
"min_x"/"max_x"/"min_y"/"max_y"/"min_z"/"max_z".structures (Sequence[object] | None) – Scene objects (e.g. waveguides, slabs) used to infer PEC faces. Any object whose
partial_real_shapefills an axis ofdomain_sizemarks that axis PEC.domain_size (tuple[float, float, float] | None) – Physical
(Lx, Ly, Lz)extent in metres. Required whenstructuresis given.wavelength (float | None) – Reference free-space wavelength. Required when
stabilize_evanescentis enabled.stabilize_evanescent (bool) – Use a complex-frequency-shifted PML suitable for resonators, waveguides, and photonic-crystal terminations with strong evanescent or grazing fields. Material crossing a PML must also be continued with
fdtdx.extend_material_to_pml()after geometry parameters are applied.pml_alpha_fraction (float) – CFS strength as a fraction of
2 pi f epsilon_0at the PML interface. The 0.20 default was selected by a late-time stability sweep of an Ez photonic-crystal surface cavity; smaller values left a growing PML mode.
- Returns:
A
BoundaryConfig.- Return type:
BoundaryConfig
- fdtdx.auto_config(wavelength, domain_size, time, *, ppw=20.0, dl=None, max_voxels=40000000, max_refractive_index=1.0, min_feature_size=None, min_cells_per_feature=3.0, budget_behavior='raise', dtype=<class 'jax.numpy.float32'>, courant_factor=0.99)[source]#
One-call simulation config: auto grid + defaults.
- Parameters:
wavelength (float) – Free-space wavelength in metres (resolution basis).
domain_size (tuple[float, float, float]) – Physical
(Lx, Ly, Lz)extent in metres.time (float) – Total simulation time in seconds.
ppw (float) – Points per wavelength. Defaults to 20.
dl (float | None) – Explicit target cell width in metres. Overrides
ppw.max_voxels (int) – Voxel budget (see
auto_grid()).max_refractive_index (float) – Highest scene refractive index used to resolve wavelength in material.
min_feature_size (float | None) – Optional smallest geometry feature to resolve.
min_cells_per_feature (float) – Target cells across the smallest feature.
budget_behavior (Literal['raise', 'coarsen']) – Whether an over-budget request raises or explicitly coarsens with a warning.
dtype (dtype) – Field dtype. Defaults to float32.
courant_factor (float) – Courant safety factor. Defaults to 0.99.
- Returns:
A
SimulationConfigready forfdtdx.place_objects(). Pair withauto_boundary_config()for the boundary objects.- Return type:
- fdtdx.auto_interface_aligned_grid(domain_size, target_spacing, *, interfaces=((), (), ()), center=(0.0, 0.0, 0.0), max_voxels=40000000)[source]#
Build a rectilinear mesh whose cells end exactly at material interfaces.
Each interval between the domain boundary and supplied interface planes is divided into the fewest equal cells whose width does not exceed
target_spacing. This removes mesh-origin changes in thin films while keeping the mesh quasi-uniform and the cell count predictable. Interface coordinates are absolute physical coordinates in the same frame ascenter.This policy is particularly useful for layered photonics: pass the slab, etch, and substrate planes on their normal axis and let subpixel smoothing handle curved or oblique in-plane boundaries.
- Parameters:
domain_size (tuple[float, float, float])
target_spacing (float | tuple[float, float, float])
interfaces (tuple[Sequence[float], Sequence[float], Sequence[float]])
center (tuple[float, float, float])
max_voxels (int)
- Return type:
- fdtdx.auto_pml_layers(physical_thickness, spacing)[source]#
Choose a uniform PML cell count that preserves physical thickness.
Refining a mesh must not silently make its absorber thinner. For an anisotropic grid, the smallest spacing controls the uniform layer count, so every face is at least
physical_thicknessthick (up to the same floating-point guard used bysnap_half_integer()).- Parameters:
physical_thickness (float)
spacing (float | tuple[float, float, float])
- Return type:
int
- fdtdx.place_objects(object_list, config, constraints, key=None)[source]#
Places simulation objects according to specified constraints and initializes containers.
- Parameters:
objects (list[SimulationObject]) – List of all simulation objects, including the simulation volume.
config (SimulationConfig) – Simulation configuration.
constraints (Sequence[Constraint]) – List of positioning/sizing constraints referencing object names.
key (jax.Array | None) – JAX random key for initialization. When
None(the default) a deterministic key is derived from_DEFAULT_KEY_SEED.object_list (Sequence[SimulationObject])
- Returns:
- A tuple containing:
ObjectContainer with placed simulation objects
ArrayContainer with initialized field arrays
ParameterContainer with device parameters
Updated SimulationConfig
Dictionary with additional initialization info
- Return type:
tuple[ObjectContainer, ArrayContainer, ParameterContainer, SimulationConfig, dict[str, Any]]
- Raises:
ValueError – If constraint resolution fails for one or more objects.
- fdtdx.apply_params(arrays, objects, params, key=None, **transform_kwargs)[source]#
Applies parameters to devices and updates source states.
- Parameters:
arrays (ArrayContainer) – Container with field arrays
objects (ObjectContainer) – Container with simulation objects
params (ParameterContainer) – Container with device parameters
key (jax.Array | None) – JAX random key for source updates. When
None(the default) a deterministic key is derived from_DEFAULT_KEY_SEED.**transform_kwargs – Keyword arguments passed to the parameter transformation.
- Returns:
- A tuple containing:
Updated ArrayContainer with applied device parameters
Updated ObjectContainer with new source states
Dictionary with parameter application info
- Return type:
tuple[ArrayContainer, ObjectContainer, dict[str, Any]]
- fdtdx.run_fdtd(arrays, objects, config, key=None, stopping_condition=None, show_progress=True, progress_callback=None)[source]#
- Parameters:
arrays (ArrayContainer)
objects (ObjectContainer)
config (SimulationConfig)
key (Array | None)
stopping_condition (StoppingCondition | None)
show_progress (bool)
progress_callback (Callable[[int, int], None] | None)
- Return type:
tuple[Array, ArrayContainer]
Configuration and grid#
- class fdtdx.SimulationConfig(*a, **k)[source]#
Configuration settings for FDTD simulations.
This class contains all the parameters needed to configure and run an FDTD simulation, including spatial and temporal discretization, hardware backend, and gradient computation settings.
- Return type:
T
- property has_symmetry: bool#
Whether any axis requests mirror symmetry.
- Returns:
- True if at least one entry of
symmetryis nonzero, meaning the domain will be reduced and a PEC/PMC wall placed on the symmetry plane(s).
- True if at least one entry of
- Return type:
bool
- property courant_number: float#
Calculate the Courant number for the simulation.
The Courant number is a dimensionless quantity that determines stability of the FDTD simulation. It represents the ratio of the physical propagation speed to the numerical propagation speed.
- Returns:
- The Courant number, scaled by the courant_factor and normalized
for 3D simulations.
- Return type:
float
- property time_step_duration: float#
Calculate the duration of a single time step.
The time step duration is determined by the Courant condition to ensure numerical stability. Realized rectilinear grids use their smallest per-axis spacings. Unresolved uniform grids use their configured scalar spacing; unresolved quasi-uniform grids use their smallest per-axis spacing as a conservative CFL bound.
- Returns:
- Time step duration in seconds, calculated using the Courant
condition and spatial resolution.
- Return type:
float
- property time_steps_total: int#
Calculate the total number of time steps for the simulation.
Determines how many discrete time steps are needed to simulate the specified total simulation time, based on the time step duration.
- Returns:
- Total number of time steps needed to reach the specified
simulation time.
- Return type:
int
- class fdtdx.GradientConfig(*a, **k)[source]#
Configuration for gradient computation in simulations.
This class handles settings for automatic differentiation, supporting either invertible differentiation with a recorder or checkpointing-based differentiation.
- Return type:
T
- class fdtdx.UniformGrid(*a, **k)[source]#
Unresolved policy for a uniform rectilinear grid.
UniformGridis user intent, not the solver mesh itself. It records the physical cell spacing while the final simulation shape may still be unknown. Object placement resolves this policy to a concreteRectilinearGridonce the volume shape is known.Keeping uniform spacing here avoids a second scalar discretization source on
SimulationConfig. Uniform grids and explicitly non-uniform grids both enter the solver through the same realizedRectilinearGridstructure.The grid origin is at the center of the simulation domain. Edge arrays therefore span
[-N/2 * spacing, +N/2 * spacing]along each axis, giving the domain symmetric negative and positive coordinates.centershifts this physical center away from the geometric origin when non-zero.- Return type:
T
- class fdtdx.QuasiUniformGrid(*a, **k)[source]#
Unresolved policy for a rectilinear grid with independent per-axis spacings.
QuasiUniformGridgeneralisesUniformGridto allow different cell widths along x, y, and z while keeping each axis internally uniform. This is sometimes called a quasi-uniform or anisotropic-uniform mesh: the grid is rectilinear and axis-aligned, but the aspect ratio is not 1 : 1 : 1.Like
UniformGrid, this is user intent rather than the solver mesh. Callingresolve()converts the policy to a concreteRectilinearGridonce the simulation shape is known. The resulting grid is centered atcenterso that coordinates span symmetrically into both negative and positive values along every axis.Example:
grid = QuasiUniformGrid(dx=10e-9, dy=10e-9, dz=20e-9) resolved = grid.resolve(shape=(100, 100, 50)) # x, y edges span [-500 nm, +500 nm]; z edges span [-500 nm, +500 nm]
- Return type:
T
- class fdtdx.RectilinearGrid(*a, **k)[source]#
Realized rectilinear simulation grid described by physical cell edges.
This is the canonical solver-facing grid representation used by fdtdx internals. A uniform grid is represented by equally spaced edge arrays, not by a separate scalar code path. Keeping one realized representation is important for the non-uniform grid migration: placement, PML profiles, mode-solver coordinates, detector weights, and Yee update metrics should all ask the grid for physical distances instead of deriving them from a global
resolutionvalue.The arrays store cell edges in metres. For a grid with
nxcells along x,x_edgeshas shape(nx + 1,)and must be strictly increasing. Cell widths, centers, face areas, and volumes are derived from these arrays.Notes
This class intentionally does not encode automatic mesh generation policy. Future policy objects such as
AutoGridorQuasiUniformGridshould resolve toRectilinearGridbefore the solver runs.- Return type:
T
Scene and materials#
API |
Role |
|---|---|
|
defines the finite physical domain |
|
permittivity, permeability, conductivity, and dispersion |
|
axis-aligned material region |
|
curved primitives with optional subpixel smoothing |
|
extruded 2D polygon; useful for PIC geometry |
|
parameterized material region for inverse design |
|
per-face boundary policy |
- class fdtdx.Material(*a, **k)[source]#
Represents an electromagnetic material with specific electrical and magnetic properties.
This class stores the fundamental electromagnetic properties of a material for use in electromagnetic simulations. Supports both isotropic and anisotropic materials.
Note
All material properties are stored internally as 9-tuples (xx, xy, xz, yx, yy, yz, zx, zy, zz components). Scalar inputs are automatically broadcast to all diagonal components.
- Return type:
T
- class fdtdx.SimulationVolume(*a, **k)[source]#
Background material for the entire simulation volume.
Defines the default material properties for the simulation background. Usually represents air/vacuum with εᵣ=1.0 and μᵣ=1.0.
- Return type:
T
- class fdtdx.ExtrudedPolygon(*a, **k)[source]#
A polygon object specified by a list of vertices.
The vertices must be given in a coordinate system centered at the origin, i.e. (0, 0) corresponds to the center of the object’s bounding box. The polygon is placed so that its center coincides with the center of the grid region allocated to this object.
The cross-section size is automatically inferred from the vertex bounding box for the two axes perpendicular to
axis, sopartial_real_shapedoes not need to be specified for those axes. The extrusion axis size must still be determined by a constraint or an explicitpartial_real_shapeentry.- Return type:
T
Sources#
All sources carry a WaveCharacter, direction/polarization information where applicable, a temporal profile, and placement inherited from SimulationObject.
API |
Spatial model |
|---|---|
|
local electric dipole |
|
finite uniform linearly polarized plane |
|
finite Gaussian beam |
|
eigenmode on a cross-section |
|
total-field/scattered-field box |
- class fdtdx.WaveCharacter(*a, **k)[source]#
Class describing a wavelength/period/frequency in free space. Importantly, the wave characteristic conversion is based on a free space wave when using the wavelength (For conversion, a refractive index of 1 is used).
- Return type:
T
Temporal profiles are SingleFrequencyProfile, GaussianPulseProfile, and CustomTimeSignalProfile.
Inverse design#
- class fdtdx.TopologyOptimizerConfig(iterations, continuation_steps=None, learning_rate=0.1, final_learning_rate_fraction=0.1, beta_start=1.0, beta_end=50.0, lower_bound=0.0, upper_bound=1.0, maximize=True, early_stop_patience=None, early_stop_min_delta=0.0001, algorithm='adam', momentum=0.9, lbfgs_memory_size=10)[source]#
Device-independent bounded Adam continuation policy.
- Parameters:
iterations (int)
continuation_steps (int | None)
learning_rate (float)
final_learning_rate_fraction (float)
beta_start (float)
beta_end (float)
lower_bound (float)
upper_bound (float)
maximize (bool)
early_stop_patience (int | None)
early_stop_min_delta (float)
algorithm (Literal['adam', 'sgd', 'lbfgs'])
momentum (float)
lbfgs_memory_size (int)
- class fdtdx.TopologyOptimizationResult(final_parameters, best_parameters, best_objective, best_step, records)[source]#
Parameters and diagnostics returned by
optimize_topology().- Parameters:
final_parameters (ndarray)
best_parameters (ndarray)
best_objective (float)
best_step (int)
records (tuple[TopologyStepRecord, ...])
- fdtdx.optimize_topology(objective, initial_parameters, config, *, accept=None, callback=None)[source]#
Run a bounded Adam optimization with automatic projection continuation.
objective(parameters, beta, fraction)returns(value, auxiliary). The scalarfractionprogresses inclusively from zero to one and lets a device objective schedule additional weights without owning an optimizer loop.acceptmay reject numerically nonphysical candidates (for example, passive-power violations) from best-design selection.- Parameters:
objective (Callable[[Array, Array, Array], tuple[Array, Any]])
initial_parameters (Array | ndarray)
config (TopologyOptimizerConfig)
accept (Callable[[Any], bool] | None)
callback (Callable[[TopologyStepRecord, ndarray, Any], None] | None)
- Return type:
- fdtdx.conic_filter(parameters, *, radius, spacing, padding='reflect')[source]#
Apply a conic minimum-feature filter with explicit boundary padding.
- Parameters:
parameters (Array)
radius (float)
spacing (float)
padding (str)
- Return type:
Array
- fdtdx.tanh_projection(values, *, beta, eta=0.5)[source]#
Smoothly project filtered values toward a binary material system.
- Parameters:
values (Array)
beta (float | Array)
eta (float)
- Return type:
Array
- fdtdx.erosion_dilation_penalty(parameters, *, radius, spacing, beta=10.0, padding='reflect')[source]#
Return the RMS morphological close/open discrepancy.
- Parameters:
parameters (Array)
radius (float)
spacing (float)
beta (float)
padding (str)
- Return type:
Array
- fdtdx.d4_symmetrize(values)[source]#
Average a square material map over the eight D4 transformations.
This is the material symmetry used by four-port crossings: four rotations and their mirror images. Applying it after filtering and projection matches the topology transform used by Tidy3D’s S-matrix example while retaining one unconstrained parameter per design pixel.
- Parameters:
values (Array)
- Return type:
Array
- fdtdx.binary_density(parameters, *, radius, spacing, threshold=0.5, padding='reflect')[source]#
Create the deterministic fully binary fabrication design.
Thresholding occurs after the same minimum-feature filter used during optimization. It is intentionally fixed at the projection threshold; objective-aware threshold sweeps would grant a hidden per-device optimization stage.
- Parameters:
parameters (Array)
radius (float)
spacing (float)
threshold (float)
padding (str)
- Return type:
Array
- class fdtdx.LevelSetBoundary2D(reference_level_set, spacing=(1.0, 1.0), narrow_band_width=4.0, maximum_displacement=2.0, interface_width=0.25, supersample=4, threshold=0.5, diagonal_connectivity=False, exterior_edges=('min_x', 'max_x', 'min_y', 'max_y'))[source]#
Binary, topology-guarded boundary-normal design parameterization.
parametersare signed physical displacements on the vertex grid. Positive displacement grows material along its outward normal and negative displacement retreats it. A cosine narrow-band window makes the Maxwell derivative exactly zero in uniform bulk regions, so the gradient is a normal boundary sensitivity rather than a pixel-density sensitivity.The basis cannot nucleate a remote component because displacement vanishes outside
narrow_band_width. Boundary collision can still merge or erase existing components, sopreserves_topology()andrebase()provide an explicit host-side acceptance guard.- Parameters:
reference_level_set (ndarray)
spacing (tuple[float, float])
narrow_band_width (float)
maximum_displacement (float)
interface_width (float)
supersample (int)
threshold (float)
diagonal_connectivity (bool)
exterior_edges (tuple[Literal['min_x', 'max_x', 'min_y', 'max_y'], ...])
- classmethod from_density(density, *, spacing=(1.0, 1.0), threshold=0.5, narrow_band_width=None, maximum_displacement=None, interface_width=None, supersample=4, diagonal_connectivity=False, exterior_edges=('min_x', 'max_x', 'min_y', 'max_y'))[source]#
Threshold a grey result once and fit its boundary level set.
- Parameters:
density (Array | ndarray)
spacing (tuple[float, float])
threshold (float)
narrow_band_width (float | None)
maximum_displacement (float | None)
interface_width (float | None)
supersample (int)
diagonal_connectivity (bool)
exterior_edges (tuple[Literal['min_x', 'max_x', 'min_y', 'max_y'], ...])
- Return type:
- initial_parameters(*, dtype=<class 'jax.numpy.float32'>)[source]#
Return the zero-displacement start for this reference boundary.
- Parameters:
dtype (dtype)
- Return type:
Array
- boundary_window(*, dtype=<class 'jax.numpy.float32'>)[source]#
Cosine window equal to one on the interface and zero in the bulk.
- Parameters:
dtype (dtype)
- Return type:
Array
- interface_normal(parameters)[source]#
Return the outward material normal on the vertex grid.
- Parameters:
parameters (Array)
- Return type:
Array
- rebase(parameters, *, preserve_topology=True)[source]#
Accept a moved interface and return a fresh signed-distance stage.
- Parameters:
parameters (Array | ndarray)
preserve_topology (bool)
- Return type:
tuple[LevelSetBoundary2D, Array]
- fdtdx.boundary_topology_signature(density, *, threshold=0.5, diagonal_connectivity=False, exterior_edges=('min_x', 'max_x', 'min_y', 'max_y'))[source]#
Return the material-component and enclosed-void counts of a 2-D mask.
Air connected to one of
exterior_edgesis exterior and is therefore not counted as a hole. Omit symmetry planes from that tuple: a half-hole touching a mirror plane then remains an enclosed hole after unfolding. This host-side diagnostic is intended for accepted candidate checks, not for differentiation inside a JIT-compiled objective.- Parameters:
density (Array | ndarray)
threshold (float)
diagonal_connectivity (bool)
exterior_edges (tuple[Literal['min_x', 'max_x', 'min_y', 'max_y'], ...])
- Return type:
BoundaryTopology
- fdtdx.topology_safe_boundary_step(basis, parameters, normal_velocity, *, step_size, backtracking_scales=(1.0, 0.5, 0.25, 0.125, 0.0625))[source]#
Take the largest proposed normal step that preserves interface topology.
normal_velocityis normally the gradient of a scalar Maxwell objective with respect to the basis parameters. The returned scale is zero when all candidates would merge, split, create, or erase a boundary component. An objective-aware optimizer should additionally accept only improving steps; this helper supplies the independent geometric guard for its line search.This is deliberately a host-side operation because connected-component topology is discrete and should never be hidden inside a surrogate JAX gradient.
- Parameters:
basis (LevelSetBoundary2D | SplineLevelSetBoundary2D)
parameters (Array | ndarray)
normal_velocity (Array | ndarray)
step_size (float)
backtracking_scales (tuple[float, ...])
- Return type:
tuple[Array, float]
- fdtdx.fixed_frequency_cavity_ldos(*, peak_resonant_ldos, quality_factor, pole_frequency, emitter_frequency, background_ldos=0.0)[source]#
Evaluate a fitted cavity pole at one immutable emitter frequency.
peak_resonant_ldosis the resonant contribution at the pole, excludingbackground_ldos. The returned value applies the single-pole Lorentzian detuning factor1 / (1 + (2 Q (f_emitter - f_pole) / f_pole)**2).Unlike optimizing peak
Q/Vwhile following a moving pole, this metric gives no benefit to a resonance that walks away from the emitter. Every operation remains differentiable with respect to the fitted pole, Q, mode volume, and ultimately the FDTD geometry.- Parameters:
peak_resonant_ldos (Array)
quality_factor (Array)
pole_frequency (Array)
emitter_frequency (Array)
background_ldos (float | Array)
- Return type:
Array
Detectors#
API |
Primary result |
|---|---|
|
selected field components over a region |
|
electromagnetic energy history |
|
complex fields at requested frequencies |
|
integrated time-domain flux |
|
frequency-domain flux |
|
complex amplitude in an eigenmode |
|
net flux through a volume |
- class fdtdx.PhasorDetector(*a, **k)[source]#
Detector for measuring frequency components of electromagnetic fields using an efficient Phasor Implementation.
This detector computes complex phasor representations of the field components at specified frequencies, enabling frequency-domain analysis of the electromagnetic fields. The amplitude and phase of the original phase can be reconstructed using jnp.abs(phasor) and jnp.angle(phasor). The reconstruction itself can then be achieved using amplitude * jnp.cos(2 * jnp.pi * freq * t + phase).
- Return type:
T
- class fdtdx.PhasorPoyntingFluxDetector(*a, **k)[source]#
Time-averaged Poynting flux through a single plane in the frequency domain.
Frequency-domain analog of
PoyntingFluxDetector. Instead of recording the instantaneous flux at every time step, it accumulates the complex field phasors (inheriting all ofPhasorDetector’s DFT / subsampling / scaling machinery) and forms the time-averaged Poynting flux<S> = 1/2 Re(E(w) x H*(w))in the post-processing methodcompute_poynting_flux(). This mirrors howModeOverlapDetectorcomputes its (also bilinear) overlap after the run.Because the flux is a product of two independently accumulated DFTs, the surface integral cannot be folded into the per-step update the way the time-domain detector does – the phasors must be complete first. All six field components are therefore always recorded.
- Return type:
T
- class fdtdx.ModeOverlapDetector(*a, **k)[source]#
Detector for measuring the overlap of a waveguide mode with the simulation fields. This detector computes the overlap integral at every frequency in
wave_characters, enabling broadband frequency-domain analysis of the electromagnetic fields.The reference mode is obtained from the waveguide mode solver (
compute_mode). For a user-supplied or analytic reference mode (e.g. a Gaussian beam) useCustomModeOverlapDetectororGaussianModeOverlapDetectorinstead; both share the same overlap machinery viaBaseModeOverlapDetector.The mode overlap is calculated by integrating the cross product of the mode fields with the simulation fields over a cross-sectional plane. This is useful for analyzing waveguide coupling efficiency, transmission coefficients, and modal decomposition of electromagnetic fields.
compute_overlap()returns a complex array of shape(num_freqs,), wherenum_freqs = len(wave_characters).- Return type:
T
Modes, ports, and metrics#
- fdtdx.compute_mode(frequency, inv_permittivities, inv_permeabilities, resolution=None, direction='+', mode_index=0, filter_pol=None, dtype=<class 'jax.numpy.float32'>, bend_radius=None, bend_axis=None, symmetry=(0, 0), transverse_coords=None, fixed_propagation_axis=None)[source]#
Compute optical modes of a waveguide cross-section.
This function uses the Tidy3D mode solver to compute the optical modes of a given waveguide cross-section defined by its permittivity distribution.
By default modes are sorted by their effective index. The mode_index argument indexes this sorted list of modes and returns the desired mode. With filter_pol, it is also possible to only index a specific polarization.
- Parameters:
frequency (float) – Operating frequency in Hz
inv_permittivities (jax.Array) – 3D array of inverse relative permittivity values
inv_permeabilities (jax.Array | float) – 3D array of inverse relative permittivity values or single float for uniform permeability distribution.
resolution (float | None) – Uniform-grid spacing in metres. Required when
transverse_coordsis not provided (uniform-grid path). Ignored whentransverse_coordsis given. Defaults to None.direction (Literal["+", "-"]) – Propagation direction, either “+” or “-“.
mode_index (int, optional) – Index of the mode to compute. Defaults to 0.
filter_pol (Literal["te", "tm"] | None, optional)
dtype (jnp.dtype, optional) – Float dtype of the simulation. Controls whether mode fields are returned as complex64 (float32) or complex128 (float64). Defaults to jnp.float32.
bend_radius (float | None, optional) – Bend radius of the waveguide in meters. Must be set together with bend_axis. When set, the mode solver uses a conformal transformation to account for the bend. Defaults to None (straight waveguide).
bend_axis (int | None, optional) – Physical axis index (0/1/2) pointing from the waveguide toward the center of curvature. Must differ from the propagation axis. Required when bend_radius is set. Defaults to None.
symmetry (tuple[int, int], optional) – Symmetry-plane condition at the min edge of each transverse axis, in the order of the two non-propagation physical axes (increasing index).
0imposes a PEC mirror (electric wall — the tidy3d default),1imposes a PMC mirror (magnetic wall). Use this when the waveguide sits on a symmetry plane of a reduced (half/quarter) domain so the mode solver reproduces the same boundary the FDTD uses there. For a +x-propagating TE mode on a y/z quarter domain with PEC at y=0 and PMC at the z Si-mid plane, pass(0, 1). Defaults to(0, 0)(PEC on both, i.e. no symmetry).transverse_coords (Sequence[Array] | None) – Optional pair of physical edge-coordinate arrays, in metres, for the two axes transverse to propagation. Each array must have one more entry than the corresponding transverse cell count. When provided, the Tidy3D mode solver receives the non-uniform rectilinear grid directly. JAX arrays are accepted; the numpy conversion happens inside the tidy3d callback so the function remains compatible with
jax.jit.fixed_propagation_axis (int | None) – Optional physical axis normal to the mode plane. This disambiguates an extruded 2-D plane whose normal axis and invariant transverse axis are both one cell wide.
- Returns:
Tuple of E, H field and the effective index as complex-valued jax arrays.
- Return type:
Tuple[jax.Array, jax.Array, jax.Array]
- fdtdx.calculate_sparam(objects, arrays, config, input_port_name, show_progress=True, input_normalization_detector_name=None, key=None)[source]#
Run the FDTD simulation and extract S-parameters from mode-overlap detectors.
Intended to be called with the outputs of
setup_sparams_simulation(). EachModeOverlapDetectorin objects contributes one entry to the returned dictionary. Because a single simulation (with one active input port) measures the transmission to all output ports simultaneously, the dictionary keys are(detector_name, input_port_name)tuples so that results from multiple calls can be merged into a full S-matrix.To simulate all input ports in one call (multiple simulations), use
calculate_sparams().- Parameters:
objects (ObjectContainer) – ObjectContainer from
setup_sparams_simulation().arrays (ArrayContainer) – ArrayContainer from
setup_sparams_simulation().config (SimulationConfig) – SimulationConfig from
setup_sparams_simulation().input_port_name (str) – Name of the active input port. Should match the
namefield of the correspondingPortSpec, or the auto-generated name"Source_<i>"when no name was supplied.show_progress (bool) – Whether to display the simulation progress bar.
input_normalization_detector_name (str | None) – Name (or substring) of the detector used to normalise the input power. Defaults to a detector whose name contains input_port_name.
key (Array | None) – JAX random key. Defaults to
PRNGKey(0).
- Returns:
A 2-tuple
(sparams, detector_states)where sparams maps(detector_name, input_port_name)to a complex scattering-amplitude array indexed by frequency. For the single-frequency detectors created bysetup_sparams_simulation(), each value has shape(1,). detector_states is the finalDetectorStatedict for every detector in the simulation.- Return type:
tuple[dict[tuple[str, str], Array], dict[str, dict[str, Array]]]
- fdtdx.calculate_sparams(objects, arrays, config, input_port_names, show_progress=True, input_normalization_detector_name=None, key=None, return_detector_states=False)[source]#
Run FDTD simulations for multiple input ports and merge S-parameters.
Calls
calculate_sparam()once per entry in input_port_names and merges all results into a single S-parameter dictionary.- Parameters:
objects (ObjectContainer) – ObjectContainer from
setup_sparams_simulation().arrays (ArrayContainer) – ArrayContainer from
setup_sparams_simulation().config (SimulationConfig) – SimulationConfig from
setup_sparams_simulation().input_port_names (Sequence[str]) – Names of the input ports to simulate.
show_progress (bool) – Whether to display the simulation progress bar.
input_normalization_detector_name (str | None) – Passed through to
calculate_sparam().key (Array | None) – JAX random key. Defaults to
PRNGKey(0).return_detector_states (bool) – When
True, return the detector states from each simulation run as a list (one entry per input port). WhenFalsean empty list is returned.
- Returns:
A 2-tuple
(sparams, detector_states_list)where sparams is the mergeddict[tuple[str, str], jax.Array]across all simulations and detector_states_list is either a list of per-simulation detector state dicts or an empty list.- Return type:
tuple[dict[tuple[str, str], Array], list[dict[str, dict[str, Array]]]]
- fdtdx.compute_energy(E, H, inv_permittivity, inv_permeability, axis=0)[source]#
Computes the total electromagnetic energy density of the field.
- Parameters:
E (jax.Array) – Electric field array with shape (3, nx, ny, nz)
H (jax.Array) – Magnetic field array with shape (3, nx, ny, nz)
inv_permittivity (jax.Array | float) – Inverse permittivity. Shape (3, nx, ny, nz) for anisotropic or scalar
inv_permeability (jax.Array | float) – Inverse permeability. Shape (3, nx, ny, nz) for anisotropic or scalar
axis (int, optional) – Axis index of the X,Y,Z component for the E and H field. Defaults to 0.
- Returns:
Total energy density array with shape (nx, ny, nz)
- Return type:
jax.Array
- fdtdx.compute_poynting_flux(E, H, axis=0)[source]#
Calculates the Poynting vector (energy flux) from E and H fields.
- Parameters:
E (jax.Array) – Electric field array with shape (3, nx, ny, nz)
H (jax.Array) – Magnetic field array with shape (3, nx, ny, nz)
axis (int, optional) – Axis for computing the poynting flux. Defaults to 0.
- Returns:
Poynting vector array with shape (3, nx, ny, nz) representing energy flux in each direction
- Return type:
jax.Array
Serialization and visualization#
Use export_json/import_from_json for the semantic scene, export_vti or export_vtr for VTK-compatible volume output, and plot_setup, plot_material, or plot_field_slice for local inspection. See output and diagnostics.
Stability contract
The upstream project is pre-1.0. These docs track the checked-out fork and use tested examples as the strongest compatibility contract. Pin a commit for production research and record it with results.