Repository navigation
Separate boundary modes from VMEC solver resolution - #181
rogeriojorge wants to merge 3 commits into
Conversation
gftd13
left a comment
There was a problem hiding this comment.
One question inline about the default MPOL headroom.
| """ | ||
| families = {'RBC': self.rc, 'ZBS': self.zs, 'RBS': self.rs, 'ZBC': self.zc} | ||
| asym = self.rs is not None or self.zc is not None | ||
| solver_mpol = self.mpol + 2 if mpol is None else mpol |
There was a problem hiding this comment.
Question on the default solver resolution:
Since MPOL is a count (VMEC keeps m < MPOL), the default self.mpol + 2 retains m only up to mpol+1, while NTOR = self.ntor + 2 retains |n| up to ntor+2. The PR description says "two above" for both, so the poloidal headroom is one mode less than described.
Why it may matter: VMEC uses the same truncated series for the interior surfaces, which need harmonics above the boundary's (e.g. m=1 × m=2 shaping couples into m=3, m=2 × m=2 into m=4). With only +1 in m, the interior R_mn(s) can be under-resolved, which affects iota(s) and the B_mn spectrum, i.e. exactly the VMEX iota and QS-breaking values we use to validate the optimization.
It doesn't affect the single-stage example (it passes VMEC_MPOL=VMEC_NTOR=9), but anyone calling to_vmec() with defaults would get it. Should the default be self.mpol + 3 (max m = mpol+2), or should the description/docstring say +1 in m?
|
@gftd13 correct: MPOL is a count, so the default adds one retained poloidal mode and two toroidal modes. I clarified the docstring and PR description. I kept the requested boundary-max + 2 defaults; these are starting resolutions, not convergence guarantees. The single-stage validation checks higher resolutions independently. Please review the wording and test the export with your boundary modes. |
Read the surface resolution from nonzero boundary coefficients instead of VMEC's solver MPOL/NTOR. Explicit
mpol,ntor, ormax_modenow truncate or pad the optimization boundary independently.Export a zero-current vacuum input with
FTOL_ARRAY=1e-12,NS_ARRAY=51,NITER_ARRAY=3500, and MPOL=boundary max(m)+2 and NTOR=boundary max(|n|)+2. MPOL is a count: the retained maxima are boundary max(m)+1 and boundary max(|n|)+2. Preserve signed modes and asymmetric coefficients.Validation: 41 field/surface tests passed; VMEX parsed the exported coefficients and controls correctly.
@gftd13 please review and test this with your single-stage input and a higher-resolution restart. Check that the default surface includes every nonzero boundary mode, and that explicit mode limits give the intended optimization variables.