Skip to content

Conservation across 2:1 seams and forest seams ​

IDGroupMilestoneBackendsFigureRegression
VV-7Dissipative terms (M4)M4 (#65)CPU, FNLyesseam-viscous-amr

Case and scope ​

A diagonal wave of large amplitude crosses 2:1 coarse-fine faces (one realm with its centre refined) and inter-realm seams (the same domain split into two realms). The conserved integrals are judged on the refined realm; the fields of the forest are judged against the single realm.

What the case catches:

  • dissipative fluxes missing from the seam registers: the dissipative fluxes are added to the inviscid ones before the seam accumulation, so the Berger–Colella reflux and the inter-realm register must carry them. At a 2:1 face the coarse and the fine side compute different viscous, heat and Ohmic fluxes, and without the register the grid leaks;
  • unfilled edge and corner ghosts: the dissipative stencils reach further than WENO's: the tangential derivatives read the edge and corner ghosts, which no inviscid stencil touches.

Models and numerics ​

ItemChoiceCode
EquationsEuler with μ=0.01, k=0.02; ideal MHD with GLM (ch=3), Bn=1, μ=0.01, η=0.01; γ=1.4models, GLM
Dissipative fluxesdissipative_order = 4, added to the inviscid fluxes before the seam accumulationadd_dissipative_fluxes, adam_flume_cpu_object.F90; numerics
Inviscid fluxesWENO5 flux splitting, characteristic variablescompute_residuals_weno, adam_flume_cpu_object.F90
Timerunge-kutta-ssp-54, CFL 0.2adam_rk_object.F90
2:1 refluxBerger–Colella register of the seam fluxes, [numerics] reflux on or offaccumulate_seam_fluxes, reflux_stage, adam_flume_cpu_object.F90; accumulate_coarse_flux, accumulate_fine_flux, adam_flux_register_object.F90; numerics
Coarse-fine ghoststhe library's 2:1 ghost fillboundary conditions
Forest seamscoupling = mirror (1:1) or refined (2:1), coupling_cadence = stage_coincident; seam ghost centres wrapped by one period along a tangential axis periodic on both realmsfill_seam_from_peer_forest, adam_flume_cpu_object.F90; wrap_periodic_tangential, adam_forest_object.F90; inter-realm seam
Conservation historyvolume integrals written every stepcompute_conservation, adam_flume_cpu_object.F90

Initial and boundary conditions ​

ItemValue
Domain[0,1]2, z null
Ranks2
Initial conditionsine-wave at 45°, A=0.01 (large, so the seams carry a real flux): the acoustic wave on Euler (density, normal velocity and temperature all vary), the magnetic (Alfvén) wave on MHD-GLM; ρ0=p0=1, wavelength 1/2
Final timet=0.05
LegGridBoundariesRuns
refined box (conserve-*-quadtree)quadtree, 4×4 blocks of 122 cells (48 per side at the base level), the blocks whose centroid lies in [0.25,0.75]2 refined 2:1 (8 coarse-fine faces)periodic in x and ywith reflux; without; without reflux and without the dissipative coefficients (the ideal twin)
forest, mirrorthe single realm split at x=0.5 into two realms of 4×4 blocks of 6×12 cells, quadtree, glued 1:1extrapolation (outflow) in x, periodic in ysingle realm; forest
forest, refinedthe single run refines x>0.5; realm 1 the coarse half, realm 2 the fine half at one more uniform level, glued 2:1; octree (nk=4), because the refined coupling needs ratio 2 along every axis, null z includedextrapolation in x, periodic in ysingle realm; forest

An octree with null z gave the same drifts as the quadtree to the printed digits at four times the cells, so the refined-box leg keeps the quadtree; the octree's 2:1 seams are exercised by the refined forest.

Input files ​

FileRole
src/tests/flume/verification/viscous/waves.pymake --refine ... --reflux, split (the two-realm forest), conserve (the drift oracle)
src/tests/flume/verification/multirealm/multirealm_oracle.pythe forest union against the single realm (--fields-only)
src/tests/flume/verification/viscous/check.sh --legs vv7runs the 6 refined-box runs and the 8 forest runs (--np N; FLUME_EXE selects the backend)
src/tests/flume/verification/make_doc_figures.py --only seam-conservationthe figure, from the histories that viscous/check.sh --legs vv7 keeps (CPU)
src/tests/flume/regression/seam-viscous-amr/input.inithe frozen Alfvén wave, A=0.01, MHD-GLM with μ and η, 482 with the centre refined 2:1, t=0.02
bash
cd src/tests/flume/verification/viscous && ./check.sh --legs vv7             # CPU
FLUME_EXE=$PWD/../../../../../exe/adam_flume_fnl ./check.sh --legs vv7       # FNL

Results ​

VV-7: drift of the integrals across seams

The drift of the mass and energy integrals per step, CPU. Left and centre: the acoustic wave on Euler and the Alfvén wave on MHD-GLM across a 2:1 box; with the reflux the integrals stay at round-off, without it they drift, and so does the ideal twin without the dissipative coefficients, so the drift is the seam, not the dissipative fluxes. Right: the forests (1:1 mirror and 2:1 refined, outflow in x) against their single-realm runs: the summed integrals of the two realms agree to round-off at every step.

Oracle (waves.py conserve). The drift of each conserved integral is divided by ∫|q|dV, the scale of its round-off (the momentum of a sine wave integrates to zero, so its own value is no scale; ψ, sourced only by the discrete ∇⋅B, is measured against ch∫|B|dV):

  • with reflux, every drift ≤10−13;
  • without reflux, the largest drift ≥10−10 (the seams are exercised);
  • the leak without reflux differs from the ideal twin's by ≥10−10: the dissipative fluxes cross the seams unmatched, and the first item shows the register removes that too.
CaseWith reflux (bound 10−13)Without (≥10−10)Dissipative minus ideal leak (≥10−10)
Euler≤1.1⋅10−173.0⋅10−52.0⋅10−6
MHD-GLM≤1.5⋅10−165.9⋅10−55.1⋅10−6

CPU and FNL (2 ranks) are identical to the printed digits except the round-off of the conserved runs, at most 1.1⋅10−16 on FNL.

Forests: the union must reproduce the single realm, fields within 10−10 relative.

ForestBoundCPUFNL
mirror and refined, Euler and MHD-GLM10−10largest difference 8.7⋅10−124.4⋅10−12

Related cases: the accuracy across the same seams is VV-8; the inviscid conservation across AMR seams is Euler AMR conservation; the forest machinery is multi-realm runs.

Findings ​

  • The forest comparison is not bitwise, unlike MV-14's piecewise-constant states: each realm evaluates the sine from its own block origins, one ulp apart at step 0 (3⋅10−15). The largest difference after the run sits at the outer x faces, not at the seam.
  • This leg found a library defect. A seam slab's edge and corner ghosts past a tangential boundary of the realm lie outside the peer domain, and were left to the boundary condition; along a periodic axis no condition fills them, and they kept their initial values. WENO never reads them, the dissipative tangential derivatives do: the mirror split went NaN at the first step (on a single realm of the same half domain the run is clean). The seam enumeration now wraps those ghost centres by one period when the axis is periodic on both realms (forest guide).