Skip to content

adam_seam_interpolation_library ​

Weight tables and pure evaluators for the 2:1 coarse->fine seam ghost fill (issue #21, plan amendment v2, milestone N0).

Geometry. Uniform Cartesian 2:1 refinement, cell-centered point values. The 8 fine ghost cells overlying a coarse donor (anchor) cell sit at octant sub-positions eta = -1/4 (sub=1) and eta = +1/4 (sub=2) of the coarse spacing, per direction. Weights are 1D vectors composed in tensor product (w = wxwywz) by the evaluators; the fill kernel (N2) reads the same tables.

Anchor position ("shift state", G3/G4). The anchor cell occupies position p of the 1D footprint; node offsets relative to the anchor are ([1..n] - p). Centered states: tricubic p=2 for sub=2, p=3 for sub=1; compatible p=2 for both. Off-centered states implement the shift-inward rule at tangential block boundaries (donors are real cells, always).

The two regimes (G1 as amended, #21 issuecomment-4869444520). Exact restriction-compatibility R o P = I (R = the existing 8-cell-mean restriction, one_or_eight=8) is PROVABLY incompatible with reproduction of quadratics for point values: any P exact on quadratics fills the octants of f = x^2 with the exact values (all H^2/16), whose 8-mean is H^2/16 /= 0 = f(anchor). Hence:

  • SEAM_FILL_TRICUBIC (default candidate): plain tensor tricubic, exact for per-direction degree <= 3, ghost accuracy q = 4, mean defect O(H^2).
  • SEAM_FILL_COMPATIBLE (diagnostic arm): the unique symmetric 3-node pair with exact R o P = I for arbitrary data, exact for linears only (q = 2). The quadratic set is the G3 safety valve (centered only; must never be reached in production maps -- reaching it is a maps-build bug).

All weights are integer/2^k rationals: EXACT in binary floating point. Partition of unity therefore holds to 0 ulp in every table.

Unrefined directions (issue #46). A quadtree refines x and y only (a binary tree x only): along an unrefined direction the fine ghost and the coarse donor share the cell, the sub-position is "coincident" (sub=3, eta=0) and the 1D weight is the identity at the anchor node, in every table. The evaluators skip the zero-weight footprint nodes, so the unread donors (beyond the cells of a block one cell thick, nk = 1) never enter the sum; on refined directions no tricubic weight is zero and the octree results are unchanged bit for bit.

Device availability (issue #22 F2). Every public procedure carries !$acc routine seq: single-source host/device, callable from OpenACC parallel regions on the FNL backend (weight tables are parameters, materialized by the compiler on device). Inert comments on non-OpenACC builds. Pinned on device by test_seam_interpolation_fnl.

Source: src/lib/common/adam_seam_interpolation_library.F90

Dependencies

Contents ​

Variables ​

NameTypeAttributesDescription
SEAM_FILL_INJECTIONinteger(kind=I4P)parameterRegime: 0th-order injection (legacy behavior).
SEAM_FILL_COMPATIBLEinteger(kind=I4P)parameterRegime: restriction-compatible fill, q=2 (diagnostic arm).
SEAM_FILL_TRICUBICinteger(kind=I4P)parameterRegime: plain tensor tricubic, q=4 (default candidate).
SEAM_FILL_QUINTICinteger(kind=I4P)parameterRegime: tensor 6-point quintic, q=6 (issue #68 D1).
SEAM_FILL_WENO6integer(kind=I4P)parameterRegime: WENO on the quintic footprint (issue #68 D2).
SEAM_FILL_QUINTIC_MPinteger(kind=I4P)parameterRegime: quintic clamped to an MP bound (issue #68 D2).
SEAM_SUB_COINCIDENTinteger(kind=I4P)parameterSub-position of an unrefined direction (eta = 0, issue #46).
SEAM_W_TRICUBICreal(kind=R8P)parameter1D cubic Lagrange weights at eta = -+1/4 and the identity at eta = 0: (node 1:4, sub 1:3, anchor position p 1:4).
SEAM_W_COMPATIBLEreal(kind=R8P)parameter1D restriction-compatible weights (node 1:3, sub 1:3, anchor position p 1:3; sub=3 the identity):
SEAM_W_QUINTICreal(kind=R8P)parameter1D quintic Lagrange weights at eta = -+1/4 and the identity at eta = 0 (node 1:6, sub 1:3, anchor position p 1:6),
SEAM_W_QUADRATICreal(kind=R8P)parameter1D centered quadratic weights (node 1:3 at offsets -1..1, sub 1:2): the G3
SEAM_RESTRICT_MEANinteger(kind=I4P)parameterRegime: the mean of the r(1) r(2) r(3) fine cells, q = 2.
SEAM_RESTRICT_LAGRANGE6integer(kind=I4P)parameterRegime: tensor 6-point Lagrange at the coarse centre, q = 6.
SEAM_RESTRICT_WENO6integer(kind=I4P)parameterRegime: WENO over the 4-point sub-stencils, mean if troubled.
SEAM_RESTRICT_IDENTITYinteger(kind=I4P)parameterPer-direction code of an unrefined direction (issue #46).
SEAM_W_LAGRANGE6real(kind=R8P)parameter1D weights of the 6-point Lagrange restriction to the coarse centre, which sits midway between the two fine cells
SEAM_W_CUBIC_MIDreal(kind=R8P)parameterCubic Lagrange weights at the midpoint of each interval of a 4-point sub-stencil (node 1:4, interval 1:3).
SEAM_D_WENO6real(kind=R8P)parameterLinear weights of the sub-stencils (sub-stencil 1:3, code 0:4); zero marks a sub-stencil that is not a candidate.
SEAM_WENO6_JUMP_RATIOreal(kind=R8P)parameterJump detector of the WENO restriction: an interval whose undivided difference exceeds this ratio times its
SEAM_WENO6_EPSreal(kind=R8P)parameterGuard of the WENO-Z weights against 0/0 on constant data.
SEAM_W_CUBIC_Qreal(kind=R8P)parameterCubic Lagrange weights of a 4-point sub-stencil at its quarter positions (node 1:4, r = (t4 - 4 s + 3)/2 = 1:8).
SEAM_D_FILL_WENO6real(kind=R8P)parameterLinear weights of the fill's sub-stencils (sub-stencil 1:3, target 1:12), all positive (computed with exact

Subroutines ​

seam_meta_unpack ​

Unpack the per-fine-ghost interpolation metadata (inverse of seam_meta_pack).

Attributes: pure

fortran
subroutine seam_meta_unpack(meta, sub, p4, p3, p6)

Arguments

NameTypeIntentAttributesDescription
metainteger(kind=I4P)inPacked metadata.
subinteger(kind=I4P)outOctant sub-position per direction (1|2|3).
p4integer(kind=I4P)outTricubic anchor position per direction (1..4).
p3integer(kind=I4P)outCompatible anchor position per direction (1..3).
p6integer(kind=I4P)outQuintic anchor position per direction (1..6).

Call graph

seam_restriction_meta_unpack ​

Unpack the per-direction restriction codes and the regime (inverse of seam_restriction_meta_pack).

Attributes: pure

fortran
subroutine seam_restriction_meta_unpack(meta, code, regime)

Arguments

NameTypeIntentAttributesDescription
metainteger(kind=I4P)inPacked metadata (/= 0).
codeinteger(kind=I4P)outRestriction code per direction.
regimeinteger(kind=I4P)outRestriction regime.

Call graph

seam_weno6_jumps ​

Flag the jumps of 6 values (issue #68 C3): interval i (nodes i, i+1) is a jump when its undivided difference exceeds SEAM_WENO6_JUMP_RATIO times the larger of its neighbours' (at the footprint ends, the inner neighbour and its linear extrapolation). Smooth data never trips it once resolved.

Attributes: pure

fortran
subroutine seam_weno6_jumps(u, jump)

Arguments

NameTypeIntentAttributesDescription
ureal(kind=R8P)inValues at the footprint nodes.
jumplogicaloutJump flag per interval.

Call graph

Functions ​

seam_tricubic_centered_pos ​

Centered anchor position for the tricubic footprint: nodes -1..2 for eta=+1/4 (p=2), nodes -2..1 for eta=-1/4 (p=3).

Attributes: pure

Returns: integer(kind=I4P)

fortran
function seam_tricubic_centered_pos(sub) result(p)

Arguments

NameTypeIntentAttributesDescription
subinteger(kind=I4P)inOctant sub-position (1 => eta=-1/4, 2 => eta=+1/4, 3 => eta=0, unrefined).

Call graph

seam_compatible_centered_pos ​

Centered anchor position for the compatible footprint (p=2 for both subs).

Attributes: pure

Returns: integer(kind=I4P)

fortran
function seam_compatible_centered_pos(sub) result(p)

Arguments

NameTypeIntentAttributesDescription
subinteger(kind=I4P)inOctant sub-position (unused: symmetric footprint).

Call graph

seam_quintic_centered_pos ​

Centered anchor position for the quintic footprint (issue #68 D1): nodes -2..3 for eta=+1/4 (p=3), nodes -3..2 for eta=-1/4 (p=4); 3 on an unrefined direction (sub=3, only the anchor is read).

Attributes: pure

Returns: integer(kind=I4P)

fortran
function seam_quintic_centered_pos(sub) result(p)

Arguments

NameTypeIntentAttributesDescription
subinteger(kind=I4P)inOctant sub-position (1 => eta=-1/4, 2 => eta=+1/4, 3 => eta=0, unrefined).

Call graph

seam_quintic_weight ​

Return the 1D weight SEAM_W_QUINTIC(node, sub, p) (issue #68 D1): the device kernels read the table through this routine, inside the module that owns it.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_quintic_weight(node, sub, p) result(w)

Arguments

NameTypeIntentAttributesDescription
nodeinteger(kind=I4P)inFootprint node (1..6).
subinteger(kind=I4P)inOctant sub-position (1|2|3).
pinteger(kind=I4P)inAnchor position (1..6).

Call graph

seam_interpolate_quintic ​

Tensor quintic interpolation on a 6x6x6 coarse footprint (issue #68 D1), same index conventions as the tricubic evaluator. Summed direction by direction (x innermost, then y, then z), the order of the FNL twin; an unrefined direction (sub=3) reads the anchor node only, so the other footprint entries along it are not referenced.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_interpolate_quintic(footprint, sub, anchor_pos) result(value_)

Arguments

NameTypeIntentAttributesDescription
footprintreal(kind=R8P)inCoarse donor values.
subinteger(kind=I4P)inOctant sub-position per direction (1|2|3).
anchor_posinteger(kind=I4P)inAnchor position per direction (1..6).

Call graph

seam_interpolate_tricubic ​

Tensor tricubic interpolation on a 4x4x4 coarse footprint. footprint(i,j,k) holds the donor values at node offsets (i - anchor_pos(1), j - anchor_pos(2), k - anchor_pos(3)) in coarse-cell units; the target is the octant center (eta(sub(1)), eta(sub(2)), eta(sub(3))), eta = (-1)^sub / 4.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_interpolate_tricubic(footprint, sub, anchor_pos) result(value_)

Arguments

NameTypeIntentAttributesDescription
footprintreal(kind=R8P)inCoarse donor values.
subinteger(kind=I4P)inOctant sub-position per direction (1|2|3).
anchor_posinteger(kind=I4P)inAnchor position per direction (1..4).

Call graph

seam_interpolate_compatible ​

Tensor restriction-compatible interpolation on a 3x3x3 coarse footprint; same index conventions as the tricubic evaluator.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_interpolate_compatible(footprint, sub, anchor_pos) result(value_)

Arguments

NameTypeIntentAttributesDescription
footprintreal(kind=R8P)inCoarse donor values.
subinteger(kind=I4P)inOctant sub-position per direction (1|2).
anchor_posinteger(kind=I4P)inAnchor position per direction (1..3).

Call graph

seam_shift_anchor_pos ​

Anchor position after the G3 shift-inward rule: clamp the centered position so the footprint node offsets ([1..footprint_n] - p) around anchor stay inside the donor block's REAL cells [1..n_cells]. Valid for n_cells >= footprint_n and anchor in [1..n_cells] (both guaranteed at maps-build; the maps pass asserts n_cells >= 4).

Attributes: pure

Returns: integer(kind=I4P)

fortran
function seam_shift_anchor_pos(anchor, n_cells, p_centered, footprint_n) result(p)

Arguments

NameTypeIntentAttributesDescription
anchorinteger(kind=I4P)inDonor anchor cell index (interior, 1-based).
n_cellsinteger(kind=I4P)inDonor block interior cell count in this direction.
p_centeredinteger(kind=I4P)inCentered anchor position for the active sub-position.
footprint_ninteger(kind=I4P)inFootprint width (4 tricubic, 3 compatible).

Call graph

seam_meta_pack ​

Pack the per-fine-ghost interpolation metadata into one integer (map-row payload, G4): bits 0-2 = octant (sub-1 per direction), bits 3-8 = tricubic anchor positions - 1 (2 bits each), bits 9-14 = compatible anchor positions - 1 (2 bits each), bits 15-17 = unrefined (coincident, sub=3) flag per direction, issue #46 (0 on every octree row: the octree payload is unchanged), bits 18-26 = quintic anchor positions - 1 (3 bits each), issue #68 D1. Regime-independent: the kernel unpacks the field matching the active fill regime. NOTE: 0 is a VALID packed value — consumers must gate on the map's flag column, never on meta /= 0.

Attributes: pure

Returns: integer(kind=I4P)

fortran
function seam_meta_pack(sub, p4, p3, p6) result(meta)

Arguments

NameTypeIntentAttributesDescription
subinteger(kind=I4P)inOctant sub-position per direction (1|2|3).
p4integer(kind=I4P)inTricubic anchor position per direction (1..4).
p3integer(kind=I4P)inCompatible anchor position per direction (1..3).
p6integer(kind=I4P)inQuintic anchor position per direction (1..6).

Call graph

seam_interpolate_quadratic ​

Tensor centered quadratic interpolation on a 3x3x3 coarse footprint (safety valve: centered anchor only, node offsets -1..1 per direction).

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_interpolate_quadratic(footprint, sub) result(value_)

Arguments

NameTypeIntentAttributesDescription
footprintreal(kind=R8P)inCoarse donor values.
subinteger(kind=I4P)inOctant sub-position per direction (1|2).

Call graph

seam_restriction_code ​

Return the per-direction code of the 6-point restriction (issue #68 C1): the position of the fine pair (first, first + 1) in the 6-node footprint, the footprint kept inside the donor block's cells 1..n_cells (shift-inward); SEAM_RESTRICT_IDENTITY on an unrefined direction (ratio 1); -1 when the fine pair is not inside the donor block (the caller keeps the mean there).

Attributes: pure

Returns: integer(kind=I4P)

fortran
function seam_restriction_code(first, n_cells, ratio) result(code)

Arguments

NameTypeIntentAttributesDescription
firstinteger(kind=I4P)inFirst of the two fine cells covered by the coarse cell (donor index).
n_cellsinteger(kind=I4P)inDonor block cells in this direction (at least 6 on a refined one).
ratiointeger(kind=I4P)inRefinement ratio in this direction (1 or 2).

Call graph

seam_restriction_meta_pack ​

Pack the per-direction restriction codes (0..5) and the regime into one integer, 1 + code(1) + 6 code(2) + 36 code(3) + 216 (regime - SEAM_RESTRICT_LAGRANGE6): 1..216 under the 6-point Lagrange, 217..432 under the WENO restriction (#68 C3), so the rows carry their regime to every evaluator (inter-realm packers included); 0 is left free for the rows that keep the mean (the map's meta default).

Attributes: pure

Returns: integer(kind=I4P)

fortran
function seam_restriction_meta_pack(code, regime) result(meta)

Arguments

NameTypeIntentAttributesDescription
codeinteger(kind=I4P)inRestriction code per direction.
regimeinteger(kind=I4P)inRestriction regime (SEAM_RESTRICT_LAGRANGE6 or SEAM_RESTRICT_WENO6).

Call graph

seam_weno6_core ​

The WENO kernel shared by the restriction and the fill (issue #68 C3, D2): a convex combination of the cubic interpolants of the candidate 4-point sub-stencils (sub-stencil s = nodes s..s+3 of the 6) at one target.

  1. Jumps: interval i (nodes i, i+1) is a jump when its undivided difference exceeds SEAM_WENO6_JUMP_RATIO times the larger of its neighbours' (at the footprint ends, the inner neighbour and its linear extrapolation).
  2. Candidates: the sub-stencils with a positive linear weight dlin(s) and free of jumps; none left: fallback (the troubled-cell value, chosen by the caller).
  3. WENO-Z weights (Borges et al. 2008, p = 2) on the Jiang-Shu indicators of each cubic over its central interval, beta = c^2 + 13/12 a^2 + 781/720 t^2 (c, a, t its central first, mean second and third differences), with tau the highest undivided difference of the candidates' union squared, O(h^8..h^12) on smooth data, so the weights reach the linear ones fast enough to keep the design order at critical points.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_weno6_core(u, dlin, wsub, fallback) result(value_)

Arguments

NameTypeIntentAttributesDescription
ureal(kind=R8P)inValues at the footprint nodes.
dlinreal(kind=R8P)inLinear weight per sub-stencil (0: not a candidate).
wsubreal(kind=R8P)inCubic weights of each candidate sub-stencil at the target.
fallbackreal(kind=R8P)inValue returned when no candidate is left.

Call graph

seam_restriction_weno6_1d ​

Return the WENO restriction of 6 fine values u to the coarse centre between nodes code+1 and code+2 (#68 C3): seam_weno6_core on the sub-stencils of SEAM_D_WENO6(:,code) with their midpoint cubics, the troubled-cell fallback the mean of the fine pair. SEAM_RESTRICT_IDENTITY (an unrefined direction) returns u(1).

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_restriction_weno6_1d(u, code) result(value_)

Arguments

NameTypeIntentAttributesDescription
ureal(kind=R8P)inFine values (footprint nodes).
codeinteger(kind=I4P)inRestriction code (0..4, or SEAM_RESTRICT_IDENTITY).

Call graph

seam_fill_weno6_1d ​

Return the WENO coarse->fine fill of 6 coarse values u at the fine ghost's centre, anchor node p + eta(sub) (issue #68 D2): seam_weno6_core on the sub-stencils that contain the target's interval (none extrapolates but at the block edge, where the one candidate is the tricubic's own one-sided cubic), linear weights SEAM_D_FILL_WENO6 reproducing the Lagrange interpolant of their union (order 6 at the centred anchor positions, 5 one cell from the block edge, 4 at it); the troubled-cell fallback is the linear interpolation on the target's interval clamped to its two values. An unrefined direction (sub = 3) returns u(p).

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_fill_weno6_1d(u, sub, p) result(value_)

Arguments

NameTypeIntentAttributesDescription
ureal(kind=R8P)inCoarse values (footprint nodes).
subinteger(kind=I4P)inOctant sub-position (1 => eta=-1/4, 2 => eta=+1/4, 3 => unrefined).
pinteger(kind=I4P)inAnchor position (1..6).

Call graph

seam_fill_quintic_mp_1d ​

Return the monotonicity-preserving quintic coarse->fine fill of 6 coarse values u at the fine ghost's centre, anchor node p + eta(sub) (issue #68 D2): the quintic of SEAM_W_QUINTIC clamped to a Suresh-Huynh (1997) MP bound. The target lies at fraction th of the interval m (nodes m, m+1), linear value L = u(m) + th (u(m+1) - u(m)); dM is the M4 minmod of the two second differences around the interval (shifted inward at the block edge), zero across a jump; the bound is [min(u(m), u(m+1), Q), max(...)] with Q = L + th (th - 1)/2 dM, widened by |th (th - 1)/2 dM|: on smooth data it contains the quintic (which differs from Q at O(h^3)), across a jump it collapses to the interval's values. At the block edge (the target a quarter cell outside the footprint, th < 0 or

  1. L is clamped to the interval and the bound widened by the extrapolation's linear and curvature terms only when the three edge-side intervals hold no jump (seam_weno6_jumps). An unrefined direction (sub = 3) returns u(p).

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_fill_quintic_mp_1d(u, sub, p) result(value_)

Arguments

NameTypeIntentAttributesDescription
ureal(kind=R8P)inCoarse values (footprint nodes).
subinteger(kind=I4P)inOctant sub-position (1 => eta=-1/4, 2 => eta=+1/4, 3 => unrefined).
pinteger(kind=I4P)inAnchor position (1..6).

Call graph

seam_minmod4 ​

Return the minmod of four values: the one of least magnitude if all share a sign, zero otherwise.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_minmod4(a, b, c, d) result(mm)

Arguments

NameTypeIntentAttributesDescription
areal(kind=R8P)inValues.
breal(kind=R8P)inValues.
creal(kind=R8P)inValues.
dreal(kind=R8P)inValues.

Call graph

seam_restriction_weno6 ​

Return the WENO restriction of the fine footprint u (#68 C3), direction by direction: x on every (j, k) line, then y, then z (the same order on every backend). An unrefined direction (code SEAM_RESTRICT_IDENTITY) reads index 1 only, the other entries of u along it are not referenced. A troubled line falls back to the mean of its fine pair, so a footprint troubled on every line returns the mean of the fine cells.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_restriction_weno6(code, u) result(value_)

Arguments

NameTypeIntentAttributesDescription
codeinteger(kind=I4P)inRestriction code per direction.
ureal(kind=R8P)inFine footprint (i, j, k).

Call graph

seam_interpolate_weno6 ​

WENO coarse->fine fill on a 6x6x6 coarse footprint (issue #68 D2), same index conventions as the quintic evaluator, direction by direction: x on every (j, k) line, then y, then z (the order of the FNL twin). An unrefined direction reads the anchor node only, so the other footprint entries along it are not referenced.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_interpolate_weno6(footprint, sub, anchor_pos) result(value_)

Arguments

NameTypeIntentAttributesDescription
footprintreal(kind=R8P)inCoarse donor values.
subinteger(kind=I4P)inOctant sub-position per direction (1|2|3).
anchor_posinteger(kind=I4P)inAnchor position per direction (1..6).

Call graph

seam_interpolate_quintic_mp ​

Monotonicity-preserving quintic coarse->fine fill on a 6x6x6 coarse footprint (issue #68 D2), direction by direction (x on every (j, k) line, then y, then z: the order of the FNL twin); an unrefined direction reads the anchor node only.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_interpolate_quintic_mp(footprint, sub, anchor_pos) result(value_)

Arguments

NameTypeIntentAttributesDescription
footprintreal(kind=R8P)inCoarse donor values.
subinteger(kind=I4P)inOctant sub-position per direction (1|2|3).
anchor_posinteger(kind=I4P)inAnchor position per direction (1..6).

Call graph

seam_restriction_weight ​

Return the 1D weight SEAM_W_LAGRANGE6(node, code) (issue #68 C2): the device kernels read the table through this routine, inside the module that owns it, as they read the coarse->fine tables through the evaluators.

Attributes: pure

Returns: real(kind=R8P)

fortran
function seam_restriction_weight(node, code) result(w)

Arguments

NameTypeIntentAttributesDescription
nodeinteger(kind=I4P)inFootprint node (1..6).
codeinteger(kind=I4P)inRestriction code (0..5).

Call graph