Skip to content

dc0sk/fnec-rust

Repository files navigation

fnec-rust

version license

fnec-rust is a Rust-native antenna modeling workspace targeting near-100% practical compatibility with 4nec2, while keeping the codebase modular, testable, and portable.

Features

  • Parse 4nec2 / NEC2 deck files (GW, GM, GR, GE, GN, EX, FR, RP, EN cards)
    • GM (Geometry Move): rotate and/or translate wire ranges in place, or append one transformed copy when tag_increment > 0
    • GR (Geometry Repeat): supported subset repeats existing wires by successive z-axis rotation
    • EX type 1: staged portability support is accepted in the parser/solver path and currently runs with EX type 0 behavior plus an explicit warning while current-source semantics remain pending
    • EX type 2: staged portability support is accepted in the parser/solver path and currently runs with EX type 0 behavior plus an explicit warning while incident-plane-wave semantics remain pending
    • EX type 4: staged portability support is accepted in the parser/solver path and currently runs with EX type 0 behavior plus an explicit warning while segment-current semantics remain pending
    • EX type 5: staged portability support is accepted in the parser/solver path and currently runs with EX type 0 behavior plus an explicit warning while qdsrc semantics remain pending
    • PT: staged portability parsing is supported; current runtime emits an explicit deferred-support warning and ignores PT electrical semantics
    • NT: staged portability parsing is supported; current runtime emits an explicit deferred-support warning and ignores NT electrical semantics
  • Hallén MoM solver — physically accurate feedpoint impedance for thin-wire antennas
    • Validated: 51-segment λ/2 dipole at 14.2 MHz → 74.24 + j13.90 Ω (matches Python reference)
      • GN 1 (perfect ground at z=0) is supported via image method; dipole-ground-51seg regression is 81.91 + j16.42 Ω
      • GN 0 (simple finite-ground reflection coefficient path) is supported; dipole-gn0-fresnel-51seg is regression-gated
      • GN 2 low above-ground finite-conductivity cases are supported on the current scoped path; the supported subset is strictly above-ground (z > 0); dipole-gn2-deferred and dipole-gn2-near-ground-51seg are regression-gated
      • Buried or interface-touching active-ground wire classes (z <= 0) remain deferred and fail fast with an actionable error instead of silently falling back
      • GN types outside the current scoped subset still remain deferred
      • GE ground-reflection flag: 1 = PEC image (handled); -1 = below-ground (warns); other values warn with valid range hint
      • Multi-wire junctioned / non-collinear Hallen (unique to fnec-rust): per-wire local cos(k·s) homogeneous vectors, KCL junction continuity rows, and correct passive-wire (zero) RHS — no other NEC2-compatible tool handles junctioned wire topologies via the Hallen integral equation; validated against NEC2 on dipole-loaded top-hat geometry (Z ≈ 12.4−j918 Ω, NEC2 ref 13.5−j896 Ω); external cross-check recommended for novel geometries
  • Segment current distribution table in CLI output (CURRENTS section after feedpoint table)
  • RP radiation-pattern execution in CLI output (RADIATION_PATTERN section with theta/phi gain rows)
  • Corpus validation can track and optionally gate external parity candidates (RP and impedance) recorded in corpus/reference-results.json
  • Pulse-basis and continuity-basis Pocklington solvers (EXPERIMENTAL — known to diverge for thin wires)
  • Sinusoidal-basis Hallen solve path with guarded residual fallback to Hallen
    • sinusoidal falls back to Hallen on single collinear chains when its residual budget is exceeded, and the budget is user-tunable via --sin-fallback-rel-max (or FNEC_SIN_FALLBACK_REL_MAX)
  • CLI binary fnec with selectable solver and RHS modes
  • FR sweep support in CLI output and corpus validation gating
  • Residual diagnostics printed to stderr on every run
  • Modular crate workspace: parser, model, solver, accel, report, project, CLI, GUI

Quick start

cargo build --release
./target/release/fnec dipole.nec

Example deck (dipole.nec):

GW 1 51 0 0 -5.282 0 0 5.282 0.001
GE
EX 0 1 26 0 1.0 0.0
FR 0 1 0 0 14.2 0.0
EN

Example output (report contract v1):

