pyoptics.fdtd.simulation

The Simulation: structure, sources, monitors and the time stepping.

Update equations (normalized units, mu = 1), Ez mode in 2D

dHx/dt = -dEz/dy,   dHy/dt = dEz/dx,
eps dEz/dt + sigma Ez = dHy/dx - dHx/dy - Jz,

Hz mode

dHz/dt = dEx/dy - dEy/dx - Mz,
eps dEx/dt + sigma Ex = dHz/dy - Jx,
eps dEy/dt + sigma Ey = -dHz/dx - Jy,

and in 1D (propagation along x) the Ez mode with Ez and Hy only. H is updated from E with forward differences, E from H with backward differences; E lives at integer, H at half-integer time steps. The conductive term is discretized semi-implicitly, E <- Ca E + Cb (curl H - J) with Ca = (1 - s)/(1 + s), Cb = dt/eps/(1 + s), s = sigma dt/(2 eps).

Classes

Simulation

FDTD simulation in 1D or 2D.

class pyoptics.fdtd.simulation.Simulation(grid, structure=(), sources=(), monitors=(), mode='Ez', boundaries='pml', background=Medium(eps=1, sigma=0), courant=0.99, dt=None, subpixel=None, dtype=<class 'numpy.float64'>)[source]

Bases: object

FDTD simulation in 1D or 2D.

Parameters:
gridGrid
structuresequence of (Shape, Medium)

Drawn in order on top of the background, later ones on top.

sourcessequence of Source
monitorssequence of Monitor
mode“Ez” or “Hz”

2D polarization: Ez has the electric field along z (out of the plane, fields Ez, Hx, Hy), Hz the magnetic field along z (Ex, Ey, Hz). Ignored in 1D, which has Ez and Hy. See the module docstring of pyoptics.fdtd for the TE/TM names.

boundariesstr, PML or sequence of them

Per axis “pml” (or a PML instance), “pec” or “periodic”; a single entry applies to all axes. Default: PML() everywhere.

backgroundMedium
courantnumber

Time step as a fraction of the stability limit.

dtnumber, optional

Explicit time step (overrides courant).

subpixelint, optional

Sub-samples per cell and axis for averaging the permittivity across material boundaries (1: staircase). Default 64 in 1D, 8 in 2D. The average is arithmetic, which is the right one for E parallel to the boundaries (1D, and the Ez mode in 2D).

dtypenumpy dtype

float64 (default) or float32.

property time

Time of the electric field (H is half a step behind).

rasterize(component)[source]

Permittivity and conductivity at the nodes of a component, averaged over subpixel**ndim samples per cell.

setup()[source]

Rasterize the structure, allocate the fields and set up sources and monitors (done by run() if needed).

step()[source]

One time step: H from n - 1/2 to n + 1/2, E from n to n + 1.

run(time=None, steps=None, callback=None, every=None, progress=False)[source]

Advance the simulation by a time span or a number of steps.

Parameters:
timenumber, optional

Simulated time span (rounded up to whole steps).

stepsint, optional
callbackcallable, optional

callback(sim), called every every steps (e.g. live plots).

everyint, optional
progressbool

Print the number of steps and the run time at the end.

energy()[source]

Electromagnetic energy 1/2 sum(eps E**2 + H**2) dV.

E and H are half a step apart, so this oscillates slightly around the true energy. With track_energy = True (set before stepping), the E term is eps E(n)*E(n + 1) instead, which makes it the quantity that the Yee scheme conserves exactly in lossless media inside PEC walls.

permittivity(component=None)[source]

Rasterized permittivity at the nodes of a component (default: the first electric component).

pml_cells()[source]

Number of PML cells per axis (0 where there is none).