Skip to content

Fix odd-grid RFFT energy weights; add a Hermite boundary diagnostic - #9

Open
rogeriojorge wants to merge 4 commits into
mainfrom
agent/fix-odd-rfft-energy
Open

rogeriojorge wants to merge 4 commits into
mainfrom
agent/fix-odd-rfft-energy

Conversation

@rogeriojorge

@rogeriojorge rogeriojorge commented Jul 13, 2026 •

Copy link
Copy Markdown
Member

Problem

The field-energy diagnostic gave the last stored rFFT coefficient weight 1 for every Nx. That is right only for even Nx (Nyquist singleton); for odd Nx that coefficient has an omitted conjugate and needs weight 2. On main, EM_energy / (0.5 * mean(F^2)) = 0.898 for a random field at Nx=7 and 0.809 at (Ny,Nx,Nz)=(3,5,4); exactly 1 for even Nx. A Landau run at Nx=3 reports exactly half the field energy of the same run at Nx=4.

Change

  • _rfft_weights(Nx, Nx_kept): k=0 weight 1, Nyquist weight 1 only for even Nx, others 2. It requires the original Nx (no guess from the stored length) and raises if the stored axis is not a full rfft (Nx_kept != Nx//2+1, e.g. cropped/dealiased arrays). simulation passes the static Nx to diagnostics.
  • hermite_tail_fraction(output, width=1): per-species fraction of the Parseval-weighted dCk norm in the outer width modes of each active Hermite axis, shape (Nt, Ns). It is a coefficient-norm indicator, not an energy.

Tests (tests/test_diagnostics.py, 22 cases)

Independent Parseval: EM_energy vs numpy full fftn sum and real-space mean for Nx in {1,2,3,4,5,6,7,8,9} with full-FFT y/z axes and singleton axes; refusal of cropped axes and of missing Nx; tail fraction with odd weights, 3 species with unequal tails, mixed active axes, zero norm.

Evidence (tested SHA 6eeebb8, rebased on main ab87385; local, Python 3.12.9, JAX 0.11.2)

python -m pytest -n 2 -q tests: 30 passed (main: 8).

No dependencies. Overlaps textually with #13 only in _simulation.py output assembly (trivial).

@codecov

codecov Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.73684% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
spectrax/_diagnostics.py 94.59% 1 Missing and 1 partial ⚠️
Files with missing lines Coverage Δ
spectrax/_simulation.py 100.00% <100.00%> (ø)
spectrax/_diagnostics.py 83.47% <94.59%> (+9.60%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rogeriojorge
rogeriojorge marked this pull request as ready for review July 13, 2026 02:57
@rogeriojorge
rogeriojorge force-pushed the agent/fix-odd-rfft-energy branch from b3454d7 to c3a6598 Compare July 16, 2026 13:46
rogeriojorge added a commit that referenced this pull request Sep 23, 2026
The study scripts now live in a separate repository pinned to a7ca601. This branch keeps only the unchanged merges of #44, #24, #12 and #17 (with #9).
@rogeriojorge
rogeriojorge force-pushed the agent/fix-odd-rfft-energy branch from c3a6598 to c773d98 Compare September 26, 2026 21:11
@rogeriojorge rogeriojorge changed the title Fix odd-grid RFFT energy weights Fix odd-grid RFFT energy weights; add a Hermite boundary diagnostic Sep 26, 2026
For odd Nx the last RFFT coefficient has an omitted conjugate and needs weight 2. hermite_tail_fraction reports the perturbation norm fraction in the outer Hermite modes, using the same Parseval weights.
The weights now come only from the original grid length and refuse a stored
x axis that is not a full rfft of it (cropped or dealiased arrays), instead of
guessing Nx from the stored length. Tests compare EM_energy with numpy's full
FFT and the real-space mean for odd/even Nx, full y/z axes and singleton
axes, and check per-species tail fractions for three species.
@rogeriojorge
rogeriojorge force-pushed the agent/fix-odd-rfft-energy branch from c773d98 to 5319c84 Compare October 3, 2026 14:27
initialize_simulation_parameters is jitted, so its Nx is a tracer; the rFFT
weights need the concrete grid length.
rogeriojorge added a commit that referenced this pull request Oct 3, 2026
…c current, per-population tails

The growth rate is now a least-squares fit over an explicit --fit-window
(default: second half of the run) of the observable the docstring names, with
the fit residual and the per-half rates printed. The movie shows the kinetic
current J_z/Omega_ce instead of curl B, which also contains dE_z/dt. Hermite
tails use hermite_tail_fraction per population (needs #9). The convergence
table is labelled as measured with the previous peak fit and the assumed
second-order extrapolation is removed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant