
3D Electromagnetics
The Gmsh generator, all four Palace configs, the raw solver output and the analysis script that regenerates every number and figure on this page are public under MIT.
A solver that runs without errors will hand you a number for every frequency you ask about. Some of those numbers describe the physics of your structure. Others describe the mesh you happened to choose. Nothing in the output file tells you which is which.
This study ran the same geometry four times in Palace on cloud GPUs, changing only the mesh density — from 15,524 to 396,740 elements, a 26× range. The differential insertion loss converged cleanly and can be quoted with an uncertainty. The return loss did not: below roughly −18 dB it moved by tens of decibels with refinement and never settled. Same run, same file — one column trustworthy, one column not.
M1 (15,524 elements)
M2 (48,304 elements)
M3 (146,339 elements)
M4 (396,740 elements)
Differential return loss for four mesh densities of the identical geometry. To the right of the dashed line at 8 GHz the two finest meshes agree within 0.24 dB — refining stops changing the answer. To the left, inside the shaded band, those same two meshes separate by up to 9.1 dB, and the coarsest and finest by up to 23 dB. That region is not a physical result; it is the solver's discretisation noise floor sampled at four resolutions.
M1 — coarsest (15,524 elements)
M4 — finest (396,740 elements)
The same comparison for insertion loss. The coarsest and finest meshes — 26× apart in element count — are visually indistinguishable across most of the band and differ by only 0.11 dB at 12 GHz. Insertion loss is a bulk energy quantity, and bulk quantities are forgiving of mesh.
A differential microstrip pair on a low-loss laminate, with a deliberate impedance discontinuity in the middle: the traces narrow from 0.42 mm to 0.22 mm for 2 mm, which is electrically what a connector footprint or an undersized via antipad looks like. The structure is a stand-in for a high-speed serial launch, not a model of any specific connector.
Structure:
Differential pair, 4 ports
Trace width:
0.42 mm
Edge-to-edge gap:
0.20 mm
Dielectric height:
0.20 mm
Length:
10 mm
Discontinuity:
0.22 mm × 2 mm
Laminate Dk:
3.7
Loss tangent:
0.004
Conductor:
Copper, 5.8e7 S/m
Upper region:
Air
Length scale:
mm (L₀ = 1e-3)
Problem type:
Driven
Element order:
2
Band:
0.05 – 12 GHz
Frequency points:
241
Adaptive tol:
1e-3
Traces & ground plane:
Finite conductivity (surface impedance)
Ports 1–4:
Lumped, R = 50 Ω, one excitation each
End walls / outer box:
PMC / 1st-order absorbing
Every level below uses byte-identical geometry, materials, boundary conditions and sweep settings. The only variable is element size. That is what makes the comparison a convergence study rather than a coincidence: any difference in the output is discretisation error and nothing else.
| Level | Elements | Degrees of freedom | Solve time |
|---|---|---|---|
M1 | 15,524 | 109,008 | 230 s |
M2 | 48,304 | 329,004 | 319 s |
M3 | 146,339 | 974,390 | 526 s |
M4 | 396,740 | 2,606,032 | 1,393 s |
All four runs used the adaptive fast-frequency sweep, which reconstructs 241 frequency points from roughly ten full solves. The finest run resolved 2.6 million degrees of freedom in 23 minutes on a cloud GPU.
The obvious test — successive refinements change the answer by a shrinking amount — turns out to be too blunt on its own. It fails a quantity that was already at numerical precision before the study began, because the remaining steps are rounding rather than error, and it fails a quantity that has plainly stopped moving but whose last step wobbles upward by hundredths of a decibel. Four verdicts are needed, not two.
Every step smaller than 0.02 dB — rounding, not error. The quantity was already at numerical precision, so there is nothing left to extrapolate.
Steps shrink cleanly and follow a power law, so Richardson extrapolation gives a limit and an uncertainty.
Stopped moving, but not along a clean power law. Trustworthy as a value; no extrapolation is quoted.
Still moving by amounts that do not shrink, or that shrink but remain far larger than the tolerance. The number describes the mesh, not the structure.
The two quantities below are from the same four runs, read at the same frequencies.
| Quantity | Freq | M1 | M2 | M3 | M4 | Verdict |
|---|---|---|---|---|---|---|
| Sdd21 insertion loss | 3 GHz | −0.075 | −0.066 | −0.064 | −0.062 | flat |
| Sdd21 insertion loss | 12 GHz | −0.871 | −0.808 | −0.781 | −0.764 | converged |
| Sdd11 return loss | 12 GHz | −8.45 | −8.82 | −8.99 | −9.09 | converged |
| Sdd11 return loss | 9 GHz | −15.33 | −15.19 | −15.15 | −15.10 | settled |
| Sdd11 return loss | 6 GHz | −49.64 | −32.59 | −29.50 | −27.87 | not converged |
| Sdd11 return loss | 3 GHz | −26.50 | −32.17 | −36.48 | −41.21 | not converged |
At 3 GHz the successive steps are −5.67, −4.31 and −4.73 dB. They are not shrinking. Refining the mesh by 26× did not move this quantity toward an answer — it simply moved it. A single-mesh run would have reported any one of these four values with equal confidence, and reported it to two decimal places. The 6 GHz row carries the same verdict for a different reason: its steps do shrink, but the last one is still 1.63 dB — six times the tolerance that defines the trust boundary — so the sequence is heading somewhere it has not arrived.
The intuitive guess is that high frequencies are harder to resolve and should be less trustworthy. The data says the opposite. At 12 GHz the discontinuity reflects roughly 12 % of the incident power — a large, real signal that every mesh captures. At 3 GHz the 2 mm step is electrically tiny and the true reflection is close to nothing, so what the solver reports is dominated by discretisation error. Refining lowers that error floor, and the number slides down with it. The rule is about signal magnitude relative to the noise floor, not about frequency.
With four levels available, the two finest can be compared directly to find where the answer stops depending on the mesh. This converts a vague worry into a stated criterion that can be quoted alongside the result.
M3 vs M4 agree within
0.25 dB
for all ≥ 8.00 GHz
where |Sdd11| ≈ −18.3 dB
M3 vs M4 agree within
0.50 dB
for all ≥ 7.30 GHz
where |Sdd11| ≈ −21.0 dB
M3 vs M4 agree within
1.00 dB
for all ≥ 6.55 GHz
where |Sdd11| ≈ −24.6 dB
There is no single magic number here, and that is worth stating plainly: the boundary moves with the tolerance you demand, from −18.3 dB at the strictest criterion to −24.6 dB at the loosest. Taking the strictest as canonical, reflections stronger than about −18 dB in this model are physical and reproducible across meshes, and weaker ones are not. Quote the criterion alongside the boundary — a trust threshold without its tolerance is just another unqualified number.
Where a quantity converges, fitting the error model e ∝ hp across the three finest levels estimates both the observed order of convergence and the value the solver would reach with an infinitely fine mesh. The gap between that estimate and the finest run is the discretisation uncertainty to quote.
| Quantity | Freq | Observed order p | Extrapolated | M4 uncertainty |
|---|---|---|---|---|
| Sdd21 | 3 GHz | already flat — every step under 0.01 dB, no fit needed | ||
| Sdd21 | 12 GHz | 1.12 | −0.73 dB | 0.04 dB |
| Sdd11 | 12 GHz | 0.99 | −9.37 dB | 0.28 dB |
| Sdd11 | 3 GHz | no fit — steps do not shrink | ||
Two rows decline to report an order, for opposite reasons. Insertion loss at 3 GHz has already stopped moving — its steps are smaller than the fit could resolve, so a power law would be fitted to rounding. Return loss at 3 GHz never stops moving, so there is no limit to extrapolate toward. An extrapolation routine that returned a confident number in either case would be describing noise.
Three numbers were identical at every mesh density, to the digits shown. They are worth singling out, because they are the checks that catch setup errors — and they are cheap enough to run on the coarsest mesh before committing to an expensive one.
100.09 Ω
Identical to two decimals at all four levels, against a closed-form Hammerstad estimate of 51.3 Ω single-ended made before any simulation ran.
99.89 %
Sum of |S|² across every port. A lossless structure must return 100 % at DC; any shortfall is energy disappearing into a modelling mistake.
~1e−12
Max |S − Sᵀ| for this passive structure, at machine precision. Confirms the port definitions and the assembled matrix are self-consistent.
The convergence study was the fifth thing that happened, not the first. Four earlier runs failed, and each failed in a way that a plausible-looking output file would have hidden. They are listed because the diagnostics that caught them are reusable.
Setting Excitation: true on every lumped port drives them simultaneously rather than one at a time. S-parameters are undefined for a single simultaneous drive, so no scattering matrix was written at all. The fix is distinct integer group indices 1–4, which produce four solves and a full 4×4 matrix.
A material was declared on a solder-mask volume the mesh never contained. Caught by a preflight check comparing every attribute in the config against the physical groups in the mesh — a comparison worth automating, since it costs nothing and fails loudly.
The end faces carrying the ports were tagged absorbing, which behaves like a matched resistive sheet in parallel with each port. Power balance read 57.6 % at DC and the port impedance came out at 26 Ω instead of 51 Ω — almost exactly half, the signature of an unintended parallel load. Nothing in the S-parameter curves looked obviously wrong.
Replacing the absorber with PEC stopped the power leak but shorted the trace to the ground plane, since the trace edge touches that face. S11 came back at 0 dB and 180° — a textbook short — with S31 at −98 dB. The correct choice is PMC: an open boundary that neither absorbs nor conducts.
With PMC end walls, power balance returned to 99.89 % at DC and port impedance to 50.0 Ω against a hand calculation of 51.3 Ω — a match the solver reached from geometry alone. Power balance, port impedance and reciprocity found all four errors. The S-parameter curves alone would have found none of them.
One mesh is not a result. A single run gives a number with no way to tell whether it describes the structure or the discretisation.
Bulk quantities converge early; small differences converge late.Insertion loss was stable across a 26× element range. Deep return-loss nulls never stabilised.
Quote a band, not just a value. “−9.37 dB with 0.28 dB discretisation uncertainty, trustworthy above 8 GHz” is a defensible claim; “−9.09 dB” alone is not.
Check invariants before curves. Power balance, reciprocity and port impedance are cheap, mesh-independent, and catch the errors that plausible-looking plots conceal.
This is a verification study, not a validation study. It establishes that the solver converges to a mesh-independent answer and identifies where. It does not establish that the answer matches a measurement — that requires VNA or TDR data on fabricated hardware, which this study does not have.
The geometry is generic. It is a differential microstrip pair with an impedance step, not a model of any particular connector, and it contains no connector body, via barrel or antipad. Real launches are more complex and lossier.
The trust boundary is specific to this model. The −18 dB figure follows from this geometry, these mesh densities, second-order elements and a chosen 0.25 dB tolerance. The method transfers; the number does not.
The geometry is generated by a parametric script: trace width, spacing, dielectric height, laminate Dk and the size and position of the discontinuity are all variables at the top of the file, and the mesh sizing is a command-line argument. Producing the four levels is one command each, and the physical group tags are emitted to match the config every time.
The solver is Palace, the open-source 3D finite-element electromagnetics code released by AWS Labs under the Apache 2.0 licence. All four runs used the same config apart from the mesh filename.
Everything needed to check this study is at github.com/numericalai/palace-mesh-convergence. The meshes are not committed because they regenerate deterministically from the generator, but the raw port-S.csv output is, so python3 analysis/convergence.py --figures reproduces every number and plot above without running the solver at all.
Refinement studies are the part of simulation practice most often skipped, because on local hardware they mean queuing four jobs instead of one. On cloud GPUs they are four launches from the same browser tab. Upload your Palace config.json and mesh to get started.
© 2026 NumericalAI, all rights reserved. |Privacy Policy |Terms of Service |Executive brief |CEM vs HFSS |FAQ