Wavebit
Differentiable electromagnetic simulation: RCWA and FDTD behind one API, on NumPy, JAX and PyTorch.
Wavebit computes how light scatters from periodic nanostructures (RCWA) and how fields evolve in time (FDTD). It differentiates through the RCWA calculation, so the model that predicts a device's response is the model that optimizes it.
- Two solvers, one lifecycle.
rcwaandfdtdsharecheck→prepare→run, the same materials, explicit length units, radian angles, and fields in V/m and A/m. - One implementation of the physics on three array backends. Cross-backend agreement is part of the test suite, not a promise.
- Gradients where you need them. Wavelength, materials, layer thicknesses and raster permittivities differentiate on JAX and PyTorch; shape dimensions on PyTorch. The full table is in the differentiation guide.
- Checked against the outside world. RETICOLO, fmmax and S4 for RCWA; Meep for FDTD; the Li (1997) crossed-grating benchmark. The numbers and how they were taken: validation.
Status: 0.0.3, alpha. RCWA is the mature path. FDTD runs on CPU in double precision; its geometry,
material and derivative support is reported by check for each problem. The API may change before
1.0. An experimental RCWA solver for metal contacts is opt-in and has its own, narrower scope; read
method selection before enabling it.
Install
Python 3.12 or newer.
pip install wavebit # NumPy backend
pip install 'wavebit[jax]' # or 'wavebit[pytorch]', or 'wavebit[jax,pytorch]' — differentiation backends
From a source checkout, for development:
git clone https://github.com/fieldalgo/wavebit.git && cd wavebit
pip install -e '.[jax,docs]' # editable, with the documentation toolchain
environment.yml builds the full development environment, including what the studies need. The
version floors in pyproject.toml are the versions the suite is verified against;
each is commented with the reason it sits where it does.
Quickstart
A binary grating on glass under normal incidence, on the NumPy backend:
import numpy as np
from wavebit import Material, Units, rcwa
problem = rcwa.Problem(
units=Units(length="nm"),
stack=rcwa.Stack(
period=(700., 700.),
bottom=Material(epsilon=2.25),
layers=(rcwa.Layer(thickness=300., epsilon=np.array([[1., 1., 12.25, 12.25]])),),
),
excitation=rcwa.Excitation(wavelength=900., sources=(rcwa.PlaneWave(polarization="s"),)),
)
numerics = rcwa.Numerics(orders=(10, 0))
result = rcwa.run(problem, numerics=numerics)
print(float(result.R.sum()), float(result.T.sum()))
print(result.transmission.order(0, 0).efficiency)
Diffraction arrays keep (wavelength, order_v, order_u) axes even for a single wavelength. R and
T are efficiencies; absolute port power and its integration measure are recorded separately.
To differentiate, prepare once and run with live leaves. JAX double precision is enabled by you, never by importing Wavebit:
import jax, jax.numpy as jnp
jax.config.update("jax_enable_x64", True)
prepared = rcwa.prepare(problem, numerics=numerics, backend="jax")
def transmitted(thickness):
layer = problem.stack.layers[0].replace(thickness=thickness)
live = problem.replace(stack=problem.stack.replace(layers=(layer,)))
return jnp.sum(prepared.run(live).T)
gradient = jax.grad(transmitted)(jnp.asarray(300.))
The FDTD entry point works the same way; examples/fdtd/pulse_slab.py
is the first thing to run. The conventions both solvers follow — relative permittivity,
exp(-iωt) phasors, bottom-to-top layers, centered cells, explicit units — are listed once in the
documentation home and defined normatively in
docs/reference/common/conventions.md.
Documentation
The prose is split by who is reading, the way NumPy's manual is:
| For a reader who | |
|---|---|
docs/guide/ |
needs the contract for one keyword: the manual |
docs/reference/ |
needs a signature or a guarantee |
docs/design/, docs/development/ |
is questioning a default, and wants what was measured to decide it |
docs/validation/ |
wants the evidence behind a claim |
tutorials/ |
has not used the API yet: start with the RCWA or FDTD notebook |
examples/ |
wants it applied to a problem |
studies/ |
wants the raw measurement behind a number in docs/ |
The same pages build as a site (pip install -e '.[docs]', then
sphinx-build -b html docs docs/_build/html); a hosted copy is coming. Every link in docs/ is a
relative link to a real file, and a test checks that every path a page cites exists.
python -m wavebit.manifest prints every option, refusal and constraint as one JSON document for
programs that need to know without reading the source
(capability manifest).
Contributing
Bug reports, questions and pull requests are welcome. CONTRIBUTING.md opens with the rule for where a new file belongs, and explains how changes are reviewed and landed.
Citation
@software{wavebit,
title = {Wavebit: Differentiable Electromagnetic Simulation Suite},
author = {Kim, Yongha},
year = {2026},
url = {https://github.com/fieldalgo/wavebit},
}
License
Apache-2.0. LICENSE also carries the third-party notices this project owes.
Contact
Metadata
Release files for wavebit 0.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| wavebit-0.0.3.tar.gz | 1.6 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wavebit-0.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.4 MB
Release files / wavebit-0.0.3.tar.gz
| Download URL | wavebit-0.0.3.tar.gz |
|---|---|
| Size | 1.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b663ea98824963ec5d071093eaa345d6df3775912c3d891016925422b573a74b
|
|
BLAKE2b-256 checksum How to use checksums |
2cd1dbed404bc0ca208628537318704513a0e0a138131a1bcbcce0fd89f5ac75
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency logRelease files / wavebit-0.0.3-py3-none-any.whl
| Download URL | wavebit-0.0.3-py3-none-any.whl |
|---|---|
| Size | 1.8 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e404618b53a548cc7ee37aae49f4b84b8e3715eb7bddff9fe63b16c406c8e906
|
|
BLAKE2b-256 checksum How to use checksums |
6b73dd37bb3622d99a9b5f84dd09bfc0929c1e0fb40df6b08a6c6fcc63897efd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency logSecurity for wavebit 0.0.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for wavebit-0.0.3.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.