Skip to content

Unification of the three integrators - PR #1 - #381

Merged
matt-pharr merged 5 commits into
developfrom
refactor/riccati-unification
Aug 15, 2026
Merged

Unification of the three integrators - PR #1#381
matt-pharr merged 5 commits into
developfrom
refactor/riccati-unification

Conversation

@matt-pharr

@matt-pharr matt-pharr commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

PR 1 of the refactor sequence in REFACTOR_PLAN.md (§3). Delivery: this PR targets develop; #387 (LocalStability) stacks on it, and the remaining work lands as a single combined interface PR on refactor/forcefreestates-result (three slice-pure commits: result struct + consumers + standalone Galerkin, staged main, solve API — the original PRs 3–5, collapsed).

What this does

  • Deletes the standalone serial-Riccati path, populate_dense_xi / _populate_dense_xi_via_serial_el!, and parallel_threads — no merging of two integration results anywhere (plan D3).
  • One integrator selector: integrator = "forward" | "riccati" in [ForceFreeStates] ("galerkin" reserved, errors until PR 4). Old keys (use_riccati, use_parallel, parallel_threads, populate_dense_xi) are warn-and-ignored via _DEPRECATED_FFS_KEYS, so pre-refactor gpec.h5 replays keep working; new TOMLs are blocked from using them by the pre-commit hook.
  • Riccati threading: uses whatever julia -t provides; the only tunable is nchunks (0 = auto, derived from msing alone — chunk sizing never consults Threads.nthreads(), so Riccati outputs are thread-count independent; new tests pin this).
  • serial_eulerlagrange_integrationforward_eulerlagrange_integration; the STRIDE driver now owns the riccati_eulerlagrange_integration name. Erroneous "shooting" terminology renamed to "forward" (legitimate STRIDE/GGJ shooting terminology untouched).
  • Riccati + kinetic_factor > 0 now errors with a clear message (plan D4: kinetic is Forward-only).
  • TOML sweep across all 22 example/fixture decks: forward for PE/kinetic decks, riccati for Δ′/stability decks; gal decks stay riccati (their PE consumes the gal-matched solution, not the integrator's).
  • New examples/DIIID-like_riccati_deltaprime_example/ (references the DIIID geqdsk by relative path, no duplication) + regression-harness/cases/diiid_n1_riccati.toml: the canonical SingularSurfaces/delta_prime_matrix track moves there; diiid_n1 keeps the ξ / perturbed-equilibrium quantities on the forward integrator.
  • Docs (stability.md, control-struct docstrings), benchmark scripts, and REFACTOR_PLAN.md amendments (upstream ALL - REFACTOR - Module-mirroring CamelCase HDF5 schema (issue #226, PR A) #363/VACUUM - Migrate surface current calculation into the VACUUM module #345 absorbed; progress checklist updated) included.

Verification

  • Targeted test files pass (307/307): runtests_eulerlagrange.jl, runtests_riccati.jl, runtests_parallel_integration.jl (incl. new thread-independence / nchunks steering / clamp-warning tests), runtests_rerun_from_h5.jl (incl. new deprecated-key replay-warn test).
  • Full test suite
  • Regression harness report (diiid_n1, diiid_n1_riccati first baseline, solovev_n1) — pasted here before this PR leaves draft
  • Docs build (build_docs_local.jl)

⚠️ Review requirement

This PR must not be merged without a third-party human reviewer's approval — non-negotiable (see REFACTOR_PLAN.md §8).

🤖 Generated with Claude Code

Replace the use_riccati / use_parallel / parallel_threads / populate_dense_xi
flag set with a single integrator = "forward" | "riccati" | "galerkin" key plus
an nchunks knob, per the ForceFreeStates modularization plan (PR 1 of 5).

- Delete the standalone serial-Riccati driver and the populate_dense_xi dense-xi
  re-run; no integration result is merged with another.
- Rename serial_eulerlagrange_integration -> forward_eulerlagrange_integration
  and give the STRIDE propagator driver the freed riccati_ name.
- Chunk sizing no longer reads Threads.nthreads(), so Riccati outputs are
  identical at any thread count; nchunks is the only tunable and clamps up to
  the singular-surface floor with a warning.
- Kinetic runs now error on the Riccati path rather than silently mis-crossing.
- The four retired keys join _DEPRECATED_FFS_KEYS and the toml-no-deprecated-keys
  hook, so old decks and gpec.h5 replays warn and continue.
- New examples/DIIID-like_riccati_deltaprime_example plus the diiid_n1_riccati
  regression case keep the delta-prime matrix covered once the DIIID-like deck
  moves to the forward integrator.

Verified on origin/develop: full suite 59 testsets / 2044 assertions / 0
failures; docs build clean; harness diiid_n1, solovev_n1 and diiid_slayer_n1 all
unchanged; delta-prime bit-identical between -t 1 and -t 4.

REFACTOR_PLAN.md is amended in the same commit: #363 and #345 merged before this
sequence branched, so the plan now records that it builds on the new HDF5 schema.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@matt-pharr
matt-pharr force-pushed the refactor/riccati-unification branch from 7fc592e to ab58849 Compare August 15, 2026 02:14
@matt-pharr
matt-pharr requested review from d-burg and logan-nc August 15, 2026 02:38
@matt-pharr
matt-pharr marked this pull request as ready for review August 15, 2026 02:45

@logan-nc logan-nc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great clarity win!

Only a few minor docs comments

Comment thread docs/src/stability.md Outdated
`eulerlagrange_integration` is the baseline driver. It integrates the EL ODE directly in
``(U_1, U_2)`` using Tsit5 with adaptive step control. Near each rational surface the
`forward_eulerlagrange_integration` is the baseline driver. It integrates the EL ODE directly
in ``(U_1, U_2)`` using Tsit5 with adaptive step control. Near each rational surface the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this Tsit5 claim out of date?

Comment thread docs/src/stability.md
``\Delta'`` matrix.

### Standard integration
### Forward integration

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should cite the main 2016 Glasser DCON reference in this section of the docs and make it clear this is our version of that approach. Similarly, we should explicitly say Riccati is our implementation of the STRIDE approach and cite it's papers.

Comment thread docs/src/stability.md Outdated
than integrating the quadratic Riccati ODE directly (which blows up when ``|S|`` is large),
the code integrates the linear EL system with `sing_der!` as the RHS and recovers
``S = U_1 U_2^{-1}`` via periodic renormalization — an approach that is mathematically
equivalent to O(Δψ) but uses the ODE solver's full 5th-order accuracy. Renormalization is

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, the "5th-order accuracy" might be out of date here. @d-burg changed the integrators a while back

@matt-pharr
matt-pharr enabled auto-merge August 15, 2026 19:12
@matt-pharr
matt-pharr disabled auto-merge August 15, 2026 19:13
@matt-pharr
matt-pharr enabled auto-merge August 15, 2026 19:20
@matt-pharr
matt-pharr merged commit a0c270f into develop Aug 15, 2026
6 checks passed
@matt-pharr
matt-pharr deleted the refactor/riccati-unification branch August 15, 2026 19:38
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.

2 participants