Skip to content

Field Updates

Electric Field Updates

fdtdx.fdtd.update.update_E(time_step, arrays, objects, config, simulate_boundaries)

Updates the electric field (E) according to Maxwell's equations using the FDTD method.

Implements the discretized form of dE/dt = (1/ε)∇×H on the Yee grid. Updates include: 1. PML boundary conditions if simulate_boundaries=True 2. Source contributions for active sources 3. Field updates based on curl of H field

Parameters:

Name Type Description Default
time_step Array

Current simulation time step

required
arrays ArrayContainer

Container with E, H fields and material properties

required
objects ObjectContainer

Container with sources, PML and other simulation objects

required
config SimulationConfig

Simulation configuration parameters

required
simulate_boundaries bool

Whether to apply PML boundary conditions

required

Returns:

Type Description
ArrayContainer

Updated ArrayContainer with new E field values

Source code in src/fdtdx/fdtd/update.py
def update_E(
    time_step: jax.Array,
    arrays: ArrayContainer,
    objects: ObjectContainer,
    config: SimulationConfig,
    simulate_boundaries: bool,
) -> ArrayContainer:
    """Updates the electric field (E) according to Maxwell's equations using the FDTD method.

    Implements the discretized form of dE/dt = (1/ε)∇×H on the Yee grid. Updates include:
    1. PML boundary conditions if simulate_boundaries=True
    2. Source contributions for active sources
    3. Field updates based on curl of H field

    Args:
        time_step: Current simulation time step
        arrays: Container with E, H fields and material properties
        objects: Container with sources, PML and other simulation objects
        config: Simulation configuration parameters
        simulate_boundaries: Whether to apply PML boundary conditions

    Returns:
        Updated ArrayContainer with new E field values
    """
    boundary_states = {}
    if simulate_boundaries:
        for pml in objects.pml_objects:
            boundary_states[pml.name] = pml.update_E_boundary_state(
                boundary_state=arrays.boundary_states[pml.name],
                H=arrays.H,
            )

    E = arrays.E + config.courant_number * curl_H(arrays.H) * arrays.inv_permittivities

    for source in objects.sources:

        def _update():
            return source.update_E(
                E=E,
                inv_permittivities=arrays.inv_permittivities,
                inv_permeabilities=arrays.inv_permeabilities,
                time_step=time_step,
                inverse=False,
            )

        E = jax.lax.cond(
            source._is_on_at_time_step_arr[time_step],
            _update,
            lambda: E,
        )

    if simulate_boundaries:
        for pml in objects.pml_objects:
            E = pml.update_E(
                E=E,
                boundary_state=boundary_states[pml.name],
                inverse_permittivity=arrays.inv_permittivities,
            )

    arrays = arrays.at["E"].set(E)
    if simulate_boundaries:
        arrays = arrays.aset("boundary_states", boundary_states)

    return arrays

fdtdx.fdtd.update.update_E_reverse(time_step, arrays, objects, config)

Reverse time step update for the electric field used in automatic differentiation.

Implements the inverse update step that transforms the electromagnetic field state from time step t+1 to time step t, leveraging the time-reversibility property of Maxwell's equations.

Parameters:

Name Type Description Default
time_step Array

Current simulation time step

required
arrays ArrayContainer

Container with E, H fields and material properties

required
objects ObjectContainer

Container with sources and other simulation objects

required
config SimulationConfig

Simulation configuration parameters

required

Returns:

Type Description
ArrayContainer

Updated ArrayContainer with reversed E field values

Source code in src/fdtdx/fdtd/update.py
def update_E_reverse(
    time_step: jax.Array,
    arrays: ArrayContainer,
    objects: ObjectContainer,
    config: SimulationConfig,
) -> ArrayContainer:
    """Reverse time step update for the electric field used in automatic differentiation.

    Implements the inverse update step that transforms the electromagnetic field state
    from time step t+1 to time step t, leveraging the time-reversibility property of
    Maxwell's equations.

    Args:
        time_step: Current simulation time step
        arrays: Container with E, H fields and material properties
        objects: Container with sources and other simulation objects
        config: Simulation configuration parameters

    Returns:
        Updated ArrayContainer with reversed E field values
    """
    """Reverse time step update for the electric field used in automatic differentiation.

    Implements the inverse update step that transforms the electromagnetic field state 
    from time step t+1 to time step t, leveraging the time-reversibility property of
    Maxwell's equations.

    Args:
        time_step: Current simulation time step
        arrays: Container with E, H fields and material properties
        objects: Container with sources and other simulation objects
        config: Simulation configuration parameters

    Returns:
        Updated ArrayContainer with reversed E field values
    """
    E = arrays.E
    for source in objects.sources:

        def _update():
            return source.update_E(
                E,
                inv_permittivities=arrays.inv_permittivities,
                inv_permeabilities=arrays.inv_permeabilities,
                time_step=time_step,
                inverse=True,
            )

        E = jax.lax.cond(
            source._is_on_at_time_step_arr[time_step],
            _update,
            lambda: E,
        )

    E = E - config.courant_number * curl_H(arrays.H) * arrays.inv_permittivities

    arrays = arrays.at["E"].set(E)

    return arrays

Magnetic Field Updates

fdtdx.fdtd.update.update_H(time_step, arrays, objects, config, simulate_boundaries)

