Skip to main content

WiTwin Maxwell — Differentiable Electromagnetic Solver

PyPI Downloads Code SizeLicense

WiTwin Maxwell is a differentiable full-wave electromagnetic solver with a PyTorch-native interface and a native CUDA FDTD runtime at its core. The FDTD field-update loops run as hand-written GPU kernels shipped in prebuilt platform wheels, while the entire workflow — scene definition, simulation dispatch, result access, and automatic differentiation — stays inside standard PyTorch through SceneModule, MaterialRegion, and adjoint backward support.

The main public solver workflow today is:

  • FDTD: Slang/CUDA Yee-grid time-domain solver with monitor extraction, multi-frequency DFT sampling, and differentiable adjoint support

Frequency-domain FDFD support is coming soon.

Get Started

Python 3.10+ and an NVIDIA GPU are required. This package depends on the base witwin package.

pip install witwin-maxwell

Public API

The main user-facing API is intentionally small:

  • Scene: domain, grid, boundaries, structures, sources, monitors, ports, and differentiable material regions
  • Simulation: runtime configuration through Simulation.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.

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.fdtd(...) FDTD supports time stepping and single- or multi-frequency DFT extraction. Simulation.fdfd(...) is coming soon.
Sources PointDipole, PlaneWave, GaussianBeam, ModeSource, TFSF PlaneWave / GaussianBeam support soft injection and TFSF(...); CW PlaneWave supports TFSF.slab(axis="z", ...) for grating illumination. 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(...), including x/y Bloch plus z PML for grating FDTD workflows.
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 uses a point source and a dielectric cube, plots a vertical electric-field slice, and backpropagates to the cube position.

import torch
import witwin.maxwell as mw

# Train the cube position directly.
box_x = torch.tensor(0.10, device="cuda", requires_grad=True)
box_position = torch.stack((box_x, box_x.new_tensor(0.0), box_x.new_tensor(0.06)))

