Boundary Conditions

Boundary conditions define how electromagnetic fields behave at the edges of your simulation domain. Proper boundary conditions are crucial for accurate FDTD simulations.

Overview

Prismo supports several types of boundary conditions:

  1. PML (Perfectly Matched Layer) - Absorbing boundaries (most common)

  2. Periodic Boundaries - For periodic structures

  3. Perfect Electric Conductor (PEC) - Metallic boundaries

  4. Perfect Magnetic Conductor (PMC) - Magnetic walls

  5. Mode Ports - Waveguide mode injection/extraction

PML (Perfectly Matched Layer)

PML boundaries absorb outgoing waves with minimal reflection. They’re the default choice for most simulations.

Basic Usage

from prismo import Simulation

sim = Simulation(
    size=(10e-6, 10e-6, 0.0),
    resolution=40e6,
    boundary_conditions='pml',  # Use PML
    pml_layers=10,               # 10 grid points thick
)

How PML Works

PML creates an artificial absorbing layer around your simulation domain:

┌────────────────────────────────┐
│ PML Layer (absorbing)          │
│  ┌──────────────────────────┐  │
│  │                          │  │
│  │  Simulation Domain       │  │
│  │  (physical region)       │  │
│  │                          │  │
│  └──────────────────────────┘  │
│                                │
└────────────────────────────────┘

Advanced PML Configuration

Fine-tune PML performance:

from prismo.boundaries import CPML, PMLParams

# Custom PML parameters
pml_params = PMLParams(
    layers=12,           # Number of PML layers
    sigma_max=1.5,       # Maximum conductivity
    kappa_max=15.0,      # Maximum kappa value
    alpha_max=0.05,      # Maximum alpha (for better absorption at grazing incidence)
    polynomial_order=3,  # Polynomial grading order
)

# Apply to simulation
sim = Simulation(
    size=(10e-6, 10e-6, 0.0),
    resolution=40e6,
    boundary_conditions='pml',
    pml_params=pml_params,
)

PML Best Practices

Thickness:

  • Minimum: 8 layers

  • Recommended: 10-12 layers

  • For high-angle reflections: 15-20 layers

When PML works well:

  • Normal or near-normal incidence

  • Broadband sources

  • Open boundaries (radiation problems)

When to use more layers:

  • Grazing incidence (waves nearly parallel to boundary)

  • Very low reflectivity requirements (< -40 dB)

  • Lossy materials near boundaries

Verifying PML Performance

Check for reflections:

# Add a field monitor near the boundary
edge_monitor = FieldMonitor(
    center=(sim.size[0]*0.45, 0.0, 0.0),  # Near edge
    size=(0.1e-6, sim.size[1], 0.0),
    components=['Ex', 'Ey', 'Ez'],
    time_domain=True,
)
sim.add_monitor(edge_monitor)

# After simulation, check for reflections
field_data = edge_monitor.get_time_data('Ex')
if np.max(np.abs(field_data[-100:])) > 0.01 * np.max(np.abs(field_data)):
    print("Warning: Significant reflections from PML")

Periodic Boundaries

For structures that repeat in space (photonic crystals, gratings, etc.):

sim = Simulation(
    size=(10e-6, 10e-6, 0.0),
    resolution=40e6,
    boundary_conditions={
        'x': 'periodic',  # Periodic in x
        'y': 'pml',       # PML in y
    },
)

Bloch Boundaries

For angled incidence in periodic structures:

# Periodic boundary with Bloch wave vector
kx = 2 * np.pi / (10e-6)  # Wave vector in x

sim = Simulation(
    size=(10e-6, 10e-6, 0.0),
    resolution=40e6,
    boundary_conditions={
        'x': ('bloch', kx),  # Bloch periodic
        'y': 'pml',
    },
)

Requirements for Periodic Boundaries

  1. Symmetry: Structure must actually be periodic

  2. Source placement: Sources must respect periodicity

  3. Grid alignment: Period must be integer number of grid cells

Perfect Conductors

PEC (Perfect Electric Conductor)

Metallic boundaries where tangential E = 0:

sim = Simulation(
    size=(10e-6, 10e-6, 0.0),
    resolution=40e6,
    boundary_conditions={
        'x': 'pec',  # Metal walls in x
        'y': 'pec',  # Metal walls in y
    },
)

Use cases:

  • Metallic cavities

  • Waveguides with metal walls

  • Symmetry planes for TE polarization