Updates the magnetic field (H) according to Maxwell's equations using the FDTD method.

Implements the discretized form of dH/dt = -(1/μ)∇×E on the Yee grid. Updates include: 1. PML boundary conditions if simulate_boundaries=True 2. Source contributions for active sources 3. Field updates based on curl of E field

The H field is updated at time points offset by half steps from the E field updates, following the Yee grid scheme.

Parameters:

Name Type Description Default
time_step Array

Current simulation time step

required
arrays ArrayContainer

Container with E, H fields and material properties

required
objects ObjectContainer

Container with sources, PML and other simulation objects

required
config SimulationConfig

Simulation configuration parameters

required
simulate_boundaries bool

Whether to apply PML boundary conditions

required

Returns:

Type Description
ArrayContainer

Updated ArrayContainer with new H field values

Source code in src/fdtdx/fdtd/update.py
def update_H(
    time_step: jax.Array,
    arrays: ArrayContainer,
    objects: ObjectContainer,
    config: SimulationConfig,
    simulate_boundaries: bool,
) -> ArrayContainer:
    """Updates the magnetic field (H) according to Maxwell's equations using the FDTD method.

    Implements the discretized form of dH/dt = -(1/μ)∇×E on the Yee grid. Updates include:
    1. PML boundary conditions if simulate_boundaries=True
    2. Source contributions for active sources
    3. Field updates based on curl of E field

    The H field is updated at time points offset by half steps from the E field updates,
    following the Yee grid scheme.

    Args:
        time_step: Current simulation time step
        arrays: Container with E, H fields and material properties
        objects: Container with sources, PML and other simulation objects
        config: Simulation configuration parameters
        simulate_boundaries: Whether to apply PML boundary conditions

    Returns:
        Updated ArrayContainer with new H field values
    """
    boundary_states = {}
    if simulate_boundaries:
        for pml in objects.pml_objects:
            boundary_states[pml.name] = pml.update_H_boundary_state(
                boundary_state=arrays.boundary_states[pml.name],
                E=arrays.E,
            )

    H = arrays.H - config.courant_number * curl_E(arrays.E) * arrays.inv_permeabilities

    for source in objects.sources:

        def _update():
            return source.update_H(
                H=H,
                inv_permittivities=arrays.inv_permittivities,
                inv_permeabilities=arrays.inv_permeabilities,
                time_step=time_step + 0.5,
                inverse=False,
            )

        H = jax.lax.cond(
            source._is_on_at_time_step_arr[time_step],
            _update,
            lambda: H,
        )

    if simulate_boundaries:
        for pml in objects.pml_objects:
            H = pml.update_H(
                H=H,
                boundary_state=boundary_states[pml.name],
                inverse_permeability=arrays.inv_permeabilities,
            )

    arrays = arrays.at["H"].set(H)
    if simulate_boundaries:
        arrays = arrays.aset("boundary_states", boundary_states)

    return arrays

fdtdx.fdtd.update.update_H_reverse(time_step, arrays, objects, config)

Reverse time step update for the magnetic field used in automatic differentiation.

Implements the inverse update step that transforms the electromagnetic field state from time step t+1 to time step t, leveraging the time-reversibility property of Maxwell's equations.

Parameters:

Name Type Description Default
time_step Array

Current simulation time step

required
arrays ArrayContainer

Container with E, H fields and material properties

required
objects ObjectContainer

Container with sources and other simulation objects

required
config SimulationConfig

Simulation configuration parameters

required

Returns:

Type Description
ArrayContainer

Updated ArrayContainer with reversed H field values

Source code in src/fdtdx/fdtd/update.py
def update_H_reverse(
    time_step: jax.Array,
    arrays: ArrayContainer,
    objects: ObjectContainer,
    config: SimulationConfig,
) -> ArrayContainer:
    """Reverse time step update for the magnetic field used in automatic differentiation.

    Implements the inverse update step that transforms the electromagnetic field state
    from time step t+1 to time step t, leveraging the time-reversibility property of
    Maxwell's equations.

    Args:
        time_step: Current simulation time step
        arrays: Container with E, H fields and material properties
        objects: Container with sources and other simulation objects
        config: Simulation configuration parameters

    Returns:
        Updated ArrayContainer with reversed H field values
    """
    """Reverse time step update for the magnetic field used in automatic differentiation.

    Implements the inverse update step that transforms the electromagnetic field state
    from time step t+1 to time step t, leveraging the time-reversibility property of
    Maxwell's equations.

    Args:
        time_step: Current simulation time step
        arrays: Container with E, H fields and material properties
        objects: Container with sources and other simulation objects
        config: Simulation configuration parameters

    Returns:
        Updated ArrayContainer with reversed H field values
    """
    H = arrays.H
    for source in objects.sources:

        def _update():
            return source.update_H(
                H,
                inv_permittivities=arrays.inv_permittivities,
                inv_permeabilities=arrays.inv_permeabilities,
                time_step=time_step + 0.5,
                inverse=True,
            )

        H = jax.lax.cond(
            source._is_on_at_time_step_arr[time_step],
            _update,
            lambda: H,
        )

    H = H + config.courant_number * curl_E(arrays.E) * arrays.inv_permeabilities

    arrays = arrays.at["H"].set(H)
    return arrays