ApplyTransferPlanWindow Subroutine

public subroutine ApplyTransferPlanWindow(plan, interp, nVar, uOld, oldFirst, oldLast, eFirst, eLast, uNew)

Execute the contiguous sub-range eFirst..eLast of a transfer plan against a WINDOW of the old field: uOld holds old elements oldFirst..oldLast only, indexed in the global old element numbering that plan%sourceElem and plan%family use, rather than the whole global field. uNew(:,:,:,k,:) receives the data of new element eFirst+k-1.

This is the point-to-point migration (AMR Stage-5 v2) entry point. Because both the old and the new partition are contiguous ranges of the same space-filling-curve leaf order, the old elements a rank's new range references form a contiguous window that a rank computes locally from the (rank-replicated) plan - see PlanWindows in the AMR controllers - and receives point-to-point instead of allgathering the global field.

Units and layout are those of MappedScalar3D %interior. The transfer operators are unchanged, so the operator identities hold as documented in the module header: exact prolongation, conservative L2 restriction.

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,oldFirst:oldLast,1:nVar)
integer, intent(in) :: oldFirst
integer, intent(in) :: oldLast
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)

Calls

proc~~applytransferplanwindow~~CallsGraph proc~applytransferplanwindow ApplyTransferPlanWindow proc~restrictfromchildren RestrictFromChildren proc~applytransferplanwindow->proc~restrictfromchildren proc~prolongtochildren ProlongToChildren proc~applytransferplanwindow->proc~prolongtochildren tmp1 tmp1 proc~restrictfromchildren->tmp1 up up proc~restrictfromchildren->up tmp2 tmp2 proc~restrictfromchildren->tmp2 proc~prolongtochildren->tmp1 proc~prolongtochildren->tmp2

Called by

proc~~applytransferplanwindow~~CalledByGraph proc~applytransferplanwindow ApplyTransferPlanWindow proc~applytransferplanrange ApplyTransferPlanRange proc~applytransferplanrange->proc~applytransferplanwindow proc~applytransferplan_dgmodel3d_t ApplyTransferPlan_DGModel3D_t proc~applytransferplan_dgmodel3d_t->proc~applytransferplanwindow proc~applytransferplan_dgmodel3d_t->proc~applytransferplanrange proc~verifywindowedapply~2 VerifyWindowedApply proc~verifywindowedapply~2->proc~applytransferplanwindow proc~applytransferplan ApplyTransferPlan proc~applytransferplan->proc~applytransferplanrange proc~adapt_amrcontroller3d Adapt_AMRController3D proc~adapt_amrcontroller3d->proc~applytransferplan_dgmodel3d_t proc~adapt_amrcontroller3d->proc~verifywindowedapply~2 proc~applytransferplan_dgmodel3d ApplyTransferPlan_DGModel3D proc~applytransferplan_dgmodel3d->proc~applytransferplan_dgmodel3d_t

Contents


