ESMF_GridCreateDistgridReg Function

private function ESMF_GridCreateDistgridReg(dimCount, minIndex, maxIndex, regDecomp, decompflag, indexflag, petMap, connList, rc)

Arguments

Type IntentOptional Attributes Name
integer :: dimCount
integer, intent(in) :: minIndex(:)
integer, intent(in) :: maxIndex(:)
integer, intent(in), optional :: regDecomp(:)
type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:)
type(ESMF_Index_Flag), intent(in), optional :: indexflag
integer, intent(in), optional :: petMap(:,:,:)
type(ESMF_DistGridConnection), intent(in), optional :: connList(:)
integer, intent(out), optional :: rc

Return Value type(ESMF_DistGrid)


Source Code

      function ESMF_GridCreateDistgridReg(dimCount, minIndex, maxIndex, regDecomp, decompFlag, &
        indexflag, petMap, connList, rc)

!
! !RETURN VALUE:
      type(ESMF_Distgrid) :: ESMF_GridCreateDistgridReg
!
! !ARGUMENTS:
       integer                                      :: dimCount
       integer,               intent(in)            :: minIndex(:)
       integer,               intent(in)            :: maxIndex(:)
       integer,               intent(in),  optional :: regDecomp(:)
       type(ESMF_Decomp_Flag), intent(in),  optional :: decompflag(:)
       type(ESMF_Index_Flag),  intent(in),  optional :: indexflag
       integer,               intent(in),  optional :: petMap(:,:,:)
       type(ESMF_DistgridConnection), intent(in), optional :: connList(:)
       integer,               intent(out), optional :: rc
