ESMF_LocStreamCreateFromFile Function

private function ESMF_LocStreamCreateFromFile(filename, keywordEnforcer, fileformat, varname, indexflag, centerflag, name, rc)

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: filename
type(ESMF_KeywordEnforcer), optional :: keywordEnforcer
type(ESMF_FileFormat_Flag), intent(in), optional :: fileformat
character(len=*), intent(in), optional :: varname
type(ESMF_Index_Flag), intent(in), optional :: indexflag
logical, intent(in), optional :: centerflag
character(len=*), intent(in), optional :: name
integer, intent(out), optional :: rc

Return Value type(ESMF_LocStream)


Source Code

      function ESMF_LocStreamCreateFromFile(filename, keywordEnforcer, &
           fileformat, varname, indexflag, centerflag, name, rc)
!
! !RETURN VALUE:
      type(ESMF_LocStream) :: ESMF_LocStreamCreateFromFile

!
! !ARGUMENTS:
      character (len=*),          intent(in)           :: filename
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
      type(ESMF_FileFormat_Flag), intent(in), optional :: fileformat
      character(len=*),           intent(in), optional :: varname
      type(ESMF_Index_Flag),      intent(in), optional :: indexflag
      logical,                    intent(in), optional :: centerflag
      character (len=*),          intent(in), optional :: name
      integer,                    intent(out),optional :: rc

! !DESCRIPTION:
!     Create a new {\tt ESMF\_LocStream} object and add the coordinate keys and mask key
!     to the LocStream using the coordinates defined in a grid file.  Currently, it 
!     supports the SCRIP format, the ESMF unstructured grid format and the UGRID format.
!     For a 2D or 3D grid in ESMF or UGRID format, it can construct the LocStream using either 
!     the center coordinates or the corner coordinates.  For a SCRIP format grid file, the
!     LocStream can only be constructed using the center coordinates.  In
!     addition, it supports 1D network topology in UGRID format.  When
!     construction a LocStream using a 1D UGRID, it always uses node
!     coordinates (i.e., corner coordinates). 
!
!     The arguments are:
!     \begin{description}
!     \item[filename]
!          Name of grid file to be used to create the location stream.  
!     \item[{[fileformat]}]
!     The file format.  The valid options are {\tt ESMF\_FILEFORMAT\_SCRIP},
!     {\tt ESMF\_FILEFORMAT\_ESMFMESH}, and {\tt ESMF\_FILEFORMAT\_UGRID}.
!      Please see section~\ref{const:fileformatflag} for a detailed description of the options.
!     If not specified, the default is {\tt ESMF\_FILEFORMAT\_SCRIP}.
!     \item[{[varname]}]
!         An optional variable name stored in the UGRID file to be used to
!         generate the mask 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. If not 
!         specified, no mask is used for a UGRID file.
!     \item[{[indexflag]}]
!          Flag that indicates how the DE-local indices are to be defined.
!          Defaults to {\tt ESMF\_INDEX\_DELOCAL}, which indicates
!          that the index range on each DE starts at 1. See Section~\ref{const:indexflag}
!          for the full range of options. 
!     \item[{[centerflag]}]
!          Flag that indicates whether to use the center coordinates to construct the location stream.
!          If true, use center coordinates, otherwise, use the corner coordinates.  If not specified,
!          use center coordinates as default.  For SCRIP files, only center coordinate 
!          is supported.
!     \item[{[name]}]
!          Name of the location stream
!     \item[{[rc]}]
!          Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!   \end{description}
!
!EOP

#ifdef ESMF_NETCDF
    integer :: totalpoints,totaldims
    type(ESMF_VM) :: vm
    integer :: numDim, buf(1), msgbuf(3)
    integer :: localrc
    integer :: PetNo, PetCnt
    type(ESMF_Index_Flag) :: indexflagLocal
    real(ESMF_KIND_R8), pointer :: coordX(:), coordY(:), coordZ(:)
    real(ESMF_KIND_R8), pointer :: coord2D(:,:), varbuffer(:)
    integer(ESMF_KIND_I4), pointer :: imask(:)
    integer :: starti, count, localcount, index
    integer :: remain, i
    integer :: meshid
    real(ESMF_KIND_R8) :: missingvalue
    type(ESMF_CoordSys_Flag) :: coordSys
    type(ESMF_LocStream) :: locStream
    type(ESMF_FileFormat_Flag) :: localfileformat
    logical :: localcenterflag, haveface
    character(len=16) :: units, location

    if (present(indexflag)) then
       indexflagLocal=indexflag
    else
       indexflagLocal=ESMF_INDEX_DELOCAL
    endif
    
    if (present(fileformat)) then
       localfileformat = fileformat
    else
       localfileformat = ESMF_FILEFORMAT_SCRIP
    endif

    if (present(centerflag)) then
       localcenterflag = centerflag
    else
       localcenterflag = .TRUE.
    endif

    if (localcenterflag) then
       location = 'face'
    else
       location = 'node'
    endif
    if (localfileformat == ESMF_FILEFORMAT_GRIDSPEC) then
        call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
          msg="Create LocStream from a GRIDSPEC file is not supported.", &
          ESMF_CONTEXT, rcToReturn=rc)
        return
    endif   

    if ( localfileformat == ESMF_FILEFORMAT_SCRIP .and. &
       .NOT. localcenterflag) then
        call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
          msg="Only allow center coordinates if the file is in SCRIP format", &
          ESMF_CONTEXT, rcToReturn=rc)
        return
    endif   

#if 0
    if (localfileformat /= ESMF_FILEFORMAT_UGRID .and. &
       (present(meshname) .or. present(varname))) then
        call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
          msg="Only UGRID file need the optional arguments meshname or varname", &
          ESMF_CONTEXT, rcToReturn=rc)
        return
    endif
#endif
   
    ! Initialize return code; assume failure until success is certain
    localrc = ESMF_RC_NOT_IMPL
    if (present(rc)) rc = ESMF_RC_NOT_IMPL

    ! get global vm information
    !
    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, localPet=PetNo, petCount=PetCnt, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return

    if (localfileformat == ESMF_FILEFORMAT_SCRIP) then 
       ! totaldims represent grid_ranks in SCRIP - 1 for unstructured and
       ! 2 for logically rectangular
       call ESMF_ScripInq(filename, grid_rank=totaldims, &
                          grid_size=totalpoints, rc=localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
             ESMF_CONTEXT, rcToReturn=rc)) return
       call ESMF_ScripInqUnits(filename, units=units, rc=localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
             ESMF_CONTEXT, rcToReturn=rc)) return
       if (units == 'degrees') then
          coordSys = ESMF_COORDSYS_SPH_DEG
       else
          coordSys = ESMF_COORDSYS_SPH_RAD
       endif   
#if 0
    elseif (localfileformat == ESMF_FILEFORMAT_GRIDSPEC) then
       ! totaldims is the dimension of the lat/lon variable: 1 for regular
       ! grid and 2 for curvilinear
       call ESMF_GridspecInq(filename, ndims=totaldims, &
                             grid_dims = grid_dims, &
                             coordids=varids, rc=localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
             ESMF_CONTEXT, rcToReturn=rc)) return
       totalpoints=grid_dims(1)*grid_dims(2)
#endif
    elseif (localfileformat == ESMF_FILEFORMAT_ESMFMESH) then
       ! totaldims is the coordDim, 2 for 2D and 3 for 3D
       if (localcenterflag) then
           call ESMF_EsmfInq(filename, elementCount=totalpoints, & 
                             coordDim=totaldims, rc=localrc)
       else
           call ESMF_EsmfInq(filename, nodeCount=totalpoints, &
                             coordDim=totaldims, rc=localrc)
       endif
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
             ESMF_CONTEXT, rcToReturn=rc)) return
       call ESMF_EsmfInqUnits(filename, units, rc=localrc)
       if (units == 'degrees') then
          coordSys = ESMF_COORDSYS_SPH_DEG
       elseif (units == 'radians') then
          coordSys = ESMF_COORDSYS_SPH_RAD
       else
          coordSys = ESMF_COORDSYS_CART
       endif   
    elseif (localfileformat == ESMF_FILEFORMAT_UGRID) then
       ! totaldims is the mesh_dimension (2 for 2D and 3 for 3D)
       if (localcenterflag) then
          call ESMF_UGridInq(filename, elementCount=totalpoints, &
                             meshid=meshid, nodeCoordDim=totaldims, &
                             faceCoordFlag=haveface, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
                ESMF_CONTEXT, rcToReturn=rc)) return
          if (totaldims == 1) then
             call ESMF_LogSetError(rcToCheck=ESMF_FAILURE, &
                    msg="1D grid does not have face coordinates", &
                    ESMF_CONTEXT, rcToReturn=rc)
             return
          endif
          if (.not. haveface) then
             call ESMF_LogSetError(rcToCheck=ESMF_FAILURE, &
                    msg="The grid file does not have face coordinates", &
                    ESMF_CONTEXT, rcToReturn=rc)
             return
          endif
       else
          call ESMF_UGridInq(filename, nodeCount=totalpoints, &
                             meshid=meshid, nodeCoordDim=totaldims, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
                  ESMF_CONTEXT, rcToReturn=rc)) return
       endif
       coordSys = ESMF_COORDSYS_SPH_DEG
    endif             

    localcount = totalpoints/PetCnt
    remain = totalpoints - (localcount*PetCnt)
    if (PetNo < remain) then
       localcount = localcount+1
       starti = localcount*PetNo+1
    else
       starti = localcount*PetNo+1+remain
    endif

    allocate(coordX(localcount), coordY(localcount),imask(localcount))
    if (localcount > 0) then 
       if (localfileformat == ESMF_FILEFORMAT_SCRIP) then 
          call ESMF_ScripGetVar(filename, grid_center_lon=coordX, grid_center_lat=coordY, &
                          grid_imask=imask, start=starti, count=localcount, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
             ESMF_CONTEXT, rcToReturn=rc)) return
#if 0
       elseif (localfileformat == ESMF_FILEFORMAT_GRIDSPEC) then 
          if (totaldims == 1) then
             call ESMF_GridspecGetVar1D(filename, varids, coordX, coordY, rc=localrc)
             !construct 2D arrays and do the distribution
             xdim=size(coordX)
             ydim=size(coordY)
#endif
       elseif (localfileformat == ESMF_FILEFORMAT_ESMFMESH) then
          allocate(coord2D(totaldims,localcount))
          call ESMF_EsmfGetCoords(filename, coord2D, imask, &
                               starti, localcount, localcenterflag, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
             ESMF_CONTEXT, rcToReturn=rc)) return
          coordX(:) = coord2D(1,:)
          coordY(:) = coord2D(2,:)
          if (totaldims == 3) then
            allocate(coordZ(localcount))
            coordZ(:) = coord2D(3,:)
          endif
          deallocate(coord2D)
       elseif (localfileformat == ESMF_FILEFORMAT_UGRID) then
          if (totaldims == 1) then
              allocate(coord2D(localcount, 2))
          else
              allocate(coord2D(localcount, totaldims))
          endif
          call ESMF_UGridGetCoords(filename, meshid, coord2D, &
                                starti, localcount, localcenterflag, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
             ESMF_CONTEXT, rcToReturn=rc)) return
          coordX(:) = coord2D(:,1)
          coordY(:) = coord2D(:,2)
          if (totaldims == 3) then
             allocate(coordZ(localcount))
             coordZ(:) = coord2D(:,3)
          endif
          deallocate(coord2D)
          ! Get mask from varname
          imask(:)=1
          if (present(varname)) then
             allocate(varbuffer(localcount))
             call ESMF_UGridGetVarByName(filename, varname, varbuffer, &
                                      startind=starti, count=localcount, &
                                      location=location, &
                                      missingvalue=missingvalue, rc=localrc)
             if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
                  ESMF_CONTEXT, rcToReturn=rc)) return
             do i=1,localcount
                if (varbuffer(i)==missingvalue) imask(i)=0
             enddo
             deallocate(varbuffer)
          endif
       endif
    endif
    ! create Location Stream
    locStream = ESMF_LocStreamCreate(name=name, localcount=localcount, indexflag=indexflagLocal,&
                coordSys = coordSys, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return

    !print *, PetNo, starti, localcount, coordX(1), coordY(1)
    
    ! Add coordinate keys based on coordSys
    if ((coordSys == ESMF_COORDSYS_SPH_DEG) .or. (coordSys == ESMF_COORDSYS_SPH_RAD)) then 

       call ESMF_LocStreamAddKey(locStream, 'ESMF:Lon',coordX, keyUnits=units, &
            keyLongName='Longitude', &
            datacopyflag=ESMF_DATACOPY_VALUE, rc=localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
       
       call ESMF_LocStreamAddKey(locStream, 'ESMF:Lat',coordY, keyUnits=units, &
            keyLongName='Latitude', &
            datacopyflag=ESMF_DATACOPY_VALUE, rc=localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
       
       !If 3D grid, add the height coordinates
       if (totaldims == 3) then
          if (localcount == 0) allocate(coordZ(localcount))
          call ESMF_LocStreamAddKey(locStream, 'ESMF:Radius',coordZ, &
               keyUnits='radius', &
               keyLongName='Height', &
               datacopyflag=ESMF_DATACOPY_VALUE, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
          deallocate(coordZ)
       endif
       
    else if (coordSys == ESMF_COORDSYS_CART) then
       
       call ESMF_LocStreamAddKey(locStream, 'ESMF:X',coordX, keyUnits=units, &
             datacopyflag=ESMF_DATACOPY_VALUE, rc=localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
       
       call ESMF_LocStreamAddKey(locStream, 'ESMF:Y',coordY, keyUnits=units, &
             datacopyflag=ESMF_DATACOPY_VALUE, rc=localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
       
       !If 3D grid, add the height coordinates
       if (totaldims == 3) then
          if (localcount == 0) allocate(coordZ(localcount))
          call ESMF_LocStreamAddKey(locStream, 'ESMF:Z',coordZ, &
                datacopyflag=ESMF_DATACOPY_VALUE, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
          deallocate(coordZ)
       endif       
    else
       call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, &
            msg="Unrecognized coordinate system.", &
            ESMF_CONTEXT, rcToReturn=rc)
       return
    endif
       
    !Add mask key
    call ESMF_LocStreamAddKey(locStream, 'ESMF:Mask',imask,  &
                              keyLongName='Mask', &
                              datacopyflag=ESMF_DATACOPY_VALUE, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return
   
    ! local garbage collection
    deallocate(coordX, coordY, imask)
    
    ESMF_LocStreamCreateFromFile = locStream
    
    if (present(rc)) rc=ESMF_SUCCESS
    return

#else
    if (present(rc)) rc = ESMF_RC_LIB_NOT_PRESENT
#endif

end function ESMF_LocStreamCreateFromFile