ExamplesMeep Examples
Straight Waveguide
Basic straight waveguide transmission simulation
Straight Waveguide
This example demonstrates the fundamental simulation of electromagnetic wave propagation through a straight dielectric waveguide.
Beginner Level: This is an ideal starting point for learning Meep basics.
Physics Background
Waveguide Principle
A dielectric waveguide confines light through total internal reflection when:
$$ n_{core} > n_{cladding} $$
Guided modes satisfy the eigenvalue equation and propagate without radiation loss.
Key Parameters
- V-number: V = (2πr/λ)√(n₁² - n₂²)
- Single-mode: V < 2.405
- Multi-mode: V > 2.405
Complete Code
"""
Straight Waveguide Simulation with OptixLog Integration
Basic waveguide transmission analysis.
"""
import os
import meep as mp
import matplotlib
matplotlib.use("agg")
import matplotlib.pyplot as plt
import numpy as np
from optixlog import Optixlog
def main():
api_key = os.getenv("OPTIX_API_KEY", "your_api_key_here")
client = Optixlog(api_key=api_key)
project = client.project(name="MeepExamples", create_if_not_exists=True)
# Parameters
resolution = 10
cell_x = 16
cell_y = 8
dpml = 1.0
w = 1.0 # waveguide width
epsilon = 12.0
fcen = 0.15
df = 0.1
nfreq = 100
run = project.run(
name="straight_waveguide",
config={
"simulation_type": "straight_waveguide",
"resolution": resolution,
"cell_size": [cell_x, cell_y],
"waveguide_width": w,
"waveguide_epsilon": epsilon,
"center_frequency": fcen
}
)
run.log(step=0, resolution=resolution, waveguide_width=w)
cell = mp.Vector3(cell_x, cell_y)
pml_layers = [mp.PML(dpml)]
geometry = [
mp.Block(
center=mp.Vector3(),
size=mp.Vector3(mp.inf, w, mp.inf),
material=mp.Medium(epsilon=epsilon)
)
]
sources = [
mp.Source(
mp.GaussianSource(fcen, fwidth=df),
component=mp.Ez,
center=mp.Vector3(-cell_x/2 + dpml + 1, 0),
size=mp.Vector3(0, w)
)
]
sim = mp.Simulation(
cell_size=cell,
geometry=geometry,
sources=sources,
boundary_layers=pml_layers,
resolution=resolution
)
# Flux monitors
input_fr = mp.FluxRegion(
center=mp.Vector3(-cell_x/2 + dpml + 2, 0),
size=mp.Vector3(0, 2*w)
)
input_flux = sim.add_flux(fcen, df, nfreq, input_fr)
output_fr = mp.FluxRegion(
center=mp.Vector3(cell_x/2 - dpml - 1, 0),
size=mp.Vector3(0, 2*w)
)
output_flux = sim.add_flux(fcen, df, nfreq, output_fr)
print("⚡ Running simulation...")
pt = mp.Vector3(cell_x/2 - dpml - 1, 0)
sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, pt, 1e-3))
# Extract results
input_power = mp.get_fluxes(input_flux)
output_power = mp.get_fluxes(output_flux)
freqs = mp.get_flux_freqs(input_flux)
transmission = [output_power[i] / input_power[i]
for i in range(len(freqs)) if input_power[i] > 0]
wavelengths = [1/f for f in freqs[:len(transmission)]]
# Log metrics
run.log(step=1,
max_transmission=float(max(transmission)),
avg_transmission=float(np.mean(transmission)))
# Create plots
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# Transmission spectrum
axes[0, 0].plot(wavelengths, transmission, 'b-', linewidth=2)
axes[0, 0].set_xlabel('Wavelength (μm)')
axes[0, 0].set_ylabel('Transmission')
axes[0, 0].set_title('Transmission Spectrum')
axes[0, 0].grid(True, alpha=0.3)
axes[0, 0].set_ylim(0, 1.1)
# Transmission vs frequency
axes[0, 1].plot(freqs[:len(transmission)], transmission, 'r-', linewidth=2)
axes[0, 1].set_xlabel('Frequency (c/a)')
axes[0, 1].set_ylabel('Transmission')
axes[0, 1].set_title('Transmission vs Frequency')
axes[0, 1].grid(True, alpha=0.3)
# Field distribution
ez_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Ez)
im1 = axes[1, 0].imshow(np.real(ez_data).T, cmap='RdBu', origin='lower')
axes[1, 0].set_title('Ez Field')
plt.colorbar(im1, ax=axes[1, 0])
# Structure
eps_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Dielectric)
im2 = axes[1, 1].imshow(eps_data.T, cmap='binary', origin='lower')
axes[1, 1].set_title('Waveguide Structure (ε)')
plt.colorbar(im2, ax=axes[1, 1])
plt.tight_layout()
run.log_matplotlib("waveguide_analysis", fig)
plt.close(fig)
run.log(step=2, simulation_completed=True)
print(f"📊 Transmission: {np.mean(transmission):.4f}")
print(f"\n✅ Simulation complete!")
if __name__ == "__main__":
main()Key Concepts
Simple Geometry
geometry = [
mp.Block(
center=mp.Vector3(),
size=mp.Vector3(mp.inf, w, mp.inf),
material=mp.Medium(epsilon=12)
)
]Line Source
sources = [
mp.Source(
mp.GaussianSource(fcen, fwidth=df),
component=mp.Ez,
center=mp.Vector3(x, 0),
size=mp.Vector3(0, w) # Line in y-direction
)
]Expected Results
High Transmission
A straight waveguide should have:
- Transmission > 95% (ideally ~100%)
- Flat spectrum across bandwidth
- Clean mode profile
Loss Sources
Any loss comes from:
- Numerical dispersion
- PML absorption
- Mode mismatch at source
OptixLog Integration
Logged Metrics
| Metric | Description |
|---|---|
waveguide_width | Core width |
max_transmission | Peak T value |
avg_transmission | Mean T value |
Logged Plots
- waveguide_analysis — 4-panel comprehensive view
Variations
Different Polarizations
Change component=mp.Ez to mp.Hz for TM polarization.
Multi-mode Waveguide
Increase width w for higher-order modes.
Different Materials
Try silicon (ε=12) vs silicon nitride (ε=4).