ExamplesMeep Examples

Faraday Rotation

Simulate polarization rotation in a gyrotropic medium with magnetic bias

Faraday Rotation Simulation

This example simulates Faraday rotation of a linearly polarized plane wave through a gyrotropic medium with an applied magnetic field bias. The polarization plane rotates as the wave propagates.

Overview

Faraday rotation is a magneto-optical effect with applications in:

  • Optical isolators: Non-reciprocal devices for laser protection
  • Modulators: Magnetic field sensors
  • Telecommunications: Fiber optic components
  • Astronomy: Measuring interstellar magnetic fields

The rotation angle is proportional to the magnetic field strength and propagation distance.

Simulation Parameters

ParameterDefault ValueDescription
resolution50Pixels per μm
epsn1.5Background permittivity
f01.0Natural frequency
gamma1e-6Damping rate
sn0.1Sigma parameter
b00.15Magnetic bias magnitude
L20.0Cell length
fsrc0.8Source frequency

Physical Setup

The simulation consists of:

  1. Gyrotropic medium: Material with off-diagonal permittivity components
  2. Magnetic bias: Applied along z-direction (propagation)
  3. Linearly polarized source: Ex-polarized plane wave
  4. PML boundaries: Absorbing layers at cell edges

The gyrotropic susceptibility creates coupling between Ex and Ey components, causing the polarization to rotate as the wave propagates.

Python Code

"""
Faraday Rotation Simulation with OptixLog Integration

Simulates Faraday rotation of a linearly polarized plane wave
through a gyrotropic medium with an applied magnetic field bias.

Based on the Meep tutorial: faraday-rotation.py
"""

import os
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():
    """Main simulation function for Faraday rotation."""
    
    if not optixlog.is_master_process():
        return
    
    try:
        client = optixlog.init(
            api_key=api_key,
            api_url=api_url,
            project=project_name,
            run_name="faraday_rotation_simulation",
            config={
                "simulation_type": "faraday_rotation",
                "description": "Faraday rotation in gyrotropic medium",
            },
            create_project_if_not_exists=True
        )
        
        # Material parameters
        epsn = 1.5     # background permittivity
        f0 = 1.0       # natural frequency
        gamma = 1e-6   # damping rate
        sn = 0.1       # sigma parameter
        b0 = 0.15      # magnitude of bias vector
        
        client.log(
            step=0,
            resolution=50,
            background_permittivity=epsn,
            natural_frequency=f0,
            bias_magnitude=b0
        )
        
        # Define gyrotropic material
        susc = [
            mp.GyrotropicLorentzianSusceptibility(
                frequency=f0,
                gamma=gamma,
                sigma=sn,
                bias=mp.Vector3(0, 0, b0)
            )
        ]
        mat = mp.Medium(epsilon=epsn, mu=1, E_susceptibilities=susc)
        
        # Simulation parameters
        tmax = 100
        L = 20.0
        cell = mp.Vector3(0, 0, L)
        fsrc = 0.8
        src_z = -8.5
        resolution = 50
        
        pml_layers = [mp.PML(thickness=1.0, direction=mp.Z)]
        
        sources = [
            mp.Source(
                mp.ContinuousSource(frequency=fsrc),
                component=mp.Ex,
                center=mp.Vector3(0, 0, src_z),
            )
        ]
        
        sim = mp.Simulation(
            cell_size=cell,
            geometry=[],
            sources=sources,
            boundary_layers=pml_layers,
            default_material=mat,
            resolution=resolution,
        )
        
        sim.run(until=tmax)
        
        client.log(step=1, simulation_completed=True)
        
        # Get field data
        ex_data = sim.get_efield_x().real
        ey_data = sim.get_efield_y().real
        z = np.linspace(-L / 2, L / 2, len(ex_data))
        
        # Calculate analytic result
        dfsq = f0**2 - 1j * fsrc * gamma - fsrc**2
        eperp = epsn + sn * f0**2 * dfsq / (dfsq**2 - (fsrc * b0) ** 2)
        eta = sn * f0**2 * fsrc * b0 / (dfsq**2 - (fsrc * b0) ** 2)
        
        k_gyro = 2 * np.pi * fsrc * np.sqrt(0.5 * (eperp - np.sqrt(eperp**2 - eta**2)))
        
        client.log(
            step=2,
            max_ex=float(np.max(np.abs(ex_data))),
            max_ey=float(np.max(np.abs(ey_data))),
            k_gyro_real=float(k_gyro.real),
        )
        
        # Calculate Verdet constant
        verdet_constant = k_gyro.real / (2 * np.pi)
        
        client.log(
            step=4,
            verdet_constant=float(verdet_constant.real),
            rotation_rate_deg_per_um=float(np.degrees(k_gyro.real)),
        )
        
    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 Faraday rotation simulation
python faraday-rotation.py

Results and Analysis

Field Components

The simulation shows:

  • Ex(z): Original polarization component (cosine-like decay)
  • Ey(z): Generated perpendicular component (sine-like growth)
  • Both envelopes agree with analytical predictions

Polarization Angle

The local polarization angle θ = arctan(Ey/Ex) increases linearly with distance, confirming the Faraday rotation effect.

Key Metrics

  • Gyromagnetic wavenumber (k_gyro): Determines rotation rate
  • Verdet constant: Rotation per unit length per unit field
  • Rotation rate: Typically measured in degrees/μm

OptixLog Metrics

  • background_permittivity: Material ε_∞
  • bias_magnitude: Applied magnetic field
  • k_gyro_real: Real part of gyromagnetic k
  • rotation_rate_deg_per_um: Faraday rotation rate

The rotation angle is θ = VBL, where V is the Verdet constant, B is the magnetic field, and L is the path length.

Physical Insights

Gyrotropic Permittivity Tensor

In a magnetized medium, the permittivity becomes:

ε = | ε_perp   -iη      0    |
    | iη       ε_perp   0    |
    | 0        0        ε_z  |

The off-diagonal terms (η) cause polarization rotation.

Non-Reciprocity

Faraday rotation is non-reciprocal:

  • Forward propagation: +θ rotation
  • Backward propagation: +θ rotation (not -θ)
  • This enables optical isolators

On this page