ExamplesMeep Examples

Metal Cavity LDOS

Compute local density of states in a metal cavity and compare with Purcell formula

Metal Cavity LDOS

This example computes the local density of states (LDOS) in a 2D metal cavity and compares the results with the analytical Purcell formula: LDOS ∝ 2Q/(πωV).

Overview

The local density of states quantifies how efficiently an emitter couples to the electromagnetic environment:

  • Purcell enhancement: Spontaneous emission rate modification in cavities
  • Quantum optics: Cavity QED and light-matter interaction
  • Nanophotonics: Plasmonic enhancement of emission
  • Sensing: LDOS changes indicate local environment modifications

Simulation Parameters

ParameterDefault ValueDescription
resolution50Pixels per μm
sxy2Cavity inner dimension
dpml1PML thickness
a1Cavity size parameter
t0.1Metal wall thickness
w0.2-0.5Aperture width range

Physical Setup

The cavity structure:

  1. Metal cavity: Perfect electric conductor (PEC) walls
  2. Air interior: Resonant volume
  3. Aperture: Variable-width opening that controls Q factor
  4. Point source: Ez-polarized source at cavity center

The LDOS is directly related to the Purcell factor: F = LDOS/LDOS₀, where LDOS₀ is the free-space value.

Python Code

"""
Metal Cavity LDOS Simulation with OptixLog Integration

Computes the local density of states (LDOS) in a metal cavity
and compares with Purcell formula 2Q/(πωV).

Based on the Meep tutorial: metal-cavity-ldos.py
"""

import os
import math
import optixlog
import meep as mp
import matplotlib
matplotlib.use("agg")
import matplotlib.pyplot as plt
import numpy as np

api_key = os.getenv("OPTIX_API_KEY", "")
api_url = os.getenv("OPTIX_API_URL", "https://optixlog.com")
project_name = os.getenv("OPTIX_PROJECT", "MeepExamples")


def metal_cavity(w, client=None, step_offset=0):
    """
    Compute LDOS for a metal cavity with aperture width w.
    """
    resolution = 50
    sxy = 2
    dpml = 1
    sxy_total = sxy + 2 * dpml
    cell = mp.Vector3(sxy_total, sxy_total)
    
    pml_layers = [mp.PML(dpml)]
    
    a = 1
    t = 0.1
    geometry = [
        mp.Block(mp.Vector3(a + 2 * t, a + 2 * t, mp.inf), material=mp.metal),
        mp.Block(mp.Vector3(a, a, mp.inf), material=mp.air),
    ]
    
    # Add aperture
    geometry.append(
        mp.Block(
            center=mp.Vector3(a / 2),
            size=mp.Vector3(2 * t, w, mp.inf),
            material=mp.air
        )
    )
    
    fcen = math.sqrt(0.5) / a
    df = 0.2
    
    sources = [
        mp.Source(
            src=mp.GaussianSource(fcen, fwidth=df),
            component=mp.Ez,
            center=mp.Vector3()
        )
    ]
    
    symmetries = [mp.Mirror(mp.Y)]
    
    sim = mp.Simulation(
        cell_size=cell,
        geometry=geometry,
        boundary_layers=pml_layers,
        sources=sources,
        symmetries=symmetries,
        resolution=resolution,
    )
    
    # Find resonance with Harminv
    h = mp.Harminv(mp.Ez, mp.Vector3(), fcen, df)
    sim.run(mp.after_sources(h), until_after_sources=500)
    
    m = h.modes[0]
    f = m.freq
    Q = m.Q
    Vmode = 0.25 * a * a
    ldos_formula = Q / Vmode / (2 * math.pi * f * math.pi * 0.5)
    
    sim.reset_meep()
    
    # Compute LDOS directly
    T = 2 * Q * (1 / f)
    sim.run(mp.dft_ldos(f, 0, 1), until_after_sources=T)
    ldos_meep = sim.ldos_data[0]
    
    return ldos_formula, ldos_meep, f, Q


def main():
    """Main simulation function for metal cavity LDOS."""
    
    if not optixlog.is_master_process():
        return
    
    try:
        client = optixlog.init(
            api_key=api_key,
            api_url=api_url,
            project=project_name,
            run_name="metal_cavity_ldos",
            config={
                "simulation_type": "ldos",
                "description": "Metal cavity LDOS analysis",
            },
            create_project_if_not_exists=True
        )
        
        client.log(
            step=0,
            resolution=50,
            cavity_size=1.0,
            metal_thickness=0.1,
        )
        
        # Aperture widths to simulate
        ws = np.arange(0.2, 0.5, 0.1)
        ldos_formula = np.zeros(len(ws))
        ldos_meep = np.zeros(len(ws))
        Q_factors = np.zeros(len(ws))
        
        for j, w in enumerate(ws):
            ldos_formula[j], ldos_meep[j], _, Q_factors[j] = metal_cavity(w)
            
            client.log(
                step=1 + j,
                aperture_width=float(w),
                Q_factor=float(Q_factors[j]),
                ldos_formula=float(ldos_formula[j]),
                ldos_meep=float(ldos_meep[j]),
            )
        
        client.log(
            step=100,
            simulation_completed=True,
            max_Q=float(np.max(Q_factors)),
            max_ldos=float(np.max(ldos_meep))
        )
        
    except Exception as e:
        print(f"Simulation Error: {e}")


if __name__ == "__main__":
    main()

How to Run

# Set your OptixLog API key
export OPTIX_API_KEY="your_api_key_here"

# Run the LDOS simulation
python metal-cavity-ldos.py

Results and Analysis

LDOS vs Aperture Size

The simulation compares:

  1. Purcell formula: LDOS = 2Q/(πωV)
  2. FDTD calculation: Direct LDOS from Meep

As aperture width decreases:

  • Q factor increases (better confinement)
  • LDOS increases proportionally
  • Agreement between formula and simulation improves

Quality Factor

The Q factor depends on aperture width:

  • Large aperture: Low Q, fast decay
  • Small aperture: High Q, long lifetime
  • Closed cavity: Q → ∞ (ideal case)

OptixLog Metrics

For each aperture width:

  • aperture_width: Current aperture size
  • Q_factor: Cavity quality factor
  • ldos_formula: Analytical Purcell prediction
  • ldos_meep: FDTD-computed LDOS
  • ldos_ratio: Agreement between methods

The LDOS computation requires running for time T ≈ 2Q/ω to capture the cavity decay accurately.

Physical Insights

Purcell Effect

The Purcell factor describes emission rate enhancement:

  • F = (3/4π²)(λ/n)³(Q/V)
  • High Q and small V maximize enhancement
  • Practical limits from fabrication and material losses

Mode Volume

The effective mode volume V:

  • Measures spatial confinement of the mode
  • Smaller V → stronger light-matter interaction
  • Defined by field energy distribution

On this page