FNEC FEEDPOINT REPORT
FORMAT_VERSION 1
FREQ_MHZ 14.200000
SOLVER_MODE hallen
PULSE_RHS Nec2

FEEDPOINTS
TAG SEG V_RE V_IM I_RE I_IM Z_RE Z_IM
1 26 1.000000 0.000000 0.013013 -0.002436 74.242874 13.899516

See docs/cli-guide.md for full option reference and docs/card-support-matrix.md for the NEC card support matrix.

Support fnec-rust

Donate via PayPal

If this project helps your work, please consider supporting ongoing development:

https://www.paypal.com/donate/?hosted_button_id=WY9U4MQ3ZAQWC

Goals

  • Primary compatibility target: 4nec2 input and workflow expectations
  • Secondary input dialect support: xnec2c where it provides real benefit
  • Solver implemented from scratch in Rust
  • CLI and GUI frontends over a shared core
  • Multithreaded CPU execution with staged GPU acceleration
  • Explicit Linux-on-ARM targets: Raspberry Pi 4 (VideoCore VI GPU) and Raspberry Pi 5 (VideoCore VII GPU)

Workspace layout

crates/
	nec_parser/
	nec_model/
	nec_solver/
	nec_accel/
	nec_report/
	nec_project/
apps/
	nec-cli/
	nec-gui/
docs/

Contributor setup

Install the required cargo tools:

cargo install cargo-audit cargo-sbom cargo-fuzz

Install the local git hooks:

make install-hooks

This configures core.hooksPath to use .githooks/.

Local workflow checks

  • Pre-commit: cargo fmt --all -- --check, cargo test --workspace
  • Pre-push: cargo audit
  • Docs validation: ./scripts/validate-doc-frontmatter.sh
  • Parser fuzz scaffold: (cd fuzz && cargo fuzz run nec_parser_parse corpus/nec_parser_parse)
  • Remote ARM64 check (Pi over SSH): bash ./scripts/pi-remote-workspace-check.sh <user@host>
  • Remote ARM64 benchmark CSV (Pi over SSH): bash ./scripts/pi-remote-benchmark.sh <user@host>
  • Remote benchmark with explicit single-thread baseline + parallel CPU sweep: FNEC_BENCH_EXECS="cpu-single cpu" bash ./scripts/pi-remote-benchmark.sh <user@host>
  • Remote benchmark with persistent history append: FNEC_BENCH_HISTORY="benchmarks/pi-benchmark-history.csv" bash ./scripts/pi-remote-benchmark.sh <user@host>
  • Benchmark CSV delta view: bash ./scripts/pi-benchmark-compare.sh <base.csv> <candidate.csv>
  • Benchmark CSV delta gate example: bash ./scripts/pi-benchmark-compare.sh --max-delta-pct 15 --fail-on-mode-drift <base.csv> <candidate.csv>
  • Append benchmark CSV to persistent history: bash ./scripts/pi-benchmark-history.sh append <candidate.csv> benchmarks/pi-benchmark-history.csv
  • Benchmark history trend summary: bash ./scripts/pi-benchmark-history.sh trend benchmarks/pi-benchmark-history.csv

GitHub Actions includes benchmark-compare.yml, which runs on PRs and compares benchmarks/pi-base.csv vs benchmarks/pi-candidate.csv when both files exist. If either file is missing, the job reports a clean skip. When it runs, it also writes a benchmark delta preview to the Actions job summary.

Troubleshooting: Mobile approval dialogs

If you review or approve workflow/tool actions from a mobile device, some approval dialogs may be truncated, fail to render all options, or not submit reliably.

  • Prefer desktop browser approval for multi-step actions (branch push, workflow changes, multi-file edits).
  • If a mobile approval appears stuck, refresh and retry from desktop rather than re-running commands repeatedly.
  • Keep command payloads and commit messages concise when you know approvals may be handled on mobile.

Version bump workflow

When bumping the workspace version:

  1. Update Cargo.toml.
  2. Regenerate the SPDX SBOM: cargo sbom --output-format spdx-json > SBOM.spdx.json
  3. Update docs/changelog.md.
  4. Update docs/releasenotes.md.
  5. Update documentation references that include the new version.

Branch policy

main stays protected. Work happens on feature branches only, followed by pull requests.

About

A free and modern NEC client written in rust.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages