Surface impedance: theory and validation
For API parameters, model setup, and troubleshooting, start with Surface impedance and impedance volumes. This page defines the boundary model and its discrete implementation, then records the validation evidence. Runtime restrictions are listed once in the practical guide; a derivation here is not a claim of support for additional geometries or backends.
The published HTML guide renders the equations and cross-references in full.
On this page
Conventions and continuous boundary model
Time, propagation, and current
gprMax uses
A forward mode in local coordinate w varies as
Consequently Im(beta) and Im(n_eff) are negative for a passive lossy
forward mode, and
Let \(\hat{\mathbf n}_m\) point from the excluded metal into the retained dielectric. The surface current and scalar boundary law are
The boundary treatment uses the collocated tangential E and H method of Kobidze [KOB2010]. Both fields in the impedance condition are evaluated at the conductor surface. In this implementation, the boundary magnetic field is represented by the surface current \(\mathbf K\) and coupled to the boundary E degree of freedom through the clipped circulation and local ADE update described below.
Here, a surface-current port is an internal boundary coupling, not a user-defined voltage or eigenmode measurement port. For an electric edge with unit tangent \(\hat{\mathbf t}_p\), it uses
With this convention, the time-averaged power dissipated at the surface is
which is non-negative when \(\operatorname{Re}Z_s\ge 0\).
Rational state-space impedance
The reusable continuous model is
It is impedance, rather than admittance, because retaining the surface current in the local boundary relation avoids fitting a very large \(1/Z_s\) for a good conductor. The implementation accepts a proper real realization internally: there is no proportional \(sE\) term. Users select resistance, a preset, or conductivity rather than supplying the realization coefficients. Every fitted model must specify a finite validity band. FDTD can advance the passive realization over its whole discrete spectrum, but the specified fit accuracy applies only inside that band. An impedance-aware FDFD solve refuses to extrapolate a declared physical or bilinear-warped evaluation frequency.
At construction time gprMax verifies that the generated coefficients are
finite, their dimensions are consistent, every eigenvalue of A has strictly negative
real part, and the direct term is non-negative. At the actual FDTD time step
the code additionally checks the mapped unit-circle response for negative
real impedance. Active surface impedances are not part of the public API.
Common-metal Foster presets
For a thick good conductor, the target under the stated time convention is
The stored resistivities for pure bulk metals at 293 K are:
Preset |
Resistivity (Ohm metre) |
Conductivity (S/m) |
Source |
|---|---|---|---|
aluminium |
\(2.650\times10^{-8}\) |
\(3.774\times10^{7}\) |
|
copper |
\(1.676\times10^{-8}\) |
\(5.966\times10^{7}\) |
|
gold |
\(2.192\times10^{-8}\) |
\(4.562\times10^{7}\) |
|
molybdenum |
\(5.340\times10^{-8}\) |
\(1.873\times10^{7}\) |
|
palladium |
\(1.054\times10^{-7}\) |
\(9.488\times10^{6}\) |
|
silver |
\(1.586\times10^{-8}\) |
\(6.305\times10^{7}\) |
|
tungsten |
\(5.280\times10^{-8}\) |
\(1.894\times10^{7}\) |
|
zinc |
\(5.964\times10^{-8}\) |
\(1.677\times10^{7}\) |
The measured reference quantity is stored as resistivity and inverted only when constructing the target impedance. Named presets describe pure bulk metal at the reference temperature, not an alloy or plated finish.
The fit uses a positive-real Foster form
The target is first normalised by the lower fit frequency and by its impedance scale. For each requested runtime order, deterministic logarithmic relaxation grids with several out-of-band extensions are tested. Active subsets from slightly overcomplete grids supply additional non-uniform starting points. The pole locations are then refined in logarithmic frequency by deterministic bounded Powell searches. At every nonlinear evaluation, column-scaled bounded least squares fits the direct term and Foster residues to the real and imaginary parts of the target with relative-error weighting. The residues remain non-negative, so the result is passive over the complete frequency axis, not only at the sample points. A separate grid of at least 16,385 points certifies the reported maximum and RMS errors.
Automatic order selection tests Foster models with 1 through 64 poles in
ascending order. It stops at the first count whose deterministic local searches
produce a certified maximum complex relative error no larger than
fit_tolerance. This is a sequential local model-order search, rather than a
claim of a mathematical global optimum over all possible pole locations. An
explicit integer is an exact state count.
The normalised good-conductor problem depends on bandwidth ratio rather than
conductivity or absolute frequency, so each ratio-and-pole-count realization
is cached and scaled to the requested band and metal. That realization is
independent of the requested tolerance; tolerance is used only to accept or
reject its certified error during order selection. Consequently every
common-metal preset selects the same pole count for the same frequency ratio
and tolerance. The reported fit error still applies only inside the requested
band.
For the default 0.2% tolerance, representative selections are:
Fit band |
Band ratio |
Selected poles |
Maximum relative error |
|---|---|---|---|
10–10.1 GHz |
1.01 |
1 |
0.10304% |
8–12 GHz |
1.5 |
2 |
0.14848% |
8–16 GHz |
2 |
3 |
0.03695% |
0.1–10 GHz |
100 |
8 |
0.1341% |
1 MHz–100 GHz |
100,000 |
13 |
0.1412% |
The realization stored by gprMax is
This scaling balances the first-order input and output coupling while preserving the Foster transfer function.
Exact trapezoidal ADE
Continuous state equation
For one boundary port, the continuous state relation is
The state is convolution memory for the surface law; it is not an electric or magnetic field inside the conductor. gprMax stores \(e^n\) and \(\mathbf x^n\) at integer electric times and \(k^{n+1/2}\) at the magnetic half time.
Discrete runtime coefficients
Trapezoidal integration gives
where
The impedance output is centred at the same half time as the surface current:
F, G, L, and Z0 define the exact discrete law used by both the
FDTD kernel and FDFD reduction. The packed FDTD coefficients store its diagonal local form
described below. gprMax requires Z0 to be finite and strictly positive. A
constant resistance is the order-zero case: F, G, and L are empty
and Z0 is the resistance.
Local Foster recurrence
For the supported metal realization, \(A\) and therefore \(F\) are diagonal. The time-step kernel does not store or multiply the zero off-diagonal entries. For pole \(m\), define
The history and state update for surface-current port \(p\) then reduce to
The read-only \(f_m,q_m\) coefficients are shared by every port using a material, while every port owns its own local \(y_{p,m}\) history. The history is summed once, the locally implicit electric edge is solved, and the independent pole states are then advanced in place. No second state buffer or dense pole-to-pole matrix product is required.
Discrete passivity
The trapezoidal map sends a discrete phase \(\theta\) to
For passive user models, gprMax samples this warped response from DC towards
the unit-circle Nyquist point and requires a non-negative real impedance to
floating-point tolerance. It also requires a strictly Hurwitz continuous
A. These checks complement, rather than replace, ordinary mesh
convergence and long-time decay tests.
Discrete geometry and contacts
Rasterized topology
The final rasterized cell ownership is authoritative. The topology check runs after all geometry objects and ordered overwrites have produced the cells used by the solver. Curved and oblique surfaces are therefore represented by the same Yee-aligned staircase as other gprMax geometry, and two individually valid primitives can still produce an invalid final union or cutout.
Impedance cells must connect locally through full voxel faces. Around a Yee edge, one impedance quadrant, two adjacent impedance quadrants, or three impedance quadrants form valid flat or staircased boundaries. Exactly two diagonally opposite impedance quadrants touch only through that edge. This non-manifold pattern is rejected because it does not define an unambiguous clipped H circulation and local boundary normal.
At every grid vertex, the impedance cells and the retained cells in the
incident 2 x 2 x 2 voxel neighbourhood must each be connected through
voxel faces whenever the respective set is non-empty. This rejects both
vertex-only impedance contacts and a pinched retained region. The check is
binary across surface models: cells assigned any surface-impedance ID count
as impedance cells, even when the IDs differ. Consequently, two impedance
regions that meet through a face form one excluded volume at that interface;
the internal metal-to-metal face receives no boundary condition.
This is a local rule, not a requirement that every impedance object in the model belong to one connected component. Separate bodies remain valid when they do not touch through only an edge or vertex and every resulting boundary is closed and manifold. To repair an invalid contact, add or thicken impedance cells so the regions connect through a full voxel face, or move them apart so they share neither an edge nor a vertex. Refining the mesh, increasing a thin feature’s thickness or a curved object’s radius, or adjusting its position can also produce an unambiguous rasterized boundary.
Yee degrees of freedom
Let a candidate electric edge be oriented along Cartesian axis a. Four
cell-centred quadrants surround that edge in the transverse b-c plane.
The compiler classifies the edge as follows:
zero metal quadrants: use the ordinary Yee update;
four metal quadrants: remove the electric degree of freedom;
one, two adjacent, or three metal quadrants: retain one boundary electric degree of freedom and compile a sparse impedance row;
exactly two diagonally opposite metal quadrants: reject the non-manifold edge contact before any field-update data are compiled.
The retained dielectric quadrants determine the electric mass and the conductive mass,
Thus a flat boundary retains one half of the ordinary dual area. A convex box edge retains three quarters; re-entrant staircase configurations can retain one quarter. Heterogeneous retained quadrants are integrated independently, including Debye, Lorentz, Drude, and inclusive mixtures. Polarization histories use only the retained areas; repeated quadrants of the same material share a history with their areas summed.
Each retained quadrant also contributes half-line magnetic-circulation segments. Duplicate segments are coalesced. Every metal/dielectric face adjacent to the electric edge creates a surface-current port, so one electric edge at a staircase corner can own more than one independent ADE state. The edge is shared, but there is one port per adjacent face and per surface model.
Interior H components are assigned zero update coefficients. At an interface, the normal H degree of freedom remains associated with the retained material; tangential boundary action is supplied by the surface current. The local face-connectivity checks above ensure that this clipped update is compiled only for an unambiguous manifold boundary.
Contacts with PEC and PMC volumes
Isotropic PEC, PMC, and surface-impedance volumes may coexist and touch.
Custom materials with infinite electric or magnetic conductivity receive the
same treatment as the built-in pec and pmc materials.
If any incident quadrant is PEC, the shared tangential E component is forced to zero and has no surface-impedance update or surface-current state. This precedence is independent of the drawing order of adjacent volumes. An existing PEC component constraint is also preserved. A diagonal PEC/SIBC contact with two separating retained quadrants produces an aggregated warning with a count and up to three example Yee-edge coordinates. Face-sharing PEC/SIBC contacts do not produce this warning.
PMC compatibility uses the existing volume solver’s H constraints. A contour sample whose final H-component material is PMC is omitted from the sparse circulation because its update coefficients force it to zero. This does not remove a quadrant’s electric storage or conductivity contribution, change the dual area, or delete an impedance-current port. It produces the same update as retaining that sample with H equal to zero. This feature does not change the PMC volume’s boundary discretisation. Domain symmetry planes use the separate treatment described below.
Directional PEC/PMC material mixtures at the impedance boundary are rejected: their averaged voxel material does not retain the directional information needed by this compiler. Use isotropic conductor volumes for these contacts.
The runnable example
examples/features/impedance_surface/pec_pmc_contacts.py places a copper
SIBC block between PEC and PMC volumes. It writes a geometry view and electric
field traces at the PEC, PMC, and exposed SIBC contacts:
python examples/features/impedance_surface/pec_pmc_contacts.py --output-dir results/contacts
Domain symmetry planes
PEC and PMC SymmetryBoundary planes are supported on all six domain faces,
including intersecting planes. An impedance volume may meet a symmetry plane;
its boundary must satisfy the topology rules after reflection across that
plane. The cut through the impedance interior does not create an end cap.
On a PEC plane, tangential E remains zero and has no impedance-current state. On a PMC plane, the clipped electric update integrates only the physical quadrants and closes the contour along the plane, where tangential H is zero. The reduced electric area gives the same update as the full mirrored geometry with odd tangential H. Surface-current ports also use their physical lengths; reported surface areas describe the modeled portion of the geometry.
The contact example can cut all three conductor volumes at the x0 plane
and add a receiver on that plane:
python examples/features/impedance_surface/pec_pmc_contacts.py --symmetry pmc --output-dir results/symmetry
Use --symmetry pec for the corresponding PEC plane. The ordinary source,
PML, and solver restrictions in Surface impedance and impedance volumes still apply.
Sparse locally implicit FDTD algorithm
Clipped-circulation stability
The public timestep cap is applied as
Here the default requested factor is one. The operational consequences and user command are in Automatic time-step margin.
For a homogeneous nondispersive exterior, retained voxel quadrants give matched electric and magnetic energy weights: each retained voxel contributes one quarter of its volume to an incident E edge and one half to an incident H face. With these weights, the compiled clipped Ampere circulation is the weighted transpose of the retained Faraday curl. The resulting geometric stability bound is the ordinary Cartesian CFL bound; quarter-cell electric areas alone do not imply an additional timestep reduction.
A strict margin below that bound matters. A retained one-voxel cavity can attain the bound exactly. Before the automatic SIBC margin was introduced, a source-free CPU audit of a passive 1 MOhm cavity at the rounded Cartesian CFL timestep showed approximately 198-fold field-norm amplification in double precision and severe late-time growth in single precision over 200,000 steps. A timestep factor of 0.99 kept both runs bounded. The tested copper-preset cavity also remained bounded at that timestep. The Automatic time-step margin now applies the 0.99 margin without requiring an explicit user command.
A historical audit using the ordinary rounded timestep and complete CPU solver
confirmed that, on the 1 mm test mesh, dt is rounded down by two binary64
ULPs and is below the mathematical CFL limit. Nevertheless, the stored
float32 coefficients of the 1 MOhm cavity give an effective Courant factor
of approximately 1.000000018 and predict the observed growth. A factor of
0.9999999 removed exponential growth in that case but still allowed large
transient amplification. See
testing/validation/impedance_surface/default_cfl_report.md for the
coefficient derivation and checks of the actual timestep rounding.
This is a demonstrated margin for the tested cases, not an unconditional stability guarantee for dispersive bulk media, PML, or every contact/source configuration. Surface passivity and amplification eigenvalues should be checked together with the geometric energy balance and actual long-time field growth.
Reproduce the audit with
python -m testing.validation.impedance_surface.stability --steps 20000.
Use --historical to disable the automatic cap within this validation
driver and reproduce the pre-protection results; this diagnostic switch is
not a simulation input option. Protected results use separate filenames so
the historical records remain available.
The derivation, scope, recorded results, and precision-sensitive reproducer
are in testing/validation/impedance_surface/stability_report.md.
Integral Ampere row
The geometry compiler creates one integrated Ampere row per retained boundary electric edge:
Here \(r_H\) is the clipped line integral of the ordinary retained H samples. \(g_p\) includes the oriented surface-current line metric; with the current compiler convention it is the negative of the accumulated positive face length. Surface normals and magnetic signs are generated from the voxel topology rather than hard-coded in the ADE kernel.
Define
The scalar port relation gives
Substitution eliminates every port current from the local solve. The exact expression executed by the Python reference path and Cython kernel is
The kernel then recovers every \(k_p^{n+1/2}\) and advances each local Foster pole
This analytic scalar elimination naturally handles several faces sharing one electric edge; it does not perform a dense solve at each time step. A flat boundary edge normally has one port and one current. A convex manifold edge can have two face ports: they share the scalar electric solve but retain separate histories and separate \(k_p\) values.
Dispersive retained quadrants
At a dispersive contact the same scalar elimination includes both bulk polarization and surface-current histories. Let \(A_q\) be the retained area assigned to material \(q\), and let \(EA_q,EB_q\) be its ordinary bulk dispersive electric coefficients before division. The electric row uses
Each retained material pole owns the area-scaled complex history
\(S=\epsilon_0 A_q T\). Using the bulk recurrence coefficients
eqt, zt, and eqt2 gives
Both the instantaneous polarization contribution and Drude’s equivalent conductivity are included in \(EA_q,EB_q\). Updating only the history term would omit their implicit contribution to the electric solve. The sparse kernel advances \(S\) with the final boundary E, after the bulk A/B stages. The private held material prevents those stages from advancing the same histories. Resetting the grid clears both polarization and surface-current states.
Real and imaginary parts occupy separate columns in the field precision. Per pole there are six real coefficients and two real state values. Each boundary edge also stores a pole offset and two corrections to the physical non-dispersive \(a_+,a_-\) values. These arrays are empty when no dispersive material touches the boundary. The magnetic circulation and surface-port geometry are unchanged.
Packed data and update order
The geometry compiler stores:
boundary edge component/index, H range, and port range;
\(a_+\), \(a_-\), and retained dual-area fraction;
H component/index records and signed half-line weights;
the precomputed old-E coefficient and inverse scalar denominator for each boundary edge;
port model, unique state offset, \(g_p\), \(g_p/Z_{0,p}\), \(1/Z_{0,p}\), face normal, and face area;
one copy of the \(f_m,q_m\) vectors and \(Z_0\) for each used material model;
one in-place \(y_{p,m}\) value per port and selected pole.
The dense material arrays use private surface-hold and volume-void
rows. The ordinary electric update preserves a boundary value without
applying a full-cell curl, and zeros interior fields. After the magnetic
update and its source corrections, the ordinary electric stages and electric
source corrections run. The sparse impedance update then replaces every held
boundary E value with the locally implicit result. This makes the impedance
row authoritative and prevents a hard source from silently overwriting it;
explicit electric-edge overlaps are rejected during compilation.
Each boundary electric edge and all of its port-state slices have one owner.
The Cython implementation can therefore use OpenMP prange without atomics
or cross-edge state races. The one or two histories on an edge are thread-local
scalars. Runtime work and state storage scale linearly with boundary area and
the selected Foster order, rather than conductor volume:
where \(N_{\Gamma,K}\) is the number of local surface-current ports and \(\overline N_p\) is their average selected pole count. Shared model coefficient storage is also linear in pole count. The optimized representation therefore avoids both the former quadratic dense-matrix arithmetic and its second per-port state buffer.
Exact surface-ADE reduction for FDFD
Algorithmic impedance
For a physical solve frequency \(f\), set
The discrete state recurrence has the exact harmonic response
For the diagonal Foster representation this is equivalently the local pole sum
The midpoint boundary equation is
For a trapezoidal realization,
The mode frequency must be positive and below temporal Nyquist. For a dynamic model, both \(f\) and the bilinear-warped frequency
must lie inside the model’s declared fit band. This catches a subtle form of ADE extrapolation near Nyquist.
Clipped row in the P/Q solver
The implemented FDFD path eliminates the scalar surface currents into the
electric coefficient rather than appending them as eigenproblem unknowns.
For boundary edge e with retained dual area \(A_e\), attached port
lengths \(\ell_p\), and the same integrated masses used by FDTD, the
dispersion-compensated solver uses
This makes the material term with the leapfrog temporal symbol reproduce the exact discrete-time surface load:
The standard rectangular finite-difference curl row is replaced by the
compiled clipped line circulation, normalized by \(A_e k_{0,\mathrm{operator}}\), where
\(k_{0,\mathrm{operator}}=\Omega/c\) is solver.operator_k0.
Independent retained masks remove metal-interior E and H
degrees of freedom without
misusing PEC masks; in particular, interface-normal H can remain present when
a collocated tangential E is a valid impedance-boundary unknown. The existing
P/Q reduction solves for \(\lambda=-n_{\mathrm{operator}}^2\), with
\(n_{\mathrm{operator}}=K_w/k_{0,\mathrm{operator}}\). The normal spacing \(\Delta w\)
then determines the phase propagation constant and public effective index:
The passive forward branch gives attenuation and evanescent decay in positive
w. Modal field reconstruction uses \(n_{\mathrm{operator}}\); source
and monitor spatial phases use \(\beta\).
Low-level calls that omit fdtd_dt retain the physical-frequency P/Q
normalization: the coefficient denominator uses \(j\omega\epsilon_0A_e\)
and \(k_{0,\mathrm{operator}}=k_0=\omega/c\), while the boundary numerator still comes from its
exact discrete recurrence. See Eigenmode ports: theory and numerical methods for both optional grid
parameters.
Important
The surface ADE, midpoint factor, boundary electric mass, conductivity, clipped transverse curl, and retained boundary polarization histories are reduced exactly for the FDTD time step. Eigenmode sources also use the owning grid’s leapfrog temporal symbol and longitudinal spatial difference. Bulk nondispersive conductivity includes its midpoint factor. Away from the surface, bulk dispersive poles still use their analytic physical-frequency response rather than the exact volume ADE transfer, so the general dispersive bulk eigenproblem is not fully time discrete. Keep modal anchors below Nyquist and check mesh/time-step convergence.
The longitudinal \(K_w\) coupling remains the standard implicit P/Q term. The source-plane mapper checks that the omitted longitudinal H weights form equal and opposite contributions in the two cells adjacent to the plane. That is why a changing wall cross-section or an impedance end cap at the modal plane is rejected.
Dispersive retained media and volume ADEs
Dispersive retained quadrants are supported by the coupled scalar row above. The modal boundary mapper also includes their exact discrete response. For \(z=\exp(j\theta)\), a complex pole contributes the real-output transfer
If \(\delta_\pm=a_\pm^{\mathrm{disp}}-a_\pm\), the additional midpoint-time Ampere load is
Both conjugate branches are required for Lorentz materials; taking the real part of a transfer evaluated at complex \(z\) gives an incorrect phase. The modal mapper adds \(\Delta Y/(j\Omega\epsilon_0 A_{\rm ret})\) to the boundary relative permittivity. Interior bulk dispersive rows still use their analytic physical-frequency response, so making the entire bulk eigenproblem exact in time remains separate work.
Eigenmode solution and FDTD injection
A direct modal solve reuses the component IDs, retained masks, clipped H
weights, dual fractions, port models, FDTD dt, and normal cell spacing
from the already compiled grid. There is no separately
redrawn FDFD wall.
This shared geometry is as important as sharing the exact discrete ADE law
(f, q, and Z0 in its local Foster form): a half-cell area or sign
mismatch would change both loss and mode phase.
For a rectangular impedance guide, extend the port one cell into the opaque
wall beyond the inner aperture bounds guide_y0, guide_y1, guide_z0,
and guide_z1. Here dy and dz are the transverse cell sizes. This
keeps the SIBC wall inside the port’s PEC rim, with or without a virtual guide:
scene.add(gprMax.EigenmodeBand(
id='copper_te10', fmin=8e9, fmax=12e9, points=21,
))
scene.add(gprMax.EigenmodePort(
port=1,
p1=(0.04, guide_y0 - dy, guide_z0 - dz),
p2=(0.04, guide_y1 + dy, guide_z1 + dz),
direction='+',
modes=(1,),
anchors=(8e9, 9e9, 10e9, 11e9, 12e9),
plot_fields=False,
))
scene.add(gprMax.EigenmodePort(
port=2,
p1=(0.08, guide_y0 - dy, guide_z0 - dz),
p2=(0.08, guide_y1 + dy, guide_z1 + dz),
direction='-',
modes=(1,),
anchors=(8e9, 9e9, 10e9, 11e9, 12e9),
plot_fields=False,
))
scene.add(gprMax.EigenmodeExcitation(
port=1, mode=1, waveform='auto', plot_waveform=False,
))
The complete four-wall geometry is shown in
testing/validation/impedance_surface/validate_copper_wall_waveguide.py.
The mode solver returns fields on their native component-specific Yee grids.
Lossy walls generally produce genuinely complex field profiles. The source
therefore uses in-phase/quadrature synthesis when a single real profile is
insufficient. The equivalent-current TF/SF correction injects tangential E
into the magnetic update and tangential H into the electric update. Magnetic
coefficients include the \(\Delta t/2\) temporal staggering and the
half-normal-cell spatial phase. Coordinate-basis handedness is applied when a
global y-normal plane gives a left-handed local (u,v,w) ordering.
Modal receivers project the total fields onto the same tracked FDFD basis and separate forward and backward coefficients. For two downstream planes at \(w_1\) and \(w_2\), a uniform single-mode guide should give
This two-plane ratio removes source amplitude and most startup sensitivity. The source-plane ratio \(b_1/a_1\) independently measures launch mismatch. See Eigenmode ports: theory and numerical methods for broadband anchor tracking, one-watt normalization, I/Q source synthesis, modal DFTs, and the complete HDF5 modal schema.
Analytical rectangular-guide reference
For the lossless TE10 mode of a guide with width \(a\), height \(b\), and air filling,
First-order wall perturbation gives the attenuation
For a complex local surface impedance, define the real geometry factor
To first order,
The physical copper reference uses \(Z_s=(1+j)\sqrt{\pi f\mu_0\rho_{\mathrm{Cu}}}\). The discrete FDFD operator test instead uses the exact algorithmic \(Z_{\mathrm{eff}}=Z_{\mathrm{alg}}/c_\theta\), because its purpose is to isolate FDFD/FDTD boundary compatibility at a finite time step. These are different comparisons and should not be conflated.
The end-to-end copper validation also removes the known lossless spatial and temporal dispersion of its cubic Yee grid from its phase comparison. For cubic spacing \(\Delta\), its analytical lossless reference is
That reference replaces \(\beta_0\) by \(\beta_Y\) in the phase term while retaining the continuum perturbation factor \(Q\). The pure continuum result is written separately so mesh dispersion remains visible rather than being mistaken for a copper-boundary error. The FDTD attenuation comparison uses \(-\ln|S_{21}|/L\), so its loss acceptance criterion is independent of this phase correction.
Exact voxel-face PMC
Use SurfaceImpedance(id='wall', resistance=float('inf')) or
#surface_impedance: wall resistance inf to impose the exact
\(Z_s\to+\infty\) limit. Its surface admittance and surface current are
zero. The retained dual area and clipped H circulation remain active:
for a lossless nondispersive retained host. This locates the PMC at the
main-voxel face; it does not zero the nearest retained half-cell H samples.
The built-in volume material pmc retains its existing discretisation.
Using it, or a material with infinite magnetic conductivity, emits a warning:
its H constraints can shift a flat wall’s effective reflection plane by half
a cell. Use infinite SIBC resistance for PMC at the voxel face. The warning
is emitted once per affected grid; unused declarations, internal TE storage
constraints, and SymmetryBoundary(type='pmc', ...) do not trigger it.
The derivation, reflection-plane tests, cavity modes, and long-run results
are in testing/validation/sibc_based_pmc/README.md.
PML and virtual-guide coupling
The supported extrusion, host, and aperture requirements are in Waveguides and absorbers. The auxiliary guide retains independent surface histories.
In 2D, only the live invariant layer is physical: index zero for TM and index one for TE. The compiler projects only active field components onto that layer and excludes artificial invariant-axis end faces. The 1D modal solve preserves Faraday derivatives while replacing the relevant Ampere and constitutive rows with the clipped derivative and discrete ADE response. Modal power is per metre and independent of synthetic invariant-axis spacing. The auxiliary guide extrudes full-mass boundary rows, retains the active Yee staggering, and allocates independent surface histories.
Modal excitation supplies its missing longitudinal circulation to the implicit surface solve and its ADE history. This applies to direct and virtual-guide sources, including exact PMC, whose tangential electric field need not vanish. See Virtual-guide aperture coupling for the aperture’s shared E/H samples and propagation-direction signs.
The coupling adds the PML correction to the magnetic circulation. For retained dual area \(A_e\), let \(Q_e\) be the signed correction to the ordinary curl from the native PML histories. The surface equation is
where \(d_e\) is the local implicit denominator, \(a_e\) its old-field numerator, \(\Phi_e^n\) the bulk-polarization history load, and \(h_p\) the sum of the Foster histories at port \(p\). The denominator and numerator include the retained-area sums of electric storage, conductivity, and instantaneous polarization terms. Uniform extrusion makes the longitudinal clipped-H fraction cancel against the retained area, so the native stretched derivative is applicable. For the continuous stretched-coordinate interpretation and its limitations, see Steven G. Johnson’s Notes on Perfectly Matched Layers. The discrete coupling above follows from the implemented clipped circulation. It preserves the physical \(E^n\) while collecting the PML forcing. After the ordinary local solve, it applies
Here \(S_{em}\) is a bulk-polarization state satisfying \(S_{em}^{n+1}=f_{em}S_{em}^n+b_{em}(E_e^n-E_e^{n+1})\). The geometric curl scaling does not require a homogeneous or lossless host. Different retained materials contribute their own masses and polarization histories; no effective bulk pole model is assigned to the PML capture row. That row has unit curl-correction coefficient and zero ordinary curl and bulk-polarization update, preventing duplicate constitutive updates.
This is algebraically the same coupled solve, including the midpoint-time surface-current and bulk-polarization histories. Adding the PML increment to \(E^n\) before solving would give the wrong damping and history for finite impedance. The automatic time-step factor of at most 0.99 also applies to these models.
Reproducible comparisons with longer physical guides, pulse absorption,
and virtual/continuous guide comparisons are in
testing/validation/impedance_surface/validate_sibc_pml.py and
testing/validation/impedance_surface/virtual_waveguide.py. Exact PMC
image comparisons are in
testing/validation/sibc_based_pmc/pml_mirror.py. These test the supported
extruded configurations; they do not establish stability for arbitrary
PML profiles or unsupported bulk media.
Lossy and Debye/Lorentz/Drude bulk contacts, including layered interfaces,
are checked against independent mirrored bulk grids in
tests/impedance_surfaces/test_pmc_pml.py. Finite surface and bulk histories
are compared with a simultaneous dense solve in
tests/impedance_surfaces/test_lossy_dispersive_pml.py. The copper microstrip
comparison is testing/validation/impedance_surface/validate_microstrip_pml.py.
CPU virtual guides extrude the complete retained-area conductivity and bulk
pole coefficients, with independent polarization and Foster histories on
every auxiliary edge. Their ordinary dispersive aperture samples use the
same bulk ADE recurrence as the continuous grid. Comparisons in
tests/test_virtual_waveguide_impedance.py cover lossy, Debye, Lorentz,
and Drude contacts, mixed hosts, both precisions, rotated 3D and TE/TM
guides, and active excitation. The comparison fixes the PML profile in both
models: cropping opaque padding otherwise changes the cross-section average
used to choose the default maximum PML conductivity.
The cropped-window cases in that test file also compare a copper ground plane
and lossy FR-4 microstrip against a physical continuation with explicit PEC
plates at the window edges, in all three orientations and both directions,
with active and passive ports. The modal PEC constraints include the static
Faraday equations at clamped E samples. The auxiliary grid omits those entire
surface rows and freezes their detached main-grid counterparts, while retaining
every magnetic term and ADE coefficient of unconstrained rows. All ports
replace complete physical SIBC walls on the rim by PEC, matching the auxiliary
update when a virtual guide is attached. The physical-continuation
tests cover one or both walls on that rim, active and passive ports, all three
normals, and both propagation directions. Opaque padding beyond a physical
wall retains its surface equation in both direct and virtual ports.
The profile audit retained in
testing/validation/impedance_surface/results/sibc_pml/profile_audit.json
found late growth with two duplicated unshifted HORIPML terms in both an
ordinary PEC guide and an SIBC guide. Reducing the time step to 0.99 alone
does not guarantee stability for arbitrary custom PML parameters.
The follow-up investigation identified the negative real part of the
unshifted product stretch as the cause. A second frequency-shift profile
tracking 1.1 * sigma1 removed this failure in the PEC and
finite/dispersive SIBC tests; see Selecting a stable second-order HORIPML profile and
testing/validation/impedance_surface/results/pml_profile_investigation/README.md.
Second-order HORIPML profile guard
HORIPML multiplies its two stretching factors. Duplicating the unshifted first-order defaults is therefore not a safe way to create a second-order absorber. For \(\kappa_1=\kappa_2=1\), \(\alpha_1=\alpha_2=0\), and identical \(\sigma\), the product has
This is negative at low frequencies and can amplify evanescent fields. The resulting growing mode persists as the time step is reduced; a CFL safety factor does not repair this profile.
During PML coefficient construction, gprMax rejects second-order HORIPML
profiles with negative real total stretch at any resolved E or H sample,
beyond floating-point tolerance. It checks the analytical quadratic in
(omega * epsilon0)**2 over all positive frequencies, including terminal
samples and the full profile before MPI partitioning. The error identifies
the slab/profile and sample, reports its parameters, and suggests a repair.
Boundary, internal, and virtual-guide absorbers share this check. Explicit
sigmamax=0 remains zero; only None requests automatic conductivity.
Passing this check excludes the demonstrated failure mechanism, rather than
certifying stability for every geometry and material.
For a classical/CFS pairing with \(\alpha_1=0\), a pointwise condition
which removes this mechanism is \(\alpha_2\geq\sigma_1/\kappa_1\)
with \(\kappa_1\kappa_2\geq1\). Alpha and sigma use the same units in
these input commands. Match the grading at every electric and magnetic
sample, including polynomial order and direction. For the duplicated
unit-kappa quartic profile, setting the second alpha profile to
1.1 * sigma1 with matching quartic grading kept the tested PEC and
finite/dispersive SIBC guides bounded for 20,000 steps.
This condition addresses the negative-real-stretch mechanism, not every
possible material, mesh, or PML stability issue. The reproducible diagnosis,
input recipe, time-step controls, and reflection results are in
testing/validation/impedance_surface/results/pml_profile_investigation/README.md.
MRIPML adds its pole terms and has different parameter normalization; do
not apply the HORIPML product argument to that formulation.
Validation and benchmarking
The 2D matrix and long-run drivers complement the comparisons below:
python -m testing.validation.impedance_surface.validate_2d --section matrix
python -m testing.validation.impedance_surface.validate_2d --section late
They cover all TE/TM axes and propagation directions, both precisions,
constant and fitted impedance, and representative 20,000-step guides with
PML. The recorded PMC evidence remains under
testing/validation/sibc_based_pmc; general surface evidence remains under
testing/validation/impedance_surface. Their configuration-specific
bounds do not certify arbitrary PML profiles or unsupported host media.
FDFD attenuation and modal launch
The focused FDFD operator test constructs a copper-lined rectangular guide, compares \(-k_0\operatorname{Im}n_{\mathrm{eff}}\) with the TE10 perturbation result using \(Z_{\mathrm{alg}}/c_\theta\), and applies a 2% relative tolerance.
testing.validation.impedance_surface.validate_copper_wall_waveguide is the
physical common-metal case. It uses a 1.6 mm by 0.8 mm copper-lined guide on a
0.1 mm cubic grid. TE10 is evaluated from 130 to 150 GHz, below the 187.37 GHz
next-mode cutoff, over a 40 mm reference-plane spacing. The independent
good-conductor formula predicts 0.204–0.234 dB insertion loss, making copper
loss materially larger than in the initial microwave-scale test.
The comparison uses 21 uniform validation frequencies from 130 to 150 GHz,
and each is an exact source-port FDFD anchor. The copper excitation spans
120–150 GHz on a 31-point, 1 GHz DFT grid. The source port uses all 31 bins
plus guards at 100, 110, 160, and 170 GHz, for 35 anchors. Each passive port uses
only 11 anchors: the four guards and seven uniformly spaced anchors from 120
to 150 GHz. Dense source anchors preserve exact in-band neff validation
and modal injection; sparse guarded passive anchors avoid repeating
unnecessary FDFD solves while retaining smooth modal interpolation. Starting
the excitation sufficiently above the 93.69 GHz TE10 cutoff prevents a slow
near-cutoff tail from entering the finite record.
The copper surface explicitly uses fit_order='auto' over 80–180 GHz with
a 0.2% tolerance and selects three poles. The model uses a 210 mm domain and a
500 ps record. The active source is at 90 mm and the passive planes are at 105
and 145 mm. The finite walls extend almost to the domain ends, leaving 97.415
ps between the record endpoint and the conservative earliest wall-end return.
This gives the source response time to settle while retaining a causally
isolated one-way propagation measurement.
The copper release checks cover three milestones. The attenuation \(-k_0\operatorname{Im}n_{\mathrm{eff}}\) stored for each exact in-band FDFD anchor is compared with \(Q\operatorname{Re}Z_s\) using a 1% relative L2 error threshold. The driven FDTD port must have maximum \(S_{11}<-20\) dB after the complex modal field is injected. Finally, attenuation obtained from the FDTD two-plane propagation factor is compared with the same perturbation theory using a 2% relative L2 error threshold. The workflow therefore exercises the copper preset, Foster fit, exact FDFD boundary reduction, complex modal source, FDTD ADE, modal projection, and propagation loss in one accepted result.
In the retained double-precision four-thread result with bulk dispersion compensation, the impedance fit error is 0.026023%, the FDFD and FDTD attenuation errors are 0.681438% and 0.759867%, and maximum reflection is -101.0893 dB. The four-thread rerun on 2026-09-04 completed in 147.019 s including analysis and plot generation.
Run the validation from the repository root:
python -m testing.validation.impedance_surface.validate_copper_wall_waveguide --threads 4
Use --reuse to reanalyse compatible cached solver output. The validation
exits non-zero when an acceptance criterion fails and writes numerical data
plus a machine-readable summary below its selected output directory.
Sparse-kernel performance
testing.benchmarking.benchmark_impedance_box alternates otherwise
identical baseline, resistive, automatic-order copper, and explicit-order
copper runs. It times the full solve and also isolates the sparse kernel and a
bulk-plus-surface hot loop:
python -m testing.benchmarking.benchmark_impedance_box \
--cells 80 --iterations 250 --threads 4 --repeats 3 \
--fit-band 8e9 12e9 --fit-tolerance 2e-3 \
--explicit-orders 4 8 16 32 \
--kernel-iterations 1000 --kernel-repeats 3 \
--hot-iterations 250 --hot-repeats 3 \
--output impedance_box_benchmark.json
The JSON records requested and selected order, boundary edges, surface ports, per-port state values and bytes, packed coefficient bytes, edge/port/pole update rates, median solve overhead, and bulk-plus-surface hot-loop overhead. The resistive case separates fixed sparse-boundary cost from pole cost, while the explicit-order sweep reveals order scaling. Results depend on compiler, CPU, thread count, boundary area, and surface-to-volume ratio; timing values are not portable CI thresholds. Wall-clock construction time should not be mixed with time-stepping overhead.
Dispersive-contact benchmark
The box benchmark accepts --exterior debye, lorentz, drude, or
mixed. The same exterior is used for its ordinary-grid baseline. The
dispersive hot loop includes both electric A/B stages, and the JSON records
boundary polarization pole count, state bytes, coefficient/index bytes, and
polarization update rate in addition to the surface-current measurements.
The combined sweep also runs pulse-driven Python/Cython comparisons, late-time decay checks, and convergence toward an ordinary PEC box as the surface resistance decreases:
python -m testing.benchmarking.benchmark_dispersive_impedance \
--cells 48 --iterations 250 --threads 4 --repeats 3 \
--explicit-orders 4 8 --kernel-iterations 1000 --kernel-repeats 3 \
--hot-iterations 250 --hot-repeats 3 \
--output testing/benchmarking/results/dispersive_impedance_2026-09-07.json
The recorded 2026-09-07 sweep passes all four driven exterior cases. Maximum Python/Cython receiver relative L2 error is \(1.17\times10^{-15}\). Reducing resistance from 0.01 to 0.001 Ohm reduces error against the PEC receiver trace approximately tenfold in every case. The final 200-sample peak is at most \(1.42\times10^{-4}\) of the run peak. These are discrete solver and limiting-case checks, not a general continuum-accuracy or unconditional-stability guarantee.
For the 6,912-edge timing box, a uniform two-pole exterior adds 221,184 state
bytes and 801,796 coefficient/index bytes. The mixed exterior needs slightly
more state at material seams. Full raw repeats, hardware information,
acceptance criteria, and a readable summary are saved in
testing/benchmarking/results/dispersive_impedance_2026-09-07.json and the
adjacent .md report. Timing noise on a shared desktop prevents using
these samples as a material speed ranking or a portable performance limit.
Analytical sphere and plane-wave comparisons
Two additional CPU validations compare the driven surface boundary with analytical electromagnetic solutions:
python -m testing.validation.impedance_surface.validate_conductor_sphere --threads 4
python -m testing.validation.impedance_surface.validate_reflection_phase --threads 4
The sphere case compares 2–7 GHz backscatter and complex angular scattering for a 16 mm radius sphere with both impedance-boundary Mie theory and the full homogeneous conducting-sphere Mie series. Conductivities are \(10^3\) and \(5.8\times10^7\) S/m. Refining the staircased boundary from 1.5 to 0.75 mm reduces backscatter RMS errors from 1.30/1.26 dB to 0.855/0.832 dB. Both fine meshes pass the 1 dB RMS, 2 dB maximum and 15% complex angular-pattern error thresholds. The coarse results are convergence diagnostics. The bulk reference evaluates scaled Bessel ratios, so the copper interior does not overflow or require numerical skin-depth cells.
The planar case compares the complex electric reflection coefficient
over 1–8 GHz, including a Debye material directly touching the wall. Its relative permittivity is \(2.5+2/(1+j\omega\,80\mathrm{ps})\). Matching incident-reference runs and an independent discrete propagation symbol remove the 30 mm receiver-to-wall propagation phase. Transverse PEC/PMC symmetry faces generate a uniform TEM wave; remote end boundaries cannot return within the 4 ns analysis record. The 0.5 mm mesh has a maximum continuum phase RMS error of 0.001497 degree across the four host/conductivity pairs. Both 1 and 0.5 mm meshes pass all plane-wave acceptance checks. The additional discrete prediction includes time staggering, the retained half-cell mass, Debye recurrence and bilinear impedance realization; its maximum phase RMS error is 0.00005387 degree. A negative-control regression removes the boundary polarisation history and fails the 0.0002 degree discrete error threshold.
Both drivers return a nonzero status on failed acceptance checks and support
--reuse for compatible local caches. Retained CSV, figures and summaries
are under testing/validation/impedance_surface/results/conductor_sphere
and results/reflection_phase. Methods, reference formulas, qualifications
and recorded comparisons are in
testing/validation/impedance_surface/analytical_validation_report.md.
Reproducibility metadata
See Surface-impedance reproducibility metadata for the stored surface realization, discrete coefficients, fit provenance, and modal anchor metadata.
Implementation map
The main implementation files are:
Module |
Responsibility |
|---|---|
|
Model validation/discretization, voxel-boundary compilation, packed records, and the Python reference update. |
|
Metal reference data, good-conductor target, and passive Foster bounded least-squares (BVLS) fit. |
|
OpenMP sparse locally implicit FDTD update. |
|
Geometry-only material resolution, marker creation, and rejection of sheet, line, and directional surface-impedance assignments. |
|
Exact ADE harmonic response and boundary-row effective coefficient. |
|
Independent retained E/H masks and clipped P/Q curl-row replacement. |
|
Maps the compiled three-dimensional boundary onto a direct modal plane and validates propagation invariance. |
|
Broadband modal interpolation and HDF5 storage of the exact complex FDFD effective-index anchors and their validity masks. |
|
Continuous/discrete model metadata and provenance. |
Internal realization diagnostics
These checks concern generated coefficients and low-level implementation work; the public API does not accept arbitrary state-space coefficients. If a preset or conductivity fit fails one of these checks, report the input and fit band rather than editing the internal coefficients to bypass it.
A must be strictly HurwitzMove every continuous pole into the open left half-plane. A pole on the imaginary axis is not accepted, even if a short run appears bounded.
non-positive discrete feedthrough Z0The locally implicit elimination divides by
Z0. Use a proper passive realization with sufficient positive direct term, or re-express the fit in a positive-real Foster form. Do not add an arbitrary epsilon merely to bypass the check.
Extension guide
Zero-thickness sheets
A sheet must retain fields on both sides and impose a jump relation, for example a generalized sheet transition condition. It cannot be implemented by marking a one-cell-thick opaque volume: doing so removes interior degrees of freedom, changes the physical thickness with mesh refinement, and creates the wrong one-sided topology. A sheet extension should introduce two-sided ports at selected Yee faces, define unambiguous ownership where sheets meet, and derive both FDTD and FDFD rows from the same discrete recurrence.
Tensor and nonlocal surfaces
A local tensor impedance couples two tangential currents at one face. Replace
the scalar Z0 elimination with a small block solve and store a vector ADE
state per face. A nonlocal \(Z(\omega,k_t)\) additionally couples
neighbouring faces or introduces tangential surface derivatives; it cannot
reuse the independent-port kernel unchanged.
Accelerators and MPI
An accelerator backend needs device-resident packed edge, port, model, and state arrays plus a sparse boundary kernel after its electric update. MPI needs deterministic ownership of a boundary E edge and its ADE states, magnetic halo availability before the surface solve, and a cross-rank modal plane assembly. The current compiler rejects these paths rather than silently falling back to a different boundary.
References
The Yee grid convention follows [YEE1966]. The collocated tangential E and H surface-impedance method used here is described by [KOB2010]. Background on surface-impedance FDTD boundaries is given by [MAL1992] and [BEG1992]. The preset resistivity provenance is [MAT1979], [DES1984A], and [DES1984S].