Skip to content

Divergence across seams ​

IDGroupMilestoneBackendsFigureRegression
AD (A2)Seam accuracy and divergenceM6 (#68), #78FNL (tables); CPU for the loop leg and the D_flux cross-checkyes—

Case and scope ​

Every div(B) column of the MHD checks is the centred divergence of the cell values, which is not the divergence GLM and EGLM act on (#68 F4). [diagnostics] divb_flux adds D_flux, the divergence of the interface normal field read from the scheme's own ψ face fluxes, the coarse 2:1 faces taking the fine fluxes (the reflux), so that it sums exactly (Gauss) over a composite grid. AD measures D_flux where the seams matter:

  • cpaw: a source-free, exact nonlinear solution with ∇⋅B=0 that crosses two seams all the time: is the seam D_flux bounded or does it grow, and does it converge?
  • loop: the field loop of MV-9 under GLM and EGLM, the case of #78 (EGLM's ⟨|Bz|⟩ 70 times its uniform level on a static 2:1 grid): is #78 a divergence difference?

What the case catches:

  • a secular growth of the seam divergence under GLM (PRISM's centred GLM lets it run away, #29);
  • a seam divergence that does not converge under refinement;
  • a broken D_flux instrument: its signed integral over a periodic composite domain must be round-off.

Models and numerics ​

ItemChoiceCode
Equationsideal MHD, γ=5/3; mixed GLM (cpaw, loop) or EGLM (loop); glm_alpha 0.18, glm_damping_length 1.0; glm_ch 2.0 (cpaw, above the fast speed, about 1.08) or 4.0 (loop)GLM, EGLM; add_eglm_sources, adam_flume_cpu_mhd_eglm_kernels.F90
SpaceWENO5 (weno-u-5) flux splitting on characteristic variablescompute_residuals_weno, adam_flume_cpu_object.F90; mhd_glm_face_split_fluxes, mhd_eglm_face_split_fluxes, adam_flume_mhd_library.F90
TimeSSP Runge–Kutta, 5 stages (runge-kutta-ssp-54), CFL 0.4adam_rk_object.F90
Seam operatorsmean restriction, tricubic fill, reflux on (always)numerics
D_flux∑d(Fψ(i+12)−Fψ(i−12))/Δxd over ch2 (GLM) or ch (EGLM), the coarse 2:1 faces corrected to the fine fluxes; the seam column over the cells within ngc of a seam; key [diagnostics] divb_fluxcompute_dflux_norms, compute_divb_history, adam_flume_cpu_object.F90 and adam_flume_fnl_object.F90; adam_flume_diagnostics_object.F90
Boundariesperiodic in x and y; extrapolation on the null z facesboundary conditions

Initial and boundary conditions ​

Itemcpawloop
Domain[0,5]×[0,5/2], null z[−1,1]×[−0.5,0.5], null z
Initial conditionMV-6 CPAW, right polarised, inclined at tan⁡α=2 (63.43°), B∥=1, amplitude 0.1, wavelength 1, ρ=1, p=0.1MV-9 field loop, radius 0.3, A0=10−3, centre (0,0); (ρ,u,v,w,p)=(1,2,1,1,1)
Gridquadtree (ratio = 4), 4×4 base blocks of N/4×N/8×1 cells, ngc = 3the same
Refined regionthe two middle block columns, x∈[0.6,1.6]: two x seams the wave crosses all the timethe box [0,1]×[−0.5,0.5]
Ladderrefined and uniform N = 64 / 128 (--long adds 256)refined N=64 against uniform N=128
Boundariesperiodic in x, y; extrapolation in zthe same
Final time10 periods (t=10)t=1
History cadenceevery 10 stepsevery step
Ranks22

Input files ​

FileRole
src/tests/flume/verification/amr-divb/make_amr_divb.pywrites the inputs from mhd/cpaw/make_cpaw.py and mhd/field-loop/make_field_loop.py; --uniform, --periods, --cleaning, --time-max, --history
src/tests/flume/verification/mhd/amr_box.pyrefine_box: the refined region, one 2:1 level at initialisation
src/tests/flume/verification/amr-divb/amr_divb_oracle.pygrowth (the cpaw floors, growth and orders) and loop (a report)
src/tests/flume/verification/amr-divb/check.shruns the legs (--legs cpaw,loop, --long, --np N, --keep)
src/tests/flume/verification/make_doc_runs.sh <runs> divb (FNL), make_doc_figures.py --only divergence-across-seamsre-runs the field loops (GLM, EGLM; refined, without reflux, uniform) with the history every step; the CPAW panel reads the histories of check.sh
bash
cd src/tests/flume/verification/amr-divb
FLUME_EXE=$PWD/../../../../../exe/adam_flume_fnl ./check.sh          # FNL: about 12 min
FLUME_EXE=$PWD/../../../../../exe/adam_flume_fnl ./check.sh --long   # adds N = 256 (30 more minutes)
./check.sh --legs loop                                               # the loop leg on the CPU

The cpaw leg costs about 2 h on the CPU (N=128 dominates): run it on FNL.

Oracle (amr_divb_oracle.py, reading the *-divb_history.dat columns). cpaw: per run the seam D_flux floor (the median over the second half of the run, the step-0 row excluded), its growth (the mean over the last quarter over the mean over the second quarter: about 1 when bounded) and the floor's order over the refined ladder; a uniform run has no seam, its floor is that of the global D_flux. Bounds: growth at most 1.5 on every refined run, floor order at least 1 on the finest pair. loop: the final seam and global D_flux and ⟨|Bz|⟩/A0, a report.

Results ​

AD: the seam D_flux against time

FNL, 2 ranks. Left: the seam maximum of D_flux on the source-free CPAW over 10 periods, refined N=64 and 128 (the histories check.sh keeps), against the global maximum of the uniform N=128 run: the seam floor is bounded and falls 10 times from 64 to 128. Right: the A2 field loop under GLM and EGLM, the refined seam maximum against the uniform global one. No divergence map: FLUME writes no divergence field, and a centred difference of the checkpoints would read unfilled ghosts exactly at the seams.

The instrument: the signed integral of D_flux over the periodic composite domain is round-off, ≤10−17 every step on the refined MHD vortex, against 4⋅10−7 without the fine fluxes; CPU and FNL agree to 10−11 relative.

cpaw (FNL, 2 ranks):

NSeam D_flux floorGrowthUniform floorSeam / uniform
645.39⋅10−40.959.97⋅10−654
1285.43⋅10−50.724.57⋅10−7119
2562.12⋅10−50.806.74⋅10−93146

loop (FNL, 2 ranks), t=1:

Field loop, t=1D_flux (seam, refined)D_flux (max, uniform)⟨|B_z|⟩/A0 refineduniform
GLM2.35⋅10−42.03⋅10−41.10⋅10−36.86⋅10−4
EGLM2.45⋅10−42.05⋅10−41.91⋅10−42.72⋅10−6

Related cases: G2 varies the GLM damping length on the same cpaw leg; G3a and G3b rerun the loop leg and fix #78; the uniform-grid cleaning is GLM divergence cleaning and EGLM cleaning.

Findings ​

  • GLM keeps the seam divergence bounded. Over 10 periods of a source-free flow the seam D_flux has no secular growth at any resolution: the upwinded (Bn,ψ) pair of FLUME bounds what PRISM's centred GLM lets run away (#29; #68 F3).
  • The seam floor converges at first order (orders +3.31 then +1.36: the first pair is pre-asymptotic), the O(H) divergence of the O(H2) flux inconsistency of a 2:1 face (#68 F1), while the uniform floor converges at 4 to 6: the seams are the divergence error of a refined run, 3146 times the uniform level at N=256.
  • #78 is not a divergence difference. GLM and EGLM leave the same D_flux, refined and uniform; EGLM's 250-fold smaller Bz on a uniform grid comes from its source term, whose centred divergence cancels the Bz the flux generates. The Bz rises 70 times on the refined grid, reproduced here to the printed digits of #78.
  • Attribution, corrected. A2 attributed the rise to the centred source divergence reading the second-order restricted ghosts at the seam, where the cancellation fails, and placed the fix in Phase G3 (a source divergence consistent with the face fluxes at the seams). G3a showed that the ghosts are not the cause: the reflux is. G3b fixed it by not refluxing B under EGLM.