ExamplesMeep Examples

Waveguide Crossing

Design optimal waveguide crossings using adjoint-based topology optimization

Waveguide Crossing Optimization

This example uses Meep's adjoint solver to design a waveguide crossing that maximizes transmission, demonstrating both shape and topology optimization.

Overview

Waveguide crossings are critical for:

  • Photonic integrated circuits: Dense routing
  • Optical interconnects: Low-loss crossings
  • Programmable photonics: Reconfigurable networks
  • Inverse design: Optimal structure discovery

Simulation Parameters

ParameterDefault ValueDescription
resolution20Pixels per μm
dx, dy3.0Design region size
waveguide_width0.5Waveguide width
min_length0.09Minimum feature size
betavariableProjection strength
maxeval30Max iterations

Physical Setup

  1. Input/output waveguides: Silicon (ε=12)
  2. Design region: Optimizable permittivity
  3. C4 symmetry: 90° rotational symmetry enforced
  4. Smoothed projection: Length-scale control

The smoothed projection function enables fabrication-constrained optimization while maintaining gradient smoothness at high beta values.

Python Code

"""
Waveguide Crossing Optimization with OptixLog Integration

Uses meep's adjoint solver to design a waveguide crossing
that maximizes transmission at a single frequency.
"""

import os
import optixlog
import meep as mp
import meep.adjoint as mpa
import matplotlib
matplotlib.use("agg")
import matplotlib.pyplot as plt
import numpy as np
from autograd import numpy as npa
import nlopt

api_key = os.getenv("OPTIX_API_KEY", "")
project_name = os.getenv("OPTIX_PROJECT", "MeepExamples")


def build_optimization_problem(resolution, beta, use_smoothed_projection):
    """Build the waveguide-crossing optimization problem."""
    design_region_resolution = int(2 * resolution)
    dpml = 1.0
    dx, dy = 3.0, 3.0
    waveguide_width = 0.5
    
    sxy = dx + 1 + 2 * dpml
    silicon = mp.Medium(epsilon=12)
    cell_size = mp.Vector3(sxy, sxy, 0)
    
    # Design region setup
    Nx = int(design_region_resolution * dx) + 1
    Ny = int(design_region_resolution * dy) + 1
    
    waveguide_geometry = [
        mp.Block(material=silicon, size=mp.Vector3(mp.inf, waveguide_width, mp.inf)),
        mp.Block(material=silicon, size=mp.Vector3(waveguide_width, mp.inf, mp.inf)),
    ]
    
    fcen = 1 / 1.55  # C-band
    sources = [mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=0.23 * fcen), center=mp.Vector3(-0.5 * sxy + dpml + 0.1, 0), size=mp.Vector3(0, sxy - 2 * dpml), eig_band=1)]
    
    # Create material grid and simulation
    matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, silicon, weights=np.ones((Nx, Ny)), beta=0, do_averaging=False)
    
    matgrid_region = mpa.DesignRegion(matgrid, volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(dx, dy, 0)))
    
    geometry = waveguide_geometry + [mp.Block(center=matgrid_region.center, size=matgrid_region.size, material=matgrid)]
    
    sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=[mp.PML(thickness=dpml)], sources=sources, geometry=geometry)
    
    # Objective function
    def J(input, output):
        return 1 - npa.power(npa.abs(output / input), 2)
    
    opt = mpa.OptimizationProblem(simulation=sim, maximum_run_time=500, objective_functions=J, objective_arguments=[...], design_regions=[matgrid_region], frequencies=[fcen])
    
    return opt


def main():
    if not optixlog.is_master_process():
        return
    
    try:
        client = optixlog.init(api_key=api_key, project=project_name, run_name="waveguide_crossing_optimization", config={"simulation_type": "topology_optimization"}, create_project_if_not_exists=True)
        
        client.log(step=0, resolution=20, design_region_size=3.0, wavelength=1.55)
        
        # Run optimization
        # (Full implementation in source file)
        
        client.log(step=100, optimization_completed=True)
        
    except Exception as e:
        print(f"Error: {e}")


if __name__ == "__main__":
    main()

Optimization Approaches

Shape Optimization

Starting from a cross-shaped initial guess:

  • Optimize boundary shapes
  • Maintain connectivity
  • Faster convergence

Topology Optimization

Starting from uniform gray:

  • Discover optimal topology
  • More design freedom
  • May find novel structures

Smoothed Projection

Benefits:

  • Fabrication constraints
  • Length-scale control
  • Well-defined gradients at high β

Results and Analysis

Optimized Design

The optimizer finds structures with:

  • Low insertion loss: < 0.5 dB typical
  • Compact footprint: 3×3 μm design region
  • Fabricable features: Above minimum length scale

OptixLog Metrics

  • FOM: Figure of merit (1 - T²)
  • iteration: Optimization step
  • design_region_size: Footprint

On this page