Skip to content

Add a geometry tolerance that holds a run until the flux surfaces stop moving - #843

Open
CharlesCNorton wants to merge 2 commits into
proximafusion:mainfrom
CharlesCNorton:state-convergence-measure
Open

Add a geometry tolerance that holds a run until the flux surfaces stop moving#843
CharlesCNorton wants to merge 2 commits into
proximafusion:mainfrom
CharlesCNorton:state-convergence-measure

Conversation

@CharlesCNorton

Copy link
Copy Markdown
Contributor

Change - VmecInput gains geometry_tolerance, a distance in metres, default 0 which leaves everything as it is. When positive, a multigrid step converges only once the force residuals meet ftol_array AND the flux surfaces have stopped moving: fc_.geometry_change, the Euclidean norm of the change in the R and Z spectral coefficients over the last nstep iterations. Vmec::AccumulateGeometryChange folds each thread's contribution over the surfaces it owns, so the measure does not depend on the thread count, and it resets at every multigrid stage because the radial grid changes between stages.

Cause - the convergence test reads the force residual, which is small in exactly the directions the equilibrium is still moving along, so a run that meets its tolerance can stop with the quantities it is used for still in motion. On examples/data/w7x.json at ns = 99, a run stopped at ftol 1e-8 leaves the magnetic axis 14.7 mm from where it settles and the mid-radius rotational transform off by 3.1e-3.

Evidence - examples/data/w7x.json at ns = 99, single grid, deviation measured against the same case run to ftol 1e-16, which takes 5884 iterations:

ftol geometry_tolerance iterations axis iota at mid-radius
1e-8 unset 333 14.6976 mm 3.1e-3
1e-8 1e-5 5602 0.0001 mm 3.0e-7
1e-8 1e-6 7002 0.0003 mm 4.0e-7
1e-12 unset 2954 0.0021 mm 4.5e-5

and cth_like_fixed_bdy at ns = 51, against its own ftol 1e-16 run at 1963 iterations:

ftol geometry_tolerance iterations axis iota at mid-radius
1e-8 unset 245 0.3222 mm 1.2e-3
1e-8 1e-5 1002 below a micron 4.8e-7
1e-8 1e-6 1602 below a micron 9.4e-8
1e-8 1e-7 2402 below a micron 3.5e-8

Ten microns of surface motion is a stricter statement about the equilibrium than ftol 1e-12 is: on W7-X it reaches iota to 3.0e-7 where ftol 1e-12 alone reaches 4.5e-5.

Tests - tests/test_geometry_tolerance.py: that the default leaves the iteration count and the wout bit-identical, that a run held to 1e-5 lands on the axis and iota of the fully converged case where the residual alone does not, that a tighter tolerance lands closer, that a negative value is rejected, and that the field survives a JSON round trip. bazel test --config=opt //vmecpp/... is 24 of 24 and pytest tests/ is 234 passed, 4 skipped. Pre-commit clean.

Scope - unset, the convergence test is the one that was there and every existing test reproduces its iteration count. The measure is computed at the printout interval only, from a copy of the R and Z coefficients, so it costs one comparison per nstep iterations. The criterion can only extend a run, never shorten one. The HDF5 read is guarded on the dataset being present, so inputs written before this still load.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

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