Appearance
Boundary conditions
Each of the six faces of the domain takes a boundary condition from its section [bc_x_min], [bc_x_max], [bc_y_min], [bc_y_max], [bc_z_min], [bc_z_max]. The condition fills the ghost cells of the blocks that touch the face before every residual evaluation; interior block faces, inter-realm seams and AMR coarse–fine faces are filled by the exchange machinery instead (below).
Input
There are six sections, [bc_x_min], [bc_x_max], [bc_y_min], [bc_y_max], [bc_z_min] and [bc_z_max], which are faces 1–6. Each section requires type. The value goes through strip_control, so CRLF files are accepted. Seven values are accepted, and matching is case-sensitive:
type | id | per-face keys |
|---|---|---|
extrapolation | BC_EXTRAPOLATION = 1 | none |
inflow | BC_INFLOW = 2 | r, u, v, w, p (+ bx, by, bz for MHD), all required |
wall-inviscid | BC_WALL_INVISCID = 3 | none |
wall-noslip | BC_WALL_NOSLIP = 4 | wall_u, wall_v, wall_w (optional, default 0; the normal one must be 0) |
wall-isothermal | BC_WALL_ISOTHERMAL = 5 | wall_temperature (required, wall_u, wall_v, wall_w as above |
periodic | library BC_PERIODIC = -1 | none |
hydrostatic | BC_HYDROSTATIC = 6 | none (reads [gravity]); refused with [eos] isothermal or barotropic |
non-reflecting | BC_NONREFLECTING = 8 | the target r, u, v, w, p (required), nr_length nr_sigma |
shock-generator | BC_SHOCK_GENERATOR = 9 | the upstream r, u, v, w, p, one of shock_deflection and shock_angle (degrees), shock_x, shock_x_end (optional); bc_y_min and bc_y_max only, Euler only (#121 S3) |
Validation:
- an unknown value stops the run and the message lists the accepted spellings;
- a missing inflow key, or a missing or non-positive
wall_temperature, is fatal; - a non-zero normal wall velocity is fatal (the wall does not move through the domain);
- periodicity must be paired:
[bc_x_min]and[bc_x_max]must both be periodic or neither, and the same for y and z; - a physical model other than Euler or MHD is fatal.
How the ghost cells are filled
update_ghost runs three steps in order:
- the intra-realm local copies;
- the MPI exchange;
set_boundary_conditions.
Step 3 walks the boundary crown map maps%local_map_bc_crown crown by crown, fec code (face 1–6, edge 7–18, corner 19–26). The CPU implementation is cpu/adam_flume_cpu_object.F90; the FNL twin is fnl/adam_flume_fnl_kernels.F90, called crown by crown from fnl/adam_flume_fnl_object.F90. Both apply the same rules.
The grid receives the six BC ids through grid%set_bc_type. That call turns on is_ijk_periodic for a periodic axis.
extrapolation: zeroth order (constant)
Each ghost copies its inward neighbour. The crowns are filled innermost first, so every ghost column ends up equal to the first interior cell: !< Zeroth-order extrapolation comment. All
inflow: prescribed state (Dirichlet on the full conservative vector)
wall-inviscid: slip wall by mirroring with a sign vector
The mirror index reflects the ghost across the face:
| face | mirror |
|---|---|
So ghost
The sign vector adam_flume_bc_object.F90:
| variable | Euler | MHD / MHD-GLM |
|---|---|---|
| — | ||
| — | ||
| — |
wall-noslip and wall-isothermal: no-slip walls
The two no-slip walls (#65, D-M4-7) mirror the cell like wall-inviscid and reflect the whole velocity about the wall velocity wall_u, wall_v, wall_w):
so the mean of the ghost and its mirror cell is the wall velocity (no slip, no penetration). The pressure is mirrored.
wall-noslip(adiabatic) mirrors the temperature, soand at the wall in the sense of the symmetric difference. wall-isothermalsets the ghost temperature to the geometric mirror,, so the geometric mean of the ghost and its mirror cell is the wall temperature, and the density from the mirrored pressure, , with . The ghost is admissible for any admissible cell. Until #65 P2 the mirror was linear, , which is negative beside gas hotter than twice the wall: on Sod's right state ( ) against a wall at the ghosts reached , silently, with no non-finite value. For the two mirrors differ by , so both are second-order at the wall.
The total energy is rebuilt from the ghost state, wall-inviscid rule (normal component odd, a perfectly conducting wall);
The rule is the pure procedure wall_noslip_ghost in adam_flume_bc_object.F90, shared by both backends. It is model-agnostic: the field components are those present in the state vector (none for Euler), so no kernel branches on the model. The ghost probe GP checks it on every face and edge, moving and resting walls, Euler and MHD with EGLM (verification).
The walls are boundary conditions of the ideal solver too: they take effect on any run. Their physical test is the compressible Couette flow between an isothermal wall and a moving adiabatic one, against its exact profiles (VV-3): the moving-wall mirror is exact for its linear velocity and symmetric temperature, the isothermal mirror
hydrostatic: an atmosphere under gravity (#73)
The ghost density and pressure continue the isothermal hydrostatic equilibrium of the first interior cell along the normal, wall-inviscid (no mass flux); the magnetic field and adam_flume_bc_object.F90 (hydrostatic_ghost).
non-reflecting: a characteristic outflow and far field (#121 S2)
The ghosts are the first interior cell plus the jumps of the characteristic variables, linearised about it (outward normal velocity
- Outgoing waves (speed
): no jump, extrapolated. - The incoming acoustic wave,
with speed : its gradient along the normal is set by the relaxation of Rudy & Strikwerda (1980) and Poinsot & Lele (1992), , . Ghost lies cells off the interior cell, and is unchanged. - Flow into the domain (
): the entropy and the tangential velocity of the target; (supersonic inflow) the whole target.
A supersonic outflow, or
When to use it. In this characteristic-upwind scheme extrapolation (outflow) and inflow (a prescribed state) already let linear waves out: they make the incoming characteristic jumps zero, or the free stream's. What they cannot do is hold a mean pressure at a subsonic outflow, and extrapolation keeps whatever pressure the box has. non-reflecting pulls it to
non-reflecting | the alternative | |
|---|---|---|
| a 2 % overpressure at Mach 0.5, left after | 0.099 | extrapolation: 1.000 |
| a packet leaving at rest ( | 2.9e-3 ( | extrapolation: 1.2e-4 |
| a packet leaving through a subsonic inflow face, left behind | 4.3e-3 | inflow: 1.4e-5 |
Source: adam_flume_bc_object.F90 (nonreflecting_ghost).
shock-generator: an oblique shock through a y face (#121 S3)
The face of a shock–boundary-layer interaction that brings the incident shock in (the top of the box). The ghosts with shock_x shock_x_end take the state behind an oblique shock in the upstream state r, u, v, w, p; the others are extrapolated, as are the edge and corner rows beyond the face. The shock is given by its deflection shock_deflection, the weak solution of the shock_angle), and turns the flow toward the opposite face. The post-shock state follows from the normal Mach number
- Refused: a flow that is not supersonic in the x-y plane, an angle outside
, a deflection beyond detachment, a face other than y, a model other than Euler (no dual energy, no passive scalars). - The rest of the face is
extrapolation: upstream ofshock_xthe free stream leaves or enters at its own state, as at an extrapolated top. A reflected shock that reaches the face beyondshock_x_endleaves through it.
Measured in the verification: at Mach 2 and
Source: adam_flume_bc_object.F90 (oblique_shock).
periodic
periodic gets no crown rows. The library tree builds true periodic neighbours, and update_ghost_local and update_ghost_mpi fill the ghosts across blocks and ranks. It is the library BC_PERIODIC (as PRISM's periodic since cd92194a), so it works with any number of blocks along the axis, one included: the tree and the maps are rebuilt once the BC types are known (#103; before, a grid not refined at init kept its boundary neighbours, which the CPU refused and the FNL silently left unfilled). The only constraint is the pairing rule in B.1.
Edges and corners (fec > 6)
An edge ghost lies outside its block along two axes, a corner ghost along three. The directional WENO stencils never read them, but a cross derivative does: the tangential derivatives of the viscous stress or of the current at a face (M4, #65) read the edge ghosts of the rows next to a block edge. They are filled so that the ghost layer continues the face ghosts, and the probe GP of the verification holds every face and edge ghost to a linear field on every path.
Each crown row carries the boundary its cell lies beyond (bc_fec, from the tree), which gives two cases:
- Beyond one realm face (
bc_feca face). The cell's other directions lead into another block, whose ghosts the exchange has filled. The face's kind applies along its normal exactly as for a face ghost, so a wall edge mirrors the exchanged ghost and negates its normal momentum. - Beyond two or three realm faces (
bc_fecan edge or a corner: an edge or a corner of the realm). The kind of one physical face among them applies, inflow first (an inflow ghost holds the inflow state whatever else it lies beyond), else the first non-seam face,realm_edge_face. It acts on the donorrealm_edge_donor: the cell mirrored about that face (any wall kind) or the first interior cell along its normal (extrapolation), with the indexes along the other axes kept. The donor therefore lies beyond the other faces only. It is a face ghost (for an edge) or an edge ghost (for a corner), already filled by the seam, the exchange or its own face. Two walls compose to a double mirror with both normal momenta negated, and a wall beside a seam mirrors the seam ghost.
Beyond seams only, the cell lies outside every realm: the re-entrant corner of an L-shaped forest, inside the step of the Woodward–Colella tunnel. It keeps a copy of its inward diagonal,
Both backends fill the crown in three passes, the rows beyond one face, then two, then three, each crown by crown, so that every donor is filled before it is read (set_boundary_conditions on the CPU, set_boundary_conditions_dev on FNL). Within the first pass no row reads another row of the pass: a wall row reads the mirrored interior cell, an extrapolation row the first interior cell along its normal (not the previous ghost of the chain, which gives the same value but is a row of the same launch: on FNL the chain raced, and a ghost beyond a block interface along another axis could read its donor before it was written; issue #65 P1). The kind of each realm face comes from [bc_*], overridden by maps%seam_face for the faces the forest glued. On FNL each launch visits the rows of its own pass only: the rows of every crown are grouped by pass on the host whenever the device map is copied (build_bc_pass_rows), and an empty pass is not launched (issue #90; before, each of the 3 ×
Before #65 P0 every row beyond two realm faces held its inward diagonal copy. On a linear field that is off by up to 0.78 of the field scale at a wall corner (wrong sign of the normal momentum, wrong position), measured by GP on the step forest.
Inter-realm seam
set_boundary_conditions leaves seam face rows untouched. The forest fills them through fill_seam_from_peer_forest, which is a plain injection copy of the peer's interior cell into this realm's ghost cell, following the seam ghost map rows. The buffers used are q when stage_active == 0, otherwise the active stage of rk%q_rk, on each side independently. update_ghost does not fill seam ghosts. Any diagnostic that reads them has to refill them explicitly; compute_divb_history does this. The field write does too: with sibling realms, save_simulation_data refills the seams and then calls update_ghost, the order of a Runge-Kutta stage, so the written ghosts (edges included) are those the stencils read. The step-0 file is the exception: it is written while each realm initialises, before the forest connects the realms, and its seam ghosts are unfilled.
2:1 AMR coarse-fine ghosts
These ghosts are library behaviour, not FLUME-specific. The regime is chosen by the optional key [amr] seam_ghost_fill = injection | restriction-compatible | tricubic. The default when the key is absent is tricubic, and an unknown value is fatal. The fill runs inside field%update_ghost_local.
Immersed solids
Immersed solids (for example regression/shock-cylinder-ib) are not a [bc_*] kind. They enter through the level-set phi and the cut spacing in compute_flux_difference, and are out of scope here.
Examples
Walls on x, extrapolation elsewhere, from src/tests/flume/verification/sod/sod-wall-x.ini:
ini
[bc_x_min]
type = wall-inviscid
[bc_x_max]
type = wall-inviscid
[bc_y_min]
type = extrapolation
[bc_y_max]
type = extrapolation
[bc_z_min]
type = extrapolation
[bc_z_max]
type = extrapolationEuler inflow, from src/tests/flume/verification/shock-cylinder/shock-cylinder.ini:
ini
[bc_x_min]
type = inflow
r = 3.7333333333333334
u = 1.25
v = 0.0
w = 0.0
p = 4.5
[bc_x_max]
type = extrapolation
[bc_y_min]
type = wall-inviscid
[bc_y_max]
type = wall-inviscid
[bc_z_min]
type = extrapolation
[bc_z_max]
type = extrapolationMHD inflow, from src/tests/flume/verification/mhd/plumbing/mhd-uniform-glm.ini:
ini
[bc_z_min]
type = inflow
r = 1.0
u = 0.3
v = -0.2
w = 0.1
p = 1.0
bx = 0.8
by = 0.5
bz = -0.3Periodic faces are written the same way, type = periodic, and must be set on both faces of an axis.