Appearance
Forward-facing step: a three-realm forest on quadtrees
| ID | Group | Milestone | Backends | Figure | Regression |
|---|---|---|---|---|---|
| EV-step | Euler | — (#46, quadtree AMR; #66) | CPU, FNL (trees leg); CPU only (full leg) | yes | — |
Case and scope
The Mach 3 wind tunnel with a step of Woodward & Colella (1984, J. Comput. Phys. 54, 115–173, §IV b): the gas enters from the left at Mach 3, hits a step of height 0.2, and forms a bow shock, a Mach reflection off the top wall and a re-reflection down the tunnel. The tunnel is L-shaped, so FLUME builds it as three rectangular realms glued by two 1:1 mirror seams, and the step is body-fitted: its two faces are physical walls of the realms, with no immersed boundary.
y = 1 +--------+-----------------------------+ wall
| B | C |
inflow | | seam | outflow
y = 0.2 +--------+ +------ wall (step top) --+
| A | wall (step front)
y = 0 +--------+
x = 0 x = 0.6 x = 3The case puts together inter-realm mirror seams (two, on different axes, misaligned), intra-realm quadtree 2:1 seams (refined boxes off the inter-realm seams) and the walls, inflow and outflow of a supersonic tunnel. What it catches:
- a quadtree that differs from the octree (#46): the same forest on quadtrees (
nk = 1) and on octrees with a nullaxis must agree column by column to round-off; - a
dependence in a 2-D flow: every run must be -invariant; - loss of positivity at the seams, the corner and the reflected shocks;
- seam defects that show as structure in the quadtree–octree difference map at the inter-realm or 2:1 seams.
The refinement is static
The boxes are placed by hand on the features of the reference solution at
Models and numerics
| Item | Choice | Code |
|---|---|---|
| Equations | compressible Euler, ideal gas, | models |
| Space | WENO5 (weno-u-5) flux splitting on characteristic variables; no positivity limiter (refused on multi-realm runs) | compute_residuals_weno, adam_flume_cpu_object.F90 |
| Time | SSP Runge–Kutta, 5 stages (runge-kutta-ssp-54), CFL 0.5 | adam_rk_object.F90 |
| Forest | three realms, two 1:1 mirror seams (A–B at | populate_inter_realm_topology, build_seam_rows, adam_forest_object.F90; numerics |
| AMR | one more level on a static box per realm (geometric box marker, block centroids), quadtree ratio = 4, reflux on | mark_by_geometry, adam_flume_common_object.F90; numerics |
| Thin-block guard | blocks thinner than | check_amr_block_cells, adam_realm_object.F90 |
| Boundaries | inflow, extrapolation (outflow), inviscid walls; realm edges compose the conditions of their faces | set_boundary_conditions, adam_flume_cpu_object.F90; realm_edge_face, realm_edge_donor, adam_flume_bc_object.F90; boundary conditions |
| Corner | untreated (Woodward and Colella reset the entropy near it) | — |
Initial and boundary conditions
| Realm | Extent | Faces |
|---|---|---|
| A | inflow, wall (bottom), wall (step front), seam with B (top) | |
| B | inflow, seam with A (bottom), seam with C (right), wall (top) | |
| C | seam with B (left), wall (step top), wall (top), outflow (extrapolation) |
The realms share the base cell
| Item | trees leg | full leg |
|---|---|---|
| Base cell | ||
| Blocks, quadtree | A: 1 block of | A: |
| Trees | quadtree (nk = 1) and octree with a null nk = 4, 16 in A) | quadtree |
| Refined boxes (one level, block centroids) | A: none (its single block touches its seam); B: | A: |
| Initial state | the inflow state everywhere: | the same |
| Final time | ||
| Ranks | 2 | 2 |
The boxes of the full leg, at
- A,
: the bow shock standing on the lower wall. - B,
, : the bow shock bending up towards the Mach stem. The column touches the B–C seam. - C,
: all of the realm except the block column on the seam. That covers the reflected shock reaching the step top, the slip line and the re-reflection off the top wall.
A refined block may not touch an inter-realm seam (C's seam is only its face coupling = refined, #52), which is available on octrees only.
Input files
| File | Role |
|---|---|
src/tests/flume/verification/step/make_step.py <dir> --tree quad|oct --cells N --refine --time-max T | writes the manifest step.ini and the realms step-A.ini, step-B.ini, step-C.ini |
src/tests/flume/verification/step/check.sh | --legs trees (default) and full; --keep keeps the checkpoints for the figures; checks positivity of every run |
src/tests/flume/verification/mhd/quadtree/quadtree_oracle.py | the |
src/tests/flume/verification/make_doc_figures.py (fig_step, fig_step_trees) | the figures, from the kept work directories of step/ |
bash
cd src/tests/flume/verification/step && ./check.sh # trees leg, CPU (about 10 min)
FLUME_EXE=$PWD/../../../../../exe/adam_flume_fnl ./check.sh # trees leg, FNL
./check.sh --legs trees,full --keep # both legs, checkpoints kept
python3 ../make_doc_figures.py --out ../../../../../docs/public/flume --only step step-treesResults

trees leg,
trees leg | Bound | Octree, null | Quadtree, nk = 1 (CPU / FNL) |
|---|---|---|---|
| 0 / 0 | |||
| against the octree, per | — | ||
| min | positive, finite | 0.469, 0.715 (both) | 0.469, 0.715 (both) |

full leg,
full leg (CPU) | Bound | Result |
|---|---|---|
| min | positive, finite | 0.344, 0.370 |
| uniform control | positive, finite | pass |
The picture has the features of the reference of Woodward and Colella:
- the bow shock standing at
on the lower wall; - its Mach reflection off the top wall at
, with the triple point near and the slip line leaving it along ; - the reflected shock striking the step top at
in a Mach reflection; - its re-reflection reaching the top wall at
.
Related cases: Multi-realm runs (the seam legs on Sod), Quadtree AMR (the quadtree on MHD), Ghost probe (the step forest's edge ghosts).
Findings
- The trees order the restriction sums differently (8 fine cells over two identical
layers, against 4), so they agree to round-off, not bit for bit; the octree is -invariant to round-off only, its tricubic seam weights depending on the sub-position. The difference map carries no structure at the seams, inter-realm or 2:1. - The
treesleg takes about 10 min on the CPU, 9 of them for the octree (its blocks split alongtoo). The fullleg is not default: about 41 min on the CPU, plus 13 min for the uniform control. - The low-Mach layer along the step top is the numerical boundary layer of the untreated corner, the artifact Woodward and Colella remove with their entropy fix.
- The zoom compares the refined run with the uniform
run. The Mach stem and the triple point sit on the B–C seam, on the base grid in both runs, and agree. C's 2:1 seam at is crossed by the reflected shock and the slip line without a kink. Downstream of it, the box resolves the shock pattern near the step top ( ) more sharply than the uniform grid, which smears it into a single blob.
What this leg caught: blocks thinner than 2 ngc (#66)
A first layout kept A's blocks at 4 cells along y and refined them. The quadtree then differed from the octree by
| Comparison | Max difference |
|---|---|
| Quadtree, np 1, against the octree, np 1 or np 2 | |
| Quadtree, np 1, against np 2 |
The difference was independent of seam_ghost_fill and of reflux. At the bisected cell, the coarse ghost density next to the step wall differed by 0.20.
The coarse ghost layers beside a finer block are restricted from
The library now refuses blocks thinner than