function ESMF_GridCreateFrmNCFile(filename, fileformat, keywordEnforcer, regDecomp, &
decompflag, delayout, isSphere, polekindflag, addCornerStagger, coordTypeKind, &
addUserArea, indexflag, addMask, varname, coordNames, rc)
! !RETURN VALUE:
type(ESMF_Grid) :: ESMF_GridCreateFrmNCFile
!
! !ARGUMENTS:
character(len=*), intent(in) :: filename
type(ESMF_FileFormat_Flag), intent(in), optional :: fileformat
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
integer, intent(in), optional :: regDecomp(:)
type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:)
type(ESMF_DELayout), intent(in), optional :: delayout
logical, intent(in), optional :: isSphere
type(ESMF_PoleKind_Flag), intent(in), optional :: polekindflag(2)
logical, intent(in), optional :: addCornerStagger
type(ESMF_TypeKind_Flag),intent(in), optional :: coordTypeKind
logical, intent(in), optional :: addUserArea
type(ESMF_Index_Flag), intent(in), optional :: indexflag
logical, intent(in), optional :: addMask
character(len=*), intent(in), optional :: varname
character(len=*), intent(in), optional :: coordNames(:)
integer, intent(out), optional :: rc
! !DESCRIPTION:
! This function creates a {\tt ESMF\_Grid} object using the grid definition from
! a grid file in NetCDF that is either in the SCRIP format or in the CF convention.
! To specify the distribution, the user passes in an array
! ({\tt regDecomp}) specifying the number of DEs to divide each
! dimension into. The array {\tt decompflag} indicates how the division into DEs is to
! occur. The default is to divide the range as evenly as possible.
! The grid defined in the file has to be a 2D logically rectangular
! grid.
!
! This call is {\em collective} across the current VM.
!
! The arguments are:
! \begin{description}
! \item[filename]
! The NetCDF Grid filename.
! \item[{[fileformat]}]
! The file format. The valid options are {\tt ESMF\_FILEFORMAT\_SCRIP} and {\tt ESMF\_FILEFORMAT\_GRIDSPEC}.
! If it is the SCRIP format, the dimension {\tt grid\_rank} in the file has to be equal to 2.
! Please see section~\ref{const:fileformatflag} for a detailed
! description of the options. If not specified, the filetype will be automatically detected.
! \item[{[regDecomp]}]
! A 2 element array specifying how the grid is decomposed.
! Each entry is the number of decounts for that dimension.
! The total decounts cannot exceed the total number of PETs. In other
! word, at most one DE is allowed per processor.
! If not specified, the default decomposition will be petCountx1.
! \item[{[decompflag]}]
! List of decomposition flags indicating how each dimension of the
! tile is to be divided between the DEs. The default setting
! is {\tt ESMF\_DECOMP\_BALANCED} in all dimensions. Please see
! section~\ref{const:decompflag} for a full description of the
! possible options. Note that currently the option
! {\tt ESMF\_DECOMP\_CYCLIC} isn't supported in Grid creation.
! \item[{[delayout]}]
! The DELayout that determines DE layout of DEs across PETs. The default is to create a default
! DELayout with the correct number of DEs according to the {\tt regDecomp}. See the documentation of
! the {\tt ESMF\_DELayoutCreate()} method for details about the default DELayout.
! \item[{[isSphere]}]
! If .true., create a periodic Grid. If .false., create a regional Grid. Defaults to .true.
! \item[{[polekindflag]}]
! Two item array which specifies the type of connection which occurs at the pole. The value in polekindflag(1)
! specifies the connection that occurs at the minimum end of the pole dimension. The value in polekindflag(2)
! specifies the connection that occurs at the maximum end of the pole dimension. Please see
! Section~\ref{const:polekind} for a full list of options. If not specified,
! the default is {\tt ESMF\_POLEKIND\_MONOPOLE} for both.
! \item[{[addCornerStagger]}]
! Uses the information in the grid file to add the Corner stagger to
! the Grid. The coordinates for the corner stagger is required for conservative
! regridding. If not specified, defaults to false.
! \item[{[coordTypeKind]}]
! The type/kind of the grid coordinate data. Only ESMF\_TYPEKIND\_R4
! and ESMF\_TYPEKIND\_R8 are allowed. Currently, ESMF\_TYPEKIND\_R4 is only
! supported for the GRIDSPEC fileformat.
! If not specified then defaults to ESMF\_TYPEKIND\_R8.
! \item[{[addUserArea]}]
! If .true., read in the cell area from the Grid file, otherwise, ESMF will calculate it. The feature
! is only supported when the grid file is in the SCRIP format. If not set, the default value is
! .false.
! \item[{[indexflag]}]
! Indicates the indexing scheme to be used in the new Grid. Please see
! section~\ref{const:indexflag} for the list of options. If not present,
! defaults to {\tt ESMF\_INDEX\_DELOCAL}.
! \item[{[addMask]}]
! If .true., generate the mask using the missing\_value attribute defined in 'varname'. This flag
! is only needed for the GRIDSPEC file format. If not set, the default value is .false.
! \item[{[varname]}]
! If addMask is true, provide a variable name stored in the grid file and
! the mask will be generated using the missing value of the data value of
! this variable. The first two dimensions of the variable has to be the
! the longitude and the latitude dimension and the mask is derived from the
! first 2D values of this variable even if this data is 3D, or 4D array.
!\item[{[coordNames]}]
! a two-element array containing the longitude and latitude variable names in a
! GRIDSPEC file if there are multiple coordinates defined in the file
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOP
type(ESMF_Grid) :: grid
type(ESMF_DistGrid) :: dgOld, dgNew
integer :: localrc
logical :: localIsSphere, localAddCorner
type(ESMF_Decomp_Flag) :: localDEcompFlag(2)
integer :: regDecompLocal(2)
type(ESMF_Index_Flag) :: localIndexFlag
type(ESMF_VM) :: vm
integer :: PetCnt
type(ESMF_FileFormat_Flag) :: localFileformat
type(ESMF_TypeKind_Flag) :: localCoordTypeKind
if (present(rc)) rc=ESMF_FAILURE
! check if the total DE counts in RegDecomp is not greater than total PETs
!
call ESMF_VMGetCurrent(vm, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! set up local pet info
call ESMF_VMGet(vm, petCount=PetCnt, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (present(fileformat)) then
localFileformat = fileformat
else
call ESMF_FileTypeCheck(filename, localFileformat, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (present(RegDecomp)) then
if (size(RegDecomp,1) > 2) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
msg="- Only 2D grid is supported in ESMF_GridCreate from file interface", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
if (PetCnt < RegDecomp(1)*RegDecomp(2)) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
msg="- The total number of DEs cannot be greater than total processor count", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
endif
if (present(regDecomp)) then
regDecompLocal(:)=regDecomp(:)
else
regDecompLocal(1)=PetCnt
regDecompLocal(2)=1
endif
if (present(isSphere)) then
localIsSphere = isSphere
else
localIsSphere = .true.
endif
if (present(addCornerStagger)) then
localAddCorner = AddCornerStagger
else
localAddCorner = .false.
endif
if (present(decompFlag)) then
localDEcompFlag = decompflag
else
localDEcompFlag(:) = ESMF_DECOMP_BALANCED
endif
if (present(indexflag)) then
localIndexFlag = indexflag
else
localIndexFlag = ESMF_INDEX_DELOCAL
endif
! Set Default coordTypeKind
if (present(coordTypeKind)) then
if (coordTypeKind .ne. ESMF_TYPEKIND_R4 .and. &
coordTypeKind .ne. ESMF_TYPEKIND_R8) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
msg="- only ESMF_TYPEKIND_R4 and ESMF_TYPEKIND_R8 are allowed", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
localCoordTypeKind=coordTypeKind
else
localCoordTypeKind=ESMF_TYPEKIND_R8
endif
! Only allow ESMF_TYPEKIND_R4 for GRIDSPEC filetye for now
if (localCoordTypeKind .eq. ESMF_TYPEKIND_R4 .and. &
localFileformat .ne. ESMF_FILEFORMAT_GRIDSPEC) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
msg="- Currently coordTypeKind == ESMF_TYPEKIND_R4 is only supported for the GRIDSPEC format", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
if (localfileformat == ESMF_FILEFORMAT_SCRIP) then
grid = ESMF_GridCreateFrmScrip(trim(filename), regDecompLocal, &
localIndexFlag, decompflag=localDEcompflag, &
isSphere=localIsSphere, polekindflag=polekindflag, &
addCornerStagger=localAddCorner, &
addUserArea=addUserArea, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else if (localfileformat == ESMF_FILEFORMAT_GRIDSPEC .or. &
localfileformat == ESMF_FILEFORMAT_TILE) then
! Right now, we call ESMF_GridCreateFrmGridspec() for both supergrid
! or regular CF Grid, eventually we will separate it into two routines
! Warning about user area in GridSpec
if (present(addUserArea)) then
if (addUserArea) then
call ESMF_LogWrite("ESMF does not currently support " // &
"user areas in GRIDSPEC format, so user areas will " // &
"not be used for the GRIDSPEC file.", &
ESMF_LOGMSG_WARNING, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
endif
if (present(addMask)) then
grid = ESMF_GridCreateFrmGridspec(trim(filename), regDecompLocal, &
localIndexFlag, decompflag=localDEcompflag, &
isSphere=localIsSphere, polekindflag=polekindflag, &
addCornerStagger=localAddCorner, &
coordTypeKind = localCoordTypeKind, &
addMask=addMask, varname=varname, coordNames=coordNames, &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else
grid = ESMF_GridCreateFrmGridspec(trim(filename), regDecompLocal, &
localIndexFlag, decompflag=localDEcompflag, &
isSphere=localIsSphere, polekindflag=polekindflag, &
addCornerStagger=localAddCorner, &
coordTypeKind = localCoordTypeKind, &
coordNames = coordNames, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
else
call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
msg="- The fileformat has to be either ESMF_FILEFORMAT_SCRIP or ESMF_FILEFORMAT_GRIDSPEC", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
ESMF_GridCreateFrmNCFile = grid
if (present(delayout)) then
! query the DistGrid from the newly created grid
call ESMF_GridGet(grid, distgrid=dgOld, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! create new DistGrid using specified DELayout
dgNew = ESMF_DistGridCreate(dgOld, delayout=delayout, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! create the final grid from intermediate grid by replacing DistGrid
ESMF_GridCreateFrmNCFile = ESMF_GridCreateCopyFromNewDG(grid, dgNew, &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! destroy the intermediate grid
call ESMF_GridDestroy(grid, noGarbage=.true., rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (present(rc)) rc=ESMF_SUCCESS
return
end function ESMF_GridCreateFrmNCFile