eqfor.f90:88 fills crmn_o with B_s on the half grid, and eqfor.f90:111 passes it to jxbforce as bsubsh, which is declared INTENT(in). jxbforce builds the full-mesh values in a local array,
REAL(rprec), DIMENSION(ns,nznt), TARGET :: bsubs ! jxbforce.f90:46
...
bsubs(js,:) = cp5*(bsubsh(js,:) + bsubsh(js+1,:)) ! jxbforce.f90:175
and that local is gone at RETURN. fileout.f90:79 then hands the same untouched half-grid crmn_o to wrout, which applies a full-mesh endpoint rule to it,
bsubsmns(:,1) = 2*bsubsmns(:,2) - bsubsmns(:,3) ! extrapolation on full grid
and writes it as !Full mesh. The note already sitting at wrout.f90:603 records this.
PARVMEC declares the same argument INTENT(inout) (jxbforce.f:33) and converts it in place, so its wout carries the full-mesh values.
currumnc and currvmnc sit downstream of bsubsmns through Compute_Currents, and the copy of that routine in read_wout_mod.f expects the half-mesh convention: it averages surfaces js and js+1 into t1. ORNL-Fusion/LIBSTELL read_wout_mod.f90 has commented those averages out and uses t1 = bsubsmns_(:,js), matching the full-mesh array PARVMEC passes it. The two halves of this repository therefore disagree with each other, and both differ from the wout file's own declaration.
Measured against the PARVMEC wout for the same input, relative to the maximum of each array:
|
bsubsmns |
currumnc |
currvmnc |
solovev |
8.0e-3 |
1.5e-10 |
4.2e-4 |
cma |
2.5e-1 |
1.0e+0 |
9.8e-1 |
cth_like_fixed_bdy |
2.5e-1 |
8.9e-1 |
5.1e-1 |
The disagreement is largest at the axis and falls outward, which is where the half and full meshes differ most.
A second consequence: the lbsubs = T correction is applied to the discarded local, so it cannot reach the wout. Running input.cth_like_fixed_bdy with LBSUBS = T leaves bsubsmns unchanged while jdotb and the Mercier terms, which are computed inside jxbforce, do change.
eqfor.f90:88fillscrmn_owithB_son the half grid, andeqfor.f90:111passes it tojxbforceasbsubsh, which is declaredINTENT(in).jxbforcebuilds the full-mesh values in a local array,and that local is gone at
RETURN.fileout.f90:79then hands the same untouched half-gridcrmn_otowrout, which applies a full-mesh endpoint rule to it,and writes it as
!Full mesh. The note already sitting at wrout.f90:603 records this.PARVMEC declares the same argument
INTENT(inout)(jxbforce.f:33) and converts it in place, so its wout carries the full-mesh values.currumncandcurrvmncsit downstream ofbsubsmnsthroughCompute_Currents, and the copy of that routine inread_wout_mod.fexpects the half-mesh convention: it averages surfacesjsandjs+1intot1. ORNL-Fusion/LIBSTELLread_wout_mod.f90has commented those averages out and usest1 = bsubsmns_(:,js), matching the full-mesh array PARVMEC passes it. The two halves of this repository therefore disagree with each other, and both differ from the wout file's own declaration.Measured against the PARVMEC wout for the same input, relative to the maximum of each array:
bsubsmnscurrumnccurrvmncsolovevcmacth_like_fixed_bdyThe disagreement is largest at the axis and falls outward, which is where the half and full meshes differ most.
A second consequence: the
lbsubs = Tcorrection is applied to the discarded local, so it cannot reach the wout. Runninginput.cth_like_fixed_bdywithLBSUBS = Tleavesbsubsmnsunchanged whilejdotband the Mercier terms, which are computed insidejxbforce, do change.