NEC-5 as a third engine
NEC-5 is LLNL’s modern rewrite of the NEC lineage — a mixed-potential formulation with basis functions in the RWG family, released in 2019 and distributed under an individual license. antennaknobs can drive it as a third engine beside momwire and PyNEC: it writes NEC-5-dialect decks, runs your licensed executable, and parses the printout back into the same impedance, current, pattern and power-budget readouts every other engine serves.
Why bother, when two engines already cross-check each other? Because the three implementations share almost nothing: momwire’s sinusoidal and B-spline families, NEC-2’s reduced/extended thin-wire kernels, and NEC-5’s mixed-potential formulation are independently derived and independently coded. When all three agree, the agreement means something — and when they split, the split is a finding (see the solver page for how antennaknobs treats cross-engine differences as data, not noise).
Licensing, and where the engine will not run
Section titled “Licensing, and where the engine will not run”NEC-5 is licensed software. antennaknobs never bundles, downloads, or hosts it: the engine activates only when you point it at a binary you license yourself, and the hosted simulator can never offer it (the license forbids service use, and the hosted machines simply have no binary). What antennaknobs generates and parses — decks and printouts — are yours to keep; captured printouts in the test suite carry the LLNL-CODE-746721 citation as End-User Reports.
Point the engine at your executable with one environment variable:
export NEC5_EXE=~/nec5/nec5cl # your licensed binaryEverything below lights up exactly when NEC5_EXE resolves — the CLI
engine name, the workbench slot entry — and disappears when it doesn’t.
If you run a local web instance with the variable set, the NEC-5 slot is
available to anyone who can reach that instance; keeping it off the open
internet is your call to make, the same as for any local service.
From the command line
Section titled “From the command line”nec5 joins the --engines roster:
# The triangle: momwire vs PyNEC vs NEC-5 on one designpython -m antennaknobs compare_patterns \ --builders beams.moxon beams.moxon beams.moxon \ --engines momwire pynec nec5 --fn triangle.pngEvery solve is one run of the binary in a scratch directory — deck in,
printout out, parsed and discarded. Sweeps batch uniformly-spaced
frequencies into a single run using NEC-5’s linear FR stepping.
What is served, what refuses
Section titled “What is served, what refuses”| capability | status |
|---|---|
| Impedance, currents, frequency sweeps | served |
| Grounds | free space, PEC, and NEC-5’s native Sommerfeld (("finite", eps_r, sigma)) |
| Buried wires | served over the Sommerfeld ground — the GE ground flag follows the deck: GE -1 0 where every conductor is below the plane, GE 1 0 where one stands at z = 0, which is the legal contact that joins a monopole to its detached screen. The two settings say opposite things about a wire end on the plane (bond it to ground, or leave the current expansion alone), so the flag is a property of the geometry and not a constant |
| Radiation patterns | served (compare_patterns, the web far-field views) |
| Feeds | plain Wire.ex, network Driven, and DrivenCurrent via NEC-5’s native current source (EX 4 — NEC-2 has no equivalent) |
| Loads | Load branches (fixed-Z and series/parallel RLC) at the port |
| Wire material | conductor loss natively; insulation via the same distributed-inductance emulation momwire uses — NEC-5 dropped NEC-4’s insulated-wire card |
| Power budget | input/radiated/wire-loss/efficiency, plus hemisphere average gain (the ground-absorption readout) |
Transmission lines, two-ports, ql/qc loads, distributed ports | refuse loudly, each naming what is unsupported |
| Ground-geometry refusals | mid-span interface crossings (the binary runs them and prints garbage), wires lying in the plane, buried wires under a PEC ground (image theory has no buried side), and coincident wires — each refused by name at construction |
Refusals are the design: NEC-5 either solves exactly what you asked or
tells you precisely why not — never a silently simplified model. The
coincident-wire refusal is the buried screen’s sharp edge: momwire’s
connected-radial spelling brings each radial up as one of N coincident
rises, a bundle momwire regularizes exactly but NEC-5 silently prints
garbage for (measured: thousands of ohms and an astronomically wrong
radiated power). So the buried-radial vertical
carries two variants, one per engine: the default connected screen
solves through momwire and refuses here; its detached variant — the
stake convention, radials lying at depth touching nothing — solves here
(the momwire#567 anchor class NEC-5’s own convention serves) and refuses
through momwire. The two conventions are two different structures, tens
of ohms apart over average soil; comparing them compares junction
physics, not solver accuracy — never expect the numbers to agree.
Two conventions worth knowing, both pinned from the NEC-5 User’s Manual during development:
- Sources sit at segment ends (knots), not segment centers as in
NEC-2. The deck writer meshes fed wires with even segment counts so the
feed lands exactly at the wire’s middle knot — the same physical point
the other engines drive. A
PortAtVertexapex feed uses this natively: its source is the named wire’s own end knot (segment 1 end 1, or segment n end 2), so no parity coercion applies and a vertex-only wire keeps its authored segment count. - The “fast” ground model is served as full Sommerfeld. NEC-5 has no
reflection-coefficient approximation (its
IPERF 0is the Sommerfeld solution), so asking for the fast model gets the accurate one, and the applied-model readout says so.
In the workbench
Section titled “In the workbench”With NEC5_EXE set on the machine serving the web UI, NEC-5 appears in
the slot A/B/C solver picker like any other backend. The natural use is
A/B: the same design and mesh in two slots, momwire against NEC-5, readouts
side by side. NEC-5 solves are one subprocess per request with no resident
state — fine for check-this-snapshot comparisons, heavier than momwire’s
in-process solves for live knob-dragging.
Honest numbers
Section titled “Honest numbers”Cross-engine agreement on reference designs runs a few ohms of impedance (the different formulations’ genuine spread) and ~0.01 dB RMS on far-field patterns. The one apparent exception closed under study, and the closing is worth telling: the day the engine landed, NEC-5’s reactance at very low heights over lossy Sommerfeld ground (≈0.05 λ) sat ~7 Ω away from the mutually-agreeing NEC-2 lineage, and was documented here as a formulation difference. The full corpus comparison then swept a dipole from 0.02 λ to 1.0 λ and found the offset is height-independent — a feed-model term from NEC-5’s knot-source mesh march, not close-ground physics — and that Richardson-extrapolating NEC-5’s (N, 2N) pair dissolves it entirely: extrapolated NEC-5 agrees with the NEC-2 lineage to ≤ 0.17 Ω in reactance at every height. Both halves are pinned in the test suite — the raw single-mesh offset and its extrapolated resolution. That is the cross-validation triangle doing its job twice: first flagging a real discrepancy, then identifying it as convergence behaviour rather than physics.
The cause of that convergence behaviour was then pinned down in its own
study. A clean first-order march is also the signature of feeding or
reading a solver half a segment wrong, so every harness-side suspect got a
discriminating experiment: the two spellings of the same feed knot solve
bit-identically; a deliberate one-segment feed slide produces an effect
one to two orders smaller than the march (and shrinking a full order
faster); NEC-5’s native current source (EX 4) — whose input-parameters
row carries the driven current exactly, leaving no readout convention in
play — walks digit-for-digit with the voltage source; segment-parity
coercion moves at most one segment on one wire, worth sub-milliohm shifts;
and LLNL’s shipped sample models run through this engine’s own
runner reproduce the shipped reference printouts to every printed digit.
The march is NEC-5’s own knot-source discretization — first-order in
segment length, converging to the same limit the other engines agree on —
which is why the (N, 2N) Richardson pair is the permanent recipe for
census-grade NEC-5 numbers rather than a workaround for a bug on either
side of the interface. LLNL’s NEC-5 Validation Manual documents the
behaviour: its introduction notes that the linear current expansion
converges more slowly than the sinusoidal expansion of the earlier NEC
codes, and §2.3’s dipole ladders demonstrate it, attributing an
N-dependent feed term to the effective shunt capacitance of the source
gap, whose width scales with segment length (Burke & Poggio, NEC 5.0,
LLNL-CODE-746721).
The formulation, and what it costs
Section titled “The formulation, and what it costs”NEC-5’s wire discretization is identified in the open — from the public
User’s Manual (§1) and black-box printout comparison, with no NEC-5
source consulted: a tent (triangular) current expansion on segment knots,
razor-blade mixed-potential testing between adjacent element centroids,
and ∫A·dl taken as the two-point centroid trapezoid. momwire implements
that exact scheme as RazorSolver with nec5_quadrature=True
(momwire#309, momwire#316), and the resulting formulation twin
reproduces NEC-5’s printouts to a constant ≈0.04 Ω down full convergence
ladders on a thin dipole, a bend, a junction-fed apex and a closed loop;
on a 10 mm wire the residual grows with a/h to ≤0.07 Ω, the signature of
a kernel-evaluation nuance rather than a further quadrature difference.
The validation page carries the panel. The twin
is the controlled experiment behind the pair recipe: on a 14 MHz dipole
the same tent basis under Galerkin testing (bs1) sits within 0.5 Ω of
its converged value at 48 segments where NEC-5’s formulation is still
outside that band at 96, and momwire’s degree-2 B-spline (bs2) gets there
at 12 (16 on an inverted-V, 32 on the fat dipole). Eight times the
segments is 64× the fill and roughly 500× the dense solve, before the
second solve the (N, 2N) pair costs.
What each engine spends per solve is measured on the same footing: a matched ladder on a 2×4 bowtie array, free space, single frequency, every process capped at 8 GB of address space. NEC-5’s peak resident set converges to about 1.02× the dense N×N matrix plus ~60 MB, and nec2c’s to the matrix plus 3–5 MB — both are essentially the in-core matrix and nothing else, which puts each engine’s ceiling near 23k segments in an 8 GB budget. momwire’s B-spline path sits higher, about 1.5× dense in free space and 2.1× under full Sommerfeld (its certified figures at 8,320 basis functions), for a ceiling of 15–18k basis functions: the working copies a higher-order basis needs while it assembles in windows. Wall clock runs the other way at that size — 8,320 segments takes nec2c 466 s, NEC-5 37 s, and momwire’s bs2 29 s. NEC-5 is a lean, fast solve; what the triangle pays for it is the mesh its formulation asks for, not the code that runs it.
Importing NEC-5 decks
Section titled “Importing NEC-5 decks”@file.nec import recognises NEC-5’s edge-source EX spellings (a
negative segment number, or the end-selector field NEC-2 never uses) and
refuses them with the dialect named rather than silently shifting the feed
half a segment to the NEC-2 reading — the NEC deck
import page has the details. Decks in the common
NEC-2 subset load normally, and NEC5Engine itself accepts them as-is.