SELF_TransferPlan_3D Module

Old-leaf -> new-leaf solution transfer plan for one adaptation epoch of the 3-D oct-forest: the driver layer of AMR Stage 3 that connects the element-local transfer operators (SELF_SolutionTransfer_3D) to the forest mutation (SELF_OctreeMesh_3D).

One adaptation epoch mutates the forest between two leaf configurations:

nOld = forest%nLeaves ; oldLeaf = forest%leaf(1:nOld)   ! snapshot BEFORE mutating
call forest%AdaptFromFlags(flag)                        ! at most one call, then
call forest%Balance2to1()                               ! any number of further
                                                        ! refinements (RefineNode too)
call BuildTransferPlan(forest,nOld,oldLeaf,plan)        ! AFTER the last mutation

Solution element index = leaf-list position (the element ordering EmitMesh produces), so the plan records, for every new leaf, where its data comes from in the old element ordering:

SELF_TRANSFER_COPY : the leaf survived unchanged; copy old element sourceElem. SELF_TRANSFER_PROLONG : the leaf descends from old leaf sourceElem; interpolate the old element's degree-N polynomial down the octree path (one step per level, so depth > 1 handles a fresh child that 2:1 balancing refined again in the same epoch). Exact, no loss. SELF_TRANSFER_RESTRICT : the leaf is (an ancestor of) a coarsened family; L2-project the eight old children family(1:8) onto their parent, then prolong down depth >= 0 further steps (depth > 0 occurs when a just-coarsened parent is immediately re-refined by 2:1 balancing). Conservative.

The reconstruction is possible after the fact because forest node ids are stable: refinement only appends nodes and coarsening only detaches children, whose level/parent/octant entries persist. Each new leaf therefore ascends its parent chain until it meets either an old leaf or a node holding a complete eight-child old-leaf family; anything else means the snapshot does not describe the epoch that produced the forest, and the builder stops with an error.

ApplyTransferPlan executes the plan on nodal data u(1:N+1,1:N+1,1:N+1,1:nElem,1:nVar) (the layout of MappedScalar3D %interior; units are those of the transferred fields) and inherits the Stage-3 operator identities: prolongation is exact polynomial interpolation and restriction is the conservative L2 projection, so the Jacobian-weighted cell integral of every variable is conserved and a refine-then-coarsen round trip is the identity to roundoff. Transfer runs once per adaptation epoch, between time steps; it is not a per-step hot path.


Uses

  • module~~self_transferplan_3d~~UsesGraph module~self_transferplan_3d SELF_TransferPlan_3D module~self_lagrange~2 SELF_Lagrange module~self_transferplan_3d->module~self_lagrange~2 module~self_constants SELF_Constants module~self_transferplan_3d->module~self_constants module~self_solutiontransfer_3d SELF_SolutionTransfer_3D module~self_transferplan_3d->module~self_solutiontransfer_3d module~self_octreemesh_3d SELF_OctreeMesh_3D module~self_transferplan_3d->module~self_octreemesh_3d module~self_lagrange~2->module~self_constants iso_fortran_env iso_fortran_env module~self_lagrange~2->iso_fortran_env iso_c_binding iso_c_binding module~self_lagrange~2->iso_c_binding module~self_lagrange_t SELF_Lagrange_t module~self_lagrange~2->module~self_lagrange_t module~self_constants->iso_fortran_env module~self_constants->iso_c_binding module~self_solutiontransfer_3d->module~self_lagrange~2 module~self_solutiontransfer_3d->module~self_constants module~self_octreemesh_3d->module~self_lagrange~2 module~self_octreemesh_3d->module~self_constants module~self_refinementprimitives_3d SELF_RefinementPrimitives_3D module~self_octreemesh_3d->module~self_refinementprimitives_3d module~self_mesh_3d~2 SELF_Mesh_3D module~self_octreemesh_3d->module~self_mesh_3d~2 module~self_refinementprimitives_3d->module~self_lagrange~2 module~self_refinementprimitives_3d->module~self_constants module~self_lagrange_t->module~self_constants module~self_lagrange_t->iso_fortran_env module~self_lagrange_t->iso_c_binding module~self_quadrature SELF_Quadrature module~self_lagrange_t->module~self_quadrature HDF5 HDF5 module~self_lagrange_t->HDF5 module~self_supportroutines SELF_SupportRoutines module~self_lagrange_t->module~self_supportroutines module~self_hdf5 SELF_HDF5 module~self_lagrange_t->module~self_hdf5 module~self_mesh_3d_t SELF_Mesh_3D_t module~self_mesh_3d~2->module~self_mesh_3d_t module~self_quadrature->module~self_constants module~self_quadrature->iso_fortran_env module~self_mesh_3d_t->module~self_lagrange~2 module~self_mesh_3d_t->module~self_constants module~self_mesh_3d_t->iso_c_binding module~self_mesh_3d_t->module~self_quadrature module~self_mesh_3d_t->HDF5 module~self_mesh_3d_t->module~self_supportroutines module~self_mesh_3d_t->module~self_hdf5 module~self_mesh SELF_Mesh module~self_mesh_3d_t->module~self_mesh module~self_domaindecomposition SELF_DomainDecomposition module~self_mesh_3d_t->module~self_domaindecomposition module~self_supportroutines->module~self_constants module~self_supportroutines->iso_fortran_env module~self_hdf5->module~self_constants module~self_hdf5->iso_fortran_env module~self_hdf5->HDF5 mpi mpi module~self_hdf5->mpi module~self_mesh->module~self_constants module~self_mesh->iso_c_binding module~self_mesh->module~self_domaindecomposition module~self_domaindecomposition_t SELF_DomainDecomposition_t module~self_domaindecomposition->module~self_domaindecomposition_t module~self_domaindecomposition_t->module~self_lagrange~2 module~self_domaindecomposition_t->module~self_constants module~self_domaindecomposition_t->iso_c_binding module~self_domaindecomposition_t->module~self_supportroutines module~self_domaindecomposition_t->mpi

