ExamplesMeep Examples

Quick Start

Your first Meep simulation with OptixLog integration

Quick Start: Your First Meep + OptixLog Simulation

This guide walks you through creating your first photonic simulation using Meep with OptixLog integration for experiment tracking.

Time Required: ~15 minutes


Prerequisites

Before starting, ensure you have:

  1. Python 3.8+ installed
  2. Meep installed (installation guide)
  3. OptixLog SDK installed
  4. API Key from optixlog.com
pip install meep optixlog matplotlib numpy
conda install -c conda-forge meep
pip install optixlog matplotlib numpy

Set Your API Key

export OPTIX_API_KEY="your_api_key_here"

Your First Simulation

Create the Simulation File

Create a file called my_first_simulation.py:

"""
My First Meep + OptixLog Simulation

A simple waveguide transmission simulation.
"""

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():
    # ========== 1. Initialize OptixLog ==========
    api_key = os.getenv("OPTIX_API_KEY", "your_api_key_here")
    
    client = Optixlog(api_key=api_key)
    project = client.project(name="MyFirstProject", create_if_not_exists=True)
    
    run = project.run(
        name="waveguide_simulation",
        config={
            "simulation_type": "waveguide",
            "resolution": 10,
            "wavelength": 1.55,
            "waveguide_width": 1.0,
            "waveguide_epsilon": 12.0
        }
    )
    
    print(f"🚀 Starting simulation - Run ID: {run.run_id}")
    
    # ========== 2. Define Simulation Parameters ==========
    resolution = 10      # pixels per unit length
    cell_x = 16          # cell size in x
    cell_y = 8           # cell size in y
    dpml = 1.0           # PML thickness
    w = 1.0              # waveguide width
    epsilon = 12.0       # waveguide permittivity
    fcen = 0.15          # center frequency
    df = 0.1             # frequency width
    
    # Log parameters
    run.log(step=0,
            resolution=resolution,
            cell_x=cell_x,
            cell_y=cell_y,
            waveguide_width=w,
            waveguide_epsilon=epsilon,
            center_frequency=fcen)
    
    # ========== 3. Create Meep Simulation ==========
    cell = mp.Vector3(cell_x, cell_y)
    pml_layers = [mp.PML(dpml)]
    
    # Simple straight waveguide
    geometry = [
        mp.Block(
            center=mp.Vector3(),
            size=mp.Vector3(mp.inf, w, mp.inf),
            material=mp.Medium(epsilon=epsilon)
        )
    ]
    
    # Gaussian pulse source
    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
    )
    
    # ========== 4. Add Monitors ==========
    # Input flux monitor
    input_flux = sim.add_flux(
        fcen, df, 50,
        mp.FluxRegion(
            center=mp.Vector3(-cell_x/2 + dpml + 2, 0),
            size=mp.Vector3(0, 2*w)
        )
    )
    
    # Output flux monitor
    output_flux = sim.add_flux(
        fcen, df, 50,
        mp.FluxRegion(
            center=mp.Vector3(cell_x/2 - dpml - 1, 0),
            size=mp.Vector3(0, 2*w)
        )
    )
    
    # ========== 5. Run Simulation ==========
    print("⚡ Running simulation...")
    
    # Run until fields decay
    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))
    
    run.log(step=1, simulation_phase="completed")
    
    # ========== 6. Extract Results ==========
    input_power = mp.get_fluxes(input_flux)
    output_power = mp.get_fluxes(output_flux)
    freqs = mp.get_flux_freqs(input_flux)
    
    # Calculate transmission
    transmission = [output_power[i] / input_power[i] 
                   for i in range(len(freqs))]
    wavelengths = [1/f for f in freqs]
    
    # Log key metrics
    max_transmission = max(transmission)
    avg_transmission = np.mean(transmission)
    
    run.log(step=2,
            max_transmission=max_transmission,
            avg_transmission=avg_transmission,
            num_frequencies=len(freqs))
    
    print(f"📊 Max transmission: {max_transmission:.4f}")
    print(f"📊 Avg transmission: {avg_transmission:.4f}")
    
    # ========== 7. Create and Log Plots ==========
    
    # Plot 1: Transmission spectrum
    fig1, ax1 = plt.subplots(figsize=(10, 6))
    ax1.plot(wavelengths, transmission, 'b-', linewidth=2)
    ax1.set_xlabel('Wavelength (Ξm)', fontsize=12)
    ax1.set_ylabel('Transmission', fontsize=12)
    ax1.set_title('Waveguide Transmission Spectrum', fontsize=14)
    ax1.grid(True, alpha=0.3)
    ax1.set_ylim(0, 1.1)
    plt.tight_layout()
    
    run.log_matplotlib("transmission_spectrum", fig1)
    plt.close(fig1)
    print("   ✅ Logged transmission spectrum")
    
    # Plot 2: Field distribution
    ez_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Ez)
    eps_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Dielectric)
    
    fig2, axes = plt.subplots(1, 2, figsize=(14, 5))
    
    # Permittivity
    im1 = axes[0].imshow(eps_data.T, cmap='binary', origin='lower')
    axes[0].set_title('Waveguide Structure')
    plt.colorbar(im1, ax=axes[0], label='Îĩ')
    
    # Ez field
    im2 = axes[1].imshow(np.real(ez_data).T, cmap='RdBu', origin='lower')
    axes[1].set_title('Ez Field')
    plt.colorbar(im2, ax=axes[1], label='Ez')
    
    plt.tight_layout()
    run.log_matplotlib("field_distribution", fig2)
    plt.close(fig2)
    print("   ✅ Logged field distribution")
    
    # ========== 8. Final Summary ==========
    run.log(step=3,
            simulation_completed=True,
            total_transmission=avg_transmission)
    
    print(f"\n✅ Simulation complete!")
    print(f"🔗 View results at: https://optixlog.com")


if __name__ == "__main__":
    main()

Run the Simulation

python my_first_simulation.py

You should see output like:

🚀 Starting simulation - Run ID: abc123...
⚡ Running simulation...
📊 Max transmission: 0.9876
📊 Avg transmission: 0.9654
   ✅ Logged transmission spectrum
   ✅ Logged field distribution

✅ Simulation complete!
🔗 View results at: https://optixlog.com

View Results on OptixLog

  1. Go to optixlog.com
  2. Navigate to your project "MyFirstProject"
  3. Click on the run "waveguide_simulation"
  4. Explore:
    • Metrics — View transmission values
    • Plots — See your logged figures
    • Config — Check simulation parameters

Understanding the Code

OptixLog Initialization

client = Optixlog(api_key=api_key)
project = client.project(name="MyFirstProject", create_if_not_exists=True)
run = project.run(name="waveguide_simulation", config={...})

This creates a hierarchical structure: Client → Project → Run

Logging Metrics

run.log(step=0, resolution=10, wavelength=1.55)

Use step to organize metrics chronologically.

Logging Plots

run.log_matplotlib("plot_name", fig)

One line to save any matplotlib figure!


Next Steps

Now that you've completed your first simulation, explore:


Common Issues

API Key Not Found: Make sure OPTIX_API_KEY is set in your environment.

Meep Import Error: Verify Meep installation with python -c "import meep"

Matplotlib Backend: Use matplotlib.use("agg") before importing pyplot for headless operation.

On this page