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).
Getting a NEC-5 deck without the engine
Section titled “Getting a NEC-5 deck without the engine”The workbench’s gear menu has Download NEC-5 .nec, and it is offered whatever
engines that machine has: writing a deck needs no binary. It is the same file the
corpus tool’s catalog-nec5/ ships for that design at that mesh and ground, from
the same writer — so a deck you download and a deck from the published set cannot
disagree. It is also the dialect that carries what NEC-2 cannot: buried wires,
wires in the ground plane, and momwire’s graded meshes.
The NEC-4.2 download
Section titled “The NEC-4.2 download”NEC-4.2 carries buried wires too, and it has its own deck download: see the NEC-4 deck. It was verified against a licensed NEC-4.2 before it was offered.
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 binaryOn Windows, in PowerShell, before starting the workbench in the same window
(EZNEC Pro+ keeps its engine in its own Docs folder as NEC5CL_x13.exe —
the suffix is the build; Docs\LastRun.log names the one it ran):
$env:NEC5_EXE = "C:\EZNEC 7.0\Docs\NEC5CL_x13.exe"That is PowerShell syntax (its prompt starts with PS). In Command Prompt
(prompt C:\Users\you>) the same line fails with “The filename, directory
name, or volume label syntax is incorrect”; the Command Prompt spelling is
set NEC5_EXE=C:\EZNEC 7.0\Docs\NEC5CL_x13.exewith no quotes. Either shell works; the variable lives in that window only, so set it and start the workbench in the same one.
To name the engine once for every start, put it in your
settings.toml instead, as nec5_exe under [engines]. The
variable wins over the file.
Seeing what the engine saw
Section titled “Seeing what the engine saw”When a NEC-5 answer surprises you, the two things to look at are the deck antennaknobs handed the binary and the printout it got back. In the workbench, the Files view shows both for the solve on screen. Two switches also keep them, for NEC-5 and NEC-2 alike:
export ANTENNAKNOBS_CAPTURE_DIR=~/ak-captures # every run leaves nec5/<hash>.nec + <hash>.outexport ANTENNAKNOBS_LOG_LEVEL=DEBUG # the deck and printout in the server log as they runThe packaged workbench takes the same two as --capture-dir DIR and
--log-level DEBUG. It also takes the engine itself as --nec5-exe PATH (and
--nec2-exe PATH), which reads the same in PowerShell and Command Prompt
and wins over NEC5_EXE, over settings.toml and over a NEC5_EXE.txt beside
the program. In settings.toml the capture folder is dir under [capture].
The capture directory is the pair of files to attach to a report; the hash in the file name is the deck’s own, so two runs of
the same deck share one pair. At INFO the log is one line per run (hash,
seconds, printout length). For NEC-5 a captured printout is also served
back for the same deck without re-running the binary; NEC-2 captures are
write-only.
Everything 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, NEC-5’s native Sommerfeld (("finite", eps_r, sigma)), and EZNEC’s MININEC-type ground (("mininec", eps_r, sigma)) as GE 1 with a bare GD |
| 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; an insulation jacket as the same coated-wire pair momwire models, spelled in cards — the equivalent radius on GW, the jacket’s inductance as LD 2, and LD 5 rescaled so the copper loss stays the real conductor’s. NEC-5 dropped NEC-4’s insulated-wire card. A jacketed wire that is also buried gets no card for momwire’s in-soil charge correction (there is nowhere on a NEC card to put one), so its deck carries CM lines saying so — the deck models that jacket as if it were in air, and its impedance will differ from antennaknobs’ own by that correction (#1677) |
| Power budget | input/radiated/wire-loss/efficiency, plus hemisphere average gain (the ground-absorption readout) |
Transmission lines, transformers, two-ports, virtual drivers, ql/qc loads | served through a multiport-Y reduction: NEC-5 solves the antenna’s admittance at its real ports, the circuit is reduced onto them, and every other reading (currents, the pattern, the power budget) runs a deck driven at the ports’ resolved voltages. NEC’s own pattern there is reported per watt the sources deliver, which is what NEC-5 prints when it carries the same network in its own cards. Two port kinds refuse loudly, each by name: a floating port, whose second terminal NEC-5 cannot expose, and a distributed port, whose knot weighting is not derived |
| Ground-geometry refusals | mid-span interface crossings (the binary runs them and prints garbage), wires lying in the plane, buried wires under a PEC or MININEC-type 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. A deck imported with an odd count is rounded the same way — 4nec2’s Example 2 dipole goes to NEC-5 as 10 segments with the source at the centre knot, not 9 with a centre segment — and the solver-slot label shows the requested count. At nine segments on a half-wave dipole that convention alone is worth a couple of ohms against the deck’s own spelling in the same engine; both converge as N grows. The two engines’ fed segments therefore differ in size: the catalog’s 50 mm feed-gap wire is one 50 mm segment under momwire’s default basis and two 25 mm segments under NEC-5. That is immaterial at an ordinary driving point, but near an open circuit the impedance follows the fed segment’s size, so this project’s cross-engine comparisons record each engine’s fed segment beside its impedance. - 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.