ESMF_ArrayCreateFromGrid Function

public function ESMF_ArrayCreateFromGrid(grid, staggerloc, typekind, gridToArrayMap, ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, name, rc)

Arguments

Type IntentOptional Attributes Name
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

Return Value type(ESMF_Array)


Source Code

      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