Source code for fdtdx.objects.boundaries.pmc

import jax
from typing_extensions import override

from fdtdx.colors import XKCD_ORANGE, Color
from fdtdx.core.jax.pytrees import autoinit, frozen_field
from fdtdx.objects.boundaries.boundary import BaseBoundary


[docs] @autoinit class PerfectMagneticConductor(BaseBoundary): """Implements perfect magnetic conductor (PMC) boundary conditions. PMC enforces H_tangential = 0 at the boundary wall. Unlike PEC, this requires explicit zeroing of tangential H components after each H field update, because the Yee grid naturally terminates as PEC (zero E_tangential), not PMC. Component zeroing per axis: - PMC on x-face: zero Hy, Hz (tangential to x) - PMC on y-face: zero Hx, Hz (tangential to y) - PMC on z-face: zero Hx, Hy (tangential to z) """ #: RGB color tuple for visualization. Defaults to orange. color: Color | None = frozen_field(default=XKCD_ORANGE) @property @override def descriptive_name(self) -> str: """Gets a human-readable name describing this PMC boundary's location. Returns: str: Description like "min_x" or "max_z" indicating position """ axis_str = "x" if self.axis == 0 else "y" if self.axis == 1 else "z" direction_str = "min" if self.direction == "-" else "max" return f"{direction_str}_{axis_str}" @property @override def thickness(self) -> int: """Gets the thickness of the PMC boundary layer in grid points. Returns: int: Number of grid points in the boundary layer (always 1 for PMC) """ return 1 @property def tangential_components(self) -> tuple[int, int]: """Gets the indices of H field components tangential to this boundary. Returns: tuple[int, int]: Indices of the two tangential components (0=Hx, 1=Hy, 2=Hz) """ if self.axis == 0: return (1, 2) # Hy, Hz tangential to x-face elif self.axis == 1: return (0, 2) # Hx, Hz tangential to y-face else: return (0, 1) # Hx, Hy tangential to z-face
[docs] @override def apply_post_H_update(self, H: jax.Array) -> jax.Array: """Zeros tangential H components at this PMC boundary face.""" comp1, comp2 = self.tangential_components sx, sy, sz = self.grid_slice H = H.at[comp1, sx, sy, sz].set(0) H = H.at[comp2, sx, sy, sz].set(0) return H