ESMF_GridSetCmmitShapeTileArb Subroutine

private subroutine ESMF_GridSetCmmitShapeTileArb(grid, name, coordTypeKind, minIndex, maxIndex, arbIndexCount, arbIndexList, keywordEnforcer, connflagDim1, connflagDim2, connflagDim3, poleStaggerLoc1, poleStaggerLoc2, poleStaggerLoc3, bipolePos1, bipolePos2, bipolePos3, coordDep1, coordDep2, coordDep3, distDim, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_Grid), intent(inout) :: grid
character(len=*), intent(in), optional :: name
type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind
integer, intent(in), optional :: minIndex(:)
integer, intent(in) :: maxIndex(:)
integer, intent(in) :: arbIndexCount
integer, intent(in) :: arbIndexList(:,:)
type(ESMF_KeywordEnforcer), optional :: keywordEnforcer
type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:)
type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:)
type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:)
type(ESMF_StaggerLoc), intent(in), optional :: poleStaggerLoc1(2)
type(ESMF_StaggerLoc), intent(in), optional :: poleStaggerLoc2(2)
type(ESMF_StaggerLoc), intent(in), optional :: poleStaggerLoc3(2)
integer, intent(in), optional :: bipolePos1(2)
integer, intent(in), optional :: bipolePos2(2)
integer, intent(in), optional :: bipolePos3(2)
integer, intent(in), optional :: coordDep1(:)
integer, intent(in), optional :: coordDep2(:)
integer, intent(in), optional :: coordDep3(:)
integer, intent(in), optional :: distDim(:)
integer, intent(out), optional :: rc

Source Code

      subroutine ESMF_GridSetCmmitShapeTileArb(grid, name,coordTypeKind, &
                minIndex, maxIndex, arbIndexCount, arbIndexList, &
        keywordEnforcer, connflagDim1, connflagDim2, connflagDim3, &
        poleStaggerLoc1, poleStaggerLoc2, poleStaggerLoc3, &
        bipolePos1, bipolePos2, bipolePos3, &
        coordDep1, coordDep2, coordDep3, &
        distDim, rc)
!
! !ARGUMENTS:

       type(ESMF_Grid),       intent(inout)        :: grid
       character (len=*),     intent(in), optional :: name
       type(ESMF_TypeKind_Flag),   intent(in), optional :: coordTypeKind
       integer,               intent(in), optional :: minIndex(:)
       integer,               intent(in)           :: maxIndex(:)
       integer,               intent(in)           :: arbIndexCount
       integer,               intent(in)           :: arbIndexList(:,:)
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
       type(ESMF_GridConn_Flag),   intent(in), optional :: connflagDim1(:)   !N. IMP.
       type(ESMF_GridConn_Flag),   intent(in), optional :: connflagDim2(:)   !N. IMP.
       type(ESMF_GridConn_Flag),   intent(in), optional :: connflagDim3(:)   !N. IMP.
       type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc1(2)!N. IMP.
       type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc2(2)!N. IMP.
       type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc3(2)!N. IMP.
       integer,               intent(in), optional :: bipolePos1(2) !N. IMP.
       integer,               intent(in), optional :: bipolePos2(2) !N. IMP.
       integer,               intent(in), optional :: bipolePos3(2) !N. IMP.
       integer,               intent(in), optional :: coordDep1(:)
       integer,               intent(in), optional :: coordDep2(:)
       integer,               intent(in), optional :: coordDep3(:)
       integer,               intent(in), optional :: distDim(:)
       integer,               intent(out), optional :: rc
