Skip to content

The solver & accuracy

antennaknobs solves antennas with momwire, an in-house method-of-moments (MoM) engine for wire structures, with an optional NEC-2 backend for cross-checking.

momwire offers two current-expansion basis families in one engine — uncommon among free tools, where basis quality is usually a paid feature:

  • B-spline — a degree-1/2 Galerkin basis, the default (degree 2),
  • sinusoidal — a NEC-2-style three-term basis, point-matched like NEC-2; useful as a cross-validator (it tracks PyNEC closely because it shares both the basis and the point matching),
  • sinusoidal-galerkin — the same three-term basis with Galerkin (integrated) test rows: exactly reciprocal Z by construction, markedly faster reactance convergence on junction-heavy geometry, and junction-node ports (free space; PEC since momwire#191). It exists so basis effects and testing effects can be told apart — the full story is momwire’s chapter 15. It also carries the one user-facing feed-model choice: NEC-compatible (the default segment-wide gap — reproduces NEC/EZNEC behaviour, including the reactance drift as the mesh refines) or Converged (a zero-width gap — converges to the B-spline answer, exactly reciprocal Y). In the workbench it is the “feed model” control in the Sin-Galerkin slot’s gear menu; on the CLI, momwire:sinusoidal-galerkin-converged. Pick NEC-compatible when cross-checking against NEC results, Converged on near-open high-Q feeds (the workbench recommends it on the designs that need it — momwire#213 measured it removing 992×/374× of the cross-basis disagreement on lazy_h/vbeam, without reducing the mesh those designs genuinely need). The plain sinusoidal solver offers no such choice: a zero-width gap cannot be expressed under point matching (momwire#212).

Plus two accelerated solvers for large problems:

  • hmatrix — ACA / hierarchical-matrix, sub-quadratic on large single-wire structures,
  • arrayblock — element-aware block-low-rank, near-linear on arrays of identical / few-shape elements.

The choice turns on two axes — total problem size, and single-structure vs. array geometry. From the solver-selection benchmark (10 designs × 7 engines, free space) and the ground-model benchmark (the same designs × 4 ground models):

Antenna classUseWhy
Single elements, small loops, beams, multiband dipolesbspline d=2 (the default), with sinusoidal / PyNEC as cross-checksall three solve in milliseconds here; d=2 converges at far coarser meshes (see below), the others confirm the answer
Large single-wire structures (rhombic, long-wires, big loops)hmatrix (ACA)sub-quadratic scaling — the only solver that beats PyNEC on rhombic at high segmentation
Arrays of identical / few-shape elements (loop/bowtie arrays, LPDA)arrayblock7–12× faster than PyNEC on large arrays; near-linear scaling

The same picks hold with a ground plane in play — the ground model changes what a solve costs, not which solver wins it.

All timings at N=81 segments/wire on a 4-core box with production-matched threading; see the benchmark docs for full tables.

  • The ground-cost ladder is consistent everywhere: free ≈ PEC < reflection-coefficient < Sommerfeld. PEC is nearly free (image method, no material solve); the reflection-coefficient ground runs ~1.5–3× a free-space solve on the dense bases; the full Sommerfeld ground ~2–5×. Since momwire 0.15.0 that Sommerfeld premium is mostly the first solve of a session: the interpolation-grid fill grows linearly with antenna size (not quadratically) and is reused across a band’s frequencies, so warm sweep ticks on the momwire bases undercut even PyNEC’s per-tick steady state on 86/90 catalog designs — see the session benchmark.
  • ACA earns its place on rhombic — fastest engine free-space (~4.0 s, beating PyNEC and every dense basis, scaling ~2×/step where dense solvers go ~5×/step), and under Sommerfeld the low-rank structure survives (the smooth ground remainder rides one compressed term): 9.3 s vs the dense B-spline’s 18.7 s.
  • ArrayBlock dominates arrays on every groundlpda free: ~1.2 s vs PyNEC’s 14 s (12×); Sommerfeld: 2.8 s vs 24 s; bowtiearray2x4 Sommerfeld: 7.3 s vs 17.3 s.
  • Against PyNEC, momwire sits within ~2× — or wins — on every ground model × design (momwire ≥ 0.9.0: a fused Sommerfeld remainder kernel made Sommerfeld solves 14–19× faster, tying or beating PyNEC’s native NEC gn 2 on 6 of 10 designs; a compiled reflection-coefficient fill took the sinusoidal basis from 5–9× behind PyNEC to 1.1–1.8×).
  • PyNEC is a great fast reference, but not universally fast — it wins Sommerfeld on mid-size single structures (moxon: 135 ms vs momwire’s best 158 ms), yet loses the log-periodic on every ground model (free: 14 s vs ArrayBlock’s 1.2 s). “Use PyNEC as the reference” holds for small designs, not arrays.
  • Among dense bases, sinusoidal stays fastest at a FIXED segment count on small/medium single structures — on every ground model. But the fair comparison is at fixed accuracy, and there the basis-convergence census (91 designs, meshes N=7–641) flipped the verdict: B-spline d=2 is already within 2 % of the converged answer at N=15–21 on 80 % of scorable designs, where the sinusoidal basis needs 3–15× more segments to arrive at the same value — which is why d=2 at N=15 is the workbench’s default solve. On port-fed, junction-heavy, and closely-spaced-wire geometry the gap is largest, and single closed loops converge on d=2 as coarse as N=7 — ~2–3× below the sinusoidal basis; details and how to check your own design: How many segments?
  • That census gap is mostly the point matching, not the basis. The momwire#182 instrument (the sinusoidal-galerkin backend) re-ran the residue cluster varying only the testing scheme: the junction-heavy sin↔bspline gaps of 1–23 % collapse to 0.01–0.33 %, and with a matched feed model the remaining basis gap on clean geometry is ~4×10⁻⁸. So sinusoidal-galerkin converges at B-spline-class meshes while keeping the sinusoidal basis — use it as the second opinion on junction-port (PortAtEnd) designs, which historically were B-spline-only and now accept either (bspline remains the default; the sin-Galerkin junction ports run in free space and over a PEC ground — momwire#191 — with finite grounds still refused).

Method-of-moments discretizes each wire into segments, and the solve builds one basis function per segment. The segments / wire (N) control in the workbench sets the design’s mesh density: every wire gets N segments per quarter-wavelength (at the design frequency), so a long radiator gets proportionally more segments than a short stub — and N means the same physical segment length on every design (N=15 ≈ λ/60). The total basis-function count — the sum across every wire — is the dimension of the impedance matrix the solver fills and factors.

That matrix is what sets both accuracy and cost:

  • Too few segments and the current distribution is under-resolved — the feed-point impedance hasn’t converged and your SWR/resonance readings are off, sometimes by a lot near a sharp feature.
  • More segments refine the answer, but the dense solvers form an N×N matrix: memory grows as and fill/factor cost as N²–N³. Past the point where the impedance stops moving, the extra segments only cost time.

Finding “enough” — the convergence sweep

Section titled “Finding “enough” — the convergence sweep”

The workbench’s convergence sweep re-solves the current antenna across a range of N and plots the resulting feed-point impedance R + jX against N. Read it like any convergence study: the curve drops steeply at small N, then flattens (“the knee”). The smallest N past the knee is your sweet spot — converged, but no slower than it needs to be. If the curve never settles, the geometry may have a feature (a tight bend, a very short feed gap) that needs finer local segmentation, or a different basis.

A quick rule of thumb: the dense bases want enough segments per half-wavelength to resolve the sinusoidal current — a couple of dozen across a half-wave element is typical. The convergence sweep turns that rule into an answer you can see for your antenna.

For the full method — convergence ladders, cross-basis validation (a flat curve can be flat at the wrong value), and the four distinct reasons a curve refuses to settle — see the advanced guide: How many segments?

Because the dense matrix grows as N², a runaway segment count (or a big array) can allocate hundreds of megabytes and stall a solve. The hosted instance therefore caps the total segment count and rejects oversized solves with a clear message rather than melting the shared box. The cap is engine-aware: the compressed arrayblock / hmatrix engines skip the dense matrix (ACA / H-matrix), so they’re allowed a much higher count — which is exactly why they exist for large arrays. The cap is off by default and enforced only on the shared hosted instance — a local pip install is uncapped; the toggle and the limits are env-configurable (see docs/deploy.md).

  • A NEC-2 reference engine (pynec-accel) runs alongside momwire, so any design can be solved two ways and compared — a built-in sanity check most tools lack.
  • The repo carries the benchmark above plus per-design solver comparisons.

In the spirit of not overselling: momwire wires are PEC by default; designs that declare a wire material (the WIRES catalog — see the wire-gauge example) get skin-effect conductor loss as a distributed series impedance in the solve itself (momwire ≥ 0.10.0, validated against NEC’s native LD 5 wire-loss card to ~0.5 %) plus the insulated-wire velocity factor (mirrored on the NEC engine as an LD 2 distributed-inductance card, agreeing on the resonance shift to ~1 %). Every momwire solver carries the loading (momwire ≥ 0.11.0): the B-spline family as a Galerkin overlap, the sinusoidal solver through NEC’s impedance boundary condition at its match points — so matched-basis cross-engine comparisons keep the full wire physics on both sides. Finite grounds are solved with a true Sommerfeld/Norton model on every momwire solver (momwire ≥ 0.8.0: NEC’s exact-image-plus-remainder decomposition; the accelerators carry the smooth remainder as one global low-rank term on their fast paths). Validation against an independent NEC-2 implementation across 0.02–0.5λ heights — including the very-low region where reflection-coefficient models are tens of ohms off — lands within ~2.4 Ω on the B-spline basis and ~0.1 Ω on the sinusoidal basis (which shares NEC’s basis, making it the sharpest check of the model). The faster reflection-coefficient model remains the default and the NEC path offers its own Sommerfeld–Norton — so real-ground results cross-check across two independent engines at every height.