# Build a minimal scene: one dielectric cube and one point dipole.
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",
    subpixel_samples=5,
)
scene.add_structure(
    mw.Structure(
        name="cube",
        geometry=mw.Box(position=box_position, size=(0.18, 0.18, 0.18)),
        material=mw.Material(eps_r=20.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",)))

sim = mw.Simulation.fdtd(
    scene,
    frequencies=[1.0e9],
    run_time=mw.TimeConfig(time_steps=32),
    spectral_sampler=mw.SpectralSampler(window="none"),
    full_field_dft=True,
)

# Run the simulation and backpropagate from a probe value.
result = sim.run()
probe = result.monitor("probe")["data"]
loss = torch.abs(probe) ** 2
loss.backward()

print("probe =", probe)
print("loss =", float(loss.detach().item()))
print("d(loss)/d(box_x) =", box_x.grad)

# Plot a vertical field slice at y = 0.
result.plot.field(axis="y", position=0.0, component="abs", field_log_scale=True)

This example is intentionally minimal and does not require wrapping the scene in a class.

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.

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 Maxwell workflows are GPU/CUDA-first.
  • Simulation.fdfd(...) is coming soon.
  • bloch_wavevector="auto" is supported for fixed-angle CW TFSF grating slabs; broadband automatic Bloch phase requests are rejected.
  • Prefer DiagonalTensor3 for anisotropic materials. Full rotated/off-diagonal Tensor3x3 support is not implemented yet.
  • The public differentiable path currently focuses on trainable inputs that affect compiled material tensors.
  • ModeSource, ModeMonitor, and ModePort are available, but they are still marked experimental.

License

GPL-3.0-or-later. See COPYING for the full license text.

Developer

Xingyu Chen

Xingyu Chen

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

witwin_maxwell-0.2.0.tar.gz (764.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

witwin_maxwell-0.2.0-cp312-cp312-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.12Windows x86-64

witwin_maxwell-0.2.0-cp312-cp312-manylinux_2_35_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.35+ x86-64

witwin_maxwell-0.2.0-cp311-cp311-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.11Windows x86-64

witwin_maxwell-0.2.0-cp311-cp311-manylinux_2_35_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.35+ x86-64

witwin_maxwell-0.2.0-cp310-cp310-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.10Windows x86-64

witwin_maxwell-0.2.0-cp310-cp310-manylinux_2_35_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.35+ x86-64

File details

Details for the file witwin_maxwell-0.2.0.tar.gz.

File metadata

  • Download URL: witwin_maxwell-0.2.0.tar.gz
  • Upload date:
  • Size: 764.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for witwin_maxwell-0.2.0.tar.gz
Algorithm Hash digest
SHA256 12da80a9c40c6f885944976139e8ed6967dff8d040299336a4109d5432d041c5
MD5 a2b51797c7d0fb359f851875802dec26
BLAKE2b-256 7cec49b03a9f500182f6d7fb8155bdb0798b763a7fb43f98300de78ba94ba4ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for witwin_maxwell-0.2.0.tar.gz:

Publisher: publish-witwin-maxwell.yml on witwin-ai/witwin-maxwell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file witwin_maxwell-0.2.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for witwin_maxwell-0.2.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 b2728fac4c07f29a69d667234bee93e0884c0561d96becafc1d4736dc52c207d
MD5 db611a5776ff1dc0f9ab1f93ada95964
BLAKE2b-256 dc2dd94ce6c305c7b7eaa6dc08206c941eea9b93780bcf251cea793b8e45b195

See more details on using hashes here.

Provenance

The following attestation bundles were made for witwin_maxwell-0.2.0-cp312-cp312-win_amd64.whl:

Publisher: publish-witwin-maxwell.yml on witwin-ai/witwin-maxwell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file witwin_maxwell-0.2.0-cp312-cp312-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for witwin_maxwell-0.2.0-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 d524fc91cd4727cd5ada60c4961f410c03106426e4c8b4dea0330ba36cba5372
MD5 0baff2503c1ecba10fe30a2bcffdfef8
BLAKE2b-256 ce619d6b8cf52c6840ab7de38788786c8b93308b38ec3e65e311ddcef5e37630

See more details on using hashes here.

Provenance

The following attestation bundles were made for witwin_maxwell-0.2.0-cp312-cp312-manylinux_2_35_x86_64.whl:

Publisher: publish-witwin-maxwell.yml on witwin-ai/witwin-maxwell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file witwin_maxwell-0.2.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for witwin_maxwell-0.2.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 7037ba99381a636f7a3eb338034a69c969e6d863bbee787cf813780c4fb21dc0
MD5 964a5f54ab033d6a7f43e20b38c993b6
BLAKE2b-256 fd9e1a487c2cb7c91f0ba24ac9880321a27cfeafe8342c5eae18f9395b1b82c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for witwin_maxwell-0.2.0-cp311-cp311-win_amd64.whl:

Publisher: publish-witwin-maxwell.yml on witwin-ai/witwin-maxwell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file witwin_maxwell-0.2.0-cp311-cp311-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for witwin_maxwell-0.2.0-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 ae88dbca32975f0d7ad059fd43b0993b7da86392fbd1784ec77cdc92e0402d53
MD5 19b086e739c9c1649be3928b564a1efd
BLAKE2b-256 70a9e3141569358444154fda0b5e28a24f3d542b0ded0f5c7f6fcf42da1b4547

See more details on using hashes here.

Provenance

The following attestation bundles were made for witwin_maxwell-0.2.0-cp311-cp311-manylinux_2_35_x86_64.whl:

Publisher: publish-witwin-maxwell.yml on witwin-ai/witwin-maxwell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file witwin_maxwell-0.2.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for witwin_maxwell-0.2.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 01842d26b4848430dfe579261601bfbd568b79e8bc5c82953eda6f03f016d547
MD5 5a4d68fa7a66755e40961db21dfebd21
BLAKE2b-256 075a38876fbcaf9bbc96678e1d4cac49b6b3f68614d07b4d5d63a5268e1f8dd4

See more details on using hashes here.

Provenance

The following attestation bundles were made for witwin_maxwell-0.2.0-cp310-cp310-win_amd64.whl:

Publisher: publish-witwin-maxwell.yml on witwin-ai/witwin-maxwell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file witwin_maxwell-0.2.0-cp310-cp310-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for witwin_maxwell-0.2.0-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 5d8d10979b9e4c4fcde5f971d2c14001dde49f3a9a7aa79824fbaeb773fa9c70
MD5 bbf764f44d2ffce13f649b840d60ffd8
BLAKE2b-256 b10d58160cd87551de53c02541dd5ea856bb7b9172449b0c69dee9206a20950c

See more details on using hashes here.

Provenance

The following attestation bundles were made for witwin_maxwell-0.2.0-cp310-cp310-manylinux_2_35_x86_64.whl:

Publisher: publish-witwin-maxwell.yml on witwin-ai/witwin-maxwell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page