Holey Waveguide Cavity
Analyze photonic crystal cavity modes formed by holes in a waveguide using Harminv
Holey Waveguide Cavity
This example simulates a photonic crystal cavity formed by introducing a defect in a periodic array of holes in a waveguide. The simulation finds resonant modes using Harminv analysis and computes transmission spectra.
Overview
Photonic crystal cavities are essential components for:
- High-Q resonators for sensing and filtering
- Cavity QED experiments
- Laser cavities with enhanced light-matter interaction
- Optical memories and slow-light devices
The holey waveguide cavity consists of a dielectric waveguide with a periodic array of air holes, where a defect (larger spacing) creates a localized cavity mode.
Simulation Parameters
| Parameter | Default Value | Description |
|---|---|---|
resolution | 20 | Pixels per μm |
eps | 13 | Dielectric constant of waveguide (Si) |
w | 1.2 | Width of waveguide |
r | 0.36 | Radius of air holes |
d | 1.4 | Defect spacing (normal = 1) |
N | 3 | Number of holes on each side |
fcen | 0.25 | Pulse center frequency |
df | 0.2 | Pulse frequency width |
Physical Setup
The cavity structure:
- Waveguide: High-index dielectric slab (ε=13, like silicon)
- Holes: Periodic array of air holes (r=0.36)
- Defect: Central region with larger hole spacing (d=1.4)
- PML: Absorbing boundaries at cell edges
The defect spacing d > 1 creates a cavity mode by introducing a "potential well" in the photonic band gap.
Python Code
"""
Holey Waveguide Cavity with OptixLog Integration
Simulates transmission through a cavity formed by holes in a waveguide,
and finds resonant modes using Harminv analysis.
Based on the Meep tutorial: holey-wvg-cavity.py
Reference: S. Fan et al., J. Opt. Soc. Am. B, 12 (7), 1267-1272 (1995)
"""
import os
import argparse
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 main(args):
"""Main simulation function for holey waveguide cavity."""
if not optixlog.is_master_process():
return
try:
run_type = "resonant_modes" if args.resonant_modes else "transmission"
client = optixlog.init(
api_key=api_key,
api_url=api_url,
project=project_name,
run_name=f"holey_waveguide_cavity_{run_type}",
config={
"simulation_type": "cavity",
"analysis_mode": run_type,
"num_holes": args.N,
},
create_project_if_not_exists=True
)
# Simulation parameters
resolution = 20
eps = 13 # dielectric constant of waveguide
w = 1.2 # width of waveguide
r = 0.36 # radius of holes
d = 1.4 # defect spacing
N = args.N # number of holes on either side
sy = args.sy # size of cell in y direction
pad = 2 # padding between last hole and PML
dpml = 1 # PML thickness
sx = 2 * (pad + dpml + N) + d - 1
fcen = args.fcen
df = args.df
# Log parameters
client.log(
step=0,
resolution=resolution,
waveguide_epsilon=eps,
waveguide_width=w,
hole_radius=r,
defect_spacing=d,
num_holes_per_side=N,
center_frequency=fcen,
frequency_width=df,
)
# Set up cell and geometry
cell = mp.Vector3(sx, sy, 0)
blk = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps))
geometry = [blk]
# Add holes
for i in range(N):
geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i)))
geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d / 2 + i))))
sim = mp.Simulation(
cell_size=cell,
geometry=geometry,
sources=[],
boundary_layers=[mp.PML(dpml)],
resolution=resolution,
)
if args.resonant_modes:
# Mode finding simulation
sim.sources.append(
mp.Source(
mp.GaussianSource(fcen, fwidth=df),
component=mp.Hz,
center=mp.Vector3()
)
)
sim.symmetries.append(mp.Mirror(mp.Y, phase=-1))
sim.symmetries.append(mp.Mirror(mp.X, phase=-1))
harminv = mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)
sim.run(
mp.at_beginning(mp.output_epsilon),
mp.after_sources(harminv),
until_after_sources=400,
)
modes = harminv.modes
client.log(step=1, num_modes_found=len(modes))
for i, mode in enumerate(modes):
client.log(
step=2 + i,
mode_number=i + 1,
frequency=float(mode.freq),
quality_factor=float(mode.Q) if mode.Q > 0 else 0,
)
else:
# Transmission spectrum simulation
sim.sources.append(
mp.Source(
mp.GaussianSource(fcen, fwidth=df),
component=mp.Ey,
center=mp.Vector3(-0.5 * sx + dpml),
size=mp.Vector3(0, w),
)
)
sim.symmetries.append(mp.Mirror(mp.Y, phase=-1))
freg = mp.FluxRegion(
center=mp.Vector3(0.5 * sx - dpml - 0.5),
size=mp.Vector3(0, 2 * w)
)
nfreq = 500
trans = sim.add_flux(fcen, df, nfreq, freg)
sim.run(
mp.at_beginning(mp.output_epsilon),
until_after_sources=mp.stop_when_fields_decayed(
50, mp.Ey, mp.Vector3(0.5 * sx - dpml - 0.5), 1e-3
),
)
flux_freqs = mp.get_flux_freqs(trans)
flux_data = mp.get_fluxes(trans)
client.log(
step=2,
num_frequencies=len(flux_freqs),
max_transmission=float(np.max(flux_data)),
)
except Exception as e:
print(f"Simulation Error: {e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-r", "--resonant_modes", action="store_true", default=False)
parser.add_argument("-N", type=int, default=3)
parser.add_argument("-sy", type=int, default=6)
parser.add_argument("-fcen", type=float, default=0.25)
parser.add_argument("-df", type=float, default=0.2)
args = parser.parse_args()
main(args)How to Run
# Set your OptixLog API key
export OPTIX_API_KEY="your_api_key_here"
# Find resonant modes with Harminv
python holey-wvg-cavity.py -r
# Compute transmission spectrum (default)
python holey-wvg-cavity.py
# Customize number of holes
python holey-wvg-cavity.py -N 5 -r
# Custom frequency range
python holey-wvg-cavity.py -fcen 0.3 -df 0.15Results and Analysis
Resonant Mode Analysis
When running with -r flag, Harminv identifies the cavity's resonant modes:
- Frequency: The resonant frequency in units of c/a
- Quality Factor (Q): Measure of energy confinement (higher = better)
- Decay Rate: Rate at which mode energy leaks from cavity
Typical results show a high-Q mode in the photonic band gap, with Q factors that increase with more holes (larger N).
Transmission Spectrum
The transmission spectrum shows:
- Band gap: Frequency range with near-zero transmission
- Cavity resonance: Sharp peak within the band gap
- Band edges: Transition regions with high transmission
OptixLog Metrics
For resonant mode analysis:
num_modes_found: Total resonant modes detectedfrequency: Mode frequencyquality_factor: Q factor for each mode
For transmission:
num_frequencies: Frequency points in spectrummax_transmission: Peak transmission value
The Q factor scales exponentially with the number of holes N. Use N=3-5 for quick tests, N=10+ for high-Q applications.
Physical Insights
Quality Factor Scaling
The cavity Q factor depends on:
- Number of holes N: Q ∝ exp(αN) for some constant α
- Hole radius r: Affects band gap width
- Defect spacing d: Tunes cavity frequency within band gap
Mode Profiles
The cavity supports modes with different symmetries:
- Odd-y modes: Field antisymmetric about waveguide axis
- Even-y modes: Field symmetric about waveguide axis
Related Examples
- Cavity Far-Field - Far-field radiation from cavities
- Ring Resonator - Alternative resonator geometry
- Metal Cavity LDOS - Local density of states analysis