Witwin Maxwell - Electromagnetic simulation (FDTD/FDFD)
Project description
Witwin Maxwell
Witwin Maxwell is a PyTorch-native differentiable full-wave electromagnetic solver for Maxwell's equations. It exposes a single public workflow, Scene -> Simulation -> Result, while keeping inverse-design and optimization workloads inside standard PyTorch through SceneModule, MaterialRegion, and automatic backward support in the FDTD path.
The repository currently ships two solver backends:
FDFD: frequency-domain finite-difference solver for single-frequency problemsFDTD: GPU-first Yee-grid time-domain solver with monitor extraction, multi-frequency DFT sampling, and differentiable adjoint support
Public API
The public model is intentionally small:
Scene: domain, grid, boundaries, structures, sources, monitors, ports, and differentiable material regionsSimulation: backend selection and runtime configuration throughSimulation.fdfd(...)orSimulation.fdtd(...)Result: structured field access, material tensors, monitor payloads, plotting, stats, and save support
For module-style inverse-design workflows, define a SceneModule, implement to_scene(), and pass that module directly into Simulation. The runtime keeps the same Scene -> Simulation -> Result contract.
Scene stays declarative. Solver-sized Yee-grid coordinates, material tensors, and related runtime state are compiled during Simulation.prepare() / Simulation.run() and live on the internal solver scene rather than the public Scene object.
Support Matrix
| Area | Currently supported | Notes |
|---|---|---|
| Solvers | Simulation.fdfd(...), Simulation.fdtd(...) |
FDFD is single-frequency. FDTD supports time stepping and single- or multi-frequency DFT extraction. |
| Sources | PointDipole, PlaneWave, GaussianBeam, ModeSource, TFSF |
PlaneWave / GaussianBeam support soft injection and TFSF(...). ModeSource is still experimental. |
| Source time | CW, GaussianPulse, RickerWavelet |
Shared waveform vocabulary across public source APIs. |
| Boundaries | none, pml, periodic, bloch, pec, pmc |
Per-axis and per-face mixed layouts are available through BoundarySpec.faces(...). |
| Materials | Isotropic eps_r, mu_r, sigma_e; Debye, Drude, Lorentz; DiagonalTensor3; MaterialRegion |
sigma_e is the public frequency-domain conductivity path. MaterialRegion is the most direct differentiable design primitive. |
| Geometry | Box, Sphere, Cylinder, Ellipsoid, Cone, Pyramid, Prism, Torus, HollowBox, Mesh |
Geometry and Structure primitives are re-exported through witwin.maxwell. |
| Monitors | PointMonitor, PlaneMonitor, FluxMonitor, ModeMonitor |
Frequency selection is available through Result.at(...). |
| Ports | ModePort |
First-class modal port object; still experimental. |
| Results | result.E, result.H, result.materials, Result.monitor(...), Result.save(...) |
Structured field and material access stay torch-native. |
| Postprocess | Equivalent currents, Stratton-Chu propagation, near-to-far transform, directivity, bistatic RCS, S-parameters, modal overlap | Use witwin.maxwell.postprocess. |
| Differentiable workflows | SceneModule, MaterialRegion, supported trainable geometry parameters, FDTD adjoint backward |
Public backward support currently targets trainable inputs that flow into the prepared-scene material tensors compiled from Scene. |
For the exhaustive user-visible capability inventory, see FEATURE_LIST.md.
Minimal Differentiable Example
The example below builds a tiny trainable design region, runs an FDTD simulation, reads a complex probe value, forms a scalar loss, and calls loss.backward() exactly like any other PyTorch program.
import torch
import witwin.maxwell as mw
class TinyInverseDesign(mw.SceneModule):
def __init__(self):
super().__init__()
self.logits = torch.nn.Parameter(torch.zeros((1, 1, 1), device="cuda"))
def to_scene(self):
scene = mw.Scene(
domain=mw.Domain(bounds=((-0.24, 0.24), (-0.24, 0.24), (-0.24, 0.24))),
grid=mw.GridSpec.uniform(0.12),
boundary=mw.BoundarySpec.pml(num_layers=2, strength=1.0),
device="cuda",
)
scene.add_material_region(
mw.MaterialRegion(
name="design",
geometry=mw.Box(position=(0.0, 0.0, 0.06), size=(0.12, 0.12, 0.12)),
density=torch.sigmoid(self.logits),
eps_bounds=(1.0, 6.0),
mu_bounds=(1.0, 1.0),
)
)
scene.add_source(
mw.PointDipole(
position=(0.0, 0.0, -0.06),
polarization="Ez",
width=0.04,
source_time=mw.GaussianPulse(
frequency=1.0e9,
fwidth=0.25e9,
amplitude=50.0,
),
)
)
scene.add_monitor(mw.PointMonitor("probe", (0.0, 0.0, 0.06), fields=("Ez",)))
return scene
model = TinyInverseDesign().cuda()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-1)
sim = mw.Simulation.fdtd(
model,
frequencies=[1.0e9],
run_time=mw.TimeConfig(time_steps=32),
spectral_sampler=mw.SpectralSampler(window="none"),
)
optimizer.zero_grad()
result = sim.run()
probe = result.monitor("probe")["data"]
target = torch.zeros((), dtype=probe.dtype, device=probe.device)
loss = torch.abs(probe - target) ** 2
loss.backward()
optimizer.step()
print("probe =", probe)
print("loss =", float(loss.detach().item()))
print("grad =", model.logits.grad)
This example is intentionally small, but it already uses the full public differentiable workflow:
SceneModule -> Simulation.fdtd(...) -> Result -> loss.backward()
The current public backward path is for trainable inputs that contribute to compiled material tensors, such as MaterialRegion.density and supported trainable geometry parameters. Parameters that only affect source placement or other non-material branches are not yet part of the public adjoint path.
Installation
Core solver workflows are CUDA-first. A working NVIDIA GPU, a CUDA-compatible PyTorch build, and slangtorch are expected.
1. Create and activate an environment
conda create -n witwin2 python=3.11 -y
conda activate witwin2
2. Install a CUDA-enabled PyTorch build
Install the PyTorch build that matches your NVIDIA driver and CUDA stack first.
3. Install Maxwell
pip install -e .
Optional packages:
tidy3dforScene.to_tidy3d(...)and benchmark cross-validation workflows
Development and Validation
Common local commands:
python -m pytest tests
python -m pytest tests/api/public/test_public_api.py tests/api/public/test_simulation_smoke.py
python -m pytest tests/boundaries/cpml/test_fdtd_cpml.py tests/monitors/observers/test_fdtd_observers.py
python -m pytest tests/gradients/test_fdtd_adjoint_bridge.py
python -m benchmark
python -m benchmark dipole_vacuum
python -m benchmark planewave_vacuum
Benchmark assets live under:
benchmark/scenes/benchmark/cache/benchmark/plots/benchmark/RESULTS.md
Current Notes
- Core FDFD and FDTD solver runs are GPU/CUDA-first.
- FDFD is a single-frequency public workflow.
- Prefer
DiagonalTensor3for anisotropic materials. Full rotated/off-diagonalTensor3x3support is not implemented yet. - The public differentiable path currently focuses on trainable inputs that affect compiled material tensors.
ModeSource,ModeMonitor, andModePortare available, but they are still marked experimental.
License
GPL-3.0-or-later. See COPYING for the full license text.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file witwin_maxwell-0.0.1.tar.gz.
File metadata
- Download URL: witwin_maxwell-0.0.1.tar.gz
- Upload date:
- Size: 563.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be6b7fea30218a6f2f4a3680316a8692346e119a5e9b48382c28d03986aa91b9
|
|
| MD5 |
843cd99ade4d23901b6716ce8d6d3e29
|
|
| BLAKE2b-256 |
20f77c5d46f02e46669b313d5f9a280797e2b8f773caef2698c20e9278dba0c8
|
Provenance
The following attestation bundles were made for witwin_maxwell-0.0.1.tar.gz:
Publisher:
publish-witwin-maxwell.yml on witwin-ai/witwin-maxwell
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
witwin_maxwell-0.0.1.tar.gz -
Subject digest:
be6b7fea30218a6f2f4a3680316a8692346e119a5e9b48382c28d03986aa91b9 - Sigstore transparency entry: 1156835664
- Sigstore integration time:
-
Permalink:
witwin-ai/witwin-maxwell@cfcdc3e44b22f0b0b5d121884e6ade159b18df58 -
Branch / Tag:
refs/tags/witwin-maxwell-v0.0.1 - Owner: https://github.com/witwin-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-witwin-maxwell.yml@cfcdc3e44b22f0b0b5d121884e6ade159b18df58 -
Trigger Event:
release
-
Statement type:
File details
Details for the file witwin_maxwell-0.0.1-py3-none-any.whl.
File metadata
- Download URL: witwin_maxwell-0.0.1-py3-none-any.whl
- Upload date:
- Size: 248.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6e857a6785f95fd8c668b7ee0fe414dd8a8ae4646e6721b04a1bde85f590c41
|
|
| MD5 |
e1621438dfe820a09102cb5d82a541fe
|
|
| BLAKE2b-256 |
244298935a0ef2cfd96f6c6eac96609b2447d34fda7ffcb55c6c1be29e6a774f
|
Provenance
The following attestation bundles were made for witwin_maxwell-0.0.1-py3-none-any.whl:
Publisher:
publish-witwin-maxwell.yml on witwin-ai/witwin-maxwell
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
witwin_maxwell-0.0.1-py3-none-any.whl -
Subject digest:
b6e857a6785f95fd8c668b7ee0fe414dd8a8ae4646e6721b04a1bde85f590c41 - Sigstore transparency entry: 1156836103
- Sigstore integration time:
-
Permalink:
witwin-ai/witwin-maxwell@cfcdc3e44b22f0b0b5d121884e6ade159b18df58 -
Branch / Tag:
refs/tags/witwin-maxwell-v0.0.1 - Owner: https://github.com/witwin-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-witwin-maxwell.yml@cfcdc3e44b22f0b0b5d121884e6ade159b18df58 -
Trigger Event:
release
-
Statement type: