ESMF_GridCreateDistgridArb Function

private function ESMF_GridCreateDistgridArb(dimCount, distDimCount, isDist, distDim, minIndex, maxIndex, arbIndexCount, arbIndexList, connList, rc)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: dimCount
integer, intent(in) :: distDimCount
logical, intent(in) :: isDist(:)
integer, intent(in) :: distDim(:)
integer, intent(in) :: minIndex(:)
integer, intent(in) :: maxIndex(:)
integer, intent(in) :: arbIndexCount
integer, intent(in) :: arbIndexList(:,:)
type(ESMF_DistGridConnection), intent(in), optional :: connList(:)
integer, intent(out), optional :: rc

Return Value type(ESMF_DistGrid)


Source Code

      function ESMF_GridCreateDistgridArb(dimCount, distDimCount, isDist, distDim, minIndex,  &
        maxIndex, arbIndexCount, arbIndexList, connList, rc)
!
! !RETURN VALUE:
      type(ESMF_Distgrid) :: ESMF_GridCreateDistgridArb
!
! !ARGUMENTS:
       integer,               intent(in)            :: dimCount
       integer,               intent(in)            :: distDimCount
       logical,               intent(in)            :: isDist(:)
       integer,               intent(in)            :: distDim(:)
       integer,               intent(in)            :: minIndex(:)
       integer,               intent(in)            :: maxIndex(:)
       integer,               intent(in)            :: arbIndexCount
       integer,               intent(in)            :: arbIndexList(:,:)
       type(ESMF_DistgridConnection), intent(in), optional :: connList(:)
       integer,               intent(out), optional :: rc
!
! !DESCRIPTION:
!
! This internal method creates a single tile, arbitrarily distributed distgrid
! (see Figure \ref{fig:GridDecomps}).
! To specify the arbitrary distribution, the user passes in an 2D array
! of local indices, where the first dimension is the number of local grid cells
! specified by {\tt localArbIndexCount} and the second dimension is the number of distributed
! dimensions.
!
! {\tt distDim} specifies which grid dimensions are arbitrarily distributed. The
! size of {\tt distDim} has to agree with the size of the second dimension of
! {\tt localArbIndex}.
!
! The arguments are:
! \begin{description}
! \item[{[minIndex]}]
!      Tuple to start the index ranges at. If not present, defaults
!      to /1,1,1,.../.
! \item[{[maxIndex]}]
!      The upper extend of the grid index ranges.
! \item[{arbIndexCount}]
!      The number of grid cells in the local DE. It is okay to have 0
!      grid cell in a local DE.
! \item[{[arbIndexList]}]
!      This 2D array specifies the indices of the PET LOCAL grid cells.  The
!      dimensions should be arbIndexCount * number of Distributed grid dimensions
!      where arbIndexCount is the input argument specified below
! \item[distDim]
!       This array specifies which dimensions are arbitrarily distributed.
!       The size of the array specifies the total distributed dimensions.
!       if not specified, defaults is all dimensions will be arbitrarily
!       distributed.  The size has to agree with the size of the second
!       dimension of {\tt localArbIndex}.
! \item[{[rc]}]
!      Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOP
    type(ESMF_DistGrid)  :: distgrid
    integer, allocatable :: undistLBound(:), undistUBound(:)
    integer, allocatable :: minDistIndex(:), maxDistIndex(:)
    integer              :: localrc
    integer              :: undistDimCount
    integer              :: i,j,ud
    integer, allocatable :: local1DIndices(:)
    integer              :: ind


    ! Initialize return code; assume failure until success is certain
    localrc = ESMF_RC_NOT_IMPL
    if (present(rc)) rc = ESMF_RC_NOT_IMPL

    ! dimCounts of the undistributed part of the grid
    undistDimCount=dimCount-distDimCount

    ! can't have all undistributed dimensions
    if (distDimCount == 0) then
       call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
                 msg="- Need to have at least one distributed dimension", &
                 ESMF_CONTEXT, rcToReturn=rc)
       return
    endif

    ! Check local arbIndexList dimension matched with local arbIndexCount and diskDimCount
    if (size(arbIndexList, 1) /= arbIndexCount) then
                  call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
                 msg="- localArbIndex 1st dimension has to match with localArbIndexCount", &
                 ESMF_CONTEXT, rcToReturn=rc)
          return
    endif

    ! prepare for conversion
    allocate(minDistIndex(distDimCount), maxDistIndex(distDimCount), stat=localrc)
    if (ESMF_LogFoundAllocError(localrc, msg="Allocating local1DIndices", &
                                     ESMF_CONTEXT, rcToReturn=rc)) return
    do j = 1, distDimCount
      ind = distDim(j)
      minDistIndex(j) = minIndex(ind)
      maxDistIndex(j) = maxIndex(ind)
    enddo

    allocate(local1DIndices(arbIndexCount), stat=localrc)
    if (ESMF_LogFoundAllocError(localrc, msg="Allocating local1DIndices", &
                                     ESMF_CONTEXT, rcToReturn=rc)) return

    ! convert local arbIndexList into local 1D sequence index list for DistGrid
    if (arbIndexCount > 0) then
      ! loop over all entries in the local index list
      do i = 1, arbIndexCount
        local1DIndices(i) = ESMF_DistGridSeqIndex(minDistIndex, maxDistIndex, &
          arbIndexList(i,:), rc=localrc)
        if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return
       enddo
    endif

   ! Calc undistLBound, undistUBound for Grid -----------------------------------------------
   if (undistDimCount > 0) then
     allocate(undistLBound(undistDimCount), stat=localrc)
     if (ESMF_LogFoundAllocError(localrc, msg="Allocating undistLBound", &
              ESMF_CONTEXT, rcToReturn=rc)) return
     allocate(undistUBound(undistDimCount), stat=localrc)
     if (ESMF_LogFoundAllocError(localrc, msg="Allocating undistUBound", &
              ESMF_CONTEXT, rcToReturn=rc)) return

      ! Fill in undistLBound, undistUBound
      ud=1
      do i=1,dimCount
         if (.not. isDist(i)) then
           undistLBound(ud)=minIndex(i)
           undistUBound(ud)=maxIndex(i)
           ud=ud+1
         endif
      enddo
   endif


   ! Create DistGrid --------------------------------------------------------------
   if (undistDimCount > 0) then
      ESMF_GridCreateDistgridArb=ESMF_DistGridCreate(local1DIndices, 1, undistLBound, undistUBound, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return
   else
      ESMF_GridCreateDistgridArb=ESMF_DistGridCreate(local1DIndices, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return
   endif


    ! Clean up memory
    deallocate(minDistIndex, maxDistIndex)
    deallocate(local1DIndices)
    if (undistDimCount > 0) then
      deallocate(undistLBound)
      deallocate(undistUBound)
    endif

    ! Return successfully
    if (present(rc)) rc = ESMF_SUCCESS
    end function ESMF_GridCreateDistgridArb