Found while re-validating the LD fix against our reference chain: on current main (b58c4ad), every GN variant — including GN 1 perfect ground — produces the free-space answer. The output banner reports the requested ground, but the numbers don't move.
Reproduction (three 8-line decks)
Half-wave 14 MHz dipole, 0.43 m (0.02λ) above ground — a height where ground coupling dominates the input impedance:
CE gn test: sommerfeld eps10 sigma.002
GW 1 21 -5.3 0 0.43 5.3 0 0.43 1e-3
GE 1
GN 2 0 0 0 10 0.002
FR 0 1 0 0 14 0
EX 0 1 11 0 1 0
XQ
EN
plus a GN 1 variant and a free-space variant (GE 0, no GN).
| deck |
onec (b58c4ad) |
nec2c 1.3 |
| free space |
76.465 +29.441j |
76.464 +29.441j ✓ |
| GN 1 (PEC) |
76.465 +29.441j |
0.953 +3.066j |
| GN 2 (εr=10, σ=0.002) |
76.465 +29.441j |
100.030 +65.948j |
A PEC ground 0.02λ under a dipole collapses R_in to ~1 Ω; onec returns the free-space impedance unchanged for all three.
The output itself shows the tell — the GN 2 run prints:
FINITE GROUND. SOMMERFELD SOLUTION
RELATIVE DIELECTRIC CONST.= 0.000
CONDUCTIVITY= 0.000E+00 MHOS/METER
i.e. the Sommerfeld path is announced but the medium parameters never arrive.
Where it appears to break
Tracing the sequential path (the one process_single_file actually runs):
process_gn_card (reporting.c) stores the raw εr/σ into gnd.impedance_ratio / gnd.impedance_ratio2 — which are derived quantities elsewhere — and never sets save.ground_epsr / save.ground_sigma.
execute_frequency_loop_sequential has no per-frequency ground setup and never reaches somnec, so ksymp/the ground constants stay at their free-space defaults for the solve.
- The correct setup block ("Set up ground parameters…", including the somnec call) exists in control.c's batch loop, but that path looks superseded/unreached from
main now.
History note: v2.2.0 behaved differently (PEC was exact there; GN 0/GN 2 were engaged but consumed the raw εr where 1/√εc is expected). Since v2.2.1-beta.1 the sequential path took over fully and all grounds fall through to free space.
Routing the sequential loop through the same ground setup control.c does (or hoisting that block into a shared helper) looks like the fix shape. Happy to re-test against nec2c/PyNEC on the full ground matrix once there's a candidate — same offer as #11.
Found while re-validating the LD fix against our reference chain: on current main (b58c4ad), every
GNvariant — includingGN 1perfect ground — produces the free-space answer. The output banner reports the requested ground, but the numbers don't move.Reproduction (three 8-line decks)
Half-wave 14 MHz dipole, 0.43 m (0.02λ) above ground — a height where ground coupling dominates the input impedance:
plus a
GN 1variant and a free-space variant (GE 0, no GN).A PEC ground 0.02λ under a dipole collapses R_in to ~1 Ω; onec returns the free-space impedance unchanged for all three.
The output itself shows the tell — the GN 2 run prints:
i.e. the Sommerfeld path is announced but the medium parameters never arrive.
Where it appears to break
Tracing the sequential path (the one
process_single_fileactually runs):process_gn_card(reporting.c) stores the raw εr/σ intognd.impedance_ratio/gnd.impedance_ratio2— which are derived quantities elsewhere — and never setssave.ground_epsr/save.ground_sigma.execute_frequency_loop_sequentialhas no per-frequency ground setup and never reachessomnec, soksymp/the ground constants stay at their free-space defaults for the solve.mainnow.History note: v2.2.0 behaved differently (PEC was exact there; GN 0/GN 2 were engaged but consumed the raw εr where 1/√εc is expected). Since v2.2.1-beta.1 the sequential path took over fully and all grounds fall through to free space.
Routing the sequential loop through the same ground setup control.c does (or hoisting that block into a shared helper) looks like the fix shape. Happy to re-test against nec2c/PyNEC on the full ground matrix once there's a candidate — same offer as #11.