libneo has two independent g-file entry points with different convention handling. The same file can yield different effective field conventions depending on which path a consumer uses.
Validated path: geqdsk_read + geqdsk_classify + geqdsk_standardise (src/magfie/geqdsk_tools.f90:264-341). Classifies COCOS from the file signs, repairs the q sign to the COCOS-3 relation, reconciles FPOL with BCENTR, and detects full-flux files via the Grad-Shafranov prefactor estimate (geqdsk_GS_prefactor), rescaling psi by 1/(2 pi) when needed. Callers: geoflux_coordinates.f90:70-71, MEPHIT (mephit_iter.F90:155-157).
Unchecked path: read_eqfile1/read_eqfile2 in src/magfie/field_divB0.f90:377-506. Raw read of the psi map, fpol, and scalars; no sign checks, no 2 pi detection; qpsi is read into a local and dropped. The comments in geqdsk_classify say sgn_cyl and exp_Bpol are "assumed in field_divB0.f90" (geqdsk_tools.f90:269,303), but nothing on the field_divB0 path verifies those assumptions. Callers include efit_to_boozer (via field_eq), which produces the Boozer files consumed by NEO-RT and NEO-2, plus bdivfree.f90 and MEPHIT's field-line integration.
Consequences:
- A full-flux g-file (COCOS 11-18 family) passes silently through
read_eqfile1 with B_pol wrong by 2 pi; on the geqdsk_tools path it is detected and rescaled. Downstream, efit_to_boozer writes a Boozer file with iota wrong by the same factor.
- A sign-reversed g-file flips the B_pol direction silently on the field_divB0 path while being normalized on the geqdsk_tools path.
For comparison, GPEC (PrincetonUniversity/GPEC) normalizes away all g-file signs on read and recomputes q from field-line integration, so it is immune to sign conventions but, like the field_divB0 path, silently wrong for full-flux files; see PrincetonUniversity/GPEC#267 for the verification. g-files with inconsistent sign conventions do circulate, so the unchecked path is exposed in practice.
Suggestion: route read_eqfile1/read_eqfile2 through geqdsk_classify (or call geqdsk_GS_prefactor directly) and at least warn, better stop, when the file violates the assumptions documented in geqdsk_tools.f90. Cheap to add since the detection code already exists.
Secondary note: geqdsk_standardise silently skips the q flip when sgn_q == 0 (mixed-sign qpsi, sign_array tie); classification prints "COCOS index could not be determined" but processing continues with unrepaired q. A hard error or explicit warning at standardisation would be safer.
Related: #116 (test failure inside geqdsk_standardise itself; different scope).
libneo has two independent g-file entry points with different convention handling. The same file can yield different effective field conventions depending on which path a consumer uses.
Validated path:
geqdsk_read+geqdsk_classify+geqdsk_standardise(src/magfie/geqdsk_tools.f90:264-341). Classifies COCOS from the file signs, repairs the q sign to the COCOS-3 relation, reconciles FPOL with BCENTR, and detects full-flux files via the Grad-Shafranov prefactor estimate (geqdsk_GS_prefactor), rescaling psi by 1/(2 pi) when needed. Callers:geoflux_coordinates.f90:70-71, MEPHIT (mephit_iter.F90:155-157).Unchecked path:
read_eqfile1/read_eqfile2insrc/magfie/field_divB0.f90:377-506. Raw read of the psi map, fpol, and scalars; no sign checks, no 2 pi detection; qpsi is read into a local and dropped. The comments ingeqdsk_classifysaysgn_cylandexp_Bpolare "assumed in field_divB0.f90" (geqdsk_tools.f90:269,303), but nothing on the field_divB0 path verifies those assumptions. Callers includeefit_to_boozer(viafield_eq), which produces the Boozer files consumed by NEO-RT and NEO-2, plusbdivfree.f90and MEPHIT's field-line integration.Consequences:
read_eqfile1with B_pol wrong by 2 pi; on the geqdsk_tools path it is detected and rescaled. Downstream,efit_to_boozerwrites a Boozer file with iota wrong by the same factor.For comparison, GPEC (PrincetonUniversity/GPEC) normalizes away all g-file signs on read and recomputes q from field-line integration, so it is immune to sign conventions but, like the field_divB0 path, silently wrong for full-flux files; see PrincetonUniversity/GPEC#267 for the verification. g-files with inconsistent sign conventions do circulate, so the unchecked path is exposed in practice.
Suggestion: route
read_eqfile1/read_eqfile2throughgeqdsk_classify(or callgeqdsk_GS_prefactordirectly) and at least warn, better stop, when the file violates the assumptions documented ingeqdsk_tools.f90. Cheap to add since the detection code already exists.Secondary note:
geqdsk_standardisesilently skips the q flip whensgn_q == 0(mixed-sign qpsi,sign_arraytie); classification prints "COCOS index could not be determined" but processing continues with unrepaired q. A hard error or explicit warning at standardisation would be safer.Related: #116 (test failure inside geqdsk_standardise itself; different scope).