An electromagnetic mode solver using the FDFD method on a rectilinear Yee-grid, written in native Rust.
pip install micromode- Grid-first API: pass arrays directly, with no required geometry model.
- Fast, portable Rust sparse backend: one production solve path.
- Practical outputs: fields,
n_eff,k_eff, mode area, polarization fractions, Lorentz overlaps, plotting, dataframe export, and HDF5 save/load. - Tensor-aware: supports scalar, diagonal anisotropic, and full tensor material grids.
- Works for both 2D cross sections and 1D slices.
You give it a material grid. It returns guided modes: effective indices, six-component fields, polarization metrics, mode area, overlaps, diagnostics, plots, and HDF5 output. MicroMode is intentionally not a CAD or geometry package. It is the solver piece you use after geometry has already been rasterized onto a mode-plane grid.
Micromode is the default mode solver in the BEAMZ FDTD engine.
import micromode as mm
wavelength_um = 1.55
freq = mm.C_0 / wavelength_um
# Arrays from your own rasterizer.
eps_xx, x_edges, y_edges = mode_plane_arrays(...)
materials = mm.Materials.from_diagonal(
eps_xx=eps_xx,
x_edges=x_edges,
y_edges=y_edges,
)
data = mm.solve_modes(
material_grid=materials,
freqs=[freq],
num_modes=2,
target_neff=2.5,
)
print(data.n_eff.values)
data.plot_field("Ex", mode_index=0)
data.to_hdf5("modes.h5")MicroMode solves the source-free frequency-domain Maxwell equations on a rasterized Yee mode plane,
On diagonal material grids this becomes a transverse eigenproblem, while full tensor or transformed grids use a first-order tensorial form. The detailed derivation is in docs/physics-model.md, and the public solver controls are summarized in docs/mode-solver-methods.md.
MicroMode is designed to make high-performance mode solving available without requiring users to install external solver stacks. The production backend is a portable Rust sparse shift-invert eigensolver, so source installs and wheels do not depend on ARPACK, UMFPACK, SuiteSparse, BLAS/ LAPACK, or a Fortran compiler. That matters for simulation workflows that need to run in CI, notebooks, container images, FDTD plugins, and cross-platform design tools.
The native solver is not a dense fallback. It uses sparse finite-difference operators throughout, applies AMD fill-reducing ordering before sparse LU factorization, stores LU factors in a packed format for repeated triangular solves, and runs an Arnoldi iteration targeted around the requested effective index. The Arnoldi stage uses shift-invert, adaptive Ritz-pair checkpointing, early stopping once requested modes are stable, and selective Ritz vector reconstruction so work is spent on the modes that will actually be returned.