function ESMF_ArrayCreateFromGrid(grid,staggerloc, typekind, &
gridToArrayMap, ungriddedLBound, ungriddedUBound, &
totalLWidth, totalUWidth, name, rc)
!
! !RETURN VALUE:
type(ESMF_Array) :: ESMF_ArrayCreateFromGrid
!
! !ARGUMENTS:
type(ESMF_Grid), intent(in) :: grid
type(ESMF_StaggerLoc), intent(in), optional :: staggerloc
type(ESMF_TypeKind_Flag), intent(in), optional :: typekind
integer, intent(in), optional :: gridToArrayMap(:)
integer, intent(in), optional :: ungriddedLBound(:)
integer, intent(in), optional :: ungriddedUBound(:)
integer, intent(in), optional :: totalLWidth(:)
integer, intent(in), optional :: totalUWidth(:)
character (len=*), intent(in), optional :: name
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
!
! Create an ESMF Array which is suitable to hold data for a particular
! stagger location in a Grid. The Array will have the correct bounds, distgridToGridMap,
! distgrid, etc. The {\tt totalWidth} variables can be used to add extra padding
! around the Array (e.g. for use as a halo).
!
! The arguments are:
! \begin{description}
!\item[{grid}]
! The grid to get the information from to create the Array.
!\item[{staggerloc}]
! The stagger location to build the Array for.
! Please see Section~\ref{const:staggerloc} for a list
! of predefined stagger locations. If not present, defaults to
! ESMF\_STAGGERLOC\_CENTER.
! \item[{[typekind]}]
! The type/kind of the newly created array data. For a full list of
! options, please see section~\ref{const:typekind}.
! If not specified then defaults to ESMF\_TYPEKIND\_R8.
!\item[{[gridToArrayMap]}]
! Indicates where each grid dimension goes in the newly created Array.
! {\tt The array gridToArrayMap} should be at least of size equal to the grid's dimCount.
! If not set defaults to (1,2,3,....). An entry of 0 indicates the grid dimension
! won't be used in the creation of the Array.
!\item[{[ungriddedLBound]}]
! The lower bounds of the non-grid Array dimensions.
!\item[{[ungriddedUBound]}]
! The upper bounds of the non-grid array dimensions.
!\item[{[totalLWidth]}]
! Extra padding to be added to the Array. {\tt totalLWidth} is the amount
! that the lower boundary of the Array should be dropped relative
! to the lower bound of the exclusive region.
!\item[{[totalUWidth]}]
! Extra padding to be added to the Array. {\tt totalUWidth} is the amount
! that the upper boundary of the Array should be raised relative
! to the upper bound of the exclusive region.
! \item[{[name]}]
! {\tt ESMF\_Grid} name.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOPI
integer :: localrc ! local error status
type(ESMF_Array) :: array
type(ESMF_ArraySpec) :: arrayspec
type(ESMF_DistGrid) :: distgrid
type(ESMF_Index_Flag) :: indexflag
type(ESMF_TypeKind_Flag) :: localTypeKind
type(ESMF_StaggerLoc) :: localStaggerLoc
integer, pointer :: arrayLBound(:),arrayUBound(:)
integer, pointer :: distgridToArrayMap(:)
integer :: dimCount
integer :: i,ungriddedDimCount, arrayDimCount, undistArrayDimCount
logical :: contains_nonzero
integer :: gridUsedDimCount
! Initialize return code; assume failure until success is certain
localrc = ESMF_RC_NOT_IMPL
if (present(rc)) rc = ESMF_RC_NOT_IMPL
! Check init status of arguments
ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc)
! Set Default TypeKind if neccessary
if (present(typekind)) then
localTypeKind=typekind
else
localTypeKind=ESMF_TYPEKIND_R8
endif
! Set Default StaggerLoc if neccessary
if (present(staggerloc)) then
localStaggerLoc=staggerloc
else
localStaggerLoc=ESMF_STAGGERLOC_CENTER
endif
! Both the bounds need to be present if either is.
if ((present(ungriddedLBound) .or. present(ungriddedUBound)) .and. &
.not. (present(ungriddedLBound) .and. present(ungriddedUBound))) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
msg="- if either ungriddedBound is present both need to be", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
! The bounds need to be the same size
if (present(ungriddedLBound) .and. present(ungriddedUBound)) then
if (size(ungriddedLBound) /= size(ungriddedUBound)) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
msg="- ungriddedLBound and ungriddedUBound must be the same size ", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
endif
! Get the ungridded dimCount
ungriddedDimCount=0
if (present(ungriddedUBound)) then
ungriddedDimCount=size(ungriddedUBound)
endif
! Get info from Grid
call ESMF_GridGet(grid, dimCount=dimCount, &
indexflag=indexflag, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! calc undist Array DimCount
undistArrayDimCount=ungriddedDimCount
! Make sure gridToArrayMap is correct size
if (present(gridToArrayMap)) then
if (size(gridToArrayMap) < dimCount) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
msg="- gridToArrayMap needs to at least be of the Grid's dimCount", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
endif
! calc the number of dimensions from the grid being used (e.g. with non-zero mapping)
if (present(gridToArrayMap)) then
gridUsedDimCount=0
do i=1,dimCount
if (gridToArrayMap(i) > 0) then
gridUsedDimCount=gridUsedDimCount+1
endif
enddo
else
! Default assumes all grid dims are used so add number of grid dims
gridUsedDimCount=dimCount
endif
! calc full Array DimCount
! Its the ungriddedDimCount + the number of non-zero entries in gridToArrayMap
arrayDimCount=ungriddedDimCount+gridUsedDimCount
! Make sure gridToArrayMap is correct size
if (present(gridToArrayMap)) then
do i=1,dimCount
if ((gridToArrayMap(i) <0) .or. (gridToArrayMap(i) > arrayDimCount)) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
msg="- gridToArrayMap value is outside range", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
enddo
endif
! Make sure gridToArrayMap contains at least one non-zero entry
if (present(gridToArrayMap)) then
contains_nonzero=.false.
do i=1,dimCount
if (gridToArrayMap(i) >0) then
contains_nonzero=.true.
endif
enddo
if (.not. contains_nonzero) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
msg="- gridToArrayMap must contains at least one value greater than 0", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
endif
! construct ArraySpec
call ESMF_ArraySpecSet(arrayspec,rank=arrayDimCount,typekind=localTypeKind, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! allocate distgridToArrayMap
allocate(distgridToArrayMap(dimCount) , stat=localrc)
if (ESMF_LogFoundAllocError(localrc, msg="Allocating distgridToArrayMap", &
ESMF_CONTEXT, rcToReturn=rc)) return
! allocate undistributed Bounds
allocate(arrayLBound(undistArrayDimCount) , stat=localrc)
if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridLBound", &
ESMF_CONTEXT, rcToReturn=rc)) return
allocate(arrayUBound(undistArrayDimCount) , stat=localrc)
if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridUBound", &
ESMF_CONTEXT, rcToReturn=rc)) return
! Get dimmap and undistibuted bounds
call ESMF_GridGetArrayInfo(grid, localstaggerloc, &
gridToArrayMap, ungriddedLBound, ungriddedUBound, &
distgrid, distgridToArrayMap, arrayLBound, arrayUBound, &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! create Array
array=ESMF_ArrayCreate(arrayspec=arrayspec, &
distgrid=distgrid, distgridToArrayMap=distgridToArrayMap, &
totalLWidth=totalLWidth, totalUWidth=totalUWidth, &
indexflag=indexflag, &
undistLBound=arrayLBound, undistUBound=arrayUBound, name=name, &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Set return value
ESMF_ArrayCreateFromGrid = array
! cleanup
deallocate(distgridToArrayMap)
deallocate(arrayLBound)
deallocate(arrayUBound)
! Return successfully
if (present(rc)) rc = ESMF_SUCCESS
end function ESMF_ArrayCreateFromGrid