From 5f626ad57250307e57f7ffece99c11f282a1dbdc Mon Sep 17 00:00:00 2001 From: Robert Oehmke Date: Wed, 19 Jul 2023 15:58:32 -0600 Subject: [PATCH] Add Geom to Field complete interface description and change to alphabetical order. --- .../Field/src/ESMF_FieldEmpty.cppF90 | 3607 ++++++++--------- 1 file changed, 1803 insertions(+), 1804 deletions(-) diff --git a/src/Infrastructure/Field/src/ESMF_FieldEmpty.cppF90 b/src/Infrastructure/Field/src/ESMF_FieldEmpty.cppF90 index 8e57276c90..21891b0a6d 100644 --- a/src/Infrastructure/Field/src/ESMF_FieldEmpty.cppF90 +++ b/src/Infrastructure/Field/src/ESMF_FieldEmpty.cppF90 @@ -1858,41 +1858,35 @@ type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below TypeKindRankDeclarationMacro(FieldEmptyCompPtr) - -#define FieldEmptyCompGridDoc() \ +#define FieldEmptyCompGBDoc() \ !---------------------------------------------------------------------------- @\ !BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Grid started with FieldEmptyCreate @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Geom started with FieldEmptyCreate @\ ! @\ ! !INTERFACE: @\ ! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompGrid(field, grid, & @\ -! farray, indexflag, keywordEnforcer, datacopyflag, staggerloc, gridToFieldMap, & @\ -! ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, rc) @\ +! subroutine ESMF_FieldEmptyCompGB(field, geom, & @\ +! farray, indexflag, datacopyflag, gridToFieldMap, ungriddedLBound, & @\ +! ungriddedUBound, totalLWidth, totalUWidth, rc) @\ ! @\ ! !ARGUMENTS: @\ -! type(ESMF_Field), intent(inout) :: field @\ -! type(ESMF_Grid), intent(in) :: grid @\ -! (ESMF_KIND_),intent(in), target :: farray() @\ -! type(ESMF_Index_Flag), intent(in) :: indexflag @\ -!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ -! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! type(ESMF_STAGGERLOC), intent(in), optional :: staggerloc @\ -! integer, intent(in), optional :: gridToFieldMap(:) @\ -! integer, intent(in), optional :: ungriddedLBound(:) @\ -! integer, intent(in), optional :: ungriddedUBound(:) @\ -! integer, intent(in), optional :: totalLWidth(:) @\ -! integer, intent(in), optional :: totalUWidth(:) @\ -! integer, intent(out), optional :: rc @\ -! @\ -! !STATUS: @\ -! \begin{itemize} @\ -! \item\apiStatusCompatibleVersion{5.2.0r} @\ -! \end{itemize} @\ +! type(ESMF_Field), intent(inout) :: field @\ +! type(ESMF_Geom), intent(in) :: geom @\ +! (ESMF_KIND_), dimension(), target :: farray @\ +! type(ESMF_Index_Flag), intent(in) :: indexflag @\ +! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ +! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(in), optional :: ungriddedLBound(:) @\ +! integer, intent(in), optional :: ungriddedUBound(:) @\ +! integer, intent(in), optional :: totalLWidth(:) @\ +! integer, intent(in), optional :: totalUWidth(:) @\ +! integer, intent(out), optional :: rc @\ ! @\ ! !DESCRIPTION: @\ ! This call completes an {\tt ESMF\_Field} allocated with the @\ -! {\tt ESMF\_FieldEmptyCreate()} call. @\ +! {\tt ESMF\_FieldEmptyCreate()} call. For an example and @\ +! associated documentation using this method see section @\ +! \ref{sec:field:usage:partial_creation}. @\ ! @\ ! The Fortran data pointer inside {\tt ESMF\_Field} can be queried but deallocating @\ ! the retrieved data pointer is not allowed. @\ @@ -1901,10 +1895,10 @@ TypeKindRankDeclarationMacro(FieldEmptyCompPtr) ! \begin{description} @\ ! \item [field] @\ ! The {\tt ESMF\_Field} object to be completed and @\ -! committed in this call. The {\tt field} will have the same dimension @\ +! committed in this call. The {\tt field} will have the same dimension @\ ! (dimCount) as the rank of the {\tt farray}. @\ -! \item [grid] @\ -! The {\tt ESMF\_Grid} object to complete the Field. @\ +! \item [geom] @\ +! The {\tt ESMF\_Geom} object to complete the Field. @\ ! \item [farray] @\ ! Native Fortran data array to be copied/referenced in the {\tt field}. @\ ! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ @@ -1916,18 +1910,12 @@ TypeKindRankDeclarationMacro(FieldEmptyCompPtr) ! Indicates whether to copy the {\tt farray} or reference it directly. @\ ! For valid values see \ref{const:datacopyflag}. The default is @\ ! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ -! \item [{[staggerloc]}] @\ -! Stagger location of data in grid cells. For valid @\ -! predefined values see section \ref{const:staggerloc}. @\ -! To create a custom stagger location see section @\ -! \ref{sec:usage:staggerloc:adv}. The default @\ -! value is {\tt ESMF\_STAGGERLOC\_CENTER}. @\ ! \item [{[gridToFieldMap]}] @\ ! List with number of elements equal to the @\ -! {\tt grid}|s dimCount. The list elements map each dimension @\ -! of the {\tt grid} to a dimension in the {\tt farray} by @\ +! {\tt geom}|s dimCount. The list elements map each dimension @\ +! of the {\tt geom} to a dimension in the {\tt farray} by @\ ! specifying the appropriate {\tt farray} dimension index. The @\ -! default is to map all of the {\tt grid}|s dimensions against the @\ +! default is to map all of the {\tt geom}|s dimensions against the @\ ! lowest dimensions of the {\tt farray} in sequence, i.e. @\ ! {\tt gridToFieldMap} = (/1,2,3,.../). @\ ! Unmapped {\tt farray} dimensions are undistributed Field @\ @@ -1981,489 +1969,484 @@ TypeKindRankDeclarationMacro(FieldEmptyCompPtr) !EOP @\ !---------------------------------------------------------------------------- @\ -#define FieldEmptyCompGridMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +#define FieldEmptyCompGBMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ !---------------------------------------------------------------------------- @\ ^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompGrid" @\ - subroutine ESMF_FieldEmptyCompGrid##mrank##D##mtypekind(field, grid, farray, & @\ - indexflag, keywordEnforcer, datacopyflag, staggerloc, gridToFieldMap, & @\ - ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, rc) @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompGB" @\ +subroutine ESMF_FieldEmptyCompGB##mrank##D##mtypekind(field, geom, farray, & @\ + indexflag, datacopyflag, gridToFieldMap, ungriddedLBound, & @\ + ungriddedUBound, totalLWidth, totalUWidth, rc) @\ @\ - ! input arguments @\ - type(ESMF_Field), intent(inout) :: field @\ - type(ESMF_Grid), intent(in) :: grid @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), intent(in), target :: farray @\ - type(ESMF_Index_Flag), intent(in) :: indexflag @\ -type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - type(ESMF_StaggerLoc), intent(in), optional ::staggerloc @\ - integer, intent(in), optional :: gridToFieldMap(:) @\ - integer, intent(in), optional :: ungriddedLBound(:) @\ - integer, intent(in), optional :: ungriddedUBound(:) @\ - integer, intent(in), optional :: totalLWidth(:) @\ - integer, intent(in), optional :: totalUWidth(:) @\ - integer, intent(out), optional :: rc @\ - ! local variables @\ - type(ESMF_StaggerLoc) :: localStaggerLoc @\ - integer :: localrc @\ - type(ESMF_Geom) :: geom @\ - type(ESMF_GridDecompType) :: decompType @\ - type(ESMF_FieldStatus_Flag) :: status @\ + ! input arguments @\ + type(ESMF_Field), intent(inout) :: field @\ + type(ESMF_Geom), intent(in) :: geom @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), target :: farray @\ + type(ESMF_Index_Flag), intent(in) :: indexflag @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + integer, intent(in), optional :: gridToFieldMap(:) @\ + integer, intent(in), optional :: ungriddedLBound(:) @\ + integer, intent(in), optional :: ungriddedUBound(:) @\ + integer, intent(in), optional :: totalLWidth(:) @\ + integer, intent(in), optional :: totalUWidth(:) @\ + integer, intent(out), optional :: rc @\ + ! local variables @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: fpointer @\ + integer :: localrc, i, j, count @\ + integer :: memDimCount, fieldUngriddedDimCount @\ + integer :: fieldDimCount, localDeCount @\ + integer :: gridDimCount, gridDimCount_norep @\ + integer :: grid_repdimcount @\ + integer :: elementCount @\ + integer :: ungriddedIndex(ESMF_MAXDIM) @\ + integer :: distgridToArrayMap (ESMF_MAXDIM) @\ + integer :: undistLBound(ESMF_MAXDIM), undistUBound(ESMF_MAXDIM) @\ + integer :: localUngriddedLBound (ESMF_MAXDIM) @\ + integer :: localUngriddedUBound (ESMF_MAXDIM) @\ + integer :: localGridToFieldMap (ESMF_MAXDIM) @\ + integer :: localMaxHaloLWidth (ESMF_MAXDIM) @\ + integer :: localMaxHaloUWidth (ESMF_MAXDIM) @\ + logical :: isGridded(ESMF_MAXDIM) @\ + integer :: distgridToGridMap(ESMF_MAXDIM) @\ + type(ESMF_Array) :: array @\ + type(ESMF_DistGrid) :: distgrid @\ + integer :: fieldUndistDimCount @\ + logical :: flipflop(ESMF_MAXDIM) @\ + type(ESMF_Index_Flag) :: g_indexflag @\ + logical :: found @\ + type(ESMF_GridDecompType) :: decompType @\ + type(ESMF_GeomType_Flag) :: geomtype @\ + type(ESMF_Grid) :: grid @\ + integer :: distgridDimCount, distgridDimCount_norep, arbdim @\ + character(len=ESMF_MAXSTR) :: fieldName @\ @\ - if (present(rc)) then @\ - rc = ESMF_RC_NOT_IMPL @\ - endif @\ - localrc = ESMF_RC_NOT_IMPL @\ + if (present(rc)) then @\ + rc = ESMF_RC_NOT_IMPL @\ + endif @\ + localrc = ESMF_RC_NOT_IMPL @\ @\ - ! make sure field, grid, farray are properly initialized @\ - ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit,grid,rc) @\ + ! make sure field, grid, farray are properly initialized @\ + ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ + ESMF_INIT_CHECK_DEEP(ESMF_GeomGetInit,geom,rc) @\ @\ - call ESMF_FieldGet(field, status=status, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! get the fieldName @\ + call ESMF_FieldGet(field, name=fieldName, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ + ! Get number of grid dimensions, number @\ + ! of distributed grid dimensions, distgrid, @\ + ! number of ungridded Field dimensions, @\ + ! and number of undistributed Field Dimensions @\ + call ESMF_GeomGet(geom, dimCount=gridDimCount, & @\ + distgridToGridMap=distgridToGridMap, localDeCount=localDeCount, & @\ + distgrid=distgrid, indexflag=g_indexflag, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ +@\ + if(.not. (indexflag .eq. g_indexflag)) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- user specified indexflag must be identical with Grid indexflag", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ +@\ + elementCount = 0 ! default to assuming no elements @\ + if (localDeCount==1) then @\ + call ESMF_DistGridGet(distgrid, localDe=0, elementCount=elementCount, & @\ + rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + elseif (localDeCount>1) then @\ + !TODO: error out because not supported @\ + endif @\ +@\ + if (elementCount > 0) then @\ + ! The following use of fptr is a bit of trickery to get all F90 @\ + ! compilers to cooperate. For some compilers the associated() test @\ + ! will return .false. for farray of size 0. Some of those compilers @\ + ! will produce a run-time error in size(fptr). Other compilers will @\ + ! return .true. for the associated() test but return 0 in size(). @\ + fpointer => farray @\ + if(.not. associated(fpointer,farray)) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & @\ + msg="- farray is not associated with memory allocation)", & @\ ESMF_CONTEXT, rcToReturn=rc) @\ return @\ endif @\ @\ - call ESMF_GridGetDecompType(grid, decompType, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - if (decompType .eq. ESMF_GRID_ARBITRARY) then @\ - if ((present(totalLWidth)) .or. (present(totalUWidth))) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- indexflag, totalLWidth or totalUWidth are not allowed for arbitrary grid", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ + if (size(fpointer)==0) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & @\ + msg="- farray is not associated with memory allocation)", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ endif @\ + endif @\ @\ - ! Set default values. @\ - if (present(staggerloc)) then @\ - if ((decompType .eq. ESMF_GRID_ARBITRARY) .and. & @\ - (staggerloc .ne. ESMF_STAGGERLOC_CENTER)) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - else @\ - localStaggerloc=staggerloc @\ - endif @\ - else @\ - localStaggerLoc = ESMF_STAGGERLOC_CENTER @\ - endif @\ + ! Check if geom is a grid, if so, check if it is arbitrary @\ + decompType = ESMF_GRID_NONARBITRARY @\ + call ESMF_GeomGet(geom, geomtype=geomtype, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - geom=ESMF_GeomCreate(grid, localStaggerloc, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + if (geomtype .eq. ESMF_GEOMTYPE_GRID) then @\ + call ESMF_GeomGet(geom, grid=grid, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + call ESMF_GridGetDecompType(grid, decompType, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + endif @\ @\ - ! Do General Geom EmptyComp @\ - call ESMF_FieldEmptyCompGB##mrank##D##mtypekind(field, geom, farray, & @\ - indexflag, datacopyflag, gridToFieldMap, ungriddedLBound, & @\ - ungriddedUBound, totalLWidth, totalUWidth, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - if (present(rc)) rc = ESMF_SUCCESS @\ - end subroutine ESMF_FieldEmptyCompGrid##mrank##D##mtypekind @\ -!---------------------------------------------------------------------------- @\ - -TypeKindRankDeclarationMacro(FieldEmptyCompGrid) - - -#define FieldEmptyCompGridPtrDoc() \ -!---------------------------------------------------------------------------- @\ -!BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Grid started with FieldEmptyCreate @\ -! @\ -! !INTERFACE: @\ -! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompGridPtr(field, grid, & @\ -! farrayPtr, keywordEnforcer, datacopyflag, staggerloc, gridToFieldMap, & @\ -! totalLWidth, totalUWidth, rc) @\ -! @\ -! !ARGUMENTS: @\ -! type(ESMF_Field), intent(inout) :: field @\ -! type(ESMF_Grid), intent(in) :: grid @\ -! (ESMF_KIND_), pointer :: farrayPtr() @\ -!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ -! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! type(ESMF_STAGGERLOC), intent(in), optional :: staggerloc @\ -! integer, intent(in), optional :: gridToFieldMap(:) @\ -! integer, intent(in), optional :: totalLWidth(:) @\ -! integer, intent(in), optional :: totalUWidth(:) @\ -! integer, intent(out), optional :: rc @\ -! @\ -! !STATUS: @\ -! \begin{itemize} @\ -! \item\apiStatusCompatibleVersion{5.2.0r} @\ -! \end{itemize} @\ -! @\ -! !DESCRIPTION: @\ -! This call completes an {\tt ESMF\_Field} allocated with the @\ -! {\tt ESMF\_FieldEmptyCreate()} call. @\ -! @\ -! \begin{sloppypar} @\ -! The Fortran data pointer inside {\tt ESMF\_Field} can be queried and deallocated when @\ -! datacopyflag is {\tt ESMF\_DATACOPY\_REFERENCE}. Note that the {\tt ESMF\_FieldDestroy} call does not deallocate @\ -! the Fortran data pointer in this case. This gives user more flexibility over memory management. @\ -! \end{sloppypar} @\ -! The Fortran data pointer inside {\tt ESMF\_Field} can be queried and deallocated when @\ -! @\ -! The arguments are: @\ -! \begin{description} @\ -! \item [field] @\ -! The {\tt ESMF\_Field} object to be completed and @\ -! committed in this call. The {\tt field} will have the same dimension @\ -! (dimCount) as the rank of the {\tt farrayPtr}. @\ -! \item [grid] @\ -! The {\tt ESMF\_Grid} object to complete the Field. @\ -! \item [farrayPtr] @\ -! Native Fortran data pointer to be copied/referenced in the {\tt field}. @\ -! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ -! for the {\tt farrayPtr}. @\ -! \item [{[datacopyflag]}] @\ -! Indicates whether to copy the {\tt farrayPtr} or reference it directly. @\ -! For valid values see \ref{const:datacopyflag}. The default is @\ -! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ -! \item [{[staggerloc]}] @\ -! Stagger location of data in grid cells. For valid @\ -! predefined values see section \ref{const:staggerloc}. @\ -! To create a custom stagger location see section @\ -! \ref{sec:usage:staggerloc:adv}. The default @\ -! value is {\tt ESMF\_STAGGERLOC\_CENTER}. @\ -! \item [{[gridToFieldMap]}] @\ -! List with number of elements equal to the @\ -! {\tt grid}|s dimCount. The list elements map each dimension @\ -! of the {\tt grid} to a dimension in the {\tt farrayPtr} by @\ -! specifying the appropriate {\tt farrayPtr} dimension index. The @\ -! default is to map all of the {\tt grid}|s dimensions against the @\ -! lowest dimensions of the {\tt farrayPtr} in sequence, i.e. @\ -! {\tt gridToFieldMap} = (/1,2,3,.../). @\ -! Unmapped {\tt farrayPtr} dimensions are undistributed Field @\ -! dimensions. @\ -! All {\tt gridToFieldMap} entries must be greater than or equal @\ -! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ -! to specify the same entry multiple times unless it is zero. @\ -! If the Field dimCount is less than the Grid dimCount then the default @\ -! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ -! entry in the {\tt gridToFieldMap} indicates that the particular @\ -! Grid dimension will be replicating the Field across the DEs along @\ -! this direction. @\ -! \item [{[totalLWidth]}] @\ -! Lower bound of halo region. The size of this array is the number @\ -! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ -! needs to be the same as they appear in the {\tt field}. Values default @\ -! to 0. If values for totalLWidth are specified they must be reflected in @\ -! the size of the {\tt field}. That is, for each gridded dimension the @\ -! {\tt field} size should be max( {\tt totalLWidth} + {\tt totalUWidth} @\ -! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ -! \item [{[totalUWidth]}] @\ -! Upper bound of halo region. The size of this array is the number @\ -! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ -! needs to be the same as they appear in the {\tt field}. Values default @\ -! to 0. If values for totalUWidth are specified they must be reflected in @\ -! the size of the {\tt field}. That is, for each gridded dimension the @\ -! {\tt field} size should max( {\tt totalLWidth} + {\tt totalUWidth} @\ -! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ -! \item [{[rc]}] @\ -! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ -! \end{description} @\ -! @\ -!EOP @\ -!---------------------------------------------------------------------------- @\ - -#define FieldEmptyCompGridPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ -!---------------------------------------------------------------------------- @\ -^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompGridPtr" @\ - subroutine ESMF_FieldEmptyCompGridPtr##mrank##D##mtypekind(field, grid, farrayPtr, & @\ - keywordEnforcer, datacopyflag, staggerloc, gridToFieldMap, & @\ - totalLWidth, totalUWidth, rc) @\ + ! Check the size of the native array. @\ + memDimCount = mrank @\ @\ - ! input arguments @\ - type(ESMF_Field) :: field @\ - type(ESMF_Grid) :: grid @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ -type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - type(ESMF_StaggerLoc), intent(in), optional ::staggerloc @\ - integer, intent(in), optional :: gridToFieldMap(:) @\ - integer, intent(in), optional :: totalLWidth(:) @\ - integer, intent(in), optional :: totalUWidth(:) @\ - integer, intent(out), optional :: rc @\ - ! local variables @\ - type(ESMF_StaggerLoc) :: localStaggerLoc @\ - integer :: localrc @\ - type(ESMF_Geom) :: geom @\ - type(ESMF_GridDecompType) :: decompType @\ - type(ESMF_FieldStatus_Flag) :: status @\ + ! Error Check Input @\ + grid_repdimcount = 0 @\ + if (present(gridToFieldMap)) then @\ + if (size(gridToFieldMap) .ne. gridDimCount) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- gridToFieldMap size must equal to grid_rank", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + do i = 1, gridDimCount @\ + if(gridToFieldMap(i) == 0) grid_repdimcount = grid_repdimcount + 1 @\ + enddo @\ + endif @\ + gridDimCount_norep = gridDimCount - grid_repdimcount @\ @\ - if (present(rc)) then @\ - rc = ESMF_RC_NOT_IMPL @\ - endif @\ - localrc = ESMF_RC_NOT_IMPL @\ + if (present(gridToFieldMap)) then @\ + localGridToFieldMap(1:gridDimCount) = & @\ + gridToFieldMap (1:gridDimCount) @\ + else @\ + do i = 1, gridDimCount @\ + localGridToFieldMap(i) = i @\ + enddo @\ + endif @\ @\ - ! make sure field, grid, farrayPtr are properly initialized @\ - ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit,grid,rc) @\ + if (decompType .eq. ESMF_GRID_NONARBITRARY) then @\ + fieldDimCount = memDimCount @\ + else @\ + call ESMF_GridGet(grid, distgridToGridMap=distgridToGridMap, & @\ + rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! find out how many grid dimensions are arbitrarily distributed and calculate @\ + ! fieldDimCount accordingly @\ + arbdim = 0 @\ + do i=1,gridDimCount @\ + if (distgridToGridMap(i) .ne. 0) arbdim = arbdim+1 @\ + enddo @\ + fieldDimCount = memDimCount + arbdim - 1 @\ @\ - call ESMF_FieldGet(field, status=status, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! If there is any replicated dimension, check if any of the arb. dimensions are replicated. @\ + ! If one arb dimension is replicated, all the arb. dimensions have to be replicated @\ + if (grid_repdimcount .ne. 0) then @\ + do i = 1,gridDimCount @\ + if(localGridToFieldMap(i) == 0) then @\ + found = .false. @\ + do j=1,arbdim @\ + if (distgridToGridMap(j) .eq. i) found = .true. @\ + enddo @\ + if (found) then @\ + ! one arb.dimension is a replicated dimension, check if other arb dimensions are @\ + ! also replicated @\ + do j=1,arbdim @\ + if (distgridToGridMap(j) .ne. i) then @\ + if (localGridToFieldMap(distgridToGridMap(j)) .ne. 0) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- Arb. grid dimensions have to be either all replicated or not replicated", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ + enddo @\ + ! all arb. dimension are replication, jump out of the first do loop @\ + ! fieldDimCount should be the same as the memDimCount @\ + fieldDimCount = memDimCount @\ + exit @\ + endif @\ + endif @\ + enddo @\ + endif @\ + endif @\ @\ - if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ + if(fieldDimCount .lt. gridDimCount_norep) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- farray rank must be greater than or equal to grid rank", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ return @\ - endif @\ -@\ - call ESMF_GridGetDecompType(grid, decompType, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + endif @\ +! refer to ticket 1888180 @\ +! if(fieldDimCount .gt. gridDimCount_norep) then @\ +! if( (.not. present(ungriddedLBound)) .or. & @\ +! (.not. present(ungriddedUBound)) ) then @\ +! call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ +! "- ungridded bounds must be present when Field has ungridded dimension(s)", & @\ +! ESMF_CONTEXT, rcToReturn=rc) @\ +! return @\ +! endif @\ +! endif @\ @\ - if (decompType .eq. ESMF_GRID_ARBITRARY) then @\ - if ((present(totalLWidth)) .or. (present(totalUWidth))) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- indexflag, totalLWidth or totalUWidth are not allowed for arbitrary grid", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - endif @\ + ! ungridded dimensions plus replicated dimensions @\ + fieldUngriddedDimCount = fieldDimCount-gridDimCount + grid_repdimcount @\ + fieldUndistDimCount = fieldDimCount-gridDimCount + grid_repdimcount @\ @\ - ! Set default values. @\ - if (present(staggerloc)) then @\ - if ((decompType .eq. ESMF_GRID_ARBITRARY) .and. & @\ - (staggerloc .ne. ESMF_STAGGERLOC_CENTER)) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & @\ + ! Error Check Input @\ + if (present(ungriddedLBound)) then @\ + if (size(ungriddedLBound) .ne. fieldUngriddedDimCount) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- ungriddedLBound size must equal to array_rank-grid_rank", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ +@\ + if (present(ungriddedUBound)) then @\ + if (size(ungriddedUBound) .ne. fieldUngriddedDimCount) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- ungriddedUBound size must equal to array_rank-grid_rank", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ +@\ + if (present(totalLWidth)) then @\ + if (size(totalLWidth) .ne. gridDimCount_norep) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- totalLWidth must equal to gridded dimCount", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ +@\ + if (present(totalUWidth)) then @\ + if (size(totalUWidth) .ne. gridDimCount_norep) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- totalUWidth must equal to gridded dimCount", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ +@\ + ! gridToFieldMap elements must be in range 0...fieldRank and unique @\ + ! algorithm to check element uniqueness: @\ + ! run time: O(ESMF_MAXDIM) @\ + ! memory: O(2*ESMF_MAXDIM) @\ + ! or O(ESMF_MAXDIM+ESMF_MAXDIM/sizeof(integer)) with bitvector @\ + flipflop = .false. @\ + do i = 1, gridDimCount @\ + if(localGridToFieldMap(i) .lt. 0 .or. & @\ + localGridToFieldMap(i) .gt. fieldDimCount) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ + msg="- gridToFieldMap element must be within range 0...array rank", & @\ ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - else @\ - localStaggerloc=staggerloc @\ - endif @\ - else @\ - localStaggerLoc = ESMF_STAGGERLOC_CENTER @\ - endif @\ + return @\ + endif @\ + if(localGridToFieldMap(i) /= 0) then @\ + if(flipflop(localGridToFieldMap(i))) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ + msg="- gridToFieldMap element must be unique", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + flipflop(localGridToFieldMap(i)) = .true. @\ +endif @\ + enddo @\ @\ - geom=ESMF_GeomCreate(grid,localStaggerloc, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + if(present(totalLWidth)) then @\ + localMaxHaloLWidth(1:gridDimCount_norep) = & @\ + totalLWidth (1:gridDimCount_norep) @\ + else @\ + localMaxHaloLWidth = 0 @\ + endif @\ @\ - ! Do General Geom EmptyComp @\ - call ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ - datacopyflag, gridToFieldMap, & @\ - totalLWidth, totalUWidth, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + if(present(totalUWidth)) then @\ + localMaxHaloUWidth(1:gridDimCount_norep) = & @\ + totalUWidth (1:gridDimCount_norep) @\ + else @\ + localMaxHaloUWidth = 0 @\ + endif @\ @\ - if (present(rc)) rc = ESMF_SUCCESS @\ - end subroutine ESMF_FieldEmptyCompGridPtr##mrank##D##mtypekind @\ + ! Here we get the lbounds and ubounds for ungridded @\ + ! dimensions from the native array, if it is not input @\ + ! through the argument list. First we need to set up @\ + ! an index array that holds the ungridded dimensions of @\ + ! the native array. @\ +@\ + ! Since we are saving the ungriddedIndex calculate it even @\ + ! if ungridded bounds are present @\ +@\ + ! Figure out which dims are ungridded @\ + isGridded = .false. @\ + do i=1, gridDimCount @\ + if(localGridToFieldMap(i) /= 0) isGridded(localGridToFieldMap(i)) = .true. @\ + enddo @\ +@\ + ! Use ungridded info to figure out the map from ungridded to field dims @\ + count=1 @\ + do i=1,fieldDimCount @\ + if (.not. isGridded(i)) then @\ + ungriddedIndex(count)=i @\ + count=count+1 @\ + endif @\ + enddo @\ +@\ + ! set Array ungridded bounds depending on what user provides@\ + if (present(ungriddedLBound)) then @\ + if(present(ungriddedUBound)) then @\ + ! Both present so copy @\ + localUngriddedLBound(1:fieldUngriddedDimCount) = & @\ + ungriddedLBound(1:fieldUngriddedDimCount) @\ + localUngriddedUBound(1:fieldUngriddedDimCount) = & @\ + ungriddedUBound(1:fieldUngriddedDimCount) @\ + else @\ + ! Copy lower bound and make upper bound high enough to fit @\ + localUngriddedLBound(1:fieldUngriddedDimCount) = & @\ + ungriddedLBound(1:fieldUngriddedDimCount) @\ + do i=1, fieldUngriddedDimCount @\ + localUngriddedUBound(i) = ungriddedLBound(i)+ & @\ + size (farray,ungriddedIndex(i))-1 @\ + enddo @\ + endif @\ + else @\ + if(present(ungriddedUBound)) then @\ + ! Copy upper bound and make lower bound low enough to fit @\ + do i=1, fieldUngriddedDimCount @\ + localUngriddedLBound(i) = ungriddedUBound(i)- & @\ + size (farray,ungriddedIndex(i))+1 @\ + enddo @\ + localUngriddedUBound(1:fieldUngriddedDimCount) = & @\ + ungriddedUBound(1:fieldUngriddedDimCount) @\ + else @\ + ! No user info copy array bounds @\ + ! Note: assumed shape bounds will be 1...size @\ + do i=1, fieldUngriddedDimCount @\ + localUngriddedLBound(i) = lbound(farray,ungriddedIndex(i)) @\ + localUngriddedUBound(i) = ubound(farray,ungriddedIndex(i)) @\ + enddo @\ + endif @\ + endif @\ +@\ + call ESMF_DistGridGet(distgrid, dimCount=distgridDimCount, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + distgridDimCount_norep = memDimCount - fieldUngriddedDimCount @\ +@\ + ! The undistributed info from the Grid needs to be @\ + ! combined with the ungridded info from the Field in order @\ + ! to create the Array for the Field. @\ + call ESMF_GeomGetArrayInfo(geom, & @\ + gridToFieldMap=localGridToFieldMap, & @\ + ungriddedLBound=localUngriddedLBound (1:fieldUngriddedDimCount), & @\ + ungriddedUBound=localUngriddedUBound (1:fieldUngriddedDimCount), & @\ + distgridToArrayMap=distgridToArrayMap, & @\ + undistLBound=undistLBound, undistUBound=undistUBound, & @\ + rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ +@\ + ! Create Array with undistributed dimensions @\ + if (decompType .eq. ESMF_GRID_NONARBITRARY) then @\ + array = ESMF_ArrayCreate(distgrid, farray, & @\ + indexflag=indexflag, datacopyflag=datacopyflag, & @\ + distgridToArrayMap=distgridToArrayMap (1:distgridDimCount), & @\ + undistLBound=undistLBound(1:fieldUndistDimCount), & @\ + undistUBound=undistUBound(1:fieldUndistDimCount), & @\ + totalLWidth=localMaxHaloLWidth(1:gridDimCount_norep), & @\ + totalUWidth=localMaxHaloUWidth(1:gridDimCount_norep), & @\ + name=fieldName, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + else @\ + array = ESMF_ArrayCreate(distgrid, farray, & @\ + indexflag=indexflag, datacopyflag=datacopyflag, & @\ + distgridToArrayMap=distgridToArrayMap (1:distgridDimCount), & @\ + undistLBound=undistLBound(1:fieldUndistDimCount), & @\ + undistUBound=undistUBound(1:fieldUndistDimCount), & @\ + name=fieldName, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + endif @\ +@\ + field%ftypep%array = array @\ +@\ + ! set array_internal to .true. because field%array is internal @\ + field%ftypep%array_internal = .true. @\ +@\ + ! Should call a common FieldEmptyCompConstructor here instead @\ + ! of just setting things up ourselves @\ + ! (The field Sets were all moved here in preparation for this) @\ + field%ftypep%gridToFieldMap(1:gridDimCount) = & @\ + localGridToFieldMap(1:gridDimCount) @\ + field%ftypep%totalLWidth(1:gridDimCount_norep) = & @\ + localMaxHaloLWidth (1:gridDimCount_norep) @\ + field%ftypep%totalUWidth(1:gridDimCount_norep) = & @\ + localMaxHaloUWidth (1:gridDimCount_norep) @\ + field%ftypep%ungriddedLBound(1:fieldUngriddedDimCount) = & @\ + localUngriddedLBound(1:fieldUngriddedDimCount) @\ + field%ftypep%ungriddedUBound(1:fieldUngriddedDimCount) = & @\ + localUngriddedUBound(1:fieldUngriddedDimCount) @\ + field%ftypep%geom = geom @\ + field%ftypep%status = ESMF_FIELDSTATUS_COMPLETE @\ + call ESMF_BaseSetStatus(field%ftypep%base, ESMF_STATUS_READY, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + field%ftypep%dimCount = gridDimCount_norep + fieldUngriddedDimCount @\ +@\ + call ESMF_FieldValidate(field, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ +@\ + if (present(rc)) rc = ESMF_SUCCESS @\ +end subroutine ESMF_FieldEmptyCompGB##mrank##D##mtypekind @\ !---------------------------------------------------------------------------- @\ -TypeKindRankDeclarationMacro(FieldEmptyCompGridPtr) +TypeKindRankDeclarationMacro(FieldEmptyCompGB) -#define FieldEmptyCompLSDoc() \ +#define FieldEmptyCompGBPtrDoc() \ !---------------------------------------------------------------------------- @\ !BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from LocStream started with FieldEmptyCreate @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Geom started with FieldEmptyCreate @\ ! @\ ! !INTERFACE: @\ ! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompLS(field, locstream, & @\ -! farray, indexflag, keywordEnforcer, datacopyflag, gridToFieldMap, & @\ -! ungriddedLBound, ungriddedUBound, rc) @\ +! subroutine ESMF_FieldEmptyCompGBPtr(field, geom, & @\ +! farrayPtr, datacopyflag, gridToFieldMap, & @\ +! totalLWidth, totalUWidth, rc) @\ ! @\ ! !ARGUMENTS: @\ -! type(ESMF_Field), intent(inout) :: field @\ -! type(ESMF_LocStream), intent(in) :: locstream @\ -! (ESMF_KIND_), intent(in), target :: farray() @\ -! type(ESMF_Index_Flag), intent(in) :: indexflag @\ -!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ -! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! integer, intent(in), optional :: gridToFieldMap(:) @\ -! integer, intent(in), optional :: ungriddedLBound(:) @\ -! integer, intent(in), optional :: ungriddedUBound(:) @\ -! integer, intent(out), optional :: rc @\ -! @\ -! !DESCRIPTION: @\ -! This call completes an {\tt ESMF\_Field} allocated with the @\ -! {\tt ESMF\_FieldEmptyCreate()} call. @\ -! @\ -! The Fortran data pointer inside {\tt ESMF\_Field} can be queried but deallocating @\ -! the retrieved data pointer is not allowed. @\ -! @\ -! The arguments are: @\ -! \begin{description} @\ -! \item [field] @\ -! The {\tt ESMF\_Field} object to be completed and @\ -! committed in this call. The {\tt field} will have the same dimension @\ -! (dimCount) as the rank of the {\tt farray}. @\ -! \item [locstream] @\ -! The {\tt ESMF\_LocStream} object to complete the Field. @\ -! \item [farray] @\ -! Native Fortran data array to be copied/referenced in the {\tt field}. @\ -! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ -! for the {\tt farray}. @\ -! \item [indexflag] @\ -! Indicate how DE-local indices are defined. See section @\ -! \ref{const:indexflag} for a list of valid indexflag options. @\ -! \item [{[datacopyflag]}] @\ -! Indicates whether to copy the {\tt farray} or reference it directly. @\ -! For valid values see \ref{const:datacopyflag}. The default is @\ -! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ -! \item [{[gridToFieldMap]}] @\ -! List with number of elements equal to the @\ -! {\tt locstream}|s dimCount. The list elements map each dimension @\ -! of the {\tt locstream} to a dimension in the {\tt farray} by @\ -! specifying the appropriate {\tt farray} dimension index. The @\ -! default is to map all of the {\tt locstream}|s dimensions against the @\ -! lowest dimensions of the {\tt farray} in sequence, i.e. @\ -! {\tt gridToFieldMap} = (/1,2,3,.../). @\ -! Unmapped {\tt farray} dimensions are undistributed Field @\ -! dimensions. @\ -! All {\tt gridToFieldMap} entries must be greater than or equal @\ -! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ -! to specify the same entry multiple times unless it is zero. @\ -! If the Field dimCount is less than the LocStream dimCount then the default @\ -! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ -! entry in the {\tt gridToFieldMap} indicates that the particular @\ -! LocStream dimension will be replicating the Field across the DEs along @\ -! this direction. @\ -! \item [{[ungriddedLBound]}] @\ -! Lower bounds of the ungridded dimensions of the {\tt field}. @\ -! The number of elements in the {\tt ungriddedLBound} is equal to the number of ungridded @\ -! dimensions in the {\tt field}. All ungridded dimensions of the @\ -! {\tt field} are also undistributed. When field dimension count is @\ -! greater than locstream dimension count, both ungriddedLBound and ungriddedUBound @\ -! must be specified. When both are specified the values are checked @\ -! for consistency. Note that the the ordering of @\ -! these ungridded dimensions is the same as their order in the {\tt field}. @\ -! \item [{[ungriddedUBound]}] @\ -! Upper bounds of the ungridded dimensions of the {\tt field}. @\ -! The number of elements in the {\tt ungriddedUBound} is equal to the number of ungridded @\ -! dimensions in the {\tt field}. All ungridded dimensions of the @\ -! {\tt field} are also undistributed. When field dimension count is @\ -! greater than locstream dimension count, both ungriddedLBound and ungriddedUBound @\ -! must be specified. When both are specified the values are checked @\ -! for consistency. Note that the the ordering of @\ -! these ungridded dimensions is the same as their order in the {\tt field}. @\ -! \item [{[rc]}] @\ -! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ -! \end{description} @\ -! @\ -!EOP @\ -!---------------------------------------------------------------------------- @\ - -#define FieldEmptyCompLSMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ -!---------------------------------------------------------------------------- @\ -^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompLS" @\ - subroutine ESMF_FieldEmptyCompLS##mrank##D##mtypekind(field, locstream, farray, & @\ - indexflag, keywordEnforcer, datacopyflag, gridToFieldMap, ungriddedLBound, & @\ - ungriddedUBound, rc) @\ -@\ - ! input arguments @\ - type(ESMF_Field), intent(inout) :: field @\ - type(ESMF_LocStream), intent(in) :: locstream @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), target :: farray @\ - type(ESMF_Index_Flag), intent(in) :: indexflag @\ -type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - integer, intent(in), optional :: gridToFieldMap(:) @\ - integer, intent(in), optional :: ungriddedLBound(:) @\ - integer, intent(in), optional :: ungriddedUBound(:) @\ - integer, intent(out), optional :: rc @\ - ! local variables @\ - integer :: localrc @\ - type(ESMF_Geom) :: geom @\ - type(ESMF_FieldStatus_Flag) :: status @\ -@\ - if (present(rc)) then @\ - rc = ESMF_RC_NOT_IMPL @\ - endif @\ - localrc = ESMF_RC_NOT_IMPL @\ -@\ - ! make sure field, locstream, farray are properly initialized @\ - ESMF_INIT_CHECK_DEEP_SHORT(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP_SHORT(ESMF_LocStreamGetInit,locstream,rc) @\ -@\ - call ESMF_FieldGet(field, status=status, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ -@\ - geom=ESMF_GeomCreate(locstream,rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - ! Do General Geom EmptyComp @\ - call ESMF_FieldEmptyCompGB##mrank##D##mtypekind(field, geom, farray, & @\ - indexflag=indexflag, datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ - ungriddedLBound=ungriddedLBound, & @\ - ungriddedUBound=ungriddedUBound, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - if (present(rc)) rc = ESMF_SUCCESS @\ - end subroutine ESMF_FieldEmptyCompLS##mrank##D##mtypekind @\ -!---------------------------------------------------------------------------- @\ - -TypeKindRankDeclarationMacro(FieldEmptyCompLS) - - -#define FieldEmptyCompLSPtrDoc() \ -!---------------------------------------------------------------------------- @\ -!BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from LocStream started with FieldEmptyCreate @\ -! @\ -! !INTERFACE: @\ -! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompLSPtr(field, locstream, & @\ -! farrayPtr, keywordEnforcer, datacopyflag, gridToFieldMap, rc) @\ -! @\ -! !ARGUMENTS: @\ -! type(ESMF_Field), intent(inout) :: field @\ -! type(ESMF_LocStream), intent(in) :: locstream @\ -! (ESMF_KIND_), pointer :: farrayPtr() @\ -!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ -! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! integer, intent(in), optional :: gridToFieldMap(:) @\ -! integer, intent(out), optional :: rc @\ +! type(ESMF_Field), intent(inou) :: field @\ +! type(ESMF_Geom), intent(in) :: geom @\ +! (ESMF_KIND_), dimension(), pointer :: farrayPtr @\ +! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ +! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(in), optional :: totalLWidth(:) @\ +! integer, intent(in), optional :: totalUWidth(:) @\ +! integer, intent(out), optional :: rc @\ ! @\ ! !DESCRIPTION: @\ ! This call completes an {\tt ESMF\_Field} allocated with the @\ -! {\tt ESMF\_FieldEmptyCreate()} call. @\ +! {\tt ESMF\_FieldEmptyCreate()} call. For an example and @\ +! associated documentation using this method see section @\ +! \ref{sec:field:usage:partial_creation}. @\ ! @\ -! \begin{sloppypar} @\ ! The Fortran data pointer inside {\tt ESMF\_Field} can be queried and deallocated when @\ ! datacopyflag is {\tt ESMF\_DATACOPY\_REFERENCE}. Note that the {\tt ESMF\_FieldDestroy} call does not deallocate @\ ! the Fortran data pointer in this case. This gives user more flexibility over memory management. @\ -! \end{sloppypar} @\ ! @\ ! The arguments are: @\ ! \begin{description} @\ @@ -2471,8 +2454,9 @@ TypeKindRankDeclarationMacro(FieldEmptyCompLS) ! The {\tt ESMF\_Field} object to be completed and @\ ! committed in this call. The {\tt field} will have the same dimension @\ ! (dimCount) as the rank of the {\tt farrayPtr}. @\ -! \item [locstream] @\ -! The {\tt ESMF\_LocStream} object to complete the Field. @\ +! \item [geom] @\ +! The {\tt ESMF\_Geom} object to complete the Field. The dimCount of the @\ +! Geom must be smaller than or equal to the rank of the {\tt farrayPtr}. @\ ! \item [farrayPtr] @\ ! Native Fortran data pointer to be copied/referenced in the {\tt field}. @\ ! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ @@ -2483,10 +2467,10 @@ TypeKindRankDeclarationMacro(FieldEmptyCompLS) ! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ ! \item [{[gridToFieldMap]}] @\ ! List with number of elements equal to the @\ -! {\tt locstream}|s dimCount. The list elements map each dimension @\ -! of the {\tt locstream} to a dimension in the {\tt farrayPtr} by @\ +! {\tt geom}|s dimCount. The list elements map each dimension @\ +! of the {\tt geom} to a dimension in the {\tt farrayPtr} by @\ ! specifying the appropriate {\tt farrayPtr} dimension index. The @\ -! default is to map all of the {\tt locstream}|s dimensions against the @\ +! default is to map all of the {\tt geom}|s dimensions against the @\ ! lowest dimensions of the {\tt farrayPtr} in sequence, i.e. @\ ! {\tt gridToFieldMap} = (/1,2,3,.../). @\ ! Unmapped {\tt farrayPtr} dimensions are undistributed Field @\ @@ -2494,11 +2478,27 @@ TypeKindRankDeclarationMacro(FieldEmptyCompLS) ! All {\tt gridToFieldMap} entries must be greater than or equal @\ ! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ ! to specify the same entry multiple times unless it is zero. @\ -! If the Field dimCount is less than the LocStream dimCount then the default @\ +! If the Field dimCount is less than the Grid dimCount then the default @\ ! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ ! entry in the {\tt gridToFieldMap} indicates that the particular @\ -! LocStream dimension will be replicating the Field across the DEs along @\ +! Grid dimension will be replicating the Field across the DEs along @\ ! this direction. @\ +! \item [{[totalLWidth]}] @\ +! Lower bound of halo region. The size of this array is the number @\ +! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ +! needs to be the same as they appear in the {\tt field}. Values default @\ +! to 0. If values for totalLWidth are specified they must be reflected in @\ +! the size of the {\tt field}. That is, for each gridded dimension the @\ +! {\tt field} size should be max( {\tt totalLWidth} + {\tt totalUWidth} @\ +! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ +! \item [{[totalUWidth]}] @\ +! Upper bound of halo region. The size of this array is the number @\ +! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ +! needs to be the same as they appear in the {\tt field}. Values default @\ +! to 0. If values for totalUWidth are specified they must be reflected in @\ +! the size of the {\tt field}. That is, for each gridded dimension the @\ +! {\tt field} size should max( {\tt totalLWidth} + {\tt totalUWidth} @\ +! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ ! \item [{[rc]}] @\ ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ ! \end{description} @\ @@ -2506,414 +2506,419 @@ TypeKindRankDeclarationMacro(FieldEmptyCompLS) !EOP @\ !---------------------------------------------------------------------------- @\ -#define FieldEmptyCompLSPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +#define FieldEmptyCompGBPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ !---------------------------------------------------------------------------- @\ ^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompLSPtr" @\ - subroutine ESMF_FieldEmptyCompLSPtr##mrank##D##mtypekind(field, & @\ - locstream, farrayPtr, keywordEnforcer, datacopyflag, gridToFieldMap, rc) @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompGBPtr" @\ +subroutine ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ + datacopyflag, gridToFieldMap, & @\ + totalLWidth, totalUWidth, rc) @\ @\ - ! input arguments @\ - type(ESMF_Field), intent(inout) :: field @\ - type(ESMF_LocStream), intent(in) :: locstream @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ -type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - integer, intent(in), optional :: gridToFieldMap(:) @\ - integer, intent(out), optional :: rc @\ - ! local variables @\ - integer :: localrc @\ - type(ESMF_Geom) :: geom @\ - type(ESMF_FieldStatus_Flag) :: status @\ + ! input arguments @\ + type(ESMF_Field), intent(inout) :: field @\ + type(ESMF_Geom), intent(in) :: geom @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + integer, intent(in), optional :: gridToFieldMap(:) @\ + integer, intent(in), optional :: totalLWidth(:) @\ + integer, intent(in), optional :: totalUWidth(:) @\ + integer, intent(out), optional :: rc @\ + ! local variables @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: fpointer @\ + integer :: localrc, i, j @\ + integer :: fieldDimCount, localDeCount @\ + integer :: memDimCount, gridDimCount, gridDimCount_norep @\ + integer :: grid_repdimcount @\ + integer :: elementCount @\ + integer :: distgridToArrayMap (ESMF_MAXDIM) @\ + integer :: undistLBound(ESMF_MAXDIM), undistUBound(ESMF_MAXDIM) @\ + integer :: localGridToFieldMap (ESMF_MAXDIM) @\ + integer :: localMaxHaloLWidth (ESMF_MAXDIM) @\ + integer :: localMaxHaloUWidth (ESMF_MAXDIM) @\ + integer :: localUngriddedLBound (ESMF_MAXDIM) @\ + integer :: localUngriddedUBound (ESMF_MAXDIM) @\ + integer :: distgridToGridMap(ESMF_MAXDIM) @\ + type(ESMF_Array) :: array @\ + type(ESMF_DistGrid) :: distgrid @\ + integer :: fieldUndistDimCount @\ + integer :: fieldUngriddedDimCount @\ + integer :: count @\ + logical :: flipflop(ESMF_MAXDIM) @\ + logical :: isGridded(ESMF_MAXDIM) @\ + type(ESMF_Index_Flag) :: indexflag @\ + logical :: found @\ + type(ESMF_GridDecompType) :: decompType @\ + type(ESMF_GeomType_Flag) :: geomtype @\ + type(ESMF_Grid) :: grid @\ + integer :: distgridDimCount, distgridDimCount_norep, arbdim @\ + character(len=ESMF_MAXSTR) :: fieldName @\ @\ - if (present(rc)) then @\ - rc = ESMF_RC_NOT_IMPL @\ - endif @\ - localrc = ESMF_RC_NOT_IMPL @\ -@\ - ! make sure field, locstream, farrayPtr are properly initialized @\ - ESMF_INIT_CHECK_DEEP_SHORT(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP_SHORT(ESMF_LocStreamGetInit,locstream,rc) @\ + if (present(rc)) then @\ + rc = ESMF_RC_NOT_IMPL @\ + endif @\ + localrc = ESMF_RC_NOT_IMPL @\ @\ - call ESMF_FieldGet(field, status=status, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! make sure field, grid, farrayPtr are properly initialized @\ + ESMF_INIT_CHECK_DEEP_SHORT(ESMF_FieldGetInit,field,rc) @\ + ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GeomGetInit,geom,rc) @\ @\ - if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ + ! get the fieldName @\ + call ESMF_FieldGet(field, name=fieldName, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - geom=ESMF_GeomCreate(locstream,rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! Get number of grid dimensions, number @\ + ! of distributed grid dimensions, distgrid, @\ + ! number of ungridded Field dimensions, @\ + ! and number of undistributed Field Dimensions @\ + call ESMF_GeomGet(geom, dimCount=gridDimCount, & @\ + distgridToGridMap=distgridToGridMap, localDeCount=localDeCount, & @\ + distgrid=distgrid, indexflag=indexflag, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - ! Do General Geom EmptyComp @\ - call ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ - datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ - rc=localrc) @\ + elementCount = 0 ! default to assuming no elements @\ + if (localDeCount==1) then @\ + call ESMF_DistGridGet(distgrid, localDe=0, elementCount=elementCount, & @\ + rc=localrc) @\ if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - if (present(rc)) rc = ESMF_SUCCESS @\ - end subroutine ESMF_FieldEmptyCompLSPtr##mrank##D##mtypekind @\ -!---------------------------------------------------------------------------- @\ - -TypeKindRankDeclarationMacro(FieldEmptyCompLSPtr) - - -#define FieldEmptyCompMeshDoc() \ -!---------------------------------------------------------------------------- @\ -!BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Mesh started with FieldEmptyCreate @\ -! @\ -! !INTERFACE: @\ -! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompMesh(field, mesh, & @\ -! farray, indexflag, keywordEnforcer, datacopyflag, meshloc, & @\ -! gridToFieldMap, ungriddedLBound, ungriddedUBound, rc) @\ -! @\ -! !ARGUMENTS: @\ -! type(ESMF_Field), intent(inout) :: field @\ -! type(ESMF_Mesh), intent(in) :: mesh @\ -! (ESMF_KIND_), intent(in), target :: farray() @\ -! type(ESMF_Index_Flag), intent(in) :: indexflag @\ -!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ -! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! type(ESMF_MeshLoc), intent(in), optional :: meshloc @\ -! integer, intent(in), optional :: gridToFieldMap(:) @\ -! integer, intent(in), optional :: ungriddedLBound(:) @\ -! integer, intent(in), optional :: ungriddedUBound(:) @\ -! integer, intent(out), optional :: rc @\ -! @\ -! !DESCRIPTION: @\ -! This call completes an {\tt ESMF\_Field} allocated with the @\ -! {\tt ESMF\_FieldEmptyCreate()} call. @\ -! @\ -! The Fortran data pointer inside {\tt ESMF\_Field} can be queried but deallocating @\ -! the retrieved data pointer is not allowed. @\ -! @\ -! The arguments are: @\ -! \begin{description} @\ -! \item [field] @\ -! The {\tt ESMF\_Field} object to be completed and @\ -! committed in this call. The {\tt field} will have the same dimension @\ -! (dimCount) as the rank of the {\tt farray}. @\ -! \item [mesh] @\ -! The {\tt ESMF\_Mesh} object to complete the Field. @\ -! \item [farray] @\ -! Native Fortran data array to be copied/referenced in the {\tt field}. @\ -! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ -! for the {\tt farray}. @\ -! \item [indexflag] @\ -! Indicate how DE-local indices are defined. See section @\ -! \ref{const:indexflag} for a list of valid indexflag options. @\ -! \item [{[datacopyflag]}] @\ -! Indicates whether to copy the {\tt farray} or reference it directly. @\ -! For valid values see \ref{const:datacopyflag}. The default is @\ -! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ -! \item [{[meshloc]}] @\ -! \begin{sloppypar} @\ -! Which part of the mesh to build the Field on. Can be set to either @\ -! {\tt ESMF\_MESHLOC\_NODE} or {\tt ESMF\_MESHLOC\_ELEMENT}. If not set, @\ -! defaults to {\tt ESMF\_MESHLOC\_NODE}. @\ -! \end{sloppypar} @\ -! \item [{[gridToFieldMap]}] @\ -! List with number of elements equal to the @\ -! {\tt mesh}|s dimCount. The list elements map each dimension @\ -! of the {\tt mesh} to a dimension in the {\tt farray} by @\ -! specifying the appropriate {\tt farray} dimension index. The @\ -! default is to map all of the {\tt mesh}|s dimensions against the @\ -! lowest dimensions of the {\tt farray} in sequence, i.e. @\ -! {\tt gridToFieldMap} = (/1,2,3,.../). @\ -! Unmapped {\tt farray} dimensions are undistributed Field @\ -! dimensions. @\ -! All {\tt gridToFieldMap} entries must be greater than or equal @\ -! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ -! to specify the same entry multiple times unless it is zero. @\ -! If the Field dimCount is less than the Mesh dimCount then the default @\ -! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ -! entry in the {\tt gridToFieldMap} indicates that the particular @\ -! Mesh dimension will be replicating the Field across the DEs along @\ -! this direction. @\ -! \item [{[ungriddedLBound]}] @\ -! Lower bounds of the ungridded dimensions of the {\tt field}. @\ -! The number of elements in the {\tt ungriddedLBound} is equal to the number of ungridded @\ -! dimensions in the {\tt field}. All ungridded dimensions of the @\ -! {\tt field} are also undistributed. When field dimension count is @\ -! greater than Mesh dimension count, both ungriddedLBound and ungriddedUBound @\ -! must be specified. When both are specified the values are checked @\ -! for consistency. Note that the the ordering of @\ -! these ungridded dimensions is the same as their order in the {\tt field}. @\ -! \item [{[ungriddedUBound]}] @\ -! Upper bounds of the ungridded dimensions of the {\tt field}. @\ -! The number of elements in the {\tt ungriddedUBound} is equal to the number of ungridded @\ -! dimensions in the {\tt field}. All ungridded dimensions of the @\ -! {\tt field} are also undistributed. When field dimension count is @\ -! greater than Mesh dimension count, both ungriddedLBound and ungriddedUBound @\ -! must be specified. When both are specified the values are checked @\ -! for consistency. Note that the the ordering of @\ -! these ungridded dimensions is the same as their order in the {\tt field}. @\ -! \item [{[rc]}] @\ -! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ -! \end{description} @\ -! @\ -!EOP @\ -!---------------------------------------------------------------------------- @\ - -#define FieldEmptyCompMeshMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ -!---------------------------------------------------------------------------- @\ -^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompMesh" @\ - subroutine ESMF_FieldEmptyCompMesh##mrank##D##mtypekind(field, mesh, farray, & @\ - indexflag, keywordEnforcer, datacopyflag, meshloc, gridToFieldMap, & @\ - ungriddedLBound, ungriddedUBound, rc) @\ -@\ - ! input arguments @\ - type(ESMF_Field), intent(inout) :: field @\ - type(ESMF_Mesh), intent(in) :: mesh @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), target :: farray @\ - type(ESMF_Index_Flag), intent(in) :: indexflag @\ -type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - type(ESMF_MeshLoc), intent(in), optional :: meshloc @\ - integer, intent(in), optional :: gridToFieldMap(:) @\ - integer, intent(in), optional :: ungriddedLBound(:) @\ - integer, intent(in), optional :: ungriddedUBound(:) @\ - integer, intent(out), optional :: rc @\ - ! local variables @\ - integer :: localrc @\ - type(ESMF_Geom) :: geom @\ - type(ESMF_FieldStatus_Flag) :: status @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + elseif (localDeCount>1) then @\ + !TODO: error out because not supported @\ + endif @\ @\ - if (present(rc)) then @\ - rc = ESMF_RC_NOT_IMPL @\ + if (elementCount > 0) then @\ + ! The following use of fptr is a bit of trickery to get all F90 @\ + ! compilers to cooperate. For some compilers the associated() test @\ + ! will return .false. for farray of size 0. Some of those compilers @\ + ! will produce a run-time error in size(fptr). Other compilers will @\ + ! return .true. for the associated() test but return 0 in size(). @\ + fpointer => farrayPtr @\ + if(.not. associated(fpointer,farrayPtr)) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & @\ + msg="- farrayPtr is not associated with memory allocation)", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ endif @\ - localrc = ESMF_RC_NOT_IMPL @\ -@\ - ! make sure field, mesh, farray are properly initialized @\ - ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP(ESMF_MeshGetInit,mesh,rc) @\ -@\ - call ESMF_FieldGet(field, status=status, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ + if (size(fpointer)==0) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & @\ + msg="- farrayPtr is not associated with memory allocation)", & @\ ESMF_CONTEXT, rcToReturn=rc) @\ return @\ endif @\ + endif @\ + ! Check if geom is a grid, if so, check if it is arbitrary @\ + decompType = ESMF_GRID_NONARBITRARY @\ + call ESMF_GeomGet(geom, geomtype=geomtype, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - geom=ESMF_GeomCreate(mesh, meshLoc=meshloc, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - ! Do General Geom EmptyComp @\ - call ESMF_FieldEmptyCompGB##mrank##D##mtypekind(field, geom, farray, & @\ - indexflag=indexflag, datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ - ungriddedLBound=ungriddedLBound, & @\ - ungriddedUBound=ungriddedUBound, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ + if (geomtype .eq. ESMF_GEOMTYPE_GRID) then @\ + call ESMF_GeomGet(geom, grid=grid, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + call ESMF_GridGetDecompType(grid, decompType, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + endif @\ @\ - if (present(rc)) rc = ESMF_SUCCESS @\ - end subroutine ESMF_FieldEmptyCompMesh##mrank##D##mtypekind @\ -!---------------------------------------------------------------------------- @\ - -TypeKindRankDeclarationMacro(FieldEmptyCompMesh) - - -#define FieldEmptyCompMeshPtrDoc() \ -!---------------------------------------------------------------------------- @\ -!BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Mesh started with FieldEmptyCreate @\ -! @\ -! !INTERFACE: @\ -! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompMeshPtr(field, mesh, & @\ -! farrayPtr, keywordEnforcer, datacopyflag, meshloc, gridToFieldMap, rc) @\ -! @\ -! !ARGUMENTS: @\ -! type(ESMF_Field), intent(inout) :: field @\ -! type(ESMF_Mesh), intent(in) :: mesh @\ -! (ESMF_KIND_), pointer :: farrayPtr() @\ -!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ -! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! type(ESMF_MeshLoc), intent(in), optional :: meshloc @\ -! integer, intent(in), optional :: gridToFieldMap(:) @\ -! integer, intent(out), optional :: rc @\ -! @\ -! !DESCRIPTION: @\ -! This call completes an {\tt ESMF\_Field} allocated with the @\ -! {\tt ESMF\_FieldEmptyCreate()} call. @\ -! @\ -! \begin{sloppypar} @\ -! The Fortran data pointer inside {\tt ESMF\_Field} can be queried and deallocated when @\ -! datacopyflag is {\tt ESMF\_DATACOPY\_REFERENCE}. Note that the {\tt ESMF\_FieldDestroy} call does not deallocate @\ -! the Fortran data pointer in this case. This gives user more flexibility over memory management. @\ -! \end{sloppypar} @\ -! @\ -! The arguments are: @\ -! \begin{description} @\ -! \item [field] @\ -! The {\tt ESMF\_Field} object to be completed and @\ -! committed in this call. The {\tt field} will have the same dimension @\ -! (dimCount) as the rank of the {\tt farrayPtr}. @\ -! \item [mesh] @\ -! The {\tt ESMF\_Mesh} object to complete the Field. @\ -! \item [farrayPtr] @\ -! Native Fortran data pointer to be copied/referenced in the {\tt field}. @\ -! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ -! for the {\tt farrayPtr}. @\ -! \item [{[datacopyflag]}] @\ -! Indicates whether to copy the {\tt farrayPtr} or reference it directly. @\ -! For valid values see \ref{const:datacopyflag}. The default is @\ -! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ -! \item [{[meshloc]}] @\ -! \begin{sloppypar} @\ -! Which part of the mesh to build the Field on. Can be set to either @\ -! {\tt ESMF\_MESHLOC\_NODE} or {\tt ESMF\_MESHLOC\_ELEMENT}. If not set, @\ -! defaults to {\tt ESMF\_MESHLOC\_NODE}. @\ -! \end{sloppypar} @\ -! \item [{[gridToFieldMap]}] @\ -! List with number of elements equal to the @\ -! {\tt mesh}|s dimCount. The list elements map each dimension @\ -! of the {\tt mesh} to a dimension in the {\tt farrayPtr} by @\ -! specifying the appropriate {\tt farrayPtr} dimension index. The @\ -! default is to map all of the {\tt mesh}|s dimensions against the @\ -! lowest dimensions of the {\tt farrayPtr} in sequence, i.e. @\ -! {\tt gridToFieldMap} = (/1,2,3,.../). @\ -! Unmapped {\tt farrayPtr} dimensions are undistributed Field @\ -! dimensions. @\ -! All {\tt gridToFieldMap} entries must be greater than or equal @\ -! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ -! to specify the same entry multiple times unless it is zero. @\ -! If the Field dimCount is less than the Mesh dimCount then the default @\ -! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ -! entry in the {\tt gridToFieldMap} indicates that the particular @\ -! Mesh dimension will be replicating the Field across the DEs along @\ -! this direction. @\ -! \item [{[rc]}] @\ -! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ -! \end{description} @\ -! @\ -!EOP @\ -!---------------------------------------------------------------------------- @\ - -#define FieldEmptyCompMeshPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ -!---------------------------------------------------------------------------- @\ -^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompMeshPtr" @\ - subroutine ESMF_FieldEmptyCompMeshPtr##mrank##D##mtypekind(field, mesh, & @\ - farrayPtr, keywordEnforcer, datacopyflag, meshloc, gridToFieldMap, rc) @\ -@\ - ! input arguments @\ - type(ESMF_Field), intent(inout) :: field @\ - type(ESMF_Mesh), intent(in) :: mesh @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ -type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - type(ESMF_MeshLoc), intent(in), optional :: meshloc @\ - integer, intent(in), optional :: gridToFieldMap(:) @\ - integer, intent(out), optional :: rc @\ - ! local variables @\ - integer :: localrc @\ - type(ESMF_Geom) :: geom @\ - type(ESMF_FieldStatus_Flag) :: status @\ + ! Error Check Input @\ + ! And count the number of replicated dimensions in the Grid @\ + grid_repdimcount = 0 @\ + if (present(gridToFieldMap)) then @\ + if (size(gridToFieldMap) .ne. gridDimCount) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- gridToFieldMap size must equal to grid_rank", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + do i = 1, gridDimCount @\ + if(gridToFieldMap(i) == 0) grid_repdimcount = grid_repdimcount + 1 @\ + enddo @\ + endif @\ + gridDimCount_norep = gridDimCount - grid_repdimcount @\ + if (present(gridToFieldMap)) then @\ + localGridToFieldMap(1:gridDimCount) = & @\ + gridToFieldMap (1:gridDimCount) @\ + else @\ + do i = 1, gridDimCount @\ + localGridToFieldMap(i) = i @\ + enddo @\ + endif @\ @\ - if (present(rc)) then @\ - rc = ESMF_RC_NOT_IMPL @\ - endif @\ - localrc = ESMF_RC_NOT_IMPL @\ + ! Check the size of the native array. @\ + memDimCount = mrank @\ @\ - ! make sure field, mesh, farrayPtr are properly initialized @\ - ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP(ESMF_MeshGetInit,mesh,rc) @\ + if (decompType .eq. ESMF_GRID_NONARBITRARY) then @\ + fieldDimCount = memDimCount @\ + else @\ + call ESMF_GridGet(grid, distgridToGridMap=distgridToGridMap, & @\ + rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! find out how many grid dimensions are arbitrarily distributed and calculate @\ + ! fieldDimCount accordingly @\ + arbdim = 0 @\ + do i=1,gridDimCount @\ + if (distgridToGridMap(i) .ne. 0) arbdim = arbdim+1 @\ + enddo @\ + fieldDimCount = memDimCount + arbdim - 1 @\ @\ - call ESMF_FieldGet(field, status=status, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! If there is any replicated dimension, check if any of the arb. dimensions are replicated. @\ + ! If one arb dimension is replicated, all the arb. dimensions have to be replicated @\ + if (grid_repdimcount .ne. 0) then @\ + do i = 1,gridDimCount @\ + if(localGridToFieldMap(i) == 0) then @\ + found = .false. @\ + do j=1,arbdim @\ + if (distgridToGridMap(j) .eq. i) found = .true. @\ + enddo @\ + if (found) then @\ + ! one arb.dimension is a replicated dimension, check if other arb dimensions are @\ + ! also replicated @\ + do j=1,arbdim @\ + if (distgridToGridMap(j) .ne. i) then @\ + if (localGridToFieldMap(distgridToGridMap(j)) .ne. 0) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- Arb. grid dimensions have to be either all replicated or not replicated", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ + enddo @\ + ! all arb. dimension are replication, jump out of the first do loop @\ + ! fieldDimCount should be the same as the memDimCount @\ + fieldDimCount = memDimCount @\ + exit @\ + endif @\ + endif @\ + enddo @\ + endif @\ + endif @\ @\ - if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ + if(fieldDimCount .lt. gridDimCount_norep) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- farrayPtr rank must be greater than or equal to grid rank", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ return @\ - endif @\ + endif @\ @\ - geom=ESMF_GeomCreate(mesh, meshLoc=meshloc, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! ungridded dimensions plus replicated dimensions @\ + fieldUngriddedDimCount = fieldDimCount-gridDimCount + grid_repdimcount @\ + fieldUndistDimCount = fieldDimCount-gridDimCount + grid_repdimcount @\ @\ - ! Do General Geom EmptyComp @\ - call ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ - datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ - rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + if (present(totalLWidth)) then @\ + if (size(totalLWidth) .ne. gridDimCount_norep) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- totalLWidth must equal to gridded dimCount", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ @\ - if (present(rc)) rc = ESMF_SUCCESS @\ - end subroutine ESMF_FieldEmptyCompMeshPtr##mrank##D##mtypekind @\ -!---------------------------------------------------------------------------- @\ - -TypeKindRankDeclarationMacro(FieldEmptyCompMeshPtr) - -! XGrid -#define FieldEmptyCompXGDoc() \ -!---------------------------------------------------------------------------- @\ -!BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from XGrid started with FieldEmptyCreate @\ -! @\ -! !INTERFACE: @\ -! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompXG(field, xgrid, & @\ -! farray, indexflag, keywordEnforcer, datacopyflag, xgridside, gridindex, & @\ -! gridToFieldMap, & @\ -! ungriddedLBound, ungriddedUBound, rc) @\ -! @\ -! !ARGUMENTS: @\ -! type(ESMF_Field), intent(inout) :: field @\ -! type(ESMF_XGrid), intent(in) :: xgrid @\ -! (ESMF_KIND_), intent(in), target :: farray() @\ -! type(ESMF_Index_Flag), intent(in) :: indexflag @\ -!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ -! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside @\ -! integer, intent(in), optional :: gridindex @\ -! integer, intent(in), optional :: gridToFieldMap(:) @\ -! integer, intent(in), optional :: ungriddedLBound(:) @\ -! integer, intent(in), optional :: ungriddedUBound(:) @\ -! integer, intent(out), optional :: rc @\ -! @\ -! !DESCRIPTION: @\ -! This call completes an {\tt ESMF\_Field} allocated with the @\ -! {\tt ESMF\_FieldEmptyCreate()} call. @\ -! @\ -! The Fortran data pointer inside {\tt ESMF\_Field} can be queried but deallocating @\ -! the retrieved data pointer is not allowed. @\ -! @\ -! The arguments are: @\ -! \begin{description} @\ -! \item [field] @\ -! The {\tt ESMF\_Field} object to be completed and @\ -! committed in this call. The {\tt field} will have the same dimension @\ -! (dimCount) as the rank of the {\tt farray}. @\ -! \item [xgrid] @\ -! The {\tt ESMF\_XGrid} object to complete the Field. @\ + if (present(totalUWidth)) then @\ + if (size(totalUWidth) .ne. gridDimCount_norep) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ + msg="- totalUWidth must equal to gridded dimCount", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ +@\ + ! gridToFieldMap elements must be in range 0...fieldRank and unique @\ + ! algorithm to check element uniqueness: @\ + ! run time: O(ESMF_MAXDIM) @\ + ! memory: O(2*ESMF_MAXDIM) @\ + ! or O(ESMF_MAXDIM+ESMF_MAXDIM/sizeof(integer)) with bitvector @\ + flipflop = .false. @\ + do i = 1, gridDimCount @\ + if(localGridToFieldMap(i) .lt. 0 .or. & @\ + localGridToFieldMap(i) .gt. fieldDimCount) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ + msg="- gridToFieldMap element must be within range 0...array rank", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + if(localGridToFieldMap(i) /= 0) then @\ + if(flipflop(localGridToFieldMap(i))) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ + msg="- gridToFieldMap element must be unique", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + flipflop(localGridToFieldMap(i)) = .true. @\ + endif @\ + enddo @\ +@\ + if(present(totalLWidth)) then @\ + localMaxHaloLWidth(1:gridDimCount_norep) = & @\ + totalLWidth (1:gridDimCount_norep) @\ + else @\ + localMaxHaloLWidth = 0 @\ + endif @\ +@\ + if(present(totalUWidth)) then @\ + localMaxHaloUWidth(1:gridDimCount_norep) = & @\ + totalUWidth (1:gridDimCount_norep) @\ + else @\ + localMaxHaloUWidth = 0 @\ + endif @\ +@\ + ! Here we get the lbounds and ubounds for ungridded @\ + ! dimensions from the native array, if it is not input @\ + ! through the argument list. First we need to set up @\ + ! an index array that holds the ungridded dimensions of @\ + ! the native array. @\ +@\ + ! Since we are saving the ungriddedIndex calculate it even @\ + ! if ungridded bounds are present @\ +@\ + ! Figure out which dims are ungridded @\ + isGridded = .false. @\ + do i=1, gridDimCount @\ + if(localGridToFieldMap(i) /= 0) isGridded(localGridToFieldMap(i)) = .true. @\ + enddo @\ +@\ + ! Use ungridded info to figure out the map from ungridded to field dims @\ + count=1 @\ + do i=1,fieldDimCount @\ + if (.not. isGridded(i)) then @\ + localUngriddedLBound(count) = lbound(farrayPtr, i) @\ + localUngriddedUBound(count) = ubound(farrayPtr, i) @\ + count=count+1 @\ + endif @\ + enddo @\ +@\ + call ESMF_DistGridGet(distgrid, dimCount=distgridDimCount, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + distgridDimCount_norep = memDimCount - fieldUndistDimCount @\ +@\ + ! The undistributed info from the Grid needs to be @\ + ! combined with the ungridded info from the Field in order @\ + ! to create the Array for the Field. @\ + call ESMF_GeomGetArrayInfo(geom, & @\ + gridToFieldMap=localGridToFieldMap, & @\ + ungriddedLBound=localUngriddedLBound (1:fieldUngriddedDimCount), & @\ + ungriddedUBound=localUngriddedUBound (1:fieldUngriddedDimCount), & @\ + distgridToArrayMap=distgridToArrayMap, & @\ + undistLBound=undistLBound, undistUBound=undistUBound, & @\ + rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ +@\ + ! Create Array with undistributed dimensions @\ + if (decompType .eq. ESMF_GRID_NONARBITRARY) then @\ + array = ESMF_ArrayCreate(distgrid, farrayPtr, datacopyflag=datacopyflag, & @\ + distgridToArrayMap=distgridToArrayMap (1:distgridDimCount), & @\ + totalLWidth=localMaxHaloLWidth(1:gridDimCount_norep), & @\ + totalUWidth=localMaxHaloUWidth(1:gridDimCount_norep), & @\ + name=fieldName, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + else @\ + array = ESMF_ArrayCreate(distgrid, farrayPtr, datacopyflag=datacopyflag, & @\ + distgridToArrayMap=distgridToArrayMap (1:distgridDimCount), & @\ + name=fieldName, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + endif @\ +@\ + field%ftypep%array = array @\ +@\ + ! set array_internal to .true. because field%array is internal @\ + field%ftypep%array_internal = .true. @\ +@\ + ! Should call a common FieldEmptyCompPtrConstructor here instead @\ + ! of just setting things up ourselves @\ + ! (The field Sets were all moved here in preparation for this) @\ + field%ftypep%gridToFieldMap(1:gridDimCount) = & @\ + localGridToFieldMap(1:gridDimCount) @\ + field%ftypep%totalLWidth(1:gridDimCount_norep) = & @\ + localMaxHaloLWidth (1:gridDimCount_norep) @\ + field%ftypep%totalUWidth(1:gridDimCount_norep) = & @\ + localMaxHaloUWidth (1:gridDimCount_norep) @\ + field%ftypep%ungriddedLBound(1:fieldUngriddedDimCount) = & @\ + localUngriddedLBound(1:fieldUngriddedDimCount) @\ + field%ftypep%ungriddedUBound(1:fieldUngriddedDimCount) = & @\ + localUngriddedUBound(1:fieldUngriddedDimCount) @\ + field%ftypep%geom = geom @\ + field%ftypep%status = ESMF_FIELDSTATUS_COMPLETE @\ + call ESMF_BaseSetStatus(field%ftypep%base, ESMF_STATUS_READY, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ + field%ftypep%dimCount = gridDimCount_norep + fieldUndistDimCount @\ +@\ + call ESMF_FieldValidate(field, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ +@\ + if (present(rc)) rc = ESMF_SUCCESS @\ +end subroutine ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind @\ +!---------------------------------------------------------------------------- @\ + +TypeKindRankDeclarationMacro(FieldEmptyCompGBPtr) + + +#define FieldEmptyCompGridDoc() \ +!---------------------------------------------------------------------------- @\ +!BOP @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Grid started with FieldEmptyCreate @\ +! @\ +! !INTERFACE: @\ +! ! Private name; call using ESMF_FieldEmptyComplete() @\ +! subroutine ESMF_FieldEmptyCompGrid(field, grid, & @\ +! farray, indexflag, keywordEnforcer, datacopyflag, staggerloc, gridToFieldMap, & @\ +! ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, rc) @\ +! @\ +! !ARGUMENTS: @\ +! type(ESMF_Field), intent(inout) :: field @\ +! type(ESMF_Grid), intent(in) :: grid @\ +! (ESMF_KIND_),intent(in), target :: farray() @\ +! type(ESMF_Index_Flag), intent(in) :: indexflag @\ +!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ +! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ +! type(ESMF_STAGGERLOC), intent(in), optional :: staggerloc @\ +! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(in), optional :: ungriddedLBound(:) @\ +! integer, intent(in), optional :: ungriddedUBound(:) @\ +! integer, intent(in), optional :: totalLWidth(:) @\ +! integer, intent(in), optional :: totalUWidth(:) @\ +! integer, intent(out), optional :: rc @\ +! @\ +! !STATUS: @\ +! \begin{itemize} @\ +! \item\apiStatusCompatibleVersion{5.2.0r} @\ +! \end{itemize} @\ +! @\ +! !DESCRIPTION: @\ +! This call completes an {\tt ESMF\_Field} allocated with the @\ +! {\tt ESMF\_FieldEmptyCreate()} call. @\ +! @\ +! The Fortran data pointer inside {\tt ESMF\_Field} can be queried but deallocating @\ +! the retrieved data pointer is not allowed. @\ +! @\ +! The arguments are: @\ +! \begin{description} @\ +! \item [field] @\ +! The {\tt ESMF\_Field} object to be completed and @\ +! committed in this call. The {\tt field} will have the same dimension @\ +! (dimCount) as the rank of the {\tt farray}. @\ +! \item [grid] @\ +! The {\tt ESMF\_Grid} object to complete the Field. @\ ! \item [farray] @\ ! Native Fortran data array to be copied/referenced in the {\tt field}. @\ ! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ @@ -2925,19 +2930,18 @@ TypeKindRankDeclarationMacro(FieldEmptyCompMeshPtr) ! Indicates whether to copy the {\tt farray} or reference it directly. @\ ! For valid values see \ref{const:datacopyflag}. The default is @\ ! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ -! \item [{[xgridside]}] @\ -! Which side of the XGrid to create the Field on (either ESMF\_XGRIDSIDE\_A, @\ -! ESMF\_XGRIDSIDE\_B, or ESMF\_XGRIDSIDE\_BALANCED). If not passed in then @\ -! defaults to ESMF\_XGRIDSIDE\_BALANCED. @\ -! \item [{[gridindex]}] @\ -! If xgridSide is ESMF\_XGRIDSIDE\_A or ESMF\_XGRIDSIDE\_B then this index tells which Grid on @\ -! that side to create the Field on. If not provided, defaults to 1. @\ +! \item [{[staggerloc]}] @\ +! Stagger location of data in grid cells. For valid @\ +! predefined values see section \ref{const:staggerloc}. @\ +! To create a custom stagger location see section @\ +! \ref{sec:usage:staggerloc:adv}. The default @\ +! value is {\tt ESMF\_STAGGERLOC\_CENTER}. @\ ! \item [{[gridToFieldMap]}] @\ ! List with number of elements equal to the @\ -! {\tt xgrid}|s dimCount. The list elements map each dimension @\ -! of the {\tt xgrid} to a dimension in the {\tt farray} by @\ +! {\tt grid}|s dimCount. The list elements map each dimension @\ +! of the {\tt grid} to a dimension in the {\tt farray} by @\ ! specifying the appropriate {\tt farray} dimension index. The @\ -! default is to map all of the {\tt xgrid}|s dimensions against the @\ +! default is to map all of the {\tt grid}|s dimensions against the @\ ! lowest dimensions of the {\tt farray} in sequence, i.e. @\ ! {\tt gridToFieldMap} = (/1,2,3,.../). @\ ! Unmapped {\tt farray} dimensions are undistributed Field @\ @@ -2945,17 +2949,17 @@ TypeKindRankDeclarationMacro(FieldEmptyCompMeshPtr) ! All {\tt gridToFieldMap} entries must be greater than or equal @\ ! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ ! to specify the same entry multiple times unless it is zero. @\ -! If the Field dimCount is less than the XGrid dimCount then the default @\ +! If the Field dimCount is less than the Grid dimCount then the default @\ ! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ ! entry in the {\tt gridToFieldMap} indicates that the particular @\ -! XGrid dimension will be replicating the Field across the DEs along @\ +! Grid dimension will be replicating the Field across the DEs along @\ ! this direction. @\ ! \item [{[ungriddedLBound]}] @\ ! Lower bounds of the ungridded dimensions of the {\tt field}. @\ ! The number of elements in the {\tt ungriddedLBound} is equal to the number of ungridded @\ ! dimensions in the {\tt field}. All ungridded dimensions of the @\ ! {\tt field} are also undistributed. When field dimension count is @\ -! greater than XGrid dimension count, both ungriddedLBound and ungriddedUBound @\ +! greater than grid dimension count, both ungriddedLBound and ungriddedUBound @\ ! must be specified. When both are specified the values are checked @\ ! for consistency. Note that the the ordering of @\ ! these ungridded dimensions is the same as their order in the {\tt field}. @\ @@ -2964,10 +2968,26 @@ TypeKindRankDeclarationMacro(FieldEmptyCompMeshPtr) ! The number of elements in the {\tt ungriddedUBound} is equal to the number of ungridded @\ ! dimensions in the {\tt field}. All ungridded dimensions of the @\ ! {\tt field} are also undistributed. When field dimension count is @\ -! greater than XGrid dimension count, both ungriddedLBound and ungriddedUBound @\ +! greater than grid dimension count, both ungriddedLBound and ungriddedUBound @\ ! must be specified. When both are specified the values are checked @\ ! for consistency. Note that the the ordering of @\ ! these ungridded dimensions is the same as their order in the {\tt field}. @\ +! \item [{[totalLWidth]}] @\ +! Lower bound of halo region. The size of this array is the number @\ +! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ +! needs to be the same as they appear in the {\tt field}. Values default @\ +! to 0. If values for totalLWidth are specified they must be reflected in @\ +! the size of the {\tt field}. That is, for each gridded dimension the @\ +! {\tt field} size should be max( {\tt totalLWidth} + {\tt totalUWidth} @\ +! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ +! \item [{[totalUWidth]}] @\ +! Upper bound of halo region. The size of this array is the number @\ +! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ +! needs to be the same as they appear in the {\tt field}. Values default @\ +! to 0. If values for totalUWidth are specified they must be reflected in @\ +! the size of the {\tt field}. That is, for each gridded dimension the @\ +! {\tt field} size should max( {\tt totalLWidth} + {\tt totalUWidth} @\ +! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ ! \item [{[rc]}] @\ ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ ! \end{description} @\ @@ -2975,41 +2995,43 @@ TypeKindRankDeclarationMacro(FieldEmptyCompMeshPtr) !EOP @\ !---------------------------------------------------------------------------- @\ -#define FieldEmptyCompXGMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +#define FieldEmptyCompGridMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ !---------------------------------------------------------------------------- @\ ^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompXG" @\ - subroutine ESMF_FieldEmptyCompXG##mrank##D##mtypekind(field, xgrid, & @\ - farray, indexflag, keywordEnforcer, datacopyflag, xgridside, gridindex, & @\ - gridToFieldMap, ungriddedLBound, & @\ - ungriddedUBound, rc) @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompGrid" @\ + subroutine ESMF_FieldEmptyCompGrid##mrank##D##mtypekind(field, grid, farray, & @\ + indexflag, keywordEnforcer, datacopyflag, staggerloc, gridToFieldMap, & @\ + ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, rc) @\ @\ ! input arguments @\ type(ESMF_Field), intent(inout) :: field @\ - type(ESMF_XGrid), intent(in) :: xgrid @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), target :: farray @\ - type(ESMF_Index_Flag), intent(in) :: indexflag @\ -type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - type(ESMF_XGridSide_Flag), intent(in), optional :: xgridSide @\ - integer, intent(in), optional :: gridIndex @\ + type(ESMF_Grid), intent(in) :: grid @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), intent(in), target :: farray @\ + type(ESMF_Index_Flag), intent(in) :: indexflag @\ +type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + type(ESMF_StaggerLoc), intent(in), optional ::staggerloc @\ integer, intent(in), optional :: gridToFieldMap(:) @\ integer, intent(in), optional :: ungriddedLBound(:) @\ integer, intent(in), optional :: ungriddedUBound(:) @\ + integer, intent(in), optional :: totalLWidth(:) @\ + integer, intent(in), optional :: totalUWidth(:) @\ integer, intent(out), optional :: rc @\ ! local variables @\ + type(ESMF_StaggerLoc) :: localStaggerLoc @\ integer :: localrc @\ type(ESMF_Geom) :: geom @\ - type(ESMF_FieldStatus_Flag) :: status @\ + type(ESMF_GridDecompType) :: decompType @\ + type(ESMF_FieldStatus_Flag) :: status @\ @\ if (present(rc)) then @\ rc = ESMF_RC_NOT_IMPL @\ endif @\ localrc = ESMF_RC_NOT_IMPL @\ @\ - ! make sure field, xgrid, farray are properly initialized @\ + ! make sure field, grid, farray are properly initialized @\ ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP(ESMF_XGridGetInit,xgrid,rc) @\ + ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit,grid,rc) @\ @\ call ESMF_FieldGet(field, status=status, rc=localrc) @\ if (ESMF_LogFoundError(localrc, & @\ @@ -3023,50 +3045,83 @@ type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below return @\ endif @\ @\ - geom=ESMF_GeomCreate(xgrid,xgridSide, gridIndex, rc=localrc) @\ + call ESMF_GridGetDecompType(grid, decompType, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ +@\ + if (decompType .eq. ESMF_GRID_ARBITRARY) then @\ + if ((present(totalLWidth)) .or. (present(totalUWidth))) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- indexflag, totalLWidth or totalUWidth are not allowed for arbitrary grid", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ +@\ + ! Set default values. @\ + if (present(staggerloc)) then @\ + if ((decompType .eq. ESMF_GRID_ARBITRARY) .and. & @\ + (staggerloc .ne. ESMF_STAGGERLOC_CENTER)) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + else @\ + localStaggerloc=staggerloc @\ + endif @\ + else @\ + localStaggerLoc = ESMF_STAGGERLOC_CENTER @\ + endif @\ +@\ + geom=ESMF_GeomCreate(grid, localStaggerloc, rc=localrc) @\ if (ESMF_LogFoundError(localrc, & @\ ESMF_ERR_PASSTHRU, & @\ ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ ! Do General Geom EmptyComp @\ call ESMF_FieldEmptyCompGB##mrank##D##mtypekind(field, geom, farray, & @\ - indexflag=indexflag, datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ - ungriddedLBound=ungriddedLBound, & @\ - ungriddedUBound=ungriddedUBound, rc=localrc) @\ + indexflag, datacopyflag, gridToFieldMap, ungriddedLBound, & @\ + ungriddedUBound, totalLWidth, totalUWidth, rc=localrc) @\ if (ESMF_LogFoundError(localrc, & @\ ESMF_ERR_PASSTHRU, & @\ ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ @\ if (present(rc)) rc = ESMF_SUCCESS @\ - end subroutine ESMF_FieldEmptyCompXG##mrank##D##mtypekind @\ + end subroutine ESMF_FieldEmptyCompGrid##mrank##D##mtypekind @\ !---------------------------------------------------------------------------- @\ -TypeKindRankDeclarationMacro(FieldEmptyCompXG) +TypeKindRankDeclarationMacro(FieldEmptyCompGrid) -#define FieldEmptyCompXGPtrDoc() \ +#define FieldEmptyCompGridPtrDoc() \ !---------------------------------------------------------------------------- @\ !BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from XGrid started with FieldEmptyCreate @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Grid started with FieldEmptyCreate @\ ! @\ ! !INTERFACE: @\ ! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompXGPtr(field, xgrid, & @\ -! farrayPtr, xgridside, gridindex, & @\ -! keywordEnforcer, datacopyflag, gridToFieldMap, rc) @\ +! subroutine ESMF_FieldEmptyCompGridPtr(field, grid, & @\ +! farrayPtr, keywordEnforcer, datacopyflag, staggerloc, gridToFieldMap, & @\ +! totalLWidth, totalUWidth, rc) @\ ! @\ ! !ARGUMENTS: @\ ! type(ESMF_Field), intent(inout) :: field @\ -! type(ESMF_XGrid), intent(in) :: xgrid @\ +! type(ESMF_Grid), intent(in) :: grid @\ ! (ESMF_KIND_), pointer :: farrayPtr() @\ !type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ ! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside @\ -! integer, intent(in), optional :: gridindex @\ +! type(ESMF_STAGGERLOC), intent(in), optional :: staggerloc @\ ! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(in), optional :: totalLWidth(:) @\ +! integer, intent(in), optional :: totalUWidth(:) @\ ! integer, intent(out), optional :: rc @\ ! @\ +! !STATUS: @\ +! \begin{itemize} @\ +! \item\apiStatusCompatibleVersion{5.2.0r} @\ +! \end{itemize} @\ +! @\ ! !DESCRIPTION: @\ ! This call completes an {\tt ESMF\_Field} allocated with the @\ ! {\tt ESMF\_FieldEmptyCreate()} call. @\ @@ -3076,6 +3131,7 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXG) ! datacopyflag is {\tt ESMF\_DATACOPY\_REFERENCE}. Note that the {\tt ESMF\_FieldDestroy} call does not deallocate @\ ! the Fortran data pointer in this case. This gives user more flexibility over memory management. @\ ! \end{sloppypar} @\ +! The Fortran data pointer inside {\tt ESMF\_Field} can be queried and deallocated when @\ ! @\ ! The arguments are: @\ ! \begin{description} @\ @@ -3083,8 +3139,8 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXG) ! The {\tt ESMF\_Field} object to be completed and @\ ! committed in this call. The {\tt field} will have the same dimension @\ ! (dimCount) as the rank of the {\tt farrayPtr}. @\ -! \item [xgrid] @\ -! The {\tt ESMF\_XGrid} object to complete the Field. @\ +! \item [grid] @\ +! The {\tt ESMF\_Grid} object to complete the Field. @\ ! \item [farrayPtr] @\ ! Native Fortran data pointer to be copied/referenced in the {\tt field}. @\ ! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ @@ -3093,19 +3149,18 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXG) ! Indicates whether to copy the {\tt farrayPtr} or reference it directly. @\ ! For valid values see \ref{const:datacopyflag}. The default is @\ ! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ -! \item [{[xgridside]}] @\ -! Which side of the XGrid to create the Field on (either ESMF\_XGRIDSIDE\_A, @\ -! ESMF\_XGRIDSIDE\_B, or ESMF\_XGRIDSIDE\_BALANCED). If not passed in then @\ -! defaults to ESMF\_XGRIDSIDE\_BALANCED. @\ -! \item [{[gridindex]}] @\ -! If xgridside is ESMF\_XGRIDSIDE\_A or ESMF\_XGRIDSIDE\_B then this index tells which Grid on @\ -! that side to create the Field on. If not provided, defaults to 1. @\ +! \item [{[staggerloc]}] @\ +! Stagger location of data in grid cells. For valid @\ +! predefined values see section \ref{const:staggerloc}. @\ +! To create a custom stagger location see section @\ +! \ref{sec:usage:staggerloc:adv}. The default @\ +! value is {\tt ESMF\_STAGGERLOC\_CENTER}. @\ ! \item [{[gridToFieldMap]}] @\ ! List with number of elements equal to the @\ -! {\tt xgrid}|s dimCount. The list elements map each dimension @\ -! of the {\tt xgrid} to a dimension in the {\tt farrayPtr} by @\ +! {\tt grid}|s dimCount. The list elements map each dimension @\ +! of the {\tt grid} to a dimension in the {\tt farrayPtr} by @\ ! specifying the appropriate {\tt farrayPtr} dimension index. The @\ -! default is to map all of the {\tt xgrid}|s dimensions against the @\ +! default is to map all of the {\tt grid}|s dimensions against the @\ ! lowest dimensions of the {\tt farrayPtr} in sequence, i.e. @\ ! {\tt gridToFieldMap} = (/1,2,3,.../). @\ ! Unmapped {\tt farrayPtr} dimensions are undistributed Field @\ @@ -3113,11 +3168,27 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXG) ! All {\tt gridToFieldMap} entries must be greater than or equal @\ ! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ ! to specify the same entry multiple times unless it is zero. @\ -! If the Field dimCount is less than the XGrid dimCount then the default @\ +! If the Field dimCount is less than the Grid dimCount then the default @\ ! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ ! entry in the {\tt gridToFieldMap} indicates that the particular @\ -! XGrid dimension will be replicating the Field across the DEs along @\ +! Grid dimension will be replicating the Field across the DEs along @\ ! this direction. @\ +! \item [{[totalLWidth]}] @\ +! Lower bound of halo region. The size of this array is the number @\ +! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ +! needs to be the same as they appear in the {\tt field}. Values default @\ +! to 0. If values for totalLWidth are specified they must be reflected in @\ +! the size of the {\tt field}. That is, for each gridded dimension the @\ +! {\tt field} size should be max( {\tt totalLWidth} + {\tt totalUWidth} @\ +! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ +! \item [{[totalUWidth]}] @\ +! Upper bound of halo region. The size of this array is the number @\ +! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ +! needs to be the same as they appear in the {\tt field}. Values default @\ +! to 0. If values for totalUWidth are specified they must be reflected in @\ +! the size of the {\tt field}. That is, for each gridded dimension the @\ +! {\tt field} size should max( {\tt totalLWidth} + {\tt totalUWidth} @\ +! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ ! \item [{[rc]}] @\ ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ ! \end{description} @\ @@ -3125,99 +3196,128 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXG) !EOP @\ !---------------------------------------------------------------------------- @\ -#define FieldEmptyCompXGPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +#define FieldEmptyCompGridPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ !---------------------------------------------------------------------------- @\ ^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompXGPtr" @\ -subroutine ESMF_FieldEmptyCompXGPtr##mrank##D##mtypekind(field, xgrid, & @\ - farrayPtr, keywordEnforcer, & @\ - datacopyflag, xgridside, gridindex, gridToFieldMap, rc) @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompGridPtr" @\ + subroutine ESMF_FieldEmptyCompGridPtr##mrank##D##mtypekind(field, grid, farrayPtr, & @\ + keywordEnforcer, datacopyflag, staggerloc, gridToFieldMap, & @\ + totalLWidth, totalUWidth, rc) @\ @\ - ! input arguments @\ - type(ESMF_Field), intent(inout) :: field @\ - type(ESMF_XGrid), intent(in) :: xgrid @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ + ! input arguments @\ + type(ESMF_Field) :: field @\ + type(ESMF_Grid) :: grid @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside @\ - integer, intent(in), optional :: gridindex @\ - integer, intent(in), optional :: gridToFieldMap(:) @\ - integer, intent(out), optional :: rc @\ - ! local variables @\ - integer :: localrc @\ - type(ESMF_Geom) :: geom @\ - type(ESMF_FieldStatus_Flag) :: status @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + type(ESMF_StaggerLoc), intent(in), optional ::staggerloc @\ + integer, intent(in), optional :: gridToFieldMap(:) @\ + integer, intent(in), optional :: totalLWidth(:) @\ + integer, intent(in), optional :: totalUWidth(:) @\ + integer, intent(out), optional :: rc @\ + ! local variables @\ + type(ESMF_StaggerLoc) :: localStaggerLoc @\ + integer :: localrc @\ + type(ESMF_Geom) :: geom @\ + type(ESMF_GridDecompType) :: decompType @\ + type(ESMF_FieldStatus_Flag) :: status @\ @\ - if (present(rc)) then @\ - rc = ESMF_RC_NOT_IMPL @\ - endif @\ - localrc = ESMF_RC_NOT_IMPL @\ + if (present(rc)) then @\ + rc = ESMF_RC_NOT_IMPL @\ + endif @\ + localrc = ESMF_RC_NOT_IMPL @\ @\ - ! make sure field, xgrid, farrayPtr are properly initialized @\ - ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP(ESMF_XGridGetInit,xgrid,rc) @\ + ! make sure field, grid, farrayPtr are properly initialized @\ + ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ + ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit,grid,rc) @\ @\ - call ESMF_FieldGet(field, status=status, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + call ESMF_FieldGet(field, status=status, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ - msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ + if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ @\ - geom=ESMF_GeomCreate(xgrid, xgridSide, gridIndex, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + call ESMF_GridGetDecompType(grid, decompType, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ -! Do General Geom EmptyComp @\ -call ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ - datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ - rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + if (decompType .eq. ESMF_GRID_ARBITRARY) then @\ + if ((present(totalLWidth)) .or. (present(totalUWidth))) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- indexflag, totalLWidth or totalUWidth are not allowed for arbitrary grid", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ + endif @\ @\ - if (present(rc)) rc = ESMF_SUCCESS @\ -end subroutine ESMF_FieldEmptyCompXGPtr##mrank##D##mtypekind @\ + ! Set default values. @\ + if (present(staggerloc)) then @\ + if ((decompType .eq. ESMF_GRID_ARBITRARY) .and. & @\ + (staggerloc .ne. ESMF_STAGGERLOC_CENTER)) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + else @\ + localStaggerloc=staggerloc @\ + endif @\ + else @\ + localStaggerLoc = ESMF_STAGGERLOC_CENTER @\ + endif @\ +@\ + geom=ESMF_GeomCreate(grid,localStaggerloc, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ +@\ + ! Do General Geom EmptyComp @\ + call ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ + datacopyflag, gridToFieldMap, & @\ + totalLWidth, totalUWidth, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ +@\ + if (present(rc)) rc = ESMF_SUCCESS @\ + end subroutine ESMF_FieldEmptyCompGridPtr##mrank##D##mtypekind @\ !---------------------------------------------------------------------------- @\ -TypeKindRankDeclarationMacro(FieldEmptyCompXGPtr) +TypeKindRankDeclarationMacro(FieldEmptyCompGridPtr) -#define FieldEmptyCompGBDoc() \ +#define FieldEmptyCompLSDoc() \ !---------------------------------------------------------------------------- @\ !BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field started with FieldEmptyCreate @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from LocStream started with FieldEmptyCreate @\ ! @\ ! !INTERFACE: @\ ! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompGB(field, geom, & @\ -! farray, indexflag, datacopyflag, gridToFieldMap, ungriddedLBound, & @\ -! ungriddedUBound, totalLWidth, totalUWidth, rc) @\ +! subroutine ESMF_FieldEmptyCompLS(field, locstream, & @\ +! farray, indexflag, keywordEnforcer, datacopyflag, gridToFieldMap, & @\ +! ungriddedLBound, ungriddedUBound, rc) @\ ! @\ ! !ARGUMENTS: @\ -! type(ESMF_Field), intent(inout) :: field @\ -! type(ESMF_Geom), intent(in) :: geom @\ -! (ESMF_KIND_), dimension(), target :: farray @\ -! type(ESMF_Index_Flag), intent(in) :: indexflag @\ -! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! integer, intent(in), optional :: gridToFieldMap(:) @\ -! integer, intent(in), optional :: ungriddedLBound(:) @\ -! integer, intent(in), optional :: ungriddedUBound(:) @\ -! integer, intent(in), optional :: totalLWidth(:) @\ -! integer, intent(in), optional :: totalUWidth(:) @\ -! integer, intent(out), optional :: rc @\ +! type(ESMF_Field), intent(inout) :: field @\ +! type(ESMF_LocStream), intent(in) :: locstream @\ +! (ESMF_KIND_), intent(in), target :: farray() @\ +! type(ESMF_Index_Flag), intent(in) :: indexflag @\ +!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ +! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ +! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(in), optional :: ungriddedLBound(:) @\ +! integer, intent(in), optional :: ungriddedUBound(:) @\ +! integer, intent(out), optional :: rc @\ ! @\ ! !DESCRIPTION: @\ ! This call completes an {\tt ESMF\_Field} allocated with the @\ -! {\tt ESMF\_FieldEmptyCreate()} call. For an example and @\ -! associated documentation using this method see section @\ -! \ref{sec:field:usage:partial_creation}. @\ +! {\tt ESMF\_FieldEmptyCreate()} call. @\ ! @\ ! The Fortran data pointer inside {\tt ESMF\_Field} can be queried but deallocating @\ ! the retrieved data pointer is not allowed. @\ @@ -3228,8 +3328,8 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXGPtr) ! The {\tt ESMF\_Field} object to be completed and @\ ! committed in this call. The {\tt field} will have the same dimension @\ ! (dimCount) as the rank of the {\tt farray}. @\ -! \item [geom] @\ -! The {\tt ESMF\_Geom} object to complete the Field. @\ +! \item [locstream] @\ +! The {\tt ESMF\_LocStream} object to complete the Field. @\ ! \item [farray] @\ ! Native Fortran data array to be copied/referenced in the {\tt field}. @\ ! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ @@ -3243,10 +3343,10 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXGPtr) ! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ ! \item [{[gridToFieldMap]}] @\ ! List with number of elements equal to the @\ -! {\tt geom}|s dimCount. The list elements map each dimension @\ -! of the {\tt geom} to a dimension in the {\tt farray} by @\ +! {\tt locstream}|s dimCount. The list elements map each dimension @\ +! of the {\tt locstream} to a dimension in the {\tt farray} by @\ ! specifying the appropriate {\tt farray} dimension index. The @\ -! default is to map all of the {\tt geom}|s dimensions against the @\ +! default is to map all of the {\tt locstream}|s dimensions against the @\ ! lowest dimensions of the {\tt farray} in sequence, i.e. @\ ! {\tt gridToFieldMap} = (/1,2,3,.../). @\ ! Unmapped {\tt farray} dimensions are undistributed Field @\ @@ -3254,17 +3354,17 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXGPtr) ! All {\tt gridToFieldMap} entries must be greater than or equal @\ ! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ ! to specify the same entry multiple times unless it is zero. @\ -! If the Field dimCount is less than the Grid dimCount then the default @\ +! If the Field dimCount is less than the LocStream dimCount then the default @\ ! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ ! entry in the {\tt gridToFieldMap} indicates that the particular @\ -! Grid dimension will be replicating the Field across the DEs along @\ +! LocStream dimension will be replicating the Field across the DEs along @\ ! this direction. @\ ! \item [{[ungriddedLBound]}] @\ ! Lower bounds of the ungridded dimensions of the {\tt field}. @\ ! The number of elements in the {\tt ungriddedLBound} is equal to the number of ungridded @\ ! dimensions in the {\tt field}. All ungridded dimensions of the @\ ! {\tt field} are also undistributed. When field dimension count is @\ -! greater than grid dimension count, both ungriddedLBound and ungriddedUBound @\ +! greater than locstream dimension count, both ungriddedLBound and ungriddedUBound @\ ! must be specified. When both are specified the values are checked @\ ! for consistency. Note that the the ordering of @\ ! these ungridded dimensions is the same as their order in the {\tt field}. @\ @@ -3273,26 +3373,10 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXGPtr) ! The number of elements in the {\tt ungriddedUBound} is equal to the number of ungridded @\ ! dimensions in the {\tt field}. All ungridded dimensions of the @\ ! {\tt field} are also undistributed. When field dimension count is @\ -! greater than grid dimension count, both ungriddedLBound and ungriddedUBound @\ +! greater than locstream dimension count, both ungriddedLBound and ungriddedUBound @\ ! must be specified. When both are specified the values are checked @\ ! for consistency. Note that the the ordering of @\ ! these ungridded dimensions is the same as their order in the {\tt field}. @\ -! \item [{[totalLWidth]}] @\ -! Lower bound of halo region. The size of this array is the number @\ -! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ -! needs to be the same as they appear in the {\tt field}. Values default @\ -! to 0. If values for totalLWidth are specified they must be reflected in @\ -! the size of the {\tt field}. That is, for each gridded dimension the @\ -! {\tt field} size should be max( {\tt totalLWidth} + {\tt totalUWidth} @\ -! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ -! \item [{[totalUWidth]}] @\ -! Upper bound of halo region. The size of this array is the number @\ -! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ -! needs to be the same as they appear in the {\tt field}. Values default @\ -! to 0. If values for totalUWidth are specified they must be reflected in @\ -! the size of the {\tt field}. That is, for each gridded dimension the @\ -! {\tt field} size should max( {\tt totalLWidth} + {\tt totalUWidth} @\ -! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ ! \item [{[rc]}] @\ ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ ! \end{description} @\ @@ -3300,484 +3384,399 @@ TypeKindRankDeclarationMacro(FieldEmptyCompXGPtr) !EOP @\ !---------------------------------------------------------------------------- @\ -#define FieldEmptyCompGBMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +#define FieldEmptyCompLSMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ !---------------------------------------------------------------------------- @\ ^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompGB" @\ -subroutine ESMF_FieldEmptyCompGB##mrank##D##mtypekind(field, geom, farray, & @\ - indexflag, datacopyflag, gridToFieldMap, ungriddedLBound, & @\ - ungriddedUBound, totalLWidth, totalUWidth, rc) @\ -@\ - ! input arguments @\ - type(ESMF_Field), intent(inout) :: field @\ - type(ESMF_Geom), intent(in) :: geom @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), target :: farray @\ - type(ESMF_Index_Flag), intent(in) :: indexflag @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - integer, intent(in), optional :: gridToFieldMap(:) @\ - integer, intent(in), optional :: ungriddedLBound(:) @\ - integer, intent(in), optional :: ungriddedUBound(:) @\ - integer, intent(in), optional :: totalLWidth(:) @\ - integer, intent(in), optional :: totalUWidth(:) @\ - integer, intent(out), optional :: rc @\ - ! local variables @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: fpointer @\ - integer :: localrc, i, j, count @\ - integer :: memDimCount, fieldUngriddedDimCount @\ - integer :: fieldDimCount, localDeCount @\ - integer :: gridDimCount, gridDimCount_norep @\ - integer :: grid_repdimcount @\ - integer :: elementCount @\ - integer :: ungriddedIndex(ESMF_MAXDIM) @\ - integer :: distgridToArrayMap (ESMF_MAXDIM) @\ - integer :: undistLBound(ESMF_MAXDIM), undistUBound(ESMF_MAXDIM) @\ - integer :: localUngriddedLBound (ESMF_MAXDIM) @\ - integer :: localUngriddedUBound (ESMF_MAXDIM) @\ - integer :: localGridToFieldMap (ESMF_MAXDIM) @\ - integer :: localMaxHaloLWidth (ESMF_MAXDIM) @\ - integer :: localMaxHaloUWidth (ESMF_MAXDIM) @\ - logical :: isGridded(ESMF_MAXDIM) @\ - integer :: distgridToGridMap(ESMF_MAXDIM) @\ - type(ESMF_Array) :: array @\ - type(ESMF_DistGrid) :: distgrid @\ - integer :: fieldUndistDimCount @\ - logical :: flipflop(ESMF_MAXDIM) @\ - type(ESMF_Index_Flag) :: g_indexflag @\ - logical :: found @\ - type(ESMF_GridDecompType) :: decompType @\ - type(ESMF_GeomType_Flag) :: geomtype @\ - type(ESMF_Grid) :: grid @\ - integer :: distgridDimCount, distgridDimCount_norep, arbdim @\ - character(len=ESMF_MAXSTR) :: fieldName @\ -@\ - if (present(rc)) then @\ - rc = ESMF_RC_NOT_IMPL @\ - endif @\ - localrc = ESMF_RC_NOT_IMPL @\ -@\ - ! make sure field, grid, farray are properly initialized @\ - ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP(ESMF_GeomGetInit,geom,rc) @\ -@\ - ! get the fieldName @\ - call ESMF_FieldGet(field, name=fieldName, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompLS" @\ + subroutine ESMF_FieldEmptyCompLS##mrank##D##mtypekind(field, locstream, farray, & @\ + indexflag, keywordEnforcer, datacopyflag, gridToFieldMap, ungriddedLBound, & @\ + ungriddedUBound, rc) @\ @\ - ! Get number of grid dimensions, number @\ - ! of distributed grid dimensions, distgrid, @\ - ! number of ungridded Field dimensions, @\ - ! and number of undistributed Field Dimensions @\ - call ESMF_GeomGet(geom, dimCount=gridDimCount, & @\ - distgridToGridMap=distgridToGridMap, localDeCount=localDeCount, & @\ - distgrid=distgrid, indexflag=g_indexflag, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! input arguments @\ + type(ESMF_Field), intent(inout) :: field @\ + type(ESMF_LocStream), intent(in) :: locstream @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), target :: farray @\ + type(ESMF_Index_Flag), intent(in) :: indexflag @\ +type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + integer, intent(in), optional :: gridToFieldMap(:) @\ + integer, intent(in), optional :: ungriddedLBound(:) @\ + integer, intent(in), optional :: ungriddedUBound(:) @\ + integer, intent(out), optional :: rc @\ + ! local variables @\ + integer :: localrc @\ + type(ESMF_Geom) :: geom @\ + type(ESMF_FieldStatus_Flag) :: status @\ @\ - if(.not. (indexflag .eq. g_indexflag)) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- user specified indexflag must be identical with Grid indexflag", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ + if (present(rc)) then @\ + rc = ESMF_RC_NOT_IMPL @\ + endif @\ + localrc = ESMF_RC_NOT_IMPL @\ @\ - elementCount = 0 ! default to assuming no elements @\ - if (localDeCount==1) then @\ - call ESMF_DistGridGet(distgrid, localDe=0, elementCount=elementCount, & @\ - rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - elseif (localDeCount>1) then @\ - !TODO: error out because not supported @\ - endif @\ + ! make sure field, locstream, farray are properly initialized @\ + ESMF_INIT_CHECK_DEEP_SHORT(ESMF_FieldGetInit,field,rc) @\ + ESMF_INIT_CHECK_DEEP_SHORT(ESMF_LocStreamGetInit,locstream,rc) @\ @\ - if (elementCount > 0) then @\ - ! The following use of fptr is a bit of trickery to get all F90 @\ - ! compilers to cooperate. For some compilers the associated() test @\ - ! will return .false. for farray of size 0. Some of those compilers @\ - ! will produce a run-time error in size(fptr). Other compilers will @\ - ! return .true. for the associated() test but return 0 in size(). @\ - fpointer => farray @\ - if(.not. associated(fpointer,farray)) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & @\ - msg="- farray is not associated with memory allocation)", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ + call ESMF_FieldGet(field, status=status, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if (size(fpointer)==0) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & @\ - msg="- farray is not associated with memory allocation)", & @\ + if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ ESMF_CONTEXT, rcToReturn=rc) @\ return @\ endif @\ - endif @\ -@\ - ! Check if geom is a grid, if so, check if it is arbitrary @\ - decompType = ESMF_GRID_NONARBITRARY @\ - call ESMF_GeomGet(geom, geomtype=geomtype, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - if (geomtype .eq. ESMF_GEOMTYPE_GRID) then @\ - call ESMF_GeomGet(geom, grid=grid, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - call ESMF_GridGetDecompType(grid, decompType, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - endif @\ @\ - ! Check the size of the native array. @\ - memDimCount = mrank @\ + geom=ESMF_GeomCreate(locstream,rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - ! Error Check Input @\ - grid_repdimcount = 0 @\ - if (present(gridToFieldMap)) then @\ - if (size(gridToFieldMap) .ne. gridDimCount) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- gridToFieldMap size must equal to grid_rank", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - do i = 1, gridDimCount @\ - if(gridToFieldMap(i) == 0) grid_repdimcount = grid_repdimcount + 1 @\ - enddo @\ - endif @\ - gridDimCount_norep = gridDimCount - grid_repdimcount @\ + ! Do General Geom EmptyComp @\ + call ESMF_FieldEmptyCompGB##mrank##D##mtypekind(field, geom, farray, & @\ + indexflag=indexflag, datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ + ungriddedLBound=ungriddedLBound, & @\ + ungriddedUBound=ungriddedUBound, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if (present(gridToFieldMap)) then @\ - localGridToFieldMap(1:gridDimCount) = & @\ - gridToFieldMap (1:gridDimCount) @\ - else @\ - do i = 1, gridDimCount @\ - localGridToFieldMap(i) = i @\ - enddo @\ - endif @\ -@\ - if (decompType .eq. ESMF_GRID_NONARBITRARY) then @\ - fieldDimCount = memDimCount @\ - else @\ - call ESMF_GridGet(grid, distgridToGridMap=distgridToGridMap, & @\ - rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - ! find out how many grid dimensions are arbitrarily distributed and calculate @\ - ! fieldDimCount accordingly @\ - arbdim = 0 @\ - do i=1,gridDimCount @\ - if (distgridToGridMap(i) .ne. 0) arbdim = arbdim+1 @\ - enddo @\ - fieldDimCount = memDimCount + arbdim - 1 @\ -@\ - ! If there is any replicated dimension, check if any of the arb. dimensions are replicated. @\ - ! If one arb dimension is replicated, all the arb. dimensions have to be replicated @\ - if (grid_repdimcount .ne. 0) then @\ - do i = 1,gridDimCount @\ - if(localGridToFieldMap(i) == 0) then @\ - found = .false. @\ - do j=1,arbdim @\ - if (distgridToGridMap(j) .eq. i) found = .true. @\ - enddo @\ - if (found) then @\ - ! one arb.dimension is a replicated dimension, check if other arb dimensions are @\ - ! also replicated @\ - do j=1,arbdim @\ - if (distgridToGridMap(j) .ne. i) then @\ - if (localGridToFieldMap(distgridToGridMap(j)) .ne. 0) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- Arb. grid dimensions have to be either all replicated or not replicated", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - endif @\ - enddo @\ - ! all arb. dimension are replication, jump out of the first do loop @\ - ! fieldDimCount should be the same as the memDimCount @\ - fieldDimCount = memDimCount @\ - exit @\ - endif @\ - endif @\ - enddo @\ - endif @\ - endif @\ + if (present(rc)) rc = ESMF_SUCCESS @\ + end subroutine ESMF_FieldEmptyCompLS##mrank##D##mtypekind @\ +!---------------------------------------------------------------------------- @\ + +TypeKindRankDeclarationMacro(FieldEmptyCompLS) + + +#define FieldEmptyCompLSPtrDoc() \ +!---------------------------------------------------------------------------- @\ +!BOP @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from LocStream started with FieldEmptyCreate @\ +! @\ +! !INTERFACE: @\ +! ! Private name; call using ESMF_FieldEmptyComplete() @\ +! subroutine ESMF_FieldEmptyCompLSPtr(field, locstream, & @\ +! farrayPtr, keywordEnforcer, datacopyflag, gridToFieldMap, rc) @\ +! @\ +! !ARGUMENTS: @\ +! type(ESMF_Field), intent(inout) :: field @\ +! type(ESMF_LocStream), intent(in) :: locstream @\ +! (ESMF_KIND_), pointer :: farrayPtr() @\ +!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ +! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ +! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(out), optional :: rc @\ +! @\ +! !DESCRIPTION: @\ +! This call completes an {\tt ESMF\_Field} allocated with the @\ +! {\tt ESMF\_FieldEmptyCreate()} call. @\ +! @\ +! \begin{sloppypar} @\ +! The Fortran data pointer inside {\tt ESMF\_Field} can be queried and deallocated when @\ +! datacopyflag is {\tt ESMF\_DATACOPY\_REFERENCE}. Note that the {\tt ESMF\_FieldDestroy} call does not deallocate @\ +! the Fortran data pointer in this case. This gives user more flexibility over memory management. @\ +! \end{sloppypar} @\ +! @\ +! The arguments are: @\ +! \begin{description} @\ +! \item [field] @\ +! The {\tt ESMF\_Field} object to be completed and @\ +! committed in this call. The {\tt field} will have the same dimension @\ +! (dimCount) as the rank of the {\tt farrayPtr}. @\ +! \item [locstream] @\ +! The {\tt ESMF\_LocStream} object to complete the Field. @\ +! \item [farrayPtr] @\ +! Native Fortran data pointer to be copied/referenced in the {\tt field}. @\ +! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ +! for the {\tt farrayPtr}. @\ +! \item [{[datacopyflag]}] @\ +! Indicates whether to copy the {\tt farrayPtr} or reference it directly. @\ +! For valid values see \ref{const:datacopyflag}. The default is @\ +! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ +! \item [{[gridToFieldMap]}] @\ +! List with number of elements equal to the @\ +! {\tt locstream}|s dimCount. The list elements map each dimension @\ +! of the {\tt locstream} to a dimension in the {\tt farrayPtr} by @\ +! specifying the appropriate {\tt farrayPtr} dimension index. The @\ +! default is to map all of the {\tt locstream}|s dimensions against the @\ +! lowest dimensions of the {\tt farrayPtr} in sequence, i.e. @\ +! {\tt gridToFieldMap} = (/1,2,3,.../). @\ +! Unmapped {\tt farrayPtr} dimensions are undistributed Field @\ +! dimensions. @\ +! All {\tt gridToFieldMap} entries must be greater than or equal @\ +! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ +! to specify the same entry multiple times unless it is zero. @\ +! If the Field dimCount is less than the LocStream dimCount then the default @\ +! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ +! entry in the {\tt gridToFieldMap} indicates that the particular @\ +! LocStream dimension will be replicating the Field across the DEs along @\ +! this direction. @\ +! \item [{[rc]}] @\ +! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ +! \end{description} @\ +! @\ +!EOP @\ +!---------------------------------------------------------------------------- @\ + +#define FieldEmptyCompLSPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +!---------------------------------------------------------------------------- @\ +^undef ESMF_METHOD @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompLSPtr" @\ + subroutine ESMF_FieldEmptyCompLSPtr##mrank##D##mtypekind(field, & @\ + locstream, farrayPtr, keywordEnforcer, datacopyflag, gridToFieldMap, rc) @\ @\ - if(fieldDimCount .lt. gridDimCount_norep) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- farray rank must be greater than or equal to grid rank", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ -! refer to ticket 1888180 @\ -! if(fieldDimCount .gt. gridDimCount_norep) then @\ -! if( (.not. present(ungriddedLBound)) .or. & @\ -! (.not. present(ungriddedUBound)) ) then @\ -! call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ -! "- ungridded bounds must be present when Field has ungridded dimension(s)", & @\ -! ESMF_CONTEXT, rcToReturn=rc) @\ -! return @\ -! endif @\ -! endif @\ + ! input arguments @\ + type(ESMF_Field), intent(inout) :: field @\ + type(ESMF_LocStream), intent(in) :: locstream @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ +type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + integer, intent(in), optional :: gridToFieldMap(:) @\ + integer, intent(out), optional :: rc @\ + ! local variables @\ + integer :: localrc @\ + type(ESMF_Geom) :: geom @\ + type(ESMF_FieldStatus_Flag) :: status @\ @\ - ! ungridded dimensions plus replicated dimensions @\ - fieldUngriddedDimCount = fieldDimCount-gridDimCount + grid_repdimcount @\ - fieldUndistDimCount = fieldDimCount-gridDimCount + grid_repdimcount @\ + if (present(rc)) then @\ + rc = ESMF_RC_NOT_IMPL @\ + endif @\ + localrc = ESMF_RC_NOT_IMPL @\ @\ - ! Error Check Input @\ - if (present(ungriddedLBound)) then @\ - if (size(ungriddedLBound) .ne. fieldUngriddedDimCount) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- ungriddedLBound size must equal to array_rank-grid_rank", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - endif @\ + ! make sure field, locstream, farrayPtr are properly initialized @\ + ESMF_INIT_CHECK_DEEP_SHORT(ESMF_FieldGetInit,field,rc) @\ + ESMF_INIT_CHECK_DEEP_SHORT(ESMF_LocStreamGetInit,locstream,rc) @\ @\ - if (present(ungriddedUBound)) then @\ - if (size(ungriddedUBound) .ne. fieldUngriddedDimCount) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- ungriddedUBound size must equal to array_rank-grid_rank", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - endif @\ + call ESMF_FieldGet(field, status=status, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if (present(totalLWidth)) then @\ - if (size(totalLWidth) .ne. gridDimCount_norep) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- totalLWidth must equal to gridded dimCount", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - endif @\ + if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ @\ - if (present(totalUWidth)) then @\ - if (size(totalUWidth) .ne. gridDimCount_norep) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- totalUWidth must equal to gridded dimCount", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - endif @\ + geom=ESMF_GeomCreate(locstream,rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - ! gridToFieldMap elements must be in range 0...fieldRank and unique @\ - ! algorithm to check element uniqueness: @\ - ! run time: O(ESMF_MAXDIM) @\ - ! memory: O(2*ESMF_MAXDIM) @\ - ! or O(ESMF_MAXDIM+ESMF_MAXDIM/sizeof(integer)) with bitvector @\ - flipflop = .false. @\ - do i = 1, gridDimCount @\ - if(localGridToFieldMap(i) .lt. 0 .or. & @\ - localGridToFieldMap(i) .gt. fieldDimCount) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ - msg="- gridToFieldMap element must be within range 0...array rank", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - if(localGridToFieldMap(i) /= 0) then @\ - if(flipflop(localGridToFieldMap(i))) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ - msg="- gridToFieldMap element must be unique", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - flipflop(localGridToFieldMap(i)) = .true. @\ -endif @\ - enddo @\ + ! Do General Geom EmptyComp @\ + call ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ + datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ + rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if(present(totalLWidth)) then @\ - localMaxHaloLWidth(1:gridDimCount_norep) = & @\ - totalLWidth (1:gridDimCount_norep) @\ - else @\ - localMaxHaloLWidth = 0 @\ - endif @\ -@\ - if(present(totalUWidth)) then @\ - localMaxHaloUWidth(1:gridDimCount_norep) = & @\ - totalUWidth (1:gridDimCount_norep) @\ - else @\ - localMaxHaloUWidth = 0 @\ - endif @\ -@\ - ! Here we get the lbounds and ubounds for ungridded @\ - ! dimensions from the native array, if it is not input @\ - ! through the argument list. First we need to set up @\ - ! an index array that holds the ungridded dimensions of @\ - ! the native array. @\ -@\ - ! Since we are saving the ungriddedIndex calculate it even @\ - ! if ungridded bounds are present @\ -@\ - ! Figure out which dims are ungridded @\ - isGridded = .false. @\ - do i=1, gridDimCount @\ - if(localGridToFieldMap(i) /= 0) isGridded(localGridToFieldMap(i)) = .true. @\ - enddo @\ + if (present(rc)) rc = ESMF_SUCCESS @\ + end subroutine ESMF_FieldEmptyCompLSPtr##mrank##D##mtypekind @\ +!---------------------------------------------------------------------------- @\ + +TypeKindRankDeclarationMacro(FieldEmptyCompLSPtr) + + +#define FieldEmptyCompMeshDoc() \ +!---------------------------------------------------------------------------- @\ +!BOP @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Mesh started with FieldEmptyCreate @\ +! @\ +! !INTERFACE: @\ +! ! Private name; call using ESMF_FieldEmptyComplete() @\ +! subroutine ESMF_FieldEmptyCompMesh(field, mesh, & @\ +! farray, indexflag, keywordEnforcer, datacopyflag, meshloc, & @\ +! gridToFieldMap, ungriddedLBound, ungriddedUBound, rc) @\ +! @\ +! !ARGUMENTS: @\ +! type(ESMF_Field), intent(inout) :: field @\ +! type(ESMF_Mesh), intent(in) :: mesh @\ +! (ESMF_KIND_), intent(in), target :: farray() @\ +! type(ESMF_Index_Flag), intent(in) :: indexflag @\ +!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ +! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ +! type(ESMF_MeshLoc), intent(in), optional :: meshloc @\ +! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(in), optional :: ungriddedLBound(:) @\ +! integer, intent(in), optional :: ungriddedUBound(:) @\ +! integer, intent(out), optional :: rc @\ +! @\ +! !DESCRIPTION: @\ +! This call completes an {\tt ESMF\_Field} allocated with the @\ +! {\tt ESMF\_FieldEmptyCreate()} call. @\ +! @\ +! The Fortran data pointer inside {\tt ESMF\_Field} can be queried but deallocating @\ +! the retrieved data pointer is not allowed. @\ +! @\ +! The arguments are: @\ +! \begin{description} @\ +! \item [field] @\ +! The {\tt ESMF\_Field} object to be completed and @\ +! committed in this call. The {\tt field} will have the same dimension @\ +! (dimCount) as the rank of the {\tt farray}. @\ +! \item [mesh] @\ +! The {\tt ESMF\_Mesh} object to complete the Field. @\ +! \item [farray] @\ +! Native Fortran data array to be copied/referenced in the {\tt field}. @\ +! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ +! for the {\tt farray}. @\ +! \item [indexflag] @\ +! Indicate how DE-local indices are defined. See section @\ +! \ref{const:indexflag} for a list of valid indexflag options. @\ +! \item [{[datacopyflag]}] @\ +! Indicates whether to copy the {\tt farray} or reference it directly. @\ +! For valid values see \ref{const:datacopyflag}. The default is @\ +! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ +! \item [{[meshloc]}] @\ +! \begin{sloppypar} @\ +! Which part of the mesh to build the Field on. Can be set to either @\ +! {\tt ESMF\_MESHLOC\_NODE} or {\tt ESMF\_MESHLOC\_ELEMENT}. If not set, @\ +! defaults to {\tt ESMF\_MESHLOC\_NODE}. @\ +! \end{sloppypar} @\ +! \item [{[gridToFieldMap]}] @\ +! List with number of elements equal to the @\ +! {\tt mesh}|s dimCount. The list elements map each dimension @\ +! of the {\tt mesh} to a dimension in the {\tt farray} by @\ +! specifying the appropriate {\tt farray} dimension index. The @\ +! default is to map all of the {\tt mesh}|s dimensions against the @\ +! lowest dimensions of the {\tt farray} in sequence, i.e. @\ +! {\tt gridToFieldMap} = (/1,2,3,.../). @\ +! Unmapped {\tt farray} dimensions are undistributed Field @\ +! dimensions. @\ +! All {\tt gridToFieldMap} entries must be greater than or equal @\ +! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ +! to specify the same entry multiple times unless it is zero. @\ +! If the Field dimCount is less than the Mesh dimCount then the default @\ +! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ +! entry in the {\tt gridToFieldMap} indicates that the particular @\ +! Mesh dimension will be replicating the Field across the DEs along @\ +! this direction. @\ +! \item [{[ungriddedLBound]}] @\ +! Lower bounds of the ungridded dimensions of the {\tt field}. @\ +! The number of elements in the {\tt ungriddedLBound} is equal to the number of ungridded @\ +! dimensions in the {\tt field}. All ungridded dimensions of the @\ +! {\tt field} are also undistributed. When field dimension count is @\ +! greater than Mesh dimension count, both ungriddedLBound and ungriddedUBound @\ +! must be specified. When both are specified the values are checked @\ +! for consistency. Note that the the ordering of @\ +! these ungridded dimensions is the same as their order in the {\tt field}. @\ +! \item [{[ungriddedUBound]}] @\ +! Upper bounds of the ungridded dimensions of the {\tt field}. @\ +! The number of elements in the {\tt ungriddedUBound} is equal to the number of ungridded @\ +! dimensions in the {\tt field}. All ungridded dimensions of the @\ +! {\tt field} are also undistributed. When field dimension count is @\ +! greater than Mesh dimension count, both ungriddedLBound and ungriddedUBound @\ +! must be specified. When both are specified the values are checked @\ +! for consistency. Note that the the ordering of @\ +! these ungridded dimensions is the same as their order in the {\tt field}. @\ +! \item [{[rc]}] @\ +! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ +! \end{description} @\ +! @\ +!EOP @\ +!---------------------------------------------------------------------------- @\ + +#define FieldEmptyCompMeshMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +!---------------------------------------------------------------------------- @\ +^undef ESMF_METHOD @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompMesh" @\ + subroutine ESMF_FieldEmptyCompMesh##mrank##D##mtypekind(field, mesh, farray, & @\ + indexflag, keywordEnforcer, datacopyflag, meshloc, gridToFieldMap, & @\ + ungriddedLBound, ungriddedUBound, rc) @\ @\ - ! Use ungridded info to figure out the map from ungridded to field dims @\ - count=1 @\ - do i=1,fieldDimCount @\ - if (.not. isGridded(i)) then @\ - ungriddedIndex(count)=i @\ - count=count+1 @\ - endif @\ - enddo @\ + ! input arguments @\ + type(ESMF_Field), intent(inout) :: field @\ + type(ESMF_Mesh), intent(in) :: mesh @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), target :: farray @\ + type(ESMF_Index_Flag), intent(in) :: indexflag @\ +type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + type(ESMF_MeshLoc), intent(in), optional :: meshloc @\ + integer, intent(in), optional :: gridToFieldMap(:) @\ + integer, intent(in), optional :: ungriddedLBound(:) @\ + integer, intent(in), optional :: ungriddedUBound(:) @\ + integer, intent(out), optional :: rc @\ + ! local variables @\ + integer :: localrc @\ + type(ESMF_Geom) :: geom @\ + type(ESMF_FieldStatus_Flag) :: status @\ @\ - ! set Array ungridded bounds depending on what user provides@\ - if (present(ungriddedLBound)) then @\ - if(present(ungriddedUBound)) then @\ - ! Both present so copy @\ - localUngriddedLBound(1:fieldUngriddedDimCount) = & @\ - ungriddedLBound(1:fieldUngriddedDimCount) @\ - localUngriddedUBound(1:fieldUngriddedDimCount) = & @\ - ungriddedUBound(1:fieldUngriddedDimCount) @\ - else @\ - ! Copy lower bound and make upper bound high enough to fit @\ - localUngriddedLBound(1:fieldUngriddedDimCount) = & @\ - ungriddedLBound(1:fieldUngriddedDimCount) @\ - do i=1, fieldUngriddedDimCount @\ - localUngriddedUBound(i) = ungriddedLBound(i)+ & @\ - size (farray,ungriddedIndex(i))-1 @\ - enddo @\ - endif @\ - else @\ - if(present(ungriddedUBound)) then @\ - ! Copy upper bound and make lower bound low enough to fit @\ - do i=1, fieldUngriddedDimCount @\ - localUngriddedLBound(i) = ungriddedUBound(i)- & @\ - size (farray,ungriddedIndex(i))+1 @\ - enddo @\ - localUngriddedUBound(1:fieldUngriddedDimCount) = & @\ - ungriddedUBound(1:fieldUngriddedDimCount) @\ - else @\ - ! No user info copy array bounds @\ - ! Note: assumed shape bounds will be 1...size @\ - do i=1, fieldUngriddedDimCount @\ - localUngriddedLBound(i) = lbound(farray,ungriddedIndex(i)) @\ - localUngriddedUBound(i) = ubound(farray,ungriddedIndex(i)) @\ - enddo @\ + if (present(rc)) then @\ + rc = ESMF_RC_NOT_IMPL @\ endif @\ - endif @\ -@\ - call ESMF_DistGridGet(distgrid, dimCount=distgridDimCount, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - distgridDimCount_norep = memDimCount - fieldUngriddedDimCount @\ -@\ - ! The undistributed info from the Grid needs to be @\ - ! combined with the ungridded info from the Field in order @\ - ! to create the Array for the Field. @\ - call ESMF_GeomGetArrayInfo(geom, & @\ - gridToFieldMap=localGridToFieldMap, & @\ - ungriddedLBound=localUngriddedLBound (1:fieldUngriddedDimCount), & @\ - ungriddedUBound=localUngriddedUBound (1:fieldUngriddedDimCount), & @\ - distgridToArrayMap=distgridToArrayMap, & @\ - undistLBound=undistLBound, undistUBound=undistUBound, & @\ - rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - ! Create Array with undistributed dimensions @\ - if (decompType .eq. ESMF_GRID_NONARBITRARY) then @\ - array = ESMF_ArrayCreate(distgrid, farray, & @\ - indexflag=indexflag, datacopyflag=datacopyflag, & @\ - distgridToArrayMap=distgridToArrayMap (1:distgridDimCount), & @\ - undistLBound=undistLBound(1:fieldUndistDimCount), & @\ - undistUBound=undistUBound(1:fieldUndistDimCount), & @\ - totalLWidth=localMaxHaloLWidth(1:gridDimCount_norep), & @\ - totalUWidth=localMaxHaloUWidth(1:gridDimCount_norep), & @\ - name=fieldName, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - else @\ - array = ESMF_ArrayCreate(distgrid, farray, & @\ - indexflag=indexflag, datacopyflag=datacopyflag, & @\ - distgridToArrayMap=distgridToArrayMap (1:distgridDimCount), & @\ - undistLBound=undistLBound(1:fieldUndistDimCount), & @\ - undistUBound=undistUBound(1:fieldUndistDimCount), & @\ - name=fieldName, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - endif @\ + localrc = ESMF_RC_NOT_IMPL @\ @\ - field%ftypep%array = array @\ + ! make sure field, mesh, farray are properly initialized @\ + ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ + ESMF_INIT_CHECK_DEEP(ESMF_MeshGetInit,mesh,rc) @\ @\ - ! set array_internal to .true. because field%array is internal @\ - field%ftypep%array_internal = .true. @\ + call ESMF_FieldGet(field, status=status, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - ! Should call a common FieldEmptyCompConstructor here instead @\ - ! of just setting things up ourselves @\ - ! (The field Sets were all moved here in preparation for this) @\ - field%ftypep%gridToFieldMap(1:gridDimCount) = & @\ - localGridToFieldMap(1:gridDimCount) @\ - field%ftypep%totalLWidth(1:gridDimCount_norep) = & @\ - localMaxHaloLWidth (1:gridDimCount_norep) @\ - field%ftypep%totalUWidth(1:gridDimCount_norep) = & @\ - localMaxHaloUWidth (1:gridDimCount_norep) @\ - field%ftypep%ungriddedLBound(1:fieldUngriddedDimCount) = & @\ - localUngriddedLBound(1:fieldUngriddedDimCount) @\ - field%ftypep%ungriddedUBound(1:fieldUngriddedDimCount) = & @\ - localUngriddedUBound(1:fieldUngriddedDimCount) @\ - field%ftypep%geom = geom @\ - field%ftypep%status = ESMF_FIELDSTATUS_COMPLETE @\ - call ESMF_BaseSetStatus(field%ftypep%base, ESMF_STATUS_READY, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - field%ftypep%dimCount = gridDimCount_norep + fieldUngriddedDimCount @\ + if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ @\ - call ESMF_FieldValidate(field, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + geom=ESMF_GeomCreate(mesh, meshLoc=meshloc, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if (present(rc)) rc = ESMF_SUCCESS @\ -end subroutine ESMF_FieldEmptyCompGB##mrank##D##mtypekind @\ + ! Do General Geom EmptyComp @\ + call ESMF_FieldEmptyCompGB##mrank##D##mtypekind(field, geom, farray, & @\ + indexflag=indexflag, datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ + ungriddedLBound=ungriddedLBound, & @\ + ungriddedUBound=ungriddedUBound, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ +@\ +@\ + if (present(rc)) rc = ESMF_SUCCESS @\ + end subroutine ESMF_FieldEmptyCompMesh##mrank##D##mtypekind @\ !---------------------------------------------------------------------------- @\ -TypeKindRankDeclarationMacro(FieldEmptyCompGB) +TypeKindRankDeclarationMacro(FieldEmptyCompMesh) -#define FieldEmptyCompGBPtrDoc() \ +#define FieldEmptyCompMeshPtrDoc() \ !---------------------------------------------------------------------------- @\ !BOP @\ -! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field started with FieldEmptyCreate @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from Mesh started with FieldEmptyCreate @\ ! @\ ! !INTERFACE: @\ ! ! Private name; call using ESMF_FieldEmptyComplete() @\ -! subroutine ESMF_FieldEmptyCompGBPtr(field, geom, & @\ -! farrayPtr, datacopyflag, gridToFieldMap, & @\ -! totalLWidth, totalUWidth, rc) @\ +! subroutine ESMF_FieldEmptyCompMeshPtr(field, mesh, & @\ +! farrayPtr, keywordEnforcer, datacopyflag, meshloc, gridToFieldMap, rc) @\ ! @\ ! !ARGUMENTS: @\ -! type(ESMF_Field), intent(inou) :: field @\ -! type(ESMF_Geom), intent(in) :: geom @\ -! (ESMF_KIND_), dimension(), pointer :: farrayPtr @\ -! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ -! integer, intent(in), optional :: gridToFieldMap(:) @\ -! integer, intent(in), optional :: totalLWidth(:) @\ -! integer, intent(in), optional :: totalUWidth(:) @\ -! integer, intent(out), optional :: rc @\ +! type(ESMF_Field), intent(inout) :: field @\ +! type(ESMF_Mesh), intent(in) :: mesh @\ +! (ESMF_KIND_), pointer :: farrayPtr() @\ +!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ +! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ +! type(ESMF_MeshLoc), intent(in), optional :: meshloc @\ +! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(out), optional :: rc @\ ! @\ ! !DESCRIPTION: @\ ! This call completes an {\tt ESMF\_Field} allocated with the @\ -! {\tt ESMF\_FieldEmptyCreate()} call. For an example and @\ -! associated documentation using this method see section @\ -! \ref{sec:field:usage:partial_creation}. @\ +! {\tt ESMF\_FieldEmptyCreate()} call. @\ ! @\ +! \begin{sloppypar} @\ ! The Fortran data pointer inside {\tt ESMF\_Field} can be queried and deallocated when @\ ! datacopyflag is {\tt ESMF\_DATACOPY\_REFERENCE}. Note that the {\tt ESMF\_FieldDestroy} call does not deallocate @\ ! the Fortran data pointer in this case. This gives user more flexibility over memory management. @\ +! \end{sloppypar} @\ ! @\ ! The arguments are: @\ ! \begin{description} @\ @@ -3785,9 +3784,8 @@ TypeKindRankDeclarationMacro(FieldEmptyCompGB) ! The {\tt ESMF\_Field} object to be completed and @\ ! committed in this call. The {\tt field} will have the same dimension @\ ! (dimCount) as the rank of the {\tt farrayPtr}. @\ -! \item [geom] @\ -! The {\tt ESMF\_Geom} object to complete the Field. The dimCount of the @\ -! Geom must be smaller than or equal to the rank of the {\tt farrayPtr}. @\ +! \item [mesh] @\ +! The {\tt ESMF\_Mesh} object to complete the Field. @\ ! \item [farrayPtr] @\ ! Native Fortran data pointer to be copied/referenced in the {\tt field}. @\ ! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ @@ -3796,12 +3794,18 @@ TypeKindRankDeclarationMacro(FieldEmptyCompGB) ! Indicates whether to copy the {\tt farrayPtr} or reference it directly. @\ ! For valid values see \ref{const:datacopyflag}. The default is @\ ! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ +! \item [{[meshloc]}] @\ +! \begin{sloppypar} @\ +! Which part of the mesh to build the Field on. Can be set to either @\ +! {\tt ESMF\_MESHLOC\_NODE} or {\tt ESMF\_MESHLOC\_ELEMENT}. If not set, @\ +! defaults to {\tt ESMF\_MESHLOC\_NODE}. @\ +! \end{sloppypar} @\ ! \item [{[gridToFieldMap]}] @\ ! List with number of elements equal to the @\ -! {\tt geom}|s dimCount. The list elements map each dimension @\ -! of the {\tt geom} to a dimension in the {\tt farrayPtr} by @\ +! {\tt mesh}|s dimCount. The list elements map each dimension @\ +! of the {\tt mesh} to a dimension in the {\tt farrayPtr} by @\ ! specifying the appropriate {\tt farrayPtr} dimension index. The @\ -! default is to map all of the {\tt geom}|s dimensions against the @\ +! default is to map all of the {\tt mesh}|s dimensions against the @\ ! lowest dimensions of the {\tt farrayPtr} in sequence, i.e. @\ ! {\tt gridToFieldMap} = (/1,2,3,.../). @\ ! Unmapped {\tt farrayPtr} dimensions are undistributed Field @\ @@ -3809,27 +3813,11 @@ TypeKindRankDeclarationMacro(FieldEmptyCompGB) ! All {\tt gridToFieldMap} entries must be greater than or equal @\ ! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ ! to specify the same entry multiple times unless it is zero. @\ -! If the Field dimCount is less than the Grid dimCount then the default @\ +! If the Field dimCount is less than the Mesh dimCount then the default @\ ! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ ! entry in the {\tt gridToFieldMap} indicates that the particular @\ -! Grid dimension will be replicating the Field across the DEs along @\ +! Mesh dimension will be replicating the Field across the DEs along @\ ! this direction. @\ -! \item [{[totalLWidth]}] @\ -! Lower bound of halo region. The size of this array is the number @\ -! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ -! needs to be the same as they appear in the {\tt field}. Values default @\ -! to 0. If values for totalLWidth are specified they must be reflected in @\ -! the size of the {\tt field}. That is, for each gridded dimension the @\ -! {\tt field} size should be max( {\tt totalLWidth} + {\tt totalUWidth} @\ -! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ -! \item [{[totalUWidth]}] @\ -! Upper bound of halo region. The size of this array is the number @\ -! of gridded dimensions in the {\tt field}. However, ordering of the elements @\ -! needs to be the same as they appear in the {\tt field}. Values default @\ -! to 0. If values for totalUWidth are specified they must be reflected in @\ -! the size of the {\tt field}. That is, for each gridded dimension the @\ -! {\tt field} size should max( {\tt totalLWidth} + {\tt totalUWidth} @\ -! + {\tt computationalCount}, {\tt exclusiveCount} ). @\ ! \item [{[rc]}] @\ ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ ! \end{description} @\ @@ -3837,371 +3825,382 @@ TypeKindRankDeclarationMacro(FieldEmptyCompGB) !EOP @\ !---------------------------------------------------------------------------- @\ -#define FieldEmptyCompGBPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +#define FieldEmptyCompMeshPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ !---------------------------------------------------------------------------- @\ ^undef ESMF_METHOD @\ -^define ESMF_METHOD "ESMF_FieldEmptyCompGBPtr" @\ -subroutine ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ - datacopyflag, gridToFieldMap, & @\ - totalLWidth, totalUWidth, rc) @\ -@\ - ! input arguments @\ - type(ESMF_Field), intent(inout) :: field @\ - type(ESMF_Geom), intent(in) :: geom @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ - type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ - integer, intent(in), optional :: gridToFieldMap(:) @\ - integer, intent(in), optional :: totalLWidth(:) @\ - integer, intent(in), optional :: totalUWidth(:) @\ - integer, intent(out), optional :: rc @\ - ! local variables @\ - mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: fpointer @\ - integer :: localrc, i, j @\ - integer :: fieldDimCount, localDeCount @\ - integer :: memDimCount, gridDimCount, gridDimCount_norep @\ - integer :: grid_repdimcount @\ - integer :: elementCount @\ - integer :: distgridToArrayMap (ESMF_MAXDIM) @\ - integer :: undistLBound(ESMF_MAXDIM), undistUBound(ESMF_MAXDIM) @\ - integer :: localGridToFieldMap (ESMF_MAXDIM) @\ - integer :: localMaxHaloLWidth (ESMF_MAXDIM) @\ - integer :: localMaxHaloUWidth (ESMF_MAXDIM) @\ - integer :: localUngriddedLBound (ESMF_MAXDIM) @\ - integer :: localUngriddedUBound (ESMF_MAXDIM) @\ - integer :: distgridToGridMap(ESMF_MAXDIM) @\ - type(ESMF_Array) :: array @\ - type(ESMF_DistGrid) :: distgrid @\ - integer :: fieldUndistDimCount @\ - integer :: fieldUngriddedDimCount @\ - integer :: count @\ - logical :: flipflop(ESMF_MAXDIM) @\ - logical :: isGridded(ESMF_MAXDIM) @\ - type(ESMF_Index_Flag) :: indexflag @\ - logical :: found @\ - type(ESMF_GridDecompType) :: decompType @\ - type(ESMF_GeomType_Flag) :: geomtype @\ - type(ESMF_Grid) :: grid @\ - integer :: distgridDimCount, distgridDimCount_norep, arbdim @\ - character(len=ESMF_MAXSTR) :: fieldName @\ -@\ - if (present(rc)) then @\ - rc = ESMF_RC_NOT_IMPL @\ - endif @\ - localrc = ESMF_RC_NOT_IMPL @\ -@\ - ! make sure field, grid, farrayPtr are properly initialized @\ - ESMF_INIT_CHECK_DEEP_SHORT(ESMF_FieldGetInit,field,rc) @\ - ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GeomGetInit,geom,rc) @\ -@\ - ! get the fieldName @\ - call ESMF_FieldGet(field, name=fieldName, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - ! Get number of grid dimensions, number @\ - ! of distributed grid dimensions, distgrid, @\ - ! number of ungridded Field dimensions, @\ - ! and number of undistributed Field Dimensions @\ - call ESMF_GeomGet(geom, dimCount=gridDimCount, & @\ - distgridToGridMap=distgridToGridMap, localDeCount=localDeCount, & @\ - distgrid=distgrid, indexflag=indexflag, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - elementCount = 0 ! default to assuming no elements @\ - if (localDeCount==1) then @\ - call ESMF_DistGridGet(distgrid, localDe=0, elementCount=elementCount, & @\ - rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - elseif (localDeCount>1) then @\ - !TODO: error out because not supported @\ - endif @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompMeshPtr" @\ + subroutine ESMF_FieldEmptyCompMeshPtr##mrank##D##mtypekind(field, mesh, & @\ + farrayPtr, keywordEnforcer, datacopyflag, meshloc, gridToFieldMap, rc) @\ @\ - if (elementCount > 0) then @\ - ! The following use of fptr is a bit of trickery to get all F90 @\ - ! compilers to cooperate. For some compilers the associated() test @\ - ! will return .false. for farray of size 0. Some of those compilers @\ - ! will produce a run-time error in size(fptr). Other compilers will @\ - ! return .true. for the associated() test but return 0 in size(). @\ - fpointer => farrayPtr @\ - if(.not. associated(fpointer,farrayPtr)) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & @\ - msg="- farrayPtr is not associated with memory allocation)", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ + ! input arguments @\ + type(ESMF_Field), intent(inout) :: field @\ + type(ESMF_Mesh), intent(in) :: mesh @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ +type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + type(ESMF_MeshLoc), intent(in), optional :: meshloc @\ + integer, intent(in), optional :: gridToFieldMap(:) @\ + integer, intent(out), optional :: rc @\ + ! local variables @\ + integer :: localrc @\ + type(ESMF_Geom) :: geom @\ + type(ESMF_FieldStatus_Flag) :: status @\ @\ - if (size(fpointer)==0) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & @\ - msg="- farrayPtr is not associated with memory allocation)", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ + if (present(rc)) then @\ + rc = ESMF_RC_NOT_IMPL @\ endif @\ - endif @\ - ! Check if geom is a grid, if so, check if it is arbitrary @\ - decompType = ESMF_GRID_NONARBITRARY @\ - call ESMF_GeomGet(geom, geomtype=geomtype, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ -@\ - if (geomtype .eq. ESMF_GEOMTYPE_GRID) then @\ - call ESMF_GeomGet(geom, grid=grid, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - call ESMF_GridGetDecompType(grid, decompType, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - endif @\ -@\ - ! Error Check Input @\ - ! And count the number of replicated dimensions in the Grid @\ - grid_repdimcount = 0 @\ - if (present(gridToFieldMap)) then @\ - if (size(gridToFieldMap) .ne. gridDimCount) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- gridToFieldMap size must equal to grid_rank", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - do i = 1, gridDimCount @\ - if(gridToFieldMap(i) == 0) grid_repdimcount = grid_repdimcount + 1 @\ - enddo @\ - endif @\ - gridDimCount_norep = gridDimCount - grid_repdimcount @\ - if (present(gridToFieldMap)) then @\ - localGridToFieldMap(1:gridDimCount) = & @\ - gridToFieldMap (1:gridDimCount) @\ - else @\ - do i = 1, gridDimCount @\ - localGridToFieldMap(i) = i @\ - enddo @\ - endif @\ -@\ - ! Check the size of the native array. @\ - memDimCount = mrank @\ + localrc = ESMF_RC_NOT_IMPL @\ @\ - if (decompType .eq. ESMF_GRID_NONARBITRARY) then @\ - fieldDimCount = memDimCount @\ - else @\ - call ESMF_GridGet(grid, distgridToGridMap=distgridToGridMap, & @\ - rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - ! find out how many grid dimensions are arbitrarily distributed and calculate @\ - ! fieldDimCount accordingly @\ - arbdim = 0 @\ - do i=1,gridDimCount @\ - if (distgridToGridMap(i) .ne. 0) arbdim = arbdim+1 @\ - enddo @\ - fieldDimCount = memDimCount + arbdim - 1 @\ + ! make sure field, mesh, farrayPtr are properly initialized @\ + ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ + ESMF_INIT_CHECK_DEEP(ESMF_MeshGetInit,mesh,rc) @\ @\ - ! If there is any replicated dimension, check if any of the arb. dimensions are replicated. @\ - ! If one arb dimension is replicated, all the arb. dimensions have to be replicated @\ - if (grid_repdimcount .ne. 0) then @\ - do i = 1,gridDimCount @\ - if(localGridToFieldMap(i) == 0) then @\ - found = .false. @\ - do j=1,arbdim @\ - if (distgridToGridMap(j) .eq. i) found = .true. @\ - enddo @\ - if (found) then @\ - ! one arb.dimension is a replicated dimension, check if other arb dimensions are @\ - ! also replicated @\ - do j=1,arbdim @\ - if (distgridToGridMap(j) .ne. i) then @\ - if (localGridToFieldMap(distgridToGridMap(j)) .ne. 0) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- Arb. grid dimensions have to be either all replicated or not replicated", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - endif @\ - enddo @\ - ! all arb. dimension are replication, jump out of the first do loop @\ - ! fieldDimCount should be the same as the memDimCount @\ - fieldDimCount = memDimCount @\ - exit @\ - endif @\ - endif @\ - enddo @\ - endif @\ - endif @\ + call ESMF_FieldGet(field, status=status, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if(fieldDimCount .lt. gridDimCount_norep) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- farrayPtr rank must be greater than or equal to grid rank", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ + if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ return @\ - endif @\ + endif @\ @\ - ! ungridded dimensions plus replicated dimensions @\ - fieldUngriddedDimCount = fieldDimCount-gridDimCount + grid_repdimcount @\ - fieldUndistDimCount = fieldDimCount-gridDimCount + grid_repdimcount @\ + geom=ESMF_GeomCreate(mesh, meshLoc=meshloc, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if (present(totalLWidth)) then @\ - if (size(totalLWidth) .ne. gridDimCount_norep) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- totalLWidth must equal to gridded dimCount", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - endif @\ + ! Do General Geom EmptyComp @\ + call ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ + datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ + rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - if (present(totalUWidth)) then @\ - if (size(totalUWidth) .ne. gridDimCount_norep) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & @\ - msg="- totalUWidth must equal to gridded dimCount", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - endif @\ + if (present(rc)) rc = ESMF_SUCCESS @\ + end subroutine ESMF_FieldEmptyCompMeshPtr##mrank##D##mtypekind @\ +!---------------------------------------------------------------------------- @\ + +TypeKindRankDeclarationMacro(FieldEmptyCompMeshPtr) + +! XGrid +#define FieldEmptyCompXGDoc() \ +!---------------------------------------------------------------------------- @\ +!BOP @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from XGrid started with FieldEmptyCreate @\ +! @\ +! !INTERFACE: @\ +! ! Private name; call using ESMF_FieldEmptyComplete() @\ +! subroutine ESMF_FieldEmptyCompXG(field, xgrid, & @\ +! farray, indexflag, keywordEnforcer, datacopyflag, xgridside, gridindex, & @\ +! gridToFieldMap, & @\ +! ungriddedLBound, ungriddedUBound, rc) @\ +! @\ +! !ARGUMENTS: @\ +! type(ESMF_Field), intent(inout) :: field @\ +! type(ESMF_XGrid), intent(in) :: xgrid @\ +! (ESMF_KIND_), intent(in), target :: farray() @\ +! type(ESMF_Index_Flag), intent(in) :: indexflag @\ +!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ +! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ +! type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside @\ +! integer, intent(in), optional :: gridindex @\ +! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(in), optional :: ungriddedLBound(:) @\ +! integer, intent(in), optional :: ungriddedUBound(:) @\ +! integer, intent(out), optional :: rc @\ +! @\ +! !DESCRIPTION: @\ +! This call completes an {\tt ESMF\_Field} allocated with the @\ +! {\tt ESMF\_FieldEmptyCreate()} call. @\ +! @\ +! The Fortran data pointer inside {\tt ESMF\_Field} can be queried but deallocating @\ +! the retrieved data pointer is not allowed. @\ +! @\ +! The arguments are: @\ +! \begin{description} @\ +! \item [field] @\ +! The {\tt ESMF\_Field} object to be completed and @\ +! committed in this call. The {\tt field} will have the same dimension @\ +! (dimCount) as the rank of the {\tt farray}. @\ +! \item [xgrid] @\ +! The {\tt ESMF\_XGrid} object to complete the Field. @\ +! \item [farray] @\ +! Native Fortran data array to be copied/referenced in the {\tt field}. @\ +! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ +! for the {\tt farray}. @\ +! \item [indexflag] @\ +! Indicate how DE-local indices are defined. See section @\ +! \ref{const:indexflag} for a list of valid indexflag options. @\ +! \item [{[datacopyflag]}] @\ +! Indicates whether to copy the {\tt farray} or reference it directly. @\ +! For valid values see \ref{const:datacopyflag}. The default is @\ +! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ +! \item [{[xgridside]}] @\ +! Which side of the XGrid to create the Field on (either ESMF\_XGRIDSIDE\_A, @\ +! ESMF\_XGRIDSIDE\_B, or ESMF\_XGRIDSIDE\_BALANCED). If not passed in then @\ +! defaults to ESMF\_XGRIDSIDE\_BALANCED. @\ +! \item [{[gridindex]}] @\ +! If xgridSide is ESMF\_XGRIDSIDE\_A or ESMF\_XGRIDSIDE\_B then this index tells which Grid on @\ +! that side to create the Field on. If not provided, defaults to 1. @\ +! \item [{[gridToFieldMap]}] @\ +! List with number of elements equal to the @\ +! {\tt xgrid}|s dimCount. The list elements map each dimension @\ +! of the {\tt xgrid} to a dimension in the {\tt farray} by @\ +! specifying the appropriate {\tt farray} dimension index. The @\ +! default is to map all of the {\tt xgrid}|s dimensions against the @\ +! lowest dimensions of the {\tt farray} in sequence, i.e. @\ +! {\tt gridToFieldMap} = (/1,2,3,.../). @\ +! Unmapped {\tt farray} dimensions are undistributed Field @\ +! dimensions. @\ +! All {\tt gridToFieldMap} entries must be greater than or equal @\ +! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ +! to specify the same entry multiple times unless it is zero. @\ +! If the Field dimCount is less than the XGrid dimCount then the default @\ +! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ +! entry in the {\tt gridToFieldMap} indicates that the particular @\ +! XGrid dimension will be replicating the Field across the DEs along @\ +! this direction. @\ +! \item [{[ungriddedLBound]}] @\ +! Lower bounds of the ungridded dimensions of the {\tt field}. @\ +! The number of elements in the {\tt ungriddedLBound} is equal to the number of ungridded @\ +! dimensions in the {\tt field}. All ungridded dimensions of the @\ +! {\tt field} are also undistributed. When field dimension count is @\ +! greater than XGrid dimension count, both ungriddedLBound and ungriddedUBound @\ +! must be specified. When both are specified the values are checked @\ +! for consistency. Note that the the ordering of @\ +! these ungridded dimensions is the same as their order in the {\tt field}. @\ +! \item [{[ungriddedUBound]}] @\ +! Upper bounds of the ungridded dimensions of the {\tt field}. @\ +! The number of elements in the {\tt ungriddedUBound} is equal to the number of ungridded @\ +! dimensions in the {\tt field}. All ungridded dimensions of the @\ +! {\tt field} are also undistributed. When field dimension count is @\ +! greater than XGrid dimension count, both ungriddedLBound and ungriddedUBound @\ +! must be specified. When both are specified the values are checked @\ +! for consistency. Note that the the ordering of @\ +! these ungridded dimensions is the same as their order in the {\tt field}. @\ +! \item [{[rc]}] @\ +! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ +! \end{description} @\ +! @\ +!EOP @\ +!---------------------------------------------------------------------------- @\ + +#define FieldEmptyCompXGMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +!---------------------------------------------------------------------------- @\ +^undef ESMF_METHOD @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompXG" @\ + subroutine ESMF_FieldEmptyCompXG##mrank##D##mtypekind(field, xgrid, & @\ + farray, indexflag, keywordEnforcer, datacopyflag, xgridside, gridindex, & @\ + gridToFieldMap, ungriddedLBound, & @\ + ungriddedUBound, rc) @\ @\ - ! gridToFieldMap elements must be in range 0...fieldRank and unique @\ - ! algorithm to check element uniqueness: @\ - ! run time: O(ESMF_MAXDIM) @\ - ! memory: O(2*ESMF_MAXDIM) @\ - ! or O(ESMF_MAXDIM+ESMF_MAXDIM/sizeof(integer)) with bitvector @\ - flipflop = .false. @\ - do i = 1, gridDimCount @\ - if(localGridToFieldMap(i) .lt. 0 .or. & @\ - localGridToFieldMap(i) .gt. fieldDimCount) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ - msg="- gridToFieldMap element must be within range 0...array rank", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - if(localGridToFieldMap(i) /= 0) then @\ - if(flipflop(localGridToFieldMap(i))) then @\ - call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_VALUE, & @\ - msg="- gridToFieldMap element must be unique", & @\ - ESMF_CONTEXT, rcToReturn=rc) @\ - return @\ - endif @\ - flipflop(localGridToFieldMap(i)) = .true. @\ - endif @\ - enddo @\ + ! input arguments @\ + type(ESMF_Field), intent(inout) :: field @\ + type(ESMF_XGrid), intent(in) :: xgrid @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), target :: farray @\ + type(ESMF_Index_Flag), intent(in) :: indexflag @\ +type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridSide @\ + integer, intent(in), optional :: gridIndex @\ + integer, intent(in), optional :: gridToFieldMap(:) @\ + integer, intent(in), optional :: ungriddedLBound(:) @\ + integer, intent(in), optional :: ungriddedUBound(:) @\ + integer, intent(out), optional :: rc @\ + ! local variables @\ + integer :: localrc @\ + type(ESMF_Geom) :: geom @\ + type(ESMF_FieldStatus_Flag) :: status @\ +@\ + if (present(rc)) then @\ + rc = ESMF_RC_NOT_IMPL @\ + endif @\ + localrc = ESMF_RC_NOT_IMPL @\ @\ - if(present(totalLWidth)) then @\ - localMaxHaloLWidth(1:gridDimCount_norep) = & @\ - totalLWidth (1:gridDimCount_norep) @\ - else @\ - localMaxHaloLWidth = 0 @\ - endif @\ + ! make sure field, xgrid, farray are properly initialized @\ + ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ + ESMF_INIT_CHECK_DEEP(ESMF_XGridGetInit,xgrid,rc) @\ @\ - if(present(totalUWidth)) then @\ - localMaxHaloUWidth(1:gridDimCount_norep) = & @\ - totalUWidth (1:gridDimCount_norep) @\ - else @\ - localMaxHaloUWidth = 0 @\ - endif @\ + call ESMF_FieldGet(field, status=status, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - ! Here we get the lbounds and ubounds for ungridded @\ - ! dimensions from the native array, if it is not input @\ - ! through the argument list. First we need to set up @\ - ! an index array that holds the ungridded dimensions of @\ - ! the native array. @\ + if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ @\ - ! Since we are saving the ungriddedIndex calculate it even @\ - ! if ungridded bounds are present @\ + geom=ESMF_GeomCreate(xgrid,xgridSide, gridIndex, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - ! Figure out which dims are ungridded @\ - isGridded = .false. @\ - do i=1, gridDimCount @\ - if(localGridToFieldMap(i) /= 0) isGridded(localGridToFieldMap(i)) = .true. @\ - enddo @\ + ! Do General Geom EmptyComp @\ + call ESMF_FieldEmptyCompGB##mrank##D##mtypekind(field, geom, farray, & @\ + indexflag=indexflag, datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ + ungriddedLBound=ungriddedLBound, & @\ + ungriddedUBound=ungriddedUBound, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - ! Use ungridded info to figure out the map from ungridded to field dims @\ - count=1 @\ - do i=1,fieldDimCount @\ - if (.not. isGridded(i)) then @\ - localUngriddedLBound(count) = lbound(farrayPtr, i) @\ - localUngriddedUBound(count) = ubound(farrayPtr, i) @\ - count=count+1 @\ - endif @\ - enddo @\ @\ - call ESMF_DistGridGet(distgrid, dimCount=distgridDimCount, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - distgridDimCount_norep = memDimCount - fieldUndistDimCount @\ + if (present(rc)) rc = ESMF_SUCCESS @\ + end subroutine ESMF_FieldEmptyCompXG##mrank##D##mtypekind @\ +!---------------------------------------------------------------------------- @\ + +TypeKindRankDeclarationMacro(FieldEmptyCompXG) + + +#define FieldEmptyCompXGPtrDoc() \ +!---------------------------------------------------------------------------- @\ +!BOP @\ +! !IROUTINE: ESMF_FieldEmptyComplete - Complete a Field from XGrid started with FieldEmptyCreate @\ +! @\ +! !INTERFACE: @\ +! ! Private name; call using ESMF_FieldEmptyComplete() @\ +! subroutine ESMF_FieldEmptyCompXGPtr(field, xgrid, & @\ +! farrayPtr, xgridside, gridindex, & @\ +! keywordEnforcer, datacopyflag, gridToFieldMap, rc) @\ +! @\ +! !ARGUMENTS: @\ +! type(ESMF_Field), intent(inout) :: field @\ +! type(ESMF_XGrid), intent(in) :: xgrid @\ +! (ESMF_KIND_), pointer :: farrayPtr() @\ +!type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ +! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ +! type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside @\ +! integer, intent(in), optional :: gridindex @\ +! integer, intent(in), optional :: gridToFieldMap(:) @\ +! integer, intent(out), optional :: rc @\ +! @\ +! !DESCRIPTION: @\ +! This call completes an {\tt ESMF\_Field} allocated with the @\ +! {\tt ESMF\_FieldEmptyCreate()} call. @\ +! @\ +! \begin{sloppypar} @\ +! The Fortran data pointer inside {\tt ESMF\_Field} can be queried and deallocated when @\ +! datacopyflag is {\tt ESMF\_DATACOPY\_REFERENCE}. Note that the {\tt ESMF\_FieldDestroy} call does not deallocate @\ +! the Fortran data pointer in this case. This gives user more flexibility over memory management. @\ +! \end{sloppypar} @\ +! @\ +! The arguments are: @\ +! \begin{description} @\ +! \item [field] @\ +! The {\tt ESMF\_Field} object to be completed and @\ +! committed in this call. The {\tt field} will have the same dimension @\ +! (dimCount) as the rank of the {\tt farrayPtr}. @\ +! \item [xgrid] @\ +! The {\tt ESMF\_XGrid} object to complete the Field. @\ +! \item [farrayPtr] @\ +! Native Fortran data pointer to be copied/referenced in the {\tt field}. @\ +! The {\tt field} dimension (dimCount) will be the same as the dimCount @\ +! for the {\tt farrayPtr}. @\ +! \item [{[datacopyflag]}] @\ +! Indicates whether to copy the {\tt farrayPtr} or reference it directly. @\ +! For valid values see \ref{const:datacopyflag}. The default is @\ +! {\tt ESMF\_DATACOPY\_REFERENCE}. @\ +! \item [{[xgridside]}] @\ +! Which side of the XGrid to create the Field on (either ESMF\_XGRIDSIDE\_A, @\ +! ESMF\_XGRIDSIDE\_B, or ESMF\_XGRIDSIDE\_BALANCED). If not passed in then @\ +! defaults to ESMF\_XGRIDSIDE\_BALANCED. @\ +! \item [{[gridindex]}] @\ +! If xgridside is ESMF\_XGRIDSIDE\_A or ESMF\_XGRIDSIDE\_B then this index tells which Grid on @\ +! that side to create the Field on. If not provided, defaults to 1. @\ +! \item [{[gridToFieldMap]}] @\ +! List with number of elements equal to the @\ +! {\tt xgrid}|s dimCount. The list elements map each dimension @\ +! of the {\tt xgrid} to a dimension in the {\tt farrayPtr} by @\ +! specifying the appropriate {\tt farrayPtr} dimension index. The @\ +! default is to map all of the {\tt xgrid}|s dimensions against the @\ +! lowest dimensions of the {\tt farrayPtr} in sequence, i.e. @\ +! {\tt gridToFieldMap} = (/1,2,3,.../). @\ +! Unmapped {\tt farrayPtr} dimensions are undistributed Field @\ +! dimensions. @\ +! All {\tt gridToFieldMap} entries must be greater than or equal @\ +! to zero and smaller than or equal to the Field dimCount. It is erroneous @\ +! to specify the same entry multiple times unless it is zero. @\ +! If the Field dimCount is less than the XGrid dimCount then the default @\ +! gridToFieldMap will contain zeros for the rightmost entries. A zero @\ +! entry in the {\tt gridToFieldMap} indicates that the particular @\ +! XGrid dimension will be replicating the Field across the DEs along @\ +! this direction. @\ +! \item [{[rc]}] @\ +! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ +! \end{description} @\ +! @\ +!EOP @\ +!---------------------------------------------------------------------------- @\ + +#define FieldEmptyCompXGPtrMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ +!---------------------------------------------------------------------------- @\ +^undef ESMF_METHOD @\ +^define ESMF_METHOD "ESMF_FieldEmptyCompXGPtr" @\ +subroutine ESMF_FieldEmptyCompXGPtr##mrank##D##mtypekind(field, xgrid, & @\ + farrayPtr, keywordEnforcer, & @\ + datacopyflag, xgridside, gridindex, gridToFieldMap, rc) @\ @\ - ! The undistributed info from the Grid needs to be @\ - ! combined with the ungridded info from the Field in order @\ - ! to create the Array for the Field. @\ - call ESMF_GeomGetArrayInfo(geom, & @\ - gridToFieldMap=localGridToFieldMap, & @\ - ungriddedLBound=localUngriddedLBound (1:fieldUngriddedDimCount), & @\ - ungriddedUBound=localUngriddedUBound (1:fieldUngriddedDimCount), & @\ - distgridToArrayMap=distgridToArrayMap, & @\ - undistLBound=undistLBound, undistUBound=undistUBound, & @\ - rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + ! input arguments @\ + type(ESMF_Field), intent(inout) :: field @\ + type(ESMF_XGrid), intent(in) :: xgrid @\ + mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ +type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside @\ + integer, intent(in), optional :: gridindex @\ + integer, intent(in), optional :: gridToFieldMap(:) @\ + integer, intent(out), optional :: rc @\ + ! local variables @\ + integer :: localrc @\ + type(ESMF_Geom) :: geom @\ + type(ESMF_FieldStatus_Flag) :: status @\ @\ - ! Create Array with undistributed dimensions @\ - if (decompType .eq. ESMF_GRID_NONARBITRARY) then @\ - array = ESMF_ArrayCreate(distgrid, farrayPtr, datacopyflag=datacopyflag, & @\ - distgridToArrayMap=distgridToArrayMap (1:distgridDimCount), & @\ - totalLWidth=localMaxHaloLWidth(1:gridDimCount_norep), & @\ - totalUWidth=localMaxHaloUWidth(1:gridDimCount_norep), & @\ - name=fieldName, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - else @\ - array = ESMF_ArrayCreate(distgrid, farrayPtr, datacopyflag=datacopyflag, & @\ - distgridToArrayMap=distgridToArrayMap (1:distgridDimCount), & @\ - name=fieldName, rc=localrc) @\ - if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + if (present(rc)) then @\ + rc = ESMF_RC_NOT_IMPL @\ endif @\ + localrc = ESMF_RC_NOT_IMPL @\ @\ - field%ftypep%array = array @\ + ! make sure field, xgrid, farrayPtr are properly initialized @\ + ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) @\ + ESMF_INIT_CHECK_DEEP(ESMF_XGridGetInit,xgrid,rc) @\ @\ - ! set array_internal to .true. because field%array is internal @\ - field%ftypep%array_internal = .true. @\ + call ESMF_FieldGet(field, status=status, rc=localrc) @\ + if (ESMF_LogFoundError(localrc, & @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - ! Should call a common FieldEmptyCompPtrConstructor here instead @\ - ! of just setting things up ourselves @\ - ! (The field Sets were all moved here in preparation for this) @\ - field%ftypep%gridToFieldMap(1:gridDimCount) = & @\ - localGridToFieldMap(1:gridDimCount) @\ - field%ftypep%totalLWidth(1:gridDimCount_norep) = & @\ - localMaxHaloLWidth (1:gridDimCount_norep) @\ - field%ftypep%totalUWidth(1:gridDimCount_norep) = & @\ - localMaxHaloUWidth (1:gridDimCount_norep) @\ - field%ftypep%ungriddedLBound(1:fieldUngriddedDimCount) = & @\ - localUngriddedLBound(1:fieldUngriddedDimCount) @\ - field%ftypep%ungriddedUBound(1:fieldUngriddedDimCount) = & @\ - localUngriddedUBound(1:fieldUngriddedDimCount) @\ - field%ftypep%geom = geom @\ - field%ftypep%status = ESMF_FIELDSTATUS_COMPLETE @\ - call ESMF_BaseSetStatus(field%ftypep%base, ESMF_STATUS_READY, rc=localrc) @\ + if(status /= ESMF_FIELDSTATUS_EMPTY) then @\ + call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & @\ + msg="- can only use this ESMF_FieldEmptyComplete with empty Field", & @\ + ESMF_CONTEXT, rcToReturn=rc) @\ + return @\ + endif @\ +@\ + geom=ESMF_GeomCreate(xgrid, xgridSide, gridIndex, rc=localrc) @\ if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ - field%ftypep%dimCount = gridDimCount_norep + fieldUndistDimCount @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ - call ESMF_FieldValidate(field, rc=localrc) @\ +! Do General Geom EmptyComp @\ +call ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind(field, geom, farrayPtr, & @\ + datacopyflag=datacopyflag, gridToFieldMap=gridToFieldMap, & @\ + rc=localrc) @\ if (ESMF_LogFoundError(localrc, & @\ - ESMF_ERR_PASSTHRU, & @\ - ESMF_CONTEXT, rcToReturn=rc)) return @\ + ESMF_ERR_PASSTHRU, & @\ + ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ if (present(rc)) rc = ESMF_SUCCESS @\ -end subroutine ESMF_FieldEmptyCompGBPtr##mrank##D##mtypekind @\ +end subroutine ESMF_FieldEmptyCompXGPtr##mrank##D##mtypekind @\ !---------------------------------------------------------------------------- @\ -TypeKindRankDeclarationMacro(FieldEmptyCompGBPtr) +TypeKindRankDeclarationMacro(FieldEmptyCompXGPtr) !------------------------------------------------------------------------------