Open source · JAX · 3-D FDTD for RF and microwave
The RF simulator that returns gradients.
Write a loss on S-parameters, a radiation pattern or a field. rfx gives its derivative with respect to the permittivity of every cell in your design region from one forward and one reverse pass. On the patch antenna below, the value and gradient over 43,008 design cells take 1.4 times as long as the simulation alone.
pip install rfx-fdtd See the showcase → GitHub
Value and gradient over 12,400 to 43,008 design cells, compared with one forward run on the same RTX A6000. Central differences would take 4.9 to 16.8 days.
What a gradient costs →Largest relative difference between the reverse-mode gradient and central finite differences on the patch (float64).
How the gradient was checked →See the gradient at work

Which cells move the match?
One reverse pass maps the sensitivity of a patch antenna’s |S11| to every substrate cell.
20,592 cells, one pass
Read the case →
What a gradient costs
Time and memory for the value and gradient against a forward run, as the design region grows.
24 s vs 4.9–16.8 days
Read the case →
Descend to the closed-form optimum
Adam through the FDTD solve finds the three layer permittivities of a broadband anti-reflection coating.
within 1.1 % of the transfer-matrix optimum
Read the case →
The forward model next to openEMS
Input impedance of the patch and |S21| of a microstrip notch filter, on the same boards as openEMS.
being re-measured under the current settling check
Read the case →What the code looks like
The objective is an ordinary Python function of the permittivity in a design box. JAX differentiates the whole time-stepping loop.
def J(eps_box): res = board.sim.forward( design_box=corners, design_eps_override=eps_box, design_box_holds_ports=True, n_steps=n_steps, checkpoint=False, checkpoint_segments=checkpoint_segments, port_s11_freqs=freqs, skip_preflight=True) s = res.s_params s = s if s.ndim == 1 else s[0] return jnp.real(s[0]) ** 2 + jnp.imag(s[0]) ** 2
v, g = jax.jit(jax.value_and_grad(J))(eps_bg)The full script builds the board, runs preflight once on it, and checks the gradient against finite differences before anything is plotted. Full script →
Start here
- Install and run a first model: Installation · Your first run
- Watch fields move before measuring them: The visual manual (the teaching films)
- Design with gradients: Autodiff and adjoint · Inverse design · Gradient behavior
- Look up a call: API reference
Before you trust a number
A result holds for the structure, mesh and observable it was checked on. Read Support Boundaries before combining features and Evidence before reporting an RF result.
