JAX-native 3D FDTD electromagnetic simulator for RF engineering
Project description
rfx
██████╗ ███████╗██╗ ██╗
██╔══██╗██╔════╝╚██╗██╔╝
██████╔╝█████╗ ╚███╔╝
██╔══██╗██╔══╝ ██╔██╗
██║ ██║██║ ██╔╝ ██╗
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝
Differentiable 3D FDTD electromagnetic simulator for RF and microwave engineering — powered by JAX.
v1.0.0 -- Production-stable release with 260+ tests and 0.000% cross-validation agreement vs OpenEMS.
v1.0.0 Highlights
- Non-uniform z mesh via
dz_profilefor thin substrates - SBP-SAT subgridding research path with JIT support
- Lumped RLC elements (series / parallel)
- Via and CurvedPatch geometry helpers
- Oblique-incidence TFSF plane-wave source
- Field animation export via
save_field_animation - Auto-configuration from geometry + frequency range
- 260+ tests with strong cavity/waveguide benchmarking and active antenna validation work
At a Glance
| GPU-accelerated | ~3,000 Mcells/s on RTX 4090 via jax.lax.scan JIT |
| Differentiable | jax.grad through full time-stepping for inverse design |
| Benchmarked | Strong agreement vs Meep/OpenEMS on core cavity and waveguide cases |
| Non-uniform mesh | Graded z-profiles for thin substrates without global refinement |
| Auto-configuration | auto_configure() derives dx, domain, CPML, timesteps from geometry |
| Lumped RLC | Series, parallel, and shunt lumped elements in any cell |
| Via & curved patch | First-class geometry primitives for PCB and antenna design |
| Animation | Time-domain field animation export (MP4/GIF) |
Installation
pip install rfx-fdtd
PyPI package name: rfx-fdtd
Python import:
import rfx
For development:
git clone https://github.com/BK3536/rfx.git
cd rfx
pip install -e ".[dev]"
GPU: Complete the JAX GPU setup for your platform before running large simulations.
Quick Start
from rfx import Simulation, Box, GaussianPulse
import numpy as np
# PEC cavity with dielectric slab — simulate up to 10 GHz
sim = Simulation(freq_max=10e9, domain=(0.048, 0.032, 0.032), boundary="pec")
sim.add_material("slab", eps_r=2.2)
sim.add(Box((0.016, 0, 0), (0.032, 0.032, 0.032)), material="slab")
# Lumped port + probe
sim.add_port(
(0.006, 0.016, 0.016),
"ez",
impedance=50.0,
waveform=GaussianPulse(f0=5e9, bandwidth=0.8),
)
sim.add_probe((0.042, 0.016, 0.016), "ez")
result = sim.run(num_periods=30)
# S11
s11_dB = 20 * np.log10(np.abs(result.s_params[0, 0, :]) + 1e-12)
Patch Antenna with Non-Uniform Mesh
from rfx import Simulation, Box, GaussianPulse, auto_configure
import numpy as np
# Auto-configure from geometry and frequency range
geometry = [
(Box((0, 0, 0), (0.06, 0.06, 0.0016)), "fr4"),
(Box((0, 0, 0), (0.06, 0.06, 0)), "pec"),
(Box((0.015, 0.011, 0.0016), (0.0444, 0.049, 0.0016)), "pec"),
]
materials = {"fr4": {"eps_r": 4.4, "sigma": 0.025}, "pec": {"eps_r": 1.0, "sigma": 1e10}}
config = auto_configure(geometry, (1e9, 4e9), materials=materials, accuracy="standard")
print(config.summary()) # Shows dx, non-uniform dz, CPML, n_steps
# Build simulation from auto-config
sim = Simulation(**config.to_sim_kwargs())
sim.add_material("fr4", eps_r=4.4, sigma=0.025)
for shape, mat in geometry:
sim.add(shape, material=mat)
sim.add_source((0.025, 0.03, 0.0008), "ez", waveform=GaussianPulse(f0=2.4e9))
sim.add_probe((0.025, 0.03, 0.0008), "ez")
result = sim.run(n_steps=config.n_steps)
modes = result.find_resonances(freq_range=(1.5e9, 3.5e9))
for m in modes:
print(f"f={m.freq/1e9:.4f} GHz, Q={m.Q:.0f}")
Inverse Design
from rfx import Simulation, Box, GaussianPulse
from rfx.optimize import DesignRegion, optimize
from rfx.optimize_objectives import minimize_s11
sim = Simulation(freq_max=10e9, domain=(0.048, 0.032, 0.032), boundary="pec")
sim.add_port((0.006, 0.016, 0.016), "ez", impedance=50.0,
waveform=GaussianPulse(f0=5e9, bandwidth=0.8))
region = DesignRegion(
corner_lo=(0.016, 0.008, 0.008),
corner_hi=(0.032, 0.024, 0.024),
eps_range=(1.0, 4.4),
)
result = optimize(sim, region, minimize_s11, n_iters=40, lr=0.05)
print(f"Final loss: {result.loss_history[-1]:.4f}")
Key Features
Simulation Engine
- 3D/2D Yee solver with CFS-CPML absorbing boundaries
- True PEC mask (component-specific tangential zeroing)
- Non-uniform z mesh for thin substrates
- SBP-SAT subgridding research path
- Periodic boundaries and oblique-incidence TFSF plane-wave source
- Auto-configuration:
auto_configure()derives dx, domain, CPML, timesteps, and source recommendation - Lumped RLC elements (series and parallel topologies)
Geometry
- CSG primitives: Box, Sphere, Cylinder
- CurvedPatch for staircase-approximated curved antenna layouts
- Via for PCB through-hole / plated interconnect modeling
Sources & Ports
- GaussianPulse, ModulatedGaussian, CW, custom waveforms
- Soft sources and polarized sources
- Lumped ports and multi-cell wire ports (conductor-to-conductor)
- Waveguide ports with modal decomposition (eigenmode solver)
- Polarized sources (Jones vector: circular, LHCP, slant45)
Materials
- Dispersive: Debye, Lorentz/Drude
- Magnetic (
mu_rvalidated) - Thin conductors with subcell correction
- Subpixel smoothing (Farjadpour/Kottke)
- Built-in library:
pec,fr4,rogers4003c,copper,alumina,ptfe,water_20c, and others
Analysis
- S-parameters: lumped, wire (JIT-DFT), waveguide (N-port matrix)
- Harminv resonance extraction (Matrix Pencil Method)
- NTFF far-field, radiation patterns, RCS
- Far-field polarization (axial ratio, tilt, sense)
- Touchstone I/O, HDF5 checkpoints, VTK export
- Time-domain field animation (MP4/GIF via
save_field_animation)
Optimization
- Design regions with
jax.gradthrough full simulation - Adam optimizer, gradient checkpointing
- Objective library:
minimize_s11,maximize_s21,target_impedance,maximize_bandwidth,maximize_directivity
Benchmark Snapshot
Core benchmark areas currently documented most strongly:
| Geometry | rfx vs Meep | rfx vs OpenEMS | rfx vs Analytical |
|---|---|---|---|
| PEC cavity TM110 | 0.010% | 0.000% | 0.013% |
| FR4 cavity (eps=4.4) | 0.006% | — | 0.013% |
| Rogers (eps=3.55) | 0.007% | — | 0.026% |
| PTFE (eps=2.2) | 0.004% | — | 0.004% |
| Alumina (eps=9.8) | 0.005% | — | 0.038% |
Patch/microstrip resonance workflows are also active, but feed/port interpretation should be documented more carefully than the cavity/waveguide benchmarks.
GPU Performance (RTX 4090)
| Grid | Steps | Time | Throughput |
|---|---|---|---|
| 23^3 | 200 | 0.087s | 28 Mcells/s |
| 33^3 | 300 | 0.086s | 125 Mcells/s |
| 43^3 | 400 | 0.103s | 310 Mcells/s |
| 63^3 | 500 | 0.095s | 1,310 Mcells/s |
Gradient (reverse-mode AD): ~0.31s for all grid sizes.
Documentation
Full documentation: remilab.ai/rfx and
repo-local guides under docs/guide/.
- User Guide — Installation, API, materials, sources, probes
- AI Agent Guide — Auto-configuration, prompt templates, design workflows
Citation
@software{kim_rfx_2026,
author = {Byungkwan Kim},
title = {rfx: JAX-based differentiable 3D FDTD simulator},
institution = {REMI Lab, Chungnam National University},
year = {2026},
url = {https://github.com/BK3536/rfx}
}
License
MIT License. See LICENSE.
Acknowledgments
Developed by Byungkwan Kim at the Radar & ElectroMagnetic Intelligence (REMI) Laboratory, Chungnam National University.
AI-assisted development: Claude (Anthropic), Codex (OpenAI).
Project details
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 rfx_fdtd-1.1.0.tar.gz.
File metadata
- Download URL: rfx_fdtd-1.1.0.tar.gz
- Upload date:
- Size: 5.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
adee745a6f38da7602645e14f22de7b2073341e248c5aff0fbdbcf3e0eb4615a
|
|
| MD5 |
16f695e56c131252abcf60dcd059cb46
|
|
| BLAKE2b-256 |
408b374179403922c9300ed8ddbfafa3fcf1e83ccd11519dfecd2c84ca00714f
|
File details
Details for the file rfx_fdtd-1.1.0-py3-none-any.whl.
File metadata
- Download URL: rfx_fdtd-1.1.0-py3-none-any.whl
- Upload date:
- Size: 234.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6891764631aa959e332b11366565943a039dd4454dfd3ca2788e9e59072a6820
|
|
| MD5 |
9d710d8cdde8ce379f6a9cca25f7bc70
|
|
| BLAKE2b-256 |
d1c05d5e1fe41b2640c82a18976cc529ab6a6c85dd358e19375cf9a9e44d9c89
|