Used by

  • module~~self_transferplan_3d~~UsedByGraph module~self_transferplan_3d SELF_TransferPlan_3D module~self_dgmodel3d_t SELF_DGModel3D_t module~self_dgmodel3d_t->module~self_transferplan_3d module~self_amrcontroller_3d SELF_AMRController_3D module~self_amrcontroller_3d->module~self_transferplan_3d module~self_amrcontroller_3d->module~self_dgmodel3d_t module~self_dgmodel3d SELF_DGModel3D module~self_dgmodel3d->module~self_transferplan_3d module~self_dgmodel3d->module~self_dgmodel3d_t module~self_dgmodel3d~2 SELF_DGModel3D module~self_dgmodel3d~2->module~self_dgmodel3d_t module~self_ecdgmodel3d_t SELF_ECDGModel3D_t module~self_ecdgmodel3d_t->module~self_dgmodel3d~2 module~self_advection_diffusion_3d_t self_advection_diffusion_3d_t module~self_advection_diffusion_3d_t->module~self_dgmodel3d~2 module~self_lineareuler3d_t self_LinearEuler3D_t module~self_lineareuler3d_t->module~self_dgmodel3d~2 module~self_nulldgmodel3d_t self_NullDGModel3D_t module~self_nulldgmodel3d_t->module~self_dgmodel3d~2 module~self_ecdgmodel3d~2 SELF_ECDGModel3D module~self_ecdgmodel3d~2->module~self_ecdgmodel3d_t module~self_ecdgmodel3d SELF_ECDGModel3D module~self_ecdgmodel3d->module~self_ecdgmodel3d_t module~self_advection_diffusion_3d~2 self_advection_diffusion_3d module~self_advection_diffusion_3d~2->module~self_advection_diffusion_3d_t module~self_ecadvection3d SELF_ECAdvection3D module~self_ecadvection3d->module~self_ecdgmodel3d_t module~self_ecadvection3d_t SELF_ECAdvection3D_t module~self_ecadvection3d->module~self_ecadvection3d_t module~self_esatmo3d SELF_ESAtmo3D module~self_esatmo3d->module~self_ecdgmodel3d_t module~self_esatmo3d_t SELF_ESAtmo3D_t module~self_esatmo3d->module~self_esatmo3d_t module~self_advection_diffusion_3d self_advection_diffusion_3d module~self_advection_diffusion_3d->module~self_advection_diffusion_3d_t module~self_lineareuler3d~2 self_LinearEuler3D module~self_lineareuler3d~2->module~self_lineareuler3d_t module~self_lineareuler3d self_LinearEuler3D module~self_lineareuler3d->module~self_lineareuler3d_t module~self_nulldgmodel3d~2 self_NullDGModel3D module~self_nulldgmodel3d~2->module~self_nulldgmodel3d_t module~self_nulldgmodel3d self_NullDGModel3D module~self_nulldgmodel3d->module~self_nulldgmodel3d_t module~self_esatmo3d_t->module~self_ecdgmodel3d~2 module~self_ecadvection3d_t->module~self_ecdgmodel3d~2 module~self_esatmo3d~2 SELF_ESAtmo3D module~self_esatmo3d~2->module~self_esatmo3d_t module~self_ecadvection3d~2 SELF_ECAdvection3D module~self_ecadvection3d~2->module~self_ecadvection3d_t

Contents


Variables

TypeVisibilityAttributesNameInitial
integer, public, parameter:: SELF_TRANSFER_COPY =0
integer, public, parameter:: SELF_TRANSFER_PROLONG =1
integer, public, parameter:: SELF_TRANSFER_RESTRICT =2

Derived Types

type, public :: TransferPlan3D

Components

TypeVisibilityAttributesNameInitial
integer, public, allocatable:: depth(:)

(nNew) number of prolongation steps below the source

integer, public, allocatable:: family(:,:)

(8,nNew) old element index per child octant (RESTRICT)

integer, public :: maxDepth =0

largest prolongation depth in the plan

integer, public :: nNew =0

new element count (= forest%nLeaves at build time)

integer, public :: nOld =0

old (pre-epoch) element count

integer, public, allocatable:: path(:,:)

(>=maxDepth,nNew) octant taken at each step, top-down

integer, public, allocatable:: sourceElem(:)

(nNew) old element index (COPY/PROLONG; 0 otherwise)

integer, public, allocatable:: sourceKind(:)

(nNew) SELF_TRANSFER_COPY / PROLONG / RESTRICT

Type-Bound Procedures

procedure, public :: Free => Free_TransferPlan3D

Subroutines

public subroutine ApplyTransferPlan(plan, interp, nVar, uOld, uNew)

Execute a transfer plan on nodal element data: uNew(:,:,:,li,:) receives old element data copied, prolonged (exact interpolation), or restricted (conservative L2 projection) according to plan entry li. interp must be the solution interpolant the data lives on (its mortar operators drive the transfer). Runs once per adaptation epoch - not a per-time-step hot path - so clarity is preferred over fused loops here.

Arguments

TypeIntentOptionalAttributesName
type(TransferPlan3D), intent(in) :: plan
type(Lagrange), intent(in) :: interp
integer, intent(in) :: nVar
real(kind=prec), intent(in) :: uOld(1:interp%N+1,1:interp%N+1,1:interp%N+1,1:plan%nOld,1:nVar)
real(kind=prec), intent(out) :: uNew(1:interp%N+1,1:interp%N+1,1:interp%N+1,1:plan%nNew,1:nVar)

public subroutine ApplyTransferPlanRange(plan, interp, nVar, uOld, eFirst, eLast, uNew)

Execute the contiguous sub-range eFirst..eLast of a transfer plan: uNew(:,:,:,k,:) receives the data of new element eFirst+k-1. uOld is the full (global) old field; the output is only the requested slice. This is the decomposed-mesh (AMR Stage 5) entry point: each rank passes its own contiguous range of the new element ordering and a gathered global old solution, and fills exactly its rank-local storage.

Arguments

TypeIntentOptionalAttributesName
type(TransferPlan3D), intent(in) :: plan
type(Lagrange), intent(in) :: interp
integer, intent(in) :: nVar
real(kind=prec), intent(in) :: uOld(1:interp%N+1,1:interp%N+1,1:interp%N+1,1:plan%nOld,1:nVar)
integer, intent(in) :: eFirst
integer, intent(in) :: eLast
real(kind=prec), intent(out) :: uNew(1:interp%N+1,1:interp%N+1,1:interp%N+1,1:eLast-eFirst+1,1:nVar)

public subroutine BuildTransferPlan(forest, nOld, oldLeaf, plan)

Build the old->new transfer plan for the adaptation epoch that took the forest from the leaf configuration (nOld, oldLeaf) - a snapshot of (forest%nLeaves, forest%leaf) taken before mutating - to its current leaf configuration. See the module documentation for the allowed mutations within one epoch. The plan is valid until the forest is mutated again.

Arguments

TypeIntentOptionalAttributesName
type(OctreeMesh3D), intent(in) :: forest
integer, intent(in) :: nOld
integer, intent(in) :: oldLeaf(1:nOld)
type(TransferPlan3D), intent(out) :: plan

public subroutine Free_TransferPlan3D(this)

Arguments

TypeIntentOptionalAttributesName
class(TransferPlan3D), intent(inout) :: this