ESMF_FieldValidate Subroutine

public subroutine ESMF_FieldValidate(field, keywordEnforcer, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_Field), intent(in) :: field
type(ESMF_KeywordEnforcer), optional :: keywordEnforcer
integer, intent(out), optional :: rc

Source Code

      subroutine ESMF_FieldValidate(field, keywordEnforcer, rc)
!
! !ARGUMENTS:
      type(ESMF_Field), intent(in)            :: field 
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
      integer,          intent(out), optional :: rc   
!
! !STATUS:
! \begin{itemize}
! \item\apiStatusCompatibleVersion{5.2.0r}
! \end{itemize}
!
! !DESCRIPTION:
!      Validates that the {\tt field} is internally consistent.
!      Currently this method determines if the {\tt field} is uninitialized 
!      or already destroyed. It validates the contained array and grid objects.
!      The code also checks if the array and grid sizes agree.
!      This check compares the distgrid contained in array and grid; 
!      then it proceeds to compare the computational bounds contained 
!      in array and grid. 
!
!      The method returns an error code if problems are found.  
!
!     The arguments are:
!     \begin{description}
!     \item [field]
!           {\tt ESMF\_Field} to validate.
!     \item [{[rc]}]
!           Return code; equals {\tt ESMF\_SUCCESS} if the {\tt field} 
!           is valid.
!     \end{description}
!
!EOP

      integer :: localrc

      type(ESMF_FieldType), pointer :: ftypep
      integer :: exclLBounds(ESMF_MAXDIM)  ! exclusive grid lower bounds
      integer :: exclUBounds(ESMF_MAXDIM)  ! exclusive grid upper bounds
      integer :: gridrank, arrayrank, gridrank_norep
      integer :: i, lDE                        ! helper variables to verify bounds
      integer :: localDECount, dimCount        ! and distgrid
      integer, allocatable :: distgridToGridMap(:)
      integer, allocatable :: distgridToPackedArrayMap(:)
      integer, allocatable :: arrayCompUBnd(:, :), arrayCompLBnd(:, :)
      type(ESMF_DistGrid)  :: arrayDistGrid, gridDistGrid
      type(ESMF_GridDecompType) :: decompType
      type(ESMF_GeomType_Flag) :: geomtype
      type(ESMF_Grid) :: grid
      type(ESMF_Status) :: basestatus

      ! Initialize
      localrc = ESMF_RC_NOT_IMPL
      if (present(rc)) rc = ESMF_RC_NOT_IMPL

      ! check variables
      ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc)

      if (.not.associated(field%ftypep)) then 
         call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_BAD, &
            msg="Uninitialized or already destroyed Field: ftypep unassociated", &
             ESMF_CONTEXT, rcToReturn=rc)
         return
      endif 

      ftypep => field%ftypep


      ! make sure the field is ready before trying to look at contents
      call ESMF_BaseGetStatus(ftypep%base, basestatus, rc=localrc)
      if (ESMF_LogFoundError(localrc, &
        ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return
      if (basestatus .ne. ESMF_STATUS_READY) then
         call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_BAD, &
            msg="Uninitialized or already destroyed Field: fieldstatus not ready", &
             ESMF_CONTEXT, rcToReturn=rc)
         return
      endif 

      ! make sure there is a grid before asking it questions.
      if (ftypep%status .eq. ESMF_FIELDSTATUS_GRIDSET .or. &
          ftypep%status .eq. ESMF_FIELDSTATUS_COMPLETE) then
          call ESMF_GeomValidate(ftypep%geom, rc=localrc)
          if (ESMF_LogFoundError(localrc, &
                                    ESMF_ERR_PASSTHRU, &
                                    ESMF_CONTEXT, rcToReturn=rc)) return

      ! get the grid decomp type if geom is grid
      decompType = ESMF_GRID_NONARBITRARY
          call ESMF_GeomGet(ftypep%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(ftypep%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   
          ! get grid dim and extents for the local piece
          call ESMF_GeomGet(ftypep%geom, dimCount=gridrank, &
                            distgrid=gridDistGrid, localDECount=localDECount, rc=localrc)
          if (localrc .ne. ESMF_SUCCESS) then
             call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_BAD, &
                msg="Cannot retrieve distgrid, gridrank, localDECount from ftypep%grid", &
                 ESMF_CONTEXT, rcToReturn=rc)
             return
          endif 
          ! Bounds only valid if there are local DE's
          do lDE=0, localDECount-1
             call ESMF_GeomGetPLocalDe(ftypep%geom, localDE=lDE,  &
                               exclusiveLBound=exclLBounds, &
                               exclusiveUBound=exclUBounds, &
                               rc=localrc)
              if (localrc .ne. ESMF_SUCCESS) then
                 call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_BAD, &
                    msg="Cannot retrieve exclusive bounds from ftypep%grid", &
                     ESMF_CONTEXT, rcToReturn=rc)
                 return
              endif 
          enddo
      endif
      ! make sure there is data before asking it questions.
      if (ftypep%status .eq. ESMF_FIELDSTATUS_COMPLETE) then
          call ESMF_ArrayValidate(array=ftypep%array, rc=localrc)
          if (localrc .ne. ESMF_SUCCESS) then
             call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_BAD, &
                msg="Cannot validate ftypep%array", &
                 ESMF_CONTEXT, rcToReturn=rc)
             return
          endif 
          call ESMF_ArrayGet(ftypep%array, dimCount=dimCount, localDECount=localDECount, &
              distgrid=arrayDistGrid, rank=arrayrank, rc=localrc)
          if (localrc .ne. ESMF_SUCCESS) then
             call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_BAD, &
                msg="Cannot retrieve dimCount, localDECount, arrayDistGrid, arrayrank from ftypep%array", &
                 ESMF_CONTEXT, rcToReturn=rc)
             return
          endif 
          
          ! Verify the distgrids in array and grid match.
          if(ESMF_DistGridMatch(gridDistGrid, arrayDistGrid, rc=localrc) &
            < ESMF_DISTGRIDMATCH_EXACT) then
              call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_BAD, &
                 msg="grid DistGrid does not match array DistGrid", &
                  ESMF_CONTEXT, rcToReturn=rc)
              return
          endif

           ! cannot use distgridToGridMap to index arrayCompBnds and compare with
          ! gridCompBnds, skip the check for arb. array for now, need to figure
          ! out how to validate -- P.Li
          if (decompType .eq. ESMF_GRID_NONARBITRARY) then

             ! Verify that array rank is greater than or equal to grid rank + ungridded bound rank
             allocate(distgridToPackedArrayMap(dimCount))

             call ESMF_ArrayGet(ftypep%array, &
                  distgridToPackedArrayMap=distgridToPackedArrayMap, &
                  rc=localrc)
             if (localrc .ne. ESMF_SUCCESS) then
                 call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_BAD, &
                 msg="Cannot retrieve distgridToPackedArrayMap from ftypep%array", &
                 ESMF_CONTEXT, rcToReturn=rc)
                return
             endif 

            ! Verify that array rank is greater than or equal to grid rank + ungridded bound rank      
            gridrank_norep = gridrank
            do i = 1, dimCount
               if( distgridToPackedArrayMap(i) == 0) gridrank_norep = gridrank_norep - 1
            enddo

            if ( arrayrank .lt. gridrank_norep) then
                call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_BAD, &
                   msg="grid rank + ungridded Bound rank not equal to array rank", &
                    ESMF_CONTEXT, rcToReturn=rc)
                return
            endif

            deallocate(distgridToPackedArrayMap)
        endif
      endif ! skip for arbitrary grid case

      if (present(rc)) rc = ESMF_SUCCESS

      end subroutine ESMF_FieldValidate