Solution transfer between an element and its eight h-refinement children (AMR Stage 3).
When a 3-D hexahedral element is refined into eight children (SELF child ordering = CGNS
corner order, child c covering the octant with half-interval indices
(octAxc(c),octAyc(c),octAzc(c)) of the parent reference cube; see
SELF_RefinementPrimitives_3D), the prognostic solution must move with the mesh:
Prolongation (parent -> 8 children): sample the parent's degree-N nodal polynomial at
the children's nodes. Each child occupies a reference half-interval in each direction, so
this is exactly a triple tensor product of the 2:1 mortar restriction operator
Lagrange%mortarR (built and identity-checked for the nonconforming interface machinery).
It is an exact interpolation: the child fields reproduce the parent polynomial with no
loss.
Restriction (8 children -> parent): the L2 projection of the (generally discontinuous
across children) fine solution back onto the parent's degree-N polynomial space, a triple
tensor product of the mortar projection operator Lagrange%mortarP (the M-inner-product
adjoint of mortarR). Each 1-D mortarP carries the 1/2 per-direction sub-interval
Jacobian, so the triple product carries the 1/8 sub-cell Jacobian appropriate for
projecting solution fields: a conservative L2 projection.
These inherit the discrete identities established for the 1-D mortar operators
(test/mortarprojection_identity.f90):
Consistency / reversibility: RestrictFromChildren(ProlongToChildren(u)) = u exactly, from
sum_k P_k R_k = I applied in each tensor direction. Refining then immediately coarsening
does not perturb the solution.
Conservation: sum_ijk w_i w_j w_k u_parent(i,j,k) =
(1/8) sum_c sum_ijk w_i w_j w_k u_child_c(i,j,k), i.e. the reference-cell integral of the
restricted parent equals the sum of the children's reference-cell integrals (each child
is an eighth of the parent). Weighted by the geometry Jacobian this is conservation of
the cell-integrated prognostic quantity.
The routines are element-local and portable (host do concurrent over children/variables);
the AMR driver maps forest parent/child relationships onto the element index ranges it passes
in. Transfer runs between time steps, so it is not a per-step hot path.
These routines remain the reference implementation and are what the CPU backend and the
multi-rank migration path execute, and they are what the transfer tests pin. On a single-rank
GPU build the same mathematics run in TransferSolution_3D_gpu
(src/gpu/SELF_SolutionTransfer.cpp), so the contractions below are performed on the device
rather than on one CPU core and the transferred field never crosses the host link; see
ApplyTransferPlan_DGModel3D.
Nodes of different colours represent the following:
Solid arrows point from a submodule to the (sub)module which it is
descended from. Dashed arrows point from a module or program unit to
modules which it uses. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Nodes of different colours represent the following:
Solid arrows point from a submodule to the (sub)module which it is
descended from. Dashed arrows point from a module or program unit to
modules which it uses. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
public subroutine ProlongToChildren(interp, nVar, uParent, uChildren)
Prolong (interpolate) a parent element's nodal solution onto its eight children.
uChildren(:,:,:,:,c) is the field on child c (SELF child ordering = CGNS corner order).
Exact for the parent's degree-N polynomial representation.