Metamaterials API Reference

Complete documentation for all classes and methods

class UnitCellDesigner

Design and analyze metamaterial unit cells including SRR, CSRR, and hybrid structures.

from metamaterials import UnitCellDesigner

designer = UnitCellDesigner(
    cell_type='srr',
    radius=80e-6,       # Ring radius in meters
    track_width=10e-6,  # Metal track width
    gap_width=5e-6,     # Gap width
    substrate='fr4'     # Substrate material
)

Constructor Parameters

ParameterTypeDescription
cell_typestr'srr', 'csrr', 'dsrr', 'wire', 'hybrid', 'efishbone'
radiusfloatRing radius in meters
track_widthfloatMetal track width in meters
gap_widthfloatGap width in meters
substratestrSubstrate material ('fr4', 'rogers', 'quartz', etc.)

Methods

calculate_resonance()float

Returns the resonance frequency in Hz based on LC model.

get_inductance()float

Returns estimated inductance in Henries.

get_capacitance()float

Returns gap capacitance in Farads.

export_gds(filename)None

Export unit cell geometry to GDSII format for fabrication.

class DispersionModel

Calculate effective medium parameters using Drude-Lorentz models.

from metamaterials import DispersionModel

model = DispersionModel(
    model_type='drude_lorentz',
    epsilon_inf=1.0,
    omega_p=15e12,    # Plasma frequency (rad/s)
    omega_0=5e12,     # Resonance frequency (rad/s)
    gamma=0.5e12      # Damping coefficient
)

Methods

epsilon(omega)complex

Returns complex permittivity at angular frequency omega.

mu(omega)complex

Returns complex permeability at angular frequency omega.

refractive_index(omega)complex

Returns complex refractive index n = sqrt(ε·μ).

impedance(omega)complex

Returns wave impedance Z = sqrt(μ/ε).

find_nim_band(freq_range)tuple

Returns (f_start, f_end) of negative index band.

class CloakDesigner

Design transformation optics cloaking structures.

from metamaterials import CloakDesigner

cloak = CloakDesigner(
    shape='cylindrical',
    inner_radius=1.0,   # Inner radius (wavelengths)
    outer_radius=2.5,   # Outer radius (wavelengths)
    n_layers=20         # Number of material layers
)

Methods

get_material_profile(r)dict

Returns {'eps_r': ..., 'eps_theta': ..., 'mu_z': ...} at radius r.

simulate_field(wavelength, angle)ndarray

Simulates electromagnetic field distribution.

calculate_scattering()float

Returns total scattering cross-section in dB.

class FDTDSolver

2D/3D finite-difference time-domain electromagnetic solver.

from metamaterials import FDTDSolver

fdtd = FDTDSolver(
    grid_size=(256, 256),
    dx=10e-9,           # Grid spacing in meters
    dt=None,            # Auto-calculate from CFL
    pml_layers=20,      # PML absorbing boundary layers
    dispersive=True     # Enable dispersive materials
)

Methods

add_source(source_type, position, params)

Add electromagnetic source (gaussian, sinusoidal, plane wave).

add_structure(geometry, material)

Add material structure to simulation domain.

run(n_steps, callbacks=None)

Run simulation for n_steps time iterations.

get_field(component)ndarray

Returns field component ('Ez', 'Hx', 'Hy', 'energy').

calculate_sparams(port1, port2)dict

Returns {'S11': ..., 'S21': ...} from field monitors.

Complete Example

import numpy as np
from metamaterials import UnitCellDesigner, DispersionModel, FDTDSolver

# Design SRR unit cell
srr = UnitCellDesigner(
    cell_type='srr',
    radius=80e-6,
    track_width=10e-6,
    gap_width=5e-6
)

f_res = srr.calculate_resonance()
print(f"Resonance frequency: {f_res/1e12:.2f} THz")

# Calculate effective medium properties
model = DispersionModel(model_type='lorentz', omega_0=2*np.pi*f_res)
frequencies = np.linspace(0.1e12, 20e12, 1000)

eps = [model.epsilon(2*np.pi*f) for f in frequencies]
mu = [model.mu(2*np.pi*f) for f in frequencies]
n = [model.refractive_index(2*np.pi*f) for f in frequencies]

# Find NIM band
nim_band = model.find_nim_band((0.1e12, 20e12))
print(f"NIM band: {nim_band[0]/1e12:.1f} - {nim_band[1]/1e12:.1f} THz")

# Run FDTD simulation
fdtd = FDTDSolver(grid_size=(256, 256), dx=1e-6)
fdtd.add_source('gaussian', position=(50, 128), params={'f0': f_res, 'width': 50e-15})
fdtd.add_structure('slab', material=model, bounds=(100, 156, 0, 256))

fdtd.run(5000)
Ez = fdtd.get_field('Ez')
sparams = fdtd.calculate_sparams(port1=30, port2=220)