!
! !DESCRIPTION:
!
! This method set an empty grid as a single tile, arbitrarily distributed grid
! (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 arbIndexCount 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 arbIndexList}.
!
! For consistency's sake the {\tt ESMF\_GridSetCommitShapeTile()} call
! should be executed in the same set or a subset of the PETs in which the
! {\tt ESMF\_GridEmptyCreate()} call was made. If the call
! is made in a subset, the Grid objects outside that subset will
! still be "empty" and not usable.
!
! The arguments are:
! \begin{description}
! \item[{[grid]}]
!     The empty {\tt ESMF\_Grid} to set information into and then commit.
! \item[{[name]}]
!          {\tt ESMF\_Grid} name.
! \item[{[coordTypeKind]}]
!     The type/kind of the grid coordinate data. All {\em numerical} types
!     listed under section~\ref{const:typekind} are supported.
!     If not specified then defaults to ESMF\_TYPEKIND\_R8.
! \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[{[arbIndexList]}]
!      This 2D array specifies the indices of the local grid cells.  The
!      dimensions should be arbIndexCount * number of Distributed grid dimensions
!      where arbIndexCount is the input argument specified below
! \item[{arbIndexCount}]
!      The number of grid cells in the local DE
! \item[{[connflagDim1]}]
!      Fortran array describing the index dimension 1 connections.
!      The first element represents the minimum end of dimension 1.
!      The second element represents the maximum end of dimension 1.
!      If array is only one element long, then that element is used
!      for both the minimum and maximum end.
!      Please see Section~\ref{const:gridconn} for a list of valid
!      options. If not present, defaults to ESMF\_GRIDCONN\_NONE.
!     [CURRENTLY NOT IMPLEMENTED]
! \item[{[connflagDim2]}]
!      Fortran array describing the index dimension 2 connections.
!      The first element represents the minimum end of dimension 2.
!      The second element represents the maximum end of dimension 2.
!      If array is only one element long, then that element is used
!      for both the minimum and maximum end.
!      Please see Section~\ref{const:gridconn} for a list of valid
!      options. If not present, defaults to ESMF\_GRIDCONN\_NONE.
!     [CURRENTLY NOT IMPLEMENTED]
! \item[{[connflagDim3]}]
!      Fortran array describing the index dimension 3 connections.
!      The first element represents the minimum end of dimension 3.
!      The second element represents the maximum end of dimension 3.
!      If array is only one element long, then that element is used
!      for both the minimum and maximum end.
!      Please see Section~\ref{const:gridconn} for a list of valid
!      options. If not present, defaults to ESMF\_GRIDCONN\_NONE.
!     [CURRENTLY NOT IMPLEMENTED]
! \item[{[poleStaggerLoc1]}]
!     Two element array describing the index dimension 1 connections.
!      The first element represents the minimum end of dimension 1.
!      The second element represents the maximum end of dimension 1.
!      If a pole, this describes which staggerlocation is at the pole at each end.
!      Please see Section~\ref{const:staggerloc} for a list
!      of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER.
!     [CURRENTLY NOT IMPLEMENTED]
! \item[{[poleStaggerLoc2]}]
!     Two element array describing the index dimension 2 connections.
!      The first element represents the minimum end of dimension 2.
!      The second element represents the maximum end of dimension 2.
!      If a pole, this describes which staggerlocation is at the pole at each end.
!      Please see Section~\ref{const:staggerloc} for a list
!      of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER.
!     [CURRENTLY NOT IMPLEMENTED]
! \item[{[poleStaggerLoc3]}]
!     Two element array describing the index dimension 3 connections.
!      The first element represents the minimum end of dimension 3.
!      The second element represents the maximum end of dimension 3.
!      If a pole, this describes which staggerlocation is at the pole at each end.
!      Please see Section~\ref{const:staggerloc} for a list
!      of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER.
!     [CURRENTLY NOT IMPLEMENTED]
! \item[{[bipolePos1]}]
!     Two element array describing the index dimension 1 connections.
!      The first element represents the minimum end of dimension 1.
!      The second element represents the maximum end of dimension 1.
!      If a bipole, this gives the index position of one of the poles.
!      The other is half way around. If not present, the default is 1.
!     [CURRENTLY NOT IMPLEMENTED]
! \item[{[bipolePos2]}]
!     Two element array describing the index dimension 2 connections.
!      The first element represents the minimum end of dimension 2.
!      The second element represents the maximum end of dimension 2.
!      If a bipole, this gives the index position of one of the poles.
!      The other is half way around. If not present, the default is 1.
!     [CURRENTLY NOT IMPLEMENTED]
! \item[{[bipolePos3]}]
!     Two element array describing the index dimension 3 connections.
!      The first element represents the minimum end of dimension 3.
!      The second element represents the maximum end of dimension 3.
!      If a bipole, this gives the index position of one of the poles.
!      The other is half way around. If not present, the default is 1.
!     [CURRENTLY NOT IMPLEMENTED]
! \item[{[coordDep1]}]
!     The size of the array specifies the number of dimensions of the
!     first coordinate component array. The values specify which
!     of the index dimensions the corresponding coordinate
!     arrays map to. The format should be /ESMF\_DIM\_ARB/ where
!     /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all
!     the arbitrarily distributed dimensions.  n is the dimension that
!     is not distributed (if exists).
!     If not present the default is /ESMF\_DIM\_ARB/ if the first dimension
!     is arbitararily distributed, or /n/ if not distributed (i.e. n=1)
!      Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB.
! \item[{[coordDep2]}]
!     The size of the array specifies the number of dimensions of the
!     second coordinate component array. The values specify which
!     of the index dimensions the corresponding coordinate
!     arrays map to. The format should be /ESMF\_DIM\_ARB/ where
!     /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all
!     the arbitrarily distributed dimensions.  n is the dimension that
!     is not distributed (if exists).
!     If not present the default is /ESMF\_DIM\_ARB/ if this dimension
!     is arbitararily distributed, or /n/ if not distributed (i.e. n=2)
!     Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB.
! \item[{[coordDep3]}]
!     The size of the array specifies the number of dimensions of the
!     third coordinate component array. The values specify which
!     of the index dimensions the corresponding coordinate
!     arrays map to. The format should be /ESMF\_DIM\_ARB/ where
!     /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all
!     the arbitrarily distributed dimensions.  n is the dimension that
!     is not distributed (if exists).
!     If not present the default is /ESMF\_DIM\_ARB/ if this dimension
!     is arbitararily distributed, or /n/ if not distributed (i.e. n=3)
!     Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB.
! \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 arbIndexList}.
! \item[{[rc]}]
!      Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOPI
    type(ESMF_DistGrid)  :: distgrid
    type(ESMF_DELayout)  :: delayout
    integer, pointer     :: petList(:)
    integer, pointer     :: undistLBound(:)
    integer, pointer     :: undistUBound(:)
    integer, pointer     :: coordDimCount(:)
    integer, pointer     :: coordDimMap(:,:)
    integer              :: localrc
    integer              :: dimCount,distDimCount,undistDimCount
    integer, pointer     :: deDimCount(:)
    integer, pointer     :: minIndexLocal(:)
    integer, pointer     :: maxIndexLocal(:)
    integer              :: i,j,d,f,i1,i2,i3,k,ind,ud
    type(ESMF_GridConn_Flag)  :: connflagDim1Local(2)
    type(ESMF_GridConn_Flag)  :: connflagDim2Local(2)
    type(ESMF_GridConn_Flag)  :: connflagDim3Local(2)
    integer              :: connCount, petListCount
    integer              :: top
    integer, pointer     :: distSize(:)
    integer, pointer     :: distDimLocal(:)
    logical, pointer     :: isDist(:)
    integer, pointer     :: local1DIndices(:)
    logical              :: found

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


    ! Compute the Grid DimCount and Derivatives ---------------------------------------------------
    ! dimCount
    dimCount=size(maxIndex)
    if ((dimCount < 2) .or. (dimCount > 3)) then
        call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
               msg="- maxIndex size and thus Grid dimCount must be either 2 or 3 when using create shape ", &
               ESMF_CONTEXT, rcToReturn=rc)
         return
    endif

    ! number of distributed dimension, distDimCount, is determined by the second dim of
    ! arbIndexList
    distDimCount = size(arbIndexList,2)
    if (distDimCount > dimCount) then
        call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
               msg="- the second dim of arbIndexList must be equal or less than grid dimension", &
               ESMF_CONTEXT, rcToReturn=rc)
         return
    endif

    allocate(distDimLocal(distDimCount), stat=localrc)
    allocate(isDist(dimCount), stat=localrc)
    if (ESMF_LogFoundAllocError(localrc, msg="Allocating distDimLocal or isDist", &
                                     ESMF_CONTEXT, rcToReturn=rc)) return

    isDist(:)=.false.
    ! check distribution info
    if (present(distDim)) then
       if (size(distDim) /= distDimCount) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
                 msg="- distDim must match with the second dimension of arbIndexList", &
                 ESMF_CONTEXT, rcToReturn=rc)
            return
       endif
       distDimLocal(:)=distDim(:)
       do i=1,distDimCount
          isDist(distDimLocal(i))=.true.
       enddo
    else
       do i=1,distDimCount
         distDimLocal(i)=i
       enddo
       isDist(1:distDimCount)=.true.
    endif

    ! Argument Consistency Checking --------------------------------------------------------------
    if ((dimCount .lt. 3) .and. present(connflagDim3)) then
       call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
                 msg="- connflagDim3 not allowed when grid is less than dimCount 3", &
                 ESMF_CONTEXT, rcToReturn=rc)
       return
    endif

    if ((dimCount .lt. 3) .and. present(poleStaggerLoc3)) then
       call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
                 msg="- poleStaggerLoc3 not allowed when grid is less than dimCount 3", &
                 ESMF_CONTEXT, rcToReturn=rc)
       return
    endif

    if ((dimCount .lt. 3) .and. present(bipolePos3)) then
       call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
                 msg="- bipolePos3 not allowed when grid is less than dimCount 3", &
                 ESMF_CONTEXT, rcToReturn=rc)
       return
    endif

    if (present(minIndex)) then
       if (size(minIndex) /= dimCount) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
               msg="- minIndex size must equal grid dimCount", &
               ESMF_CONTEXT, rcToReturn=rc)
          return
       endif
    endif



   ! Check for non-valid connection types here

    ! Set Defaults -------------------------------------------------------------
    ! Set default for minIndex
    allocate(minIndexLocal(dimCount), stat=localrc)
    if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", &
                                     ESMF_CONTEXT, rcToReturn=rc)) return

    if (present(minIndex)) then
       minIndexLocal(:)=minIndex(:)
    else
       do i=1,dimCount
          minIndexLocal(i)=1
       enddo
    endif

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

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

    do i=1,distDimCount
       ind = distDimLocal(i)
       distSize(i)=maxIndexLocal(ind)-minIndexLocal(ind)+1
    enddo

    ! 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 arbIndexList dimension matched with arbIndexCount and diskDimCount
    if (size(arbIndexList, 1) /= arbIndexCount) then
       call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
                 msg="- arbIndexList 1st dimension has to match with arbIndexCount", &
                 ESMF_CONTEXT, rcToReturn=rc)
       return
    endif

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

    ! convert arbIndexList into 1D index array for DistGrid
    if (arbIndexCount > 0) then
       do i = 1, arbIndexCount
          local1DIndices(i) = arbIndexList(i,1)-1
          if (distDimCount >= 2) then
             do j = 2, distDimCount
                local1DIndices(i) = local1DIndices(i)*distSize(j) + arbIndexList(i,j)-1
             enddo
          endif
          local1DIndices(i) = local1DIndices(i)+1
       enddo
    endif

    ! Set Default for connections (although they don't work yet in distgrid/array, so they aren't really used anywhere yet.)
    if (present(connflagDim1)) then
       if (size(connflagDim1) == 1) then
          connflagDim1Local(1)=connflagDim1(1)
          connflagDim1Local(2)=connflagDim1(1)    ! if only 1 connection is specified then repeat for both ends
       else if (size(connflagDim1) >= 2) then
          connflagDim1Local(1)=connflagDim1(1)
          connflagDim1Local(2)=connflagDim1(2)
       endif
    else
       connflagDim1Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection
       connflagDim1Local(2)=ESMF_GRIDCONN_NONE
    endif

    if (present(connflagDim2)) then
       if (size(connflagDim2) == 1) then
          connflagDim2Local(1)=connflagDim2(1)
          connflagDim2Local(2)=connflagDim2(1)    ! if only 1 connection is specified then repeat for both ends
       else if (size(connflagDim2) >= 2) then
          connflagDim2Local(1)=connflagDim2(1)
          connflagDim2Local(2)=connflagDim2(2)
       endif
    else
       connflagDim2Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection
       connflagDim2Local(2)=ESMF_GRIDCONN_NONE
    endif

    if (present(connflagDim3)) then
       if (size(connflagDim3) == 1) then
          connflagDim3Local(1)=connflagDim3(1)
          connflagDim3Local(2)=connflagDim3(1)    ! if only 1 connection is specified then repeat for both ends
       else if (size(connflagDim3) >= 2) then
          connflagDim3Local(1)=connflagDim3(1)
          connflagDim3Local(2)=connflagDim3(2)
       endif
    else
       connflagDim3Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection
       connflagDim3Local(2)=ESMF_GRIDCONN_NONE
    endif


    ! check for not implemented functionality
    if (connflagDim1Local(1) /= ESMF_GRIDCONN_NONE .or. &
        connflagDim1Local(2) /= ESMF_GRIDCONN_NONE) then
       call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, &
                 msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", &
                 ESMF_CONTEXT, rcToReturn=rc)
       return
    endif

    if (connflagDim2Local(1) /= ESMF_GRIDCONN_NONE .or. &
        connflagDim2Local(2) /= ESMF_GRIDCONN_NONE) then
       call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, &
                 msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", &
                 ESMF_CONTEXT, rcToReturn=rc)
       return
    endif

    if (connflagDim3Local(1) /= ESMF_GRIDCONN_NONE .or. &
        connflagDim3Local(2) /= ESMF_GRIDCONN_NONE) then
       call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, &
                 msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", &
                 ESMF_CONTEXT, rcToReturn=rc)
       return
    endif

   ! Setup Connections between tile sides ----------------------------------------

   ! CONNECTIONS DON'T WORK YET SO NOT IMPLEMENTED

   ! Convert coordDeps to coordDimCount and coordDimMap -------------------------------
   allocate(coordDimCount(dimCount), stat=localrc)
   if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", &
              ESMF_CONTEXT, rcToReturn=rc)) return
   allocate(coordDimMap(dimCount,dimCount), stat=localrc)
   if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", &
              ESMF_CONTEXT, rcToReturn=rc)) return

   if (present(coordDep1)) then
      ! error checking, if this dimension is arbitrary, one of the
      ! coordinate dimension has to be be ESMF_DIM_ARB
      if (isDist(1)) then
        found = .false.
        do i=1,size(coordDep1)
          if (coordDep1(i) == ESMF_DIM_ARB) found = .true.
        enddo
        if (.not. found) then
           call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
                 msg="- coordDep1 does not contain ESMF_DIM_ARB", &
                 ESMF_CONTEXT, rcToReturn=rc)
            return
        endif
      endif     
      coordDimCount(1)=size(coordDep1)
      coordDimMap(1,:)=0
      do i=1,size(coordDep1)
         coordDimMap(1,i)=coordDep1(i)
      enddo
   else
      coordDimCount(1)=1
      ! ESMF_DIM_ARB if 1 is distributed, otherwise 1
      if (isDist(1)) then
        coordDimMap(1,1)=ESMF_DIM_ARB
      else
        coordDimMap(1,1)=1
      endif
   endif

   if (present(coordDep2)) then
      ! error checking, one of the dimensions has to be ESMF_DIM_ARB
      ! if dimension 2 is arbitrary
      if (isDist(2)) then
        found = .false.
        do i=1,size(coordDep2)
          if (coordDep2(i) == ESMF_DIM_ARB) found = .true.
        enddo
        if (.not. found) then
           call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
                 msg="- coordDep2 does not contain ESMF_DIM_ARB", &
                 ESMF_CONTEXT, rcToReturn=rc)
            return
        endif
      endif     
      coordDimCount(2)=size(coordDep2)
      coordDimMap(2,:)=0
      do i=1,size(coordDep2)
         coordDimMap(2,i)=coordDep2(i)
      enddo
   else
      coordDimCount(2)=1
      ! ESMF_DIM_ARB if 1 is distributed, otherwise 1
      if (isDist(2)) then
        coordDimMap(2,1)=ESMF_DIM_ARB
      else
        coordDimMap(2,1)=2
      endif
   endif

   if (dimCount > 2) then
      if (present(coordDep3)) then
        ! error checking, one of the dimensions has to be ESMF_DIM_ARB
        ! if dimension 3 is arbitrary
        if (isDist(3)) then
          found = .false.
          do i=1,size(coordDep3)
            if (coordDep3(i) == ESMF_DIM_ARB) found = .true.
          enddo
          if (.not. found) then
            call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
                 msg="- coordDep3 does not contain ESMF_DIM_ARB", &
                 ESMF_CONTEXT, rcToReturn=rc)
            return
          endif
        endif   
        coordDimCount(3)=size(coordDep3)
        coordDimMap(3,:)=0
        do i=1,size(coordDep3)
           coordDimMap(3,i)=coordDep3(i)
        enddo
      else
        coordDimCount(3)=1
        ! ESMF_DIM_ARB if 1 is distributed, otherwise 1
        if (isDist(3)) then
          coordDimMap(3,1)=ESMF_DIM_ARB
        else
          coordDimMap(3,1)=3
        endif
      endif
   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)=minIndexLocal(i)
           undistUBound(ud)=maxIndexLocal(i)
           ud=ud+1
         endif
      enddo
   endif


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


   ! Create Grid from specification -----------------------------------------------
   call ESMF_GridSetFromDistGrid(grid, coordTypeKind=coordTypeKind, &
                               distgrid=distgrid, distDim=distDimLocal, &
                               coordDimCount=coordDimCount, coordDimMap=coordDimMap, &
                               minIndex=minIndexLocal, maxIndex=maxIndexLocal, &
                               localArbIndexCount=arbIndexCount, localArbIndex=arbIndexList, &
                               name=name, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return

    ! Set internal items to be destroyed with grid
    call ESMF_GridSetDestroyDistgrid(grid,destroy=.true., rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return

    call ESMF_GridSetDestroyDELayout(grid,destroy=.false., rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return

    ! Clean up memory
    deallocate(minIndexLocal)
    deallocate(maxIndexLocal)
    deallocate(local1DIndices)
    deallocate(isDist)
    deallocate(distDimLocal)
    deallocate(coordDimCount)
    deallocate(coordDimMap)
    if (undistDimCount > 0) then
       deallocate(undistLBound)
       deallocate(undistUBound)
    endif
    deallocate(distSize)

    ! Commit Grid -----------------------------------------------------------------
    call ESMF_GridCommit(grid, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return

    ! Return successfully
    if (present(rc)) rc = ESMF_SUCCESS
    end subroutine ESMF_GridSetCmmitShapeTileArb