Source Code

  subroutine ApplyTransferPlanWindow(plan,interp,nVar,uOld,oldFirst,oldLast,eFirst,eLast,uNew)
    !! Execute the contiguous sub-range eFirst..eLast of a transfer plan against a WINDOW of
    !! the old field: uOld holds old elements oldFirst..oldLast only, indexed in the global old
    !! element numbering that plan%sourceElem and plan%family use, rather than the whole global
    !! field. uNew(:,:,:,k,:) receives the data of new element eFirst+k-1.
    !!
    !! This is the point-to-point migration (AMR Stage-5 v2) entry point. Because both the old
    !! and the new partition are contiguous ranges of the same space-filling-curve leaf order,
    !! the old elements a rank's new range references form a contiguous window that a rank
    !! computes locally from the (rank-replicated) plan - see PlanWindows in the AMR
    !! controllers - and receives point-to-point instead of allgathering the global field.
    !!
    !! Units and layout are those of MappedScalar3D %interior. The transfer operators are
    !! unchanged, so the operator identities hold as documented in the module header: exact
    !! prolongation, conservative L2 restriction.
    implicit none
    type(TransferPlan3D),intent(in) :: plan
    type(Lagrange),intent(in) :: interp
    integer,intent(in) :: nVar
    integer,intent(in) :: oldFirst
    integer,intent(in) :: oldLast
    real(prec),intent(in) :: uOld(1:interp%N+1,1:interp%N+1,1:interp%N+1,oldFirst:oldLast,1:nVar)
    integer,intent(in) :: eFirst
    integer,intent(in) :: eLast
    real(prec),intent(out) :: uNew(1:interp%N+1,1:interp%N+1,1:interp%N+1,1:eLast-eFirst+1,1:nVar)
    ! Local
    integer :: li,lo,c,step,Np
    real(prec),allocatable :: buf(:,:,:,:),kids(:,:,:,:,:),fam(:,:,:,:,:)

    if(.not. allocated(plan%sourceKind)) then
      print*,__FILE__,':',__LINE__, &
        ' : Error : ApplyTransferPlan called with an unbuilt TransferPlan3D.'
      stop 1
    endif
    if(eFirst < 1 .or. eLast > plan%nNew .or. eLast < eFirst) then
      print*,__FILE__,':',__LINE__, &
        ' : Error : ApplyTransferPlanRange called with a range outside 1..nNew.'
      stop 1
    endif
    if(oldFirst < 1 .or. oldLast > plan%nOld .or. oldLast < oldFirst) then
      print*,__FILE__,':',__LINE__, &
        ' : Error : ApplyTransferPlanWindow called with an old-element window outside'// &
        ' 1..nOld.'
      stop 1
    endif

    Np = interp%N+1
    allocate(buf(1:Np,1:Np,1:Np,1:nVar))
    allocate(kids(1:Np,1:Np,1:Np,1:nVar,1:8))
    allocate(fam(1:Np,1:Np,1:Np,1:nVar,1:8))

    do li = eFirst,eLast
      lo = li-eFirst+1

      ! Every old element this entry reads must lie inside the supplied window. A window that
      ! does not cover the entry is a routing error (the window was computed from a different
      ! plan or a different partition), so report it rather than read outside the array. On the
      ! whole-field path the condition can never fire; the cost is a handful of integer
      ! comparisons per element, once per adaptation epoch.
      if(plan%sourceKind(li) == SELF_TRANSFER_RESTRICT) then
        do c = 1,8
          if(plan%family(c,li) < oldFirst .or. plan%family(c,li) > oldLast) then
            print*,__FILE__,':',__LINE__, &
              ' : Error : new element',li,' restricts from old element',plan%family(c,li), &
              ' outside the supplied old-element window',oldFirst,oldLast
            stop 1
          endif
        enddo
      elseif(plan%sourceElem(li) < oldFirst .or. plan%sourceElem(li) > oldLast) then
        print*,__FILE__,':',__LINE__, &
          ' : Error : new element',li,' sources old element',plan%sourceElem(li), &
          ' outside the supplied old-element window',oldFirst,oldLast
        stop 1
      endif

      if(plan%sourceKind(li) == SELF_TRANSFER_COPY) then
        uNew(1:Np,1:Np,1:Np,lo,1:nVar) = uOld(1:Np,1:Np,1:Np,plan%sourceElem(li),1:nVar)
        cycle
      endif

      if(plan%sourceKind(li) == SELF_TRANSFER_RESTRICT) then
        do c = 1,8
          fam(1:Np,1:Np,1:Np,1:nVar,c) = uOld(1:Np,1:Np,1:Np,plan%family(c,li),1:nVar)
        enddo
        call RestrictFromChildren(interp,nVar,fam,buf)
      else ! SELF_TRANSFER_PROLONG
        buf(1:Np,1:Np,1:Np,1:nVar) = uOld(1:Np,1:Np,1:Np,plan%sourceElem(li),1:nVar)
      endif

      do step = 1,plan%depth(li)
        call ProlongToChildren(interp,nVar,buf,kids)
        buf(1:Np,1:Np,1:Np,1:nVar) = kids(1:Np,1:Np,1:Np,1:nVar,plan%path(step,li))
      enddo

      uNew(1:Np,1:Np,1:Np,lo,1:nVar) = buf(1:Np,1:Np,1:Np,1:nVar)

    enddo

    deallocate(buf,kids,fam)

  endsubroutine ApplyTransferPlanWindow