Metamaterials API Reference
Complete documentation for all classes and methods
Classes
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
| Parameter | Type | Description |
|---|---|---|
cell_type | str | 'srr', 'csrr', 'dsrr', 'wire', 'hybrid', 'efishbone' |
radius | float | Ring radius in meters |
track_width | float | Metal track width in meters |
gap_width | float | Gap width in meters |
substrate | str | Substrate 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)