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