function ESMF_GridCreateFrmDistGrid(distgrid, &
distgridToGridMap, &
coordSys, coordTypeKind, coordDimCount, coordDimMap, &
gridEdgeLWidth, gridEdgeUWidth, gridAlign, &
gridMemLBound, indexflag, name, vm, rc)
!
! !RETURN VALUE:
type(ESMF_Grid) :: ESMF_GridCreateFrmDistGrid
!
! !ARGUMENTS:
type(ESMF_DistGrid), intent(in) :: distgrid
integer, intent(in), optional :: distgridToGridMap(:)
type(ESMF_CoordSys_Flag),intent(in), optional :: coordSys
type(ESMF_TypeKind_Flag),intent(in), optional :: coordTypeKind
integer, intent(in), optional :: coordDimCount(:)
integer, intent(in), optional :: coordDimMap(:,:)
integer, intent(in), optional :: gridEdgeLWidth(:)
integer, intent(in), optional :: gridEdgeUWidth(:)
integer, intent(in), optional :: gridAlign(:)
integer, intent(in), optional :: gridMemLBound(:)
type(ESMF_Index_Flag), intent(in), optional :: indexflag
character (len=*), intent(in), optional :: name
type(ESMF_VM), intent(in), optional :: vm
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
! This is the most general form of creation for an {\tt ESMF\_Grid}
! object. It allows the user to fully specify the topology and index space
! using the DistGrid methods and then build a grid out
! of the resulting DistGrid. Note that since the Grid created by this call
! uses {\tt distgrid} as a description of its index space, the resulting Grid
! will have exactly the same number of dimensions (i.e. the same dimCount) as
! {\tt distgrid}. The {\tt distgridToGridMap} argument
! specifies how the Grid dimensions are mapped to the {\tt distgrid}.
! The {\tt coordDimCount} and {\tt coordDimMap} arguments
! allow the user to specify how the coordinate arrays should map to the grid
! dimensions. (Note, though, that creating a grid does not allocate coordinate
! storage. A method such as {\tt ESMF\_GridAddCoord()} must be called
! before adding coordinate values.)
!
! The arguments are:
! \begin{description}
! \item[distgrid]
! {\tt ESMF\_DistGrid} object that describes how the array is decomposed and
! distributed over DEs.
! \item[{[distgridToGridMap]}]
! List that has dimCount elements.
! The elements map each dimension of distgrid to a dimension in the grid.
! (i.e. the values should range from 1 to dimCount). If not specified, the default
! is to map all of distgrid's dimensions against the dimensions of the
! grid in sequence.
! \item[{[coordSys]}]
! The coordinate system of the grid coordinate data.
! For a full list of options, please see Section~\ref{const:coordsys}.
! If not specified then defaults to ESMF\_COORDSYS\_SPH\_DEG.
! \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[{[coordDimCount]}]
! List that has dimCount elements.
! Gives the dimension of each component (e.g. x) array. This is
! to allow factorization of the coordinate arrays. If not specified
! all arrays are the same size as the grid.
! \item[{[coordDimMap]}]
! 2D list of size dimCount x dimCount. This array describes the
! map of each component array's dimensions onto the grids
! dimensions. Each entry {\tt coordDimMap(i,j)} tells which
! grid dimension component i's, jth dimension maps to.
! Note that if j is bigger than {\tt coordDimCount(i)} it is ignored.
! The default for each row i is {\tt coordDimMap(i,:)=(1,2,3,4,...)}.
! \item[{[gridEdgeLWidth]}]
! The padding around the lower edges of the grid. This padding is between
! the index space corresponding to the cells and the boundary of the
! the exclusive region. This extra space is to contain the extra
! padding for non-center stagger locations, and should be big enough
! to hold any stagger in the grid. If this and gridAlign are not present then
! defaults to 0, 0, ..., 0 (all zeros).
! \item[{[gridEdgeUWidth]}]
! The padding around the upper edges of the grid. This padding is between
! the index space corresponding to the cells and the boundary of the
! the exclusive region. This extra space is to contain the extra
! padding for non-center stagger locations, and should be big enough
! to hold any stagger in the grid. If this and gridAlign are not present then
! defaults to 1, 1, ..., 1 (all ones).
! \item[{[gridAlign]}]
! Specification of how the stagger locations should align with the cell
! index space (can be overridden by the individual staggerAligns). If
! the gridEdgeWidths are not specified than this argument
! implies the gridEdgeWidths. If the gridEdgeWidths are specified and this argument isn't
! then this argument is implied by the gridEdgeWidths.
! If this and the gridEdgeWidths are not specified, then defaults to
! -1, -1, ..., -1 (all negative ones).
! \item[{[gridMemLBound]}]
! Specifies the lower index range of the memory of every DE in this Grid.
! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden
! by staggerMemLBound.
! \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[{[name]}]
! {\tt ESMF\_Grid} name.
! \item[{[vm]}]
! If present, the Grid object is created on the specified
! {\tt ESMF\_VM} object. The default is to create on the VM of the
! current context.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOP
integer :: localrc ! local error status
type(ESMF_Grid) :: grid
integer :: nameLen
type(ESMF_InterArray) :: gridEdgeLWidthArg ! Language Interface Helper Var
type(ESMF_InterArray) :: gridEdgeUWidthArg ! Language Interface Helper Var
type(ESMF_InterArray) :: gridAlignArg ! Language Interface Helper Var
type(ESMF_InterArray) :: gridMemLBoundArg ! Language Interface Helper Var
type(ESMF_InterArray) :: distgridToGridMapArg ! Language Interface Helper Var
type(ESMF_InterArray) :: coordDimCountArg ! Language Interface Helper Var
type(ESMF_InterArray) :: coordDimMapArg ! Language Interface Helper Var
integer :: intDestroyDistgrid,intDestroyDELayout
integer, allocatable :: collocation(:)
logical :: arbSeqIndexFlag
integer :: i, deCount, distDimCount, arbDim
type(ESMF_DELayout) :: delayout
type(ESMF_Pointer) :: vmThis
logical :: actualFlag
character(ESMF_MAXSTR), dimension(2) :: callbacktest
integer, dimension(2) :: callbacktest_lens
! 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_DistGridGetInit, distgrid, rc)
! Translate F90 arguments to C++ friendly form
!! name
nameLen=0
if (present(name)) then
nameLen=len_trim(name)
endif
! Must make sure the local PET is associated with an actual member
actualFlag = .true.
if (present(vm)) then
call ESMF_VMGetThis(vm, vmThis)
if (vmThis == ESMF_NULL_POINTER) then
actualFlag = .false. ! local PET is not for an actual member of Array
endif
endif
arbDim = -1 ! initialize
if (actualFlag) then
! Safe to access distgrid on local PET to get rank from input information
!! Check if the DistGrid is an arbitrary distgrid
call ESMF_DistGridGet(distgrid, delayout=delayout, dimCount=distDimCount, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_DELayoutGet(delayout, localDECount=deCount, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (deCount > 0) then
allocate(collocation(distDimCount)) ! dimCount
call ESMF_DistGridGet(distgrid, collocation=collocation, rc=localrc)
do i=1,distDimCount
call ESMF_DistGridGet(distgrid, localDE=0, collocation=collocation(i), &
arbSeqIndexFlag=arbSeqIndexFlag, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (arbSeqIndexFlag) arbDim = i
enddo
deallocate(collocation)
endif
endif
if (arbDim /= -1) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
msg="- distgrid should not contain arbitrary sequence indices", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
!! coordTypeKind
! It doesn't look like it needs to be translated, but test to make sure
!! staggerWidths
gridEdgeLWidthArg = ESMF_InterArrayCreate(gridEdgeLWidth, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
gridEdgeUWidthArg = ESMF_InterArrayCreate(gridEdgeUWidth, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
gridAlignArg = ESMF_InterArrayCreate(gridAlign, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
gridMemLBoundArg = ESMF_InterArrayCreate(gridMemLBound, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
!! distgridToGridMap
distgridToGridMapArg = ESMF_InterArrayCreate(distgridToGridMap, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
!! Description of array factorization
coordDimCountArg = ESMF_InterArrayCreate(coordDimCount, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
coordDimMapArg = ESMF_InterArrayCreate(farray2D=coordDimMap, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Initialize this grid object as invalid
grid%this = ESMF_NULL_POINTER
!! Convert destroyDistGrid flag
! default to don't destroy, subroutine used to actually set flags in other creates
intDestroyDistgrid=0
intDestroyDELayout=0
! Call C++ Subroutine to do the create
call c_ESMC_gridcreatefromdistgrid(grid%this, nameLen, name, &
coordTypeKind, distgrid, distgridToGridMapArg, coordsys, &
coordDimCountArg, coordDimMapArg, &
gridEdgeLWidthArg, gridEdgeUWidthArg, gridAlignArg, gridMemLBoundArg,&
indexflag, intDestroyDistGrid, intDestroyDELayout, vm, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
#if 0
! set Attributes for some of the basic information
if (present(coordSys)) then
call c_esmc_attributesetvalue(grid%this, 'coordSys', ESMF_TYPEKIND_I4, &
1, coordSys%coordsys, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (present(coordTypeKind)) then
callbacktest(1) = "CALLBACKESMF_GridGet"
callbacktest_lens(1)=8
callbacktest_lens(2)=12
call c_esmc_attributesetcharlist(grid%this, 'coordTypeKind', ESMF_TYPEKIND_CHARACTER, &
2, callbacktest, callbacktest_lens, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (present(indexflag)) then
call c_esmc_attributesetvalue(grid%this, 'indexflag', ESMF_TYPEKIND_I4, &
1, indexflag%i_type, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
#endif
! Deallocate helper variables
call ESMF_InterArrayDestroy(gridEdgeLWidthArg, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_InterArrayDestroy(gridEdgeUWidthArg, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_InterArrayDestroy(gridAlignArg, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_InterArrayDestroy(gridMemLBoundArg, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_InterArrayDestroy(distgridToGridMapArg, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_InterArrayDestroy(coordDimCountArg, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_InterArrayDestroy(coordDimMapArg, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Set return value
ESMF_GridCreateFrmDistGrid = grid
! Set init status
ESMF_INIT_SET_CREATED(ESMF_GridCreateFrmDistGrid)
! Return successfully
if (present(rc)) rc = ESMF_SUCCESS
end function ESMF_GridCreateFrmDistGrid