Skip to content

Field and Efficiency Metrics

Field Metrics

fdtdx.core.physics.metrics.compute_energy(E, H, inv_permittivity, inv_permeability)

Computes the total electromagnetic energy density of the field.

Parameters:

Name Type Description Default
E Array

Electric field array with shape (3, nx, ny, nz)

required
H Array

Magnetic field array with shape (3, nx, ny, nz)

required
inv_permittivity Array

Inverse of the electric permittivity array

required
inv_permeability Array

Inverse of the magnetic permeability array

required

Returns:

Type Description
Array

Total energy density array with shape (nx, ny, nz)

Source code in src/fdtdx/core/physics/metrics.py
def compute_energy(
    E: jax.Array,
    H: jax.Array,
    inv_permittivity: jax.Array,
    inv_permeability: jax.Array,
) -> jax.Array:
    """Computes the total electromagnetic energy density of the field.

    Args:
        E: Electric field array with shape (3, nx, ny, nz)
        H: Magnetic field array with shape (3, nx, ny, nz)
        inv_permittivity: Inverse of the electric permittivity array
        inv_permeability: Inverse of the magnetic permeability array

    Returns:
        Total energy density array with shape (nx, ny, nz)
    """
    abs_E = jnp.sum(jnp.square(E), axis=0)
    energy_E = 0.5 * (1 / inv_permittivity) * abs_E

    abs_H = jnp.sum(jnp.square(H), axis=0)
    energy_H = 0.5 * (1 / inv_permeability) * abs_H

    total_energy = energy_E + energy_H
    return total_energy

fdtdx.core.physics.metrics.normalize_by_energy(E, H, inv_permittivity, inv_permeability)

Normalizes electromagnetic fields by their total energy.

Parameters:

Name Type Description Default
E Array

Electric field array with shape (3, nx, ny, nz)

required
H Array

Magnetic field array with shape (3, nx, ny, nz)

required
inv_permittivity Array

Inverse of the electric permittivity array

required
inv_permeability Array

Inverse of the magnetic permeability array

required

Returns:

Type Description
tuple[Array, Array]

Tuple of (normalized E field, normalized H field)

Source code in src/fdtdx/core/physics/metrics.py
def normalize_by_energy(
    E: jax.Array,
    H: jax.Array,
    inv_permittivity: jax.Array,
    inv_permeability: jax.Array,
) -> tuple[jax.Array, jax.Array]:
    """Normalizes electromagnetic fields by their total energy.

    Args:
        E: Electric field array with shape (3, nx, ny, nz)
        H: Magnetic field array with shape (3, nx, ny, nz)
        inv_permittivity: Inverse of the electric permittivity array
        inv_permeability: Inverse of the magnetic permeability array

    Returns:
        Tuple of (normalized E field, normalized H field)
    """
    total_energy = compute_energy(
        E=E,
        H=H,
        inv_permittivity=inv_permittivity,
        inv_permeability=inv_permeability,
    )
    energy_root = jnp.sqrt(jnp.sum(total_energy))
    norm_E = E / energy_root
    norm_H = H / energy_root
    return norm_E, norm_H

fdtdx.core.physics.metrics.poynting_flux(E, H)

Calculates the Poynting vector (energy flux) from E and H fields.

Parameters:

Name Type Description Default
E Array

Electric field array with shape (3, nx, ny, nz)

required
H Array

Magnetic field array with shape (3, nx, ny, nz)

required

Returns:

Type Description
Array

Poynting vector array with shape (3, nx, ny, nz) representing

Array

energy flux in each direction

Source code in src/fdtdx/core/physics/metrics.py
def poynting_flux(E: jax.Array, H: jax.Array) -> jax.Array:
    """Calculates the Poynting vector (energy flux) from E and H fields.

    Args:
        E: Electric field array with shape (3, nx, ny, nz)
        H: Magnetic field array with shape (3, nx, ny, nz)

    Returns:
        Poynting vector array with shape (3, nx, ny, nz) representing
        energy flux in each direction
    """
    return jnp.cross(
        jnp.conj(E),
        H,
        axisa=0,
        axisb=0,
        axisc=0,
    )

Efficiency Metrics

fdtdx.core.physics.losses.metric_efficiency(detector_states, in_names, out_names, metric_name)

Calculate efficiency metrics between input and output detectors.

Computes efficiency ratios between input and output detectors by comparing their metric values (e.g. energy, power). For each input-output detector pair, calculates the ratio of output/input metric values.

Parameters:

Name Type Description Default
detector_states dict[str, dict[str, Array]]

Dictionary mapping detector names to their state dictionaries, which contain metric values as JAX arrays

required
in_names Sequence[str]

Names of input detectors to use as reference

required
out_names Sequence[str]

Names of output detectors to compare against inputs

required
metric_name str

Name of the metric to compare between detectors (e.g. "energy")

required

Returns:

Type Description
tuple[Array, dict[str, Any]]

tuple containing: - jax.Array: Mean efficiency across all input-output pairs - dict: Additional info including individual metric values and efficiencies with keys like: "{detector}{metric}" for raw metric values "{out}{by}_{in}_efficiency" for individual efficiency ratios

Source code in src/fdtdx/core/physics/losses.py
def metric_efficiency(
    detector_states: dict[str, dict[str, jax.Array]],
    in_names: Sequence[str],
    out_names: Sequence[str],
    metric_name: str,
) -> tuple[jax.Array, dict[str, Any]]:
    """Calculate efficiency metrics between input and output detectors.

    Computes efficiency ratios between input and output detectors by comparing their
    metric values (e.g. energy, power). For each input-output detector pair, calculates
    the ratio of output/input metric values.

    Args:
        detector_states: Dictionary mapping detector names to their state dictionaries,
            which contain metric values as JAX arrays
        in_names: Names of input detectors to use as reference
        out_names: Names of output detectors to compare against inputs
        metric_name: Name of the metric to compare between detectors (e.g. "energy")

    Returns:
        tuple containing:
            - jax.Array: Mean efficiency across all input-output pairs
            - dict: Additional info including individual metric values and efficiencies
              with keys like:
                "{detector}_{metric}" for raw metric values
                "{out}_{by}_{in}_efficiency" for individual efficiency ratios
    """
    efficiencies, info = [], {}
    for in_name in in_names:
        in_value = jax.lax.stop_gradient(detector_states[in_name][metric_name].mean())
        info[f"{in_name}_{metric_name}"] = in_value
        for out_name in out_names:
            out_value = detector_states[out_name][metric_name].mean()
            eff = jnp.where(in_value == 0, 0, out_value / in_value)
            efficiencies.append(eff)
            info[f"{out_name}_{metric_name}"] = out_value
            info[f"{out_name}_by_{in_name}_efficiency"] = eff
    objective = jnp.mean(jnp.asarray(efficiencies))
    return objective, info