PMC (Perfect Magnetic Conductor)

Magnetic walls where tangential H = 0:

sim = Simulation(
    size=(10e-6, 10e-6, 0.0),
    resolution=40e6,
    boundary_conditions={
        'x': 'pmc',  # Magnetic walls
        'y': 'pml',
    },
)

Use cases:

  • Symmetry planes for TM polarization

  • Certain theoretical models

Symmetry Boundaries

Exploit symmetry to reduce computational domain:

Example: Symmetric Waveguide

# Only simulate half the structure
sim = Simulation(
    size=(10e-6, 5e-6, 0.0),  # Half height
    resolution=40e6,
    boundary_conditions={
        'x': 'pml',
        'y_min': 'pec',  # Symmetry plane at y=0
        'y_max': 'pml',
    },
)
Full structure:        Simulated half:
┌──────────┐          ┌──────────┐
│          │          │          │
│   Core   │          │   Core   │
│          │          ├══════════┤ ← PEC symmetry plane
│   Core   │
│          │
└──────────┘

Mixed Boundaries

Different boundaries on different sides:

sim = Simulation(
    size=(10e-6, 10e-6, 5e-6),
    resolution=40e6,
    is_3d=True,
    boundary_conditions={
        'x_min': 'pml',
        'x_max': 'pml',
        'y_min': 'pml',
        'y_max': 'pml',
        'z_min': 'pec',      # Metal substrate
        'z_max': 'pml',      # Open top
    },
)

Choosing the Right Boundary

Scenario

Recommended Boundary

Open space radiation

PML

Waveguide ports

Mode ports

Photonic crystal

Periodic or Bloch

Metal cavity

PEC

Symmetric structure

PEC/PMC (symmetry)

Substrate simulation

PEC (bottom), PML (sides/top)

Common Issues and Solutions

High Reflections from PML

Problem: Fields reflecting back into simulation domain

Solutions:

  1. Increase PML layers (try 15-20)

  2. Adjust PML parameters (increase sigma_max)

  3. Ensure sources are not too close to PML

  4. Check for evanescent waves reaching PML

# Better PML for grazing incidence
pml_params = PMLParams(
    layers=20,
    sigma_max=2.0,
    alpha_max=0.1,  # Helps with grazing incidence
)

Periodic Boundary Phase Errors

Problem: Incorrect results with periodic boundaries

Solutions:

  1. Verify structure is truly periodic

  2. Check grid alignment with period

  3. Ensure source respects periodicity

# Verify period is integer grid cells
period = 5e-6
dx = 1.0 / sim.resolution
cells_per_period = period / dx
assert abs(cells_per_period - round(cells_per_period)) < 1e-6, \
    "Period must be integer number of cells"

PEC/PMC Polarization Mismatch

Problem: Using wrong symmetry boundary for polarization

Solution: Match boundary to polarization

For TE polarization (E tangential to symmetry plane):

  • Use PEC symmetry

For TM polarization (H tangential to symmetry plane):

  • Use PMC symmetry

Performance Considerations

Computational Cost

Boundary condition performance (fastest to slowest):

  1. PEC/PMC (trivial, no extra cost)

  2. Periodic (minimal extra cost)

  3. PML (moderate, ~10-20% overhead)

Memory Usage

  • PEC/PMC: No extra memory

  • Periodic: No extra memory

  • PML: Requires extra field storage (~10-20% more memory)

Validation Tests

PML Reflection Test

def test_pml_reflectivity(sim, source_amplitude=1.0):
    """Measure PML reflectivity."""
    # Place monitor at simulation center
    center_monitor = FieldMonitor(
        center=(0.0, 0.0, 0.0),
        size=(0.1e-6, 0.1e-6, 0.0),
        components=['Ex'],
        time_domain=True,
    )

    # Run simulation
    sim.run(100e-15)

    # Get field at late times (after reflections would arrive)
    Ex_data = center_monitor.get_time_data('Ex')[0]
    late_time_field = Ex_data[-100:]

    # Reflectivity
    reflectivity = np.max(np.abs(late_time_field)) / source_amplitude
    reflectivity_db = 20 * np.log10(reflectivity)

    print(f"PML reflectivity: {reflectivity_db:.1f} dB")

    return reflectivity_db

Good PML: < -40 dB Acceptable: -30 to -40 dB Poor: > -30 dB

See Also