!
! !DESCRIPTION:
!
! This internal method creates a single tile, regularly distributed distgrid
! (see Figure \ref{fig:GridDecomps}).
! To specify the distribution, the user passes in an array
! ({\tt regDecomp}) specifying the number of DEs to divide each
! dimension into. The array {\tt decompFlag} indicates how the division into DEs is to
! occur.  The default is to divide the range as evenly as possible.
!
! The arguments are:
! \begin{description}
! \item[{[regDecomp]}]
!      List that has the same number of elements as {\tt maxIndex}.
!      Each entry is the number of decounts for that dimension.
!      If not specified, the default decomposition will be petCountx1x1..x1.
! \item[{[decompflag]}]
!      List of decomposition flags indicating how each dimension of the
!      tile is to be divided between the DEs. The default setting
!      is {\tt ESMF\_DECOMP\_BALANCED} in all dimensions. Please see
!      Section~\ref{const:decompflag} for a full description of the
!      possible options. Note that currently the option
!      {\tt ESMF\_DECOMP\_CYCLIC} isn't supported in Grid creation.
! \item[{minIndex}]
!      The bottom extent of the grid array. If not given then the value defaults
!      to /1,1,1,.../.
! \item[{maxIndex}]
!      The upper extent of the grid array.
! \item[{[indexflag]}]
!      Indicates the indexing scheme to be used in the new Grid. Please see
!      Section~\ref{const:indexflag} for the list of options. If not present,
!      defaults to ESMF\_INDEX\_DELOCAL.
! \item[{[petMap]}]
!       Sets the mapping of pets to the created DEs. This 3D
!       should be of size regDecomp(1) x regDecomp(2) x regDecomp(3)
!       If the Grid is 2D, then the last dimension is of size 1.
! \item[{[rc]}]
!      Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOPI
    type(ESMF_DELayout)  :: delayout
    type(ESMF_VM)        :: vm
    integer, pointer     :: petList(:)
    integer              :: localrc
    integer              :: i
    integer, pointer     :: regDecompLocal(:)
    type(ESMF_Decomp_Flag), pointer :: decompflagLocal(:)
    integer, pointer     :: minIndexLocal(:), maxIndexLocal(:)
    integer              :: deCount
    integer              :: i1,i2,i3,k

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


    ! Argument Consistency Checking --------------------------------------------------------------
    if (present(regDecomp)) then
        if (size(regDecomp) .lt. dimCount) then
            call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
                    msg="- regDecomp size doesn't match Grid dimCount ", &
                    ESMF_CONTEXT, rcToReturn=rc)
            return
        endif
    endif

    if (present(decompFlag)) then
        ! Make sure size is correct
        if (size(decompFlag) .lt. dimCount) then
            call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
                    msg="- decompFlag size doesn't match Grid dimCount ", &
                    ESMF_CONTEXT, rcToReturn=rc)
            return
        endif

        ! CYCLIC decomposition isn't allowed when creating a Grid
        do i=1,size(decompFlag)
           if (decompFlag(i) == ESMF_DECOMP_CYCLIC) then
              call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_OUTOFRANGE, &
                    msg="- decompFlag isn't allowed to be" // &
                        " ESMF_DECOMP_CYCLIC when creating a Grid.", &
                    ESMF_CONTEXT, rcToReturn=rc)
              return
           endif
        enddo
     endif


    ! Set default for regDecomp
    allocate(regDecompLocal(dimCount), stat=localrc)
    if (ESMF_LogFoundAllocError(localrc, msg="Allocating regDecompLocal", &
                                     ESMF_CONTEXT, rcToReturn=rc)) return

    if (present(regDecomp)) then
       regDecompLocal(:)=regDecomp(:)
    else
       ! The default is 1D divided among all the Pets
       call ESMF_VMGetCurrent(vm,rc=localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
       call ESMF_VMGet(vm,petCount=regDecompLocal(1),rc=localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
       do i=2,dimCount
          regDecompLocal(i)=1
       enddo
    endif


  if (present(petMap)) then
     if (dimCount > 2) then
          if ((size(petMap,1) /= regDecompLocal(1)) .or. &
              (size(petMap,2) /= regDecompLocal(2)) .or. &
              (size(petMap,3) /= regDecompLocal(3))) then
              call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
                     msg="- petMap wrong size in one or more dimensions", &
                     ESMF_CONTEXT, rcToReturn=rc)
              return
          endif
      else
          if ((size(petMap,1) /= regDecompLocal(1)) .or. &
              (size(petMap,2) /= regDecompLocal(2)) .or. &
              (size(petMap,3) /= 1)) then
              call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
                     msg="- petMap wrong size in one or more dimensions", &
                     ESMF_CONTEXT, rcToReturn=rc)
              return
          endif
      endif
    endif


   ! Set default for decomp flag based on gridEdgeWidths -----------------------------------
   ! NOTE: This is a temporary fix until we have something better implemented in distGrid

    ! Set default for decompFlag
    allocate(decompFlagLocal(dimCount), stat=localrc)
    if (ESMF_LogFoundAllocError(localrc, msg="Allocating decompFlagLocal", &
                                     ESMF_CONTEXT, rcToReturn=rc)) return

    if (present(decompFlag)) then
        decompFlagLocal(:)=decompFlag(:)
    else
        decompFlagLocal(:)=ESMF_DECOMP_BALANCED
    endif


   ! Process PetMap --------------------------------------------------------------
   !! Calculate deCount
   deCount=1
   do i=1,dimCount
      deCount=deCount*regDecompLocal(i)
   enddo

   ! create DELayout based on presence of petMap
   if (present(petMap)) then
      !! Allocate petList
      allocate(petList(deCount), stat=localrc)
      if (ESMF_LogFoundAllocError(localrc, msg="Allocating petList", &
              ESMF_CONTEXT, rcToReturn=rc)) return


      !! copy petMap to petList
      if (dimCount > 2) then
         k=1
         do i3=1,regDecompLocal(3)
         do i2=1,regDecompLocal(2)
         do i1=1,regDecompLocal(1)
            petList(k)=petMap(i1,i2,i3)
            k=k+1
         enddo
         enddo
         enddo
      else
         k=1
         do i3=1,1
         do i2=1,regDecompLocal(2)
         do i1=1,regDecompLocal(1)
            petList(k)=petMap(i1,i2,i3)
            k=k+1
         enddo
         enddo
         enddo
      endif

      !! create delayout from the petList
      delayout=ESMF_DELayoutCreate(petMap=petList,rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return
      !! Get rid of list
      deallocate(petList)
   else
      !! create a default delayout
      delayout=ESMF_DELayoutCreate(deCount=deCount,rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return
   endif

   call ESMF_DELayoutGet(delayout, decount=decount, rc=localrc)

   ! Create DistGrid --------------------------------------------------------------
   ESMF_GridCreateDistgridReg=ESMF_DistGridCreate(minIndex=minIndex, maxIndex=maxIndex, &
              regDecomp=regDecompLocal, decompFlag=decompFlagLocal, delayout=delayout,&
              indexflag=indexflag, &
              connectionList=connList, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return



    ! Clean up memory
    deallocate(regDecompLocal)
    deallocate(decompFlagLocal)

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