Skip to content

Allow selecting a faster second-order static GS operator - #98

Merged
kpentland merged 5 commits into
mainfrom
static-gs-operator-order
Aug 14, 2026
Merged

Allow selecting a faster second-order static GS operator#98
kpentland merged 5 commits into
mainfrom
static-gs-operator-order

Conversation

@nicamo

@nicamo nicamo commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

This adds a small, opt-in choice of finite-difference order for the static Grad-Shafranov solver.

  • Add gs_operator_order={2, 4} to GSstaticsolver.NKGSsolver.
  • Keep fourth order as the default, preserving existing behaviour.
  • Select FreeGS4E's existing GSsparse second-order operator or GSsparse4thOrder fourth-order operator.
  • Reject unsupported values with a clear ValueError.
  • Document the option and accuracy trade-off in Example 2.
  • Add tests for the second-order equilibrium and invalid operator orders.

No stencil or numerical solver implementation is duplicated in FreeGSNKE.

Linear-solver path

Although the FreeGS4E factory is named createVcycle, FreeGSNKE configures it with:

nlevels=1
direct=True

This constructs MGDirect, performs a sparse LU factorisation with SciPy, and uses direct back-solves. No multigrid restriction, prolongation, smoothing, or V-cycle is performed.

The second-order benefit therefore comes primarily from constructing and factorising a sparser matrix.

Performance

On the standard 65 x 129 static-solver test equilibrium:

Measurement Fourth order Second order Change
Solver construction 0.274 s 0.127 s 54% faster
Nonlinear solve after construction 0.205 s 0.208 s essentially unchanged
Total 0.487 s 0.351 s 28% faster

The total gain will be largest when solver objects are constructed frequently. Reusing an already-factorised solver reduces the benefit because repeated direct back-solves cost approximately the same.

Accuracy and compatibility

Second order has the expected spatial discretisation accuracy trade-off and is therefore opt-in. The default remains gs_operator_order=4.

The regression test verifies that the second-order equilibrium agrees with the established static equilibrium baseline within 0.3% of the reference flux range.

Verification

  • python -m pytest -q freegsnke/tests/test_static_solver.py
  • 3 passed
  • Example 2 remains valid notebook JSON

@nicamo nicamo added the enhancement New feature or request label Aug 4, 2026
@nicamo
nicamo changed the base branch from streamlining to main August 4, 2026 11:49

@kpentland kpentland 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.

Nice addition if users need speed!

@kpentland kpentland added the ready-for-final-tests Pull request is ready to run final pre-merge tests label Aug 14, 2026
@kpentland
kpentland merged commit 82ef798 into main Aug 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request ready-for-final-tests Pull request is ready to run final pre-merge tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants