REMI Lab
OPEN KNOWLEDGE / TOOLS

ADI Solver (Experimental)

이 페이지의 내용

solver="adi" is an implicit time-stepping scheme that can take steps larger than the usual Courant limit. It is experimental. This page shows when it helps, what the larger step costs in accuracy, and what it cannot model.

Why it exists

The default solver="yee" is explicit. Its time step is set by the smallest cell anywhere in the mesh, so one thin layer or narrow gap forces tiny steps on the whole model. ADI (the Zheng–Chen–Zhang two-sub-step scheme) removes that stability limit, and adi_cfl_factor sets how many times larger than the Yee step it goes.

Stability is free; accuracy is not. ADI adds a dispersion error that grows roughly as the square of the step. adi_cfl_factor is a speed setting, not an accuracy setting.

Example: a PEC cavity three ways

This resonates an empty 24 × 12 × 36 mm PEC cavity with explicit Yee and with ADI at factors 2 and 5, and compares the TE101 frequency with the closed form:

import numpy as np
from rfx import GaussianPulse, Simulation
C0 = 299_792_458.0
a, b, d = 24e-3, 12e-3, 36e-3
f_te101 = C0 / 2 * np.sqrt((1 / a) ** 2 + (1 / d) ** 2)
def cavity(solver, factor=2.0):
sim = Simulation(freq_max=12e9, domain=(a, b, d), dx=1.5e-3,
boundary="pec", solver=solver, adi_cfl_factor=factor)
sim.add_source((0.37 * a, 0.41 * b, 0.20 * d), "ey",
waveform=GaussianPulse(f0=f_te101, bandwidth=0.9),
amplitude_kind="field") # ADI implements field sources only
sim.add_probe((0.63 * a, 0.58 * b, 0.80 * d), "ey")
return sim
for label, solver, factor in [("yee", "yee", 1.0),
("adi x2", "adi", 2.0),
("adi x5", "adi", 5.0)]:
sim = cavity(solver, factor)
dt = sim.run(n_steps=2, skip_preflight=True).dt
n_steps = int(6.9e-9 / dt) # the same 6.9 ns record each time
result = sim.run(n_steps=n_steps)
modes = result.find_resonances(freq_range=(0.7 * f_te101, 1.5 * f_te101))
te101 = min(modes, key=lambda m: abs(m.freq - f_te101))
err = 100 * (te101.freq - f_te101) / f_te101
print(f"{label}: {n_steps} steps, TE101 error {err:+.2f}%")

The ADI runs take a half and a fifth of the Yee steps for the same record, and their TE101 error grows with the factor. The factor-5 run triggers the adi_3d_accuracy preflight advisory.

Choosing adi_cfl_factor

The committed check holds the 3-D lane at the default factor 2 within 2 % of the analytic eigenfrequency of an empty PEC cavity (tests/unit/misc/test_review_tier1_validation_battery.py::test_optc1_adi_3d_cavity_eigenfrequency). Larger factors are not judged; the error grows with the factor and shrinks with finer cells.

Use adi_cfl_factor <= 2 when a frequency must be accurate. The default is 2; a larger factor trades accuracy for larger steps on stiff meshes.

What ADI can model

ADI runs a small subset of rfx:

  • mode="3d" or mode="2d_tmz", on a uniform mesh;
  • boundary="pec" only. Every absorbing boundary is refused when the Simulation is built, and the default boundary is "cpml", so pass boundary="pec" explicitly;
  • a uniform, non-dispersive dielectric filling the whole domain. A dielectric or conductivity interface is refused;
  • soft sources with amplitude_kind="field" (add_source) and point probes.

It refuses everything else before the first step: interior conductors of any kind (volumes, sheets, wires), ports, TFSF, waveguide, coaxial and Floquet ports, lumped RLC elements, dispersive materials, DFT planes, NTFF boxes, graded meshes and subgridding. run() also refuses until_decay, snapshots, checkpointing, subpixel smoothing and conformal_pec.

Interior PEC is refused at every factor. A conductor inside the domain made the ADI fields grow without bound, even at factor 1. Preflight reports adi_interior_pec_unsupported, and run() and forward() raise even if you skip preflight. A PEC domain boundary is fine. For a model with metal inside, use solver="yee".

solver="adi" is differentiable: jax.grad flows through the implicit solves.

Limits

  • Experimental. The 3-D lane is checked against an analytic PEC cavity (within 2 % at factor 2), and the 2-D TMz lane against a cavity resonance at factor 5. Neither contains a conductor or material interface, and ADI refuses both.
  • No demonstrated speed-up. The larger step is allowed, but no measured end-to-end speed and accuracy gain on a real stiff mesh has been published. Do not assume ADI is faster for your model.
  • Accuracy falls with the factor. Keep adi_cfl_factor <= 2 for frequency-accurate results, or use Yee.
  • No interior metal, ports or S-parameters. Use solver="yee" for antennas, circuits and anything you will publish.
  • Status and scope: see the support matrix.

For a longer walk-through, run examples/tutorials/adi_solver_demo.py from a source checkout.

Back to top ↑