ESMF_FieldHalo.F90 Source File


This file depends on

sourcefile~~esmf_fieldhalo.f90~~EfferentGraph sourcefile~esmf_fieldhalo.f90 ESMF_FieldHalo.F90 sourcefile~esmf_array.f90 ESMF_Array.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_array.f90 sourcefile~esmf_base.f90 ESMF_Base.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_base.f90 sourcefile~esmf_delayout.f90 ESMF_DELayout.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_delayout.f90 sourcefile~esmf_field.f90 ESMF_Field.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_field.f90 sourcefile~esmf_initmacros.f90 ESMF_InitMacros.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_initmacros.f90 sourcefile~esmf_logerr.f90 ESMF_LogErr.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_logerr.f90 sourcefile~esmf_rhandle.f90 ESMF_RHandle.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_rhandle.f90 sourcefile~esmf_util.f90 ESMF_Util.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_util.f90 sourcefile~esmf_utiltypes.f90 ESMF_UtilTypes.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_vm.f90 ESMF_VM.F90 sourcefile~esmf_fieldhalo.f90->sourcefile~esmf_vm.f90 sourcefile~esmf_array.f90->sourcefile~esmf_base.f90 sourcefile~esmf_array.f90->sourcefile~esmf_delayout.f90 sourcefile~esmf_array.f90->sourcefile~esmf_initmacros.f90 sourcefile~esmf_array.f90->sourcefile~esmf_logerr.f90 sourcefile~esmf_array.f90->sourcefile~esmf_rhandle.f90 sourcefile~esmf_array.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_array.f90->sourcefile~esmf_vm.f90 sourcefile~esmf_arrayha.f90 ESMF_ArrayHa.F90 sourcefile~esmf_array.f90->sourcefile~esmf_arrayha.f90 sourcefile~esmf_arrayspec.f90 ESMF_ArraySpec.F90 sourcefile~esmf_array.f90->sourcefile~esmf_arrayspec.f90 sourcefile~esmf_distgrid.f90 ESMF_DistGrid.F90 sourcefile~esmf_array.f90->sourcefile~esmf_distgrid.f90 sourcefile~esmf_dynamicmask.f90 ESMF_DynamicMask.F90 sourcefile~esmf_array.f90->sourcefile~esmf_dynamicmask.f90 sourcefile~esmf_f90interface.f90 ESMF_F90Interface.F90 sourcefile~esmf_array.f90->sourcefile~esmf_f90interface.f90 sourcefile~esmf_factorread.f90 ESMF_FactorRead.F90 sourcefile~esmf_array.f90->sourcefile~esmf_factorread.f90 sourcefile~esmf_localarray.f90 ESMF_LocalArray.F90 sourcefile~esmf_array.f90->sourcefile~esmf_localarray.f90 sourcefile~esmf_base.f90->sourcefile~esmf_initmacros.f90 sourcefile~esmf_base.f90->sourcefile~esmf_logerr.f90 sourcefile~esmf_base.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_base.f90->sourcefile~esmf_vm.f90 sourcefile~esmf_ioutil.f90 ESMF_IOUtil.F90 sourcefile~esmf_base.f90->sourcefile~esmf_ioutil.f90 sourcefile~esmf_delayout.f90->sourcefile~esmf_base.f90 sourcefile~esmf_delayout.f90->sourcefile~esmf_initmacros.f90 sourcefile~esmf_delayout.f90->sourcefile~esmf_logerr.f90 sourcefile~esmf_delayout.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_delayout.f90->sourcefile~esmf_vm.f90 sourcefile~esmf_delayout.f90->sourcefile~esmf_f90interface.f90 sourcefile~esmf_delayout.f90->sourcefile~esmf_ioutil.f90 sourcefile~esmf_field.f90->sourcefile~esmf_array.f90 sourcefile~esmf_field.f90->sourcefile~esmf_base.f90 sourcefile~esmf_field.f90->sourcefile~esmf_delayout.f90 sourcefile~esmf_field.f90->sourcefile~esmf_initmacros.f90 sourcefile~esmf_field.f90->sourcefile~esmf_logerr.f90 sourcefile~esmf_field.f90->sourcefile~esmf_util.f90 sourcefile~esmf_field.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_field.f90->sourcefile~esmf_arrayspec.f90 sourcefile~esmf_field.f90->sourcefile~esmf_distgrid.f90 sourcefile~esmf_geom.f90 ESMF_Geom.F90 sourcefile~esmf_field.f90->sourcefile~esmf_geom.f90 sourcefile~esmf_grid.f90 ESMF_Grid.F90 sourcefile~esmf_field.f90->sourcefile~esmf_grid.f90 sourcefile~esmf_info.f90 ESMF_Info.F90 sourcefile~esmf_field.f90->sourcefile~esmf_info.f90 sourcefile~esmf_field.f90->sourcefile~esmf_localarray.f90 sourcefile~esmf_locstream.f90 ESMF_LocStream.F90 sourcefile~esmf_field.f90->sourcefile~esmf_locstream.f90 sourcefile~esmf_mesh.f90 ESMF_Mesh.F90 sourcefile~esmf_field.f90->sourcefile~esmf_mesh.f90 sourcefile~esmf_staggerloc.f90 ESMF_StaggerLoc.F90 sourcefile~esmf_field.f90->sourcefile~esmf_staggerloc.f90 sourcefile~esmf_time.f90 ESMF_Time.F90 sourcefile~esmf_field.f90->sourcefile~esmf_time.f90 sourcefile~esmf_xgrid.f90 ESMF_XGrid.F90 sourcefile~esmf_field.f90->sourcefile~esmf_xgrid.f90 sourcefile~esmf_xgridcreate.f90 ESMF_XGridCreate.F90 sourcefile~esmf_field.f90->sourcefile~esmf_xgridcreate.f90 sourcefile~esmf_initmacros.f90->sourcefile~esmf_logerr.f90 sourcefile~esmf_initmacros.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_logerr.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_logerr.f90->sourcefile~esmf_ioutil.f90 sourcefile~esmf_utilstring.f90 ESMF_UtilString.F90 sourcefile~esmf_logerr.f90->sourcefile~esmf_utilstring.f90 sourcefile~esmf_rhandle.f90->sourcefile~esmf_base.f90 sourcefile~esmf_rhandle.f90->sourcefile~esmf_initmacros.f90 sourcefile~esmf_rhandle.f90->sourcefile~esmf_logerr.f90 sourcefile~esmf_rhandle.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_rhandle.f90->sourcefile~esmf_vm.f90 sourcefile~esmf_rhandle.f90->sourcefile~esmf_f90interface.f90 sourcefile~esmf_rhandle.f90->sourcefile~esmf_ioutil.f90 sourcefile~esmf_util.f90->sourcefile~esmf_initmacros.f90 sourcefile~esmf_util.f90->sourcefile~esmf_logerr.f90 sourcefile~esmf_util.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_util.f90->sourcefile~esmf_ioutil.f90 sourcefile~esmf_util.f90->sourcefile~esmf_utilstring.f90 sourcefile~esmf_vm.f90->sourcefile~esmf_initmacros.f90 sourcefile~esmf_vm.f90->sourcefile~esmf_logerr.f90 sourcefile~esmf_vm.f90->sourcefile~esmf_utiltypes.f90 sourcefile~esmf_vm.f90->sourcefile~esmf_f90interface.f90 sourcefile~esmf_vm.f90->sourcefile~esmf_ioutil.f90

Files dependent on this one

sourcefile~~esmf_fieldhalo.f90~~AfferentGraph sourcefile~esmf_fieldhalo.f90 ESMF_FieldHalo.F90 sourcefile~esmf.f90 ESMF.F90 sourcefile~esmf.f90->sourcefile~esmf_fieldhalo.f90

Source Code

! $Id$
!
! Earth System Modeling Framework
! Copyright (c) 2002-2025, University Corporation for Atmospheric Research, 
! Massachusetts Institute of Technology, Geophysical Fluid Dynamics 
! Laboratory, University of Michigan, National Centers for Environmental 
! Prediction, Los Alamos National Laboratory, Argonne National Laboratory, 
! NASA Goddard Space Flight Center.
! Licensed under the University of Illinois-NCSA License.
!
!==============================================================================
#define ESMF_FILENAME "ESMF_FieldHalo.F90"
!==============================================================================
!
! ESMF Field Halo Module
module ESMF_FieldHaloMod
!
!==============================================================================
!
! This file contains the Fortran implementation of Field Halo methods.
!
!------------------------------------------------------------------------------
! INCLUDES
#include "ESMF.h"

!==============================================================================
!BOPI
! !MODULE: ESMF_FieldHaloMod
!

!   Fortran API of Field Halo
!
!------------------------------------------------------------------------------

! !USES:
  use ESMF_UtilTypesMod     ! ESMF utility types
  use ESMF_InitMacrosMod    ! ESMF initializer macros
  use ESMF_BaseMod          ! ESMF base class
  use ESMF_LogErrMod        ! ESMF error handling
  use ESMF_ArrayMod
  use ESMF_FieldMod
  use ESMF_FieldGetMod
  use ESMF_VMMod
  use ESMF_DELayoutMod
  use ESMF_RHandleMod
  use ESMF_UtilMod

  implicit none

!------------------------------------------------------------------------------
! !PRIVATE TYPES:
  private
      
!------------------------------------------------------------------------------
! !PUBLIC TYPES:
      
!------------------------------------------------------------------------------

!------------------------------------------------------------------------------
!
! !PUBLIC MEMBER FUNCTIONS:

! - ESMF-public methods:
  public ESMF_FieldHalo
  public ESMF_FieldHaloRelease
  public ESMF_FieldHaloStore
  public ESMF_FieldIsCreated          ! Check if a Field object is created
  public ESMF_FieldLog

!EOPI
!------------------------------------------------------------------------------

!------------------------------------------------------------------------------
! The following line turns the CVS identifier string into a printable variable.
  character(*), parameter, private :: version = &
    '$Id$'

!==============================================================================
! 
! INTERFACE BLOCKS
!
!==============================================================================


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

contains

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!



!==================== communication calls ===========================


!------------------------------------------------------------------------------
#undef  ESMF_METHOD
#define ESMF_METHOD "ESMF_FieldHalo()"
!BOP
! !IROUTINE: ESMF_FieldHalo - Execute a FieldHalo operation
!
! !INTERFACE:
  subroutine ESMF_FieldHalo(field, routehandle, keywordEnforcer,  &
                            routesyncflag, finishedflag, checkflag, rc)
!
! !ARGUMENTS:
    type(ESMF_Field),          intent(inout)          :: field
    type(ESMF_RouteHandle),    intent(inout)          :: routehandle
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords for the below
    type(ESMF_RouteSync_Flag), intent(in),  optional  :: routesyncflag
    logical,                   intent(out), optional  :: finishedflag
    logical,                   intent(in),  optional  :: checkflag
    integer,                   intent(out), optional  :: rc
!
!
! !STATUS:
! \begin{itemize}
! \item\apiStatusCompatibleVersion{5.2.0r}
! \end{itemize}
!
! !DESCRIPTION:
!   Execute a precomputed Field halo operation for {\tt field}. 
!   The {\tt field} argument must match the Field used during 
!   {\tt ESMF\_FieldHaloStore()} in {\em type}, {\em kind}, and 
!   memory layout of the {\em gridded} dimensions. However, the size, number, 
!   and index order of {\em ungridded} dimensions may be different. See section
!   \ref{RH:Reusability} for a more detailed discussion of RouteHandle 
!   reusability.
!
!   See {\tt ESMF\_FieldHaloStore()} on how to precompute {\tt routehandle}.
!
!   This call is {\em collective} across the current VM.
!
!   \begin{description}
!   \item [field]
!     {\tt ESMF\_Field} containing data to be haloed.
!   \item [routehandle]
!     Handle to the precomputed Route.
!   \item [{[routesyncflag]}]
!     Indicate communication option. Default is {\tt ESMF\_ROUTESYNC\_BLOCKING},
!     resulting in a blocking operation.
!     See section \ref{const:routesync} for a complete list of valid settings.
!   \item [{[finishedflag]}]
!     \begin{sloppypar}
!     Used in combination with {\tt routesyncflag = ESMF\_ROUTESYNC\_NBTESTFINISH}.
!     Returned {\tt finishedflag} equal to {\tt .true.} indicates that all
!     operations have finished. A value of {\tt .false.} indicates that there
!     are still unfinished operations that require additional calls with
!     {\tt routesyncflag = ESMF\_ROUTESYNC\_NBTESTFINISH}, or a final call with
!     {\tt routesyncflag = ESMF\_ROUTESYNC\_NBWAITFINISH}. For all other {\tt routesyncflag}
!     settings the returned value in {\tt finishedflag} is always {\tt .true.}.
!     \end{sloppypar}
!   \item [{[checkflag]}]
!     If set to {\tt .TRUE.} the input Field pair will be checked for
!     consistency with the precomputed operation provided by {\tt routehandle}.
!     If set to {\tt .FALSE.} {\em (default)} only a very basic input check
!     will be performed, leaving many inconsistencies undetected. Set
!     {\tt checkflag} to {\tt .FALSE.} to achieve highest performance.
!   \item [{[rc]}]
!     Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!   \end{description}
!
!EOP
!------------------------------------------------------------------------------
    integer                 :: localrc      ! local return code

    ! local variables
    type(ESMF_Array)        :: array

    ! initialize return code; assume routine not implemented
    localrc = ESMF_RC_NOT_IMPL
    if (present(rc)) rc = ESMF_RC_NOT_IMPL

    ! Check init status of arguments
    ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, field, rc)
    ESMF_INIT_CHECK_DEEP(ESMF_RouteHandleGetInit, routehandle, rc)
    
    call ESMF_FieldGet(field, array=array, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return
    
    ! Call into the Array interface, which will sort out optional arguments
    call ESMF_ArrayHalo(array, routehandle=routehandle, routesyncflag=routesyncflag, &
      finishedflag=finishedflag, checkflag=checkflag, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return
    
    ! return successfully
    if (present(rc)) rc = ESMF_SUCCESS

  end subroutine ESMF_FieldHalo
!------------------------------------------------------------------------------


!------------------------------------------------------------------------------
#undef  ESMF_METHOD
#define ESMF_METHOD "ESMF_FieldHaloRelease()"
!BOP
! !IROUTINE: ESMF_FieldHaloRelease - Release resources associated with a Field halo operation
!
! !INTERFACE:
  subroutine ESMF_FieldHaloRelease(routehandle, keywordEnforcer, noGarbage, rc)
!
! !ARGUMENTS:
    type(ESMF_RouteHandle), intent(inout)           :: routehandle
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
    logical,                intent(in),   optional  :: noGarbage
    integer,                intent(out),  optional  :: rc
!
!
! !STATUS:
! \begin{itemize}
! \item\apiStatusCompatibleVersion{5.2.0r}
! \item\apiStatusModifiedSinceVersion{5.2.0r}
! \begin{description}
! \item[8.0.0] Added argument {\tt noGarbage}.
!   The argument provides a mechanism to override the default garbage collection
!   mechanism when destroying an ESMF object.
! \end{description}
! \end{itemize}
!
! !DESCRIPTION:
!   Release resources associated with a Field halo operation.
!   After this call {\tt routehandle} becomes invalid.
!
!   \begin{description}
!   \item [routehandle]
!     Handle to the precomputed Route.
!   \item[{[noGarbage]}]
!     If set to {\tt .TRUE.} the object will be fully destroyed and removed
!     from the ESMF garbage collection system. Note however that under this 
!     condition ESMF cannot protect against accessing the destroyed object 
!     through dangling aliases -- a situation which may lead to hard to debug 
!     application crashes.
! 
!     It is generally recommended to leave the {\tt noGarbage} argument
!     set to {\tt .FALSE.} (the default), and to take advantage of the ESMF 
!     garbage collection system which will prevent problems with dangling
!     aliases or incorrect sequences of destroy calls. However this level of
!     support requires that a small remnant of the object is kept in memory
!     past the destroy call. This can lead to an unexpected increase in memory
!     consumption over the course of execution in applications that use 
!     temporary ESMF objects. For situations where the repeated creation and 
!     destruction of temporary objects leads to memory issues, it is 
!     recommended to call with {\tt noGarbage} set to {\tt .TRUE.}, fully 
!     removing the entire temporary object from memory.
!   \item [{[rc]}]
!     Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!   \end{description}
!
!EOP
!------------------------------------------------------------------------------
    integer                 :: localrc      ! local return code

    ! initialize return code; assume routine not implemented
    localrc = ESMF_RC_NOT_IMPL
    if (present(rc)) rc = ESMF_RC_NOT_IMPL

    ! Check init status of arguments, deal with optional Array args
    ESMF_INIT_CHECK_DEEP(ESMF_RouteHandleGetInit, routehandle, rc)
        
    ! Call into the RouteHandle code
    call ESMF_RouteHandleRelease(routehandle, noGarbage=noGarbage, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return
    
    ! return successfully
    if (present(rc)) rc = ESMF_SUCCESS

  end subroutine ESMF_FieldHaloRelease
!------------------------------------------------------------------------------


!------------------------------------------------------------------------------
#undef  ESMF_METHOD
#define ESMF_METHOD "ESMF_FieldHaloStore()"
!BOP
! !IROUTINE: ESMF_FieldHaloStore - Store a FieldHalo operation
!
! !INTERFACE:
    subroutine ESMF_FieldHaloStore(field, routehandle, keywordEnforcer,  &
      startregion, haloLDepth, haloUDepth, rc)
!
! !ARGUMENTS:
    type(ESMF_Field),            intent(inout)           :: field
    type(ESMF_RouteHandle),      intent(inout)           :: routehandle
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
    type(ESMF_StartRegion_Flag), intent(in),    optional :: startregion
    integer,                     intent(in),    optional :: haloLDepth(:)
    integer,                     intent(in),    optional :: haloUDepth(:)
    integer,                     intent(out),   optional :: rc
!
!
! !STATUS:
! \begin{itemize}
! \item\apiStatusCompatibleVersion{5.2.0r}
! \end{itemize}
!
! !DESCRIPTION:
!   Store a Field halo operation over the data in {\tt field}. By default,
!   i.e. without specifying {\tt startregion}, {\tt haloLDepth} and
!   {\tt haloUDepth}, all elements in the total Field region that lie outside
!   the exclusive region will be considered potential destination elements for
!   halo. However, only those elements that have a corresponding halo source
!   element, i.e. an exclusive element on one of the DEs, will be updated under
!   the halo operation. Elements that have no associated source remain 
!   unchanged under halo.
!
!   Specifying {\tt startregion} allows to change the shape of the 
!   effective halo region from the inside. Setting this flag to
!   {\tt ESMF\_STARTREGION\_COMPUTATIONAL} means that only elements outside 
!   the computational region of the Field are considered for potential
!   destination elements for the halo operation. The default is {\tt ESMF\_STARTREGION\_EXCLUSIVE}.
!
!   The {\tt haloLDepth} and {\tt haloUDepth} arguments allow to reduce
!   the extent of the effective halo region. Starting at the region specified
!   by {\tt startregion}, the {\tt haloLDepth} and {\tt haloUDepth}
!   define a halo depth in each direction. Note that the maximum halo region is
!   limited by the total Field region, independent of the actual
!   {\tt haloLDepth} and {\tt haloUDepth} setting. The total Field region is
!   local DE specific. The {\tt haloLDepth} and {\tt haloUDepth} are interpreted
!   as the maximum desired extent, reducing the potentially larger region
!   available for the halo operation.
!
!   The routine returns an {\tt ESMF\_RouteHandle} that can be used to call 
!   {\tt ESMF\_FieldHalo()} on any Field that matches 
!   {\tt field} in {\em type}, {\em kind}, and 
!   memory layout of the {\em gridded} dimensions. However, the size, number, 
!   and index order of {\em ungridded} dimensions may be different. See section
!   \ref{RH:Reusability} for a more detailed discussion of RouteHandle 
!   reusability.
!  
!   This call is {\em collective} across the current VM.  
!
!   \begin{description}
!   \item [field]
!     {\tt ESMF\_Field} containing data to be haloed. The data in this Field may be
!     destroyed by this call.
!   \item [routehandle]
!     Handle to the precomputed Route.
!   \item [{[startregion]}]
!     \begin{sloppypar}
!     The start of the effective halo region on every DE. The default
!     setting is {\tt ESMF\_STARTREGION\_EXCLUSIVE}, rendering all non-exclusive
!     elements potential halo destination elements.
!     See section \ref{const:startregion} for a complete list of
!     valid settings.
!     \end{sloppypar}
!   \item[{[haloLDepth]}] 
!     This vector specifies the lower corner of the effective halo
!     region with respect to the lower corner of {\tt startregion}.
!     The size of {\tt haloLDepth} must equal the number of distributed Array
!     dimensions.
!   \item[{[haloUDepth]}] 
!     This vector specifies the upper corner of the effective halo
!     region with respect to the upper corner of {\tt startregion}.
!     The size of {\tt haloUDepth} must equal the number of distributed Array
!     dimensions.
!   \item [{[rc]}]
!     Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!   \end{description}
!
!EOP
!------------------------------------------------------------------------------
    integer                         :: localrc        ! local return code

    ! local variables
    type(ESMF_Array)                :: array

    ! initialize return code; assume routine not implemented
    localrc = ESMF_RC_NOT_IMPL
    if (present(rc)) rc = ESMF_RC_NOT_IMPL

    ! Check init status of arguments
    ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, field, rc)
    
    ! query the field for its internal array
    call ESMF_FieldGet(field, array=array, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return

    ! Call into the Array interface, which will sort out optional arguments
    call ESMF_ArrayHaloStore(array, routehandle=routehandle, &
      startregion=startregion, haloLDepth=haloLDepth, &
      haloUDepth=haloUDepth, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return
    
    ! return successfully
    if (present(rc)) rc = ESMF_SUCCESS

  end subroutine ESMF_FieldHaloStore
!------------------------------------------------------------------------------


!------------------------------------------------------------------------------
#undef  ESMF_METHOD
#define ESMF_METHOD "ESMF_FieldIsCreated()"
!BOP
! !IROUTINE: ESMF_FieldIsCreated - Check whether a Field object has been created

! !INTERFACE:
  function ESMF_FieldIsCreated(field, keywordEnforcer, rc)
! !RETURN VALUE:
    logical :: ESMF_FieldIsCreated
!
! !ARGUMENTS:
    type(ESMF_Field), intent(in)            :: field
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
    integer,             intent(out), optional :: rc

! !DESCRIPTION:
!   Return {\tt .true.} if the {\tt field} has been created. Otherwise return 
!   {\tt .false.}. If an error occurs, i.e. {\tt rc /= ESMF\_SUCCESS} is 
!   returned, the return value of the function will also be {\tt .false.}.
!
! The arguments are:
!   \begin{description}
!   \item[field]
!     {\tt ESMF\_Field} queried.
!   \item[{[rc]}]
!     Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!   \end{description}
!
!EOP
!------------------------------------------------------------------------------
    ESMF_FieldIsCreated = .false.   ! initialize
    if (present(rc)) rc = ESMF_SUCCESS
    if (ESMF_FieldGetInit(field)==ESMF_INIT_CREATED) &
      ESMF_FieldIsCreated = .true.
  end function
!------------------------------------------------------------------------------


!------------------------------------------------------------------------------
#undef  ESMF_METHOD
#define ESMF_METHOD "ESMF_FieldLog()"
!BOP
! !IROUTINE: ESMF_FieldLog - Log Field information

! !INTERFACE:
  subroutine ESMF_FieldLog(field, keywordEnforcer, prefix, logMsgFlag, deepFlag, rc)
!
! !ARGUMENTS:
    type(ESMF_Field),       intent(in)              :: field
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
    character(len=*),       intent(in),   optional  :: prefix
    type(ESMF_LogMsg_Flag), intent(in),   optional  :: logMsgFlag
    logical,                intent(in),   optional  :: deepFlag
    integer, intent(out),                 optional  :: rc
!
! !DESCRIPTION:
!   Write information about {\tt field} to the ESMF default Log.
!
!   The arguments are:
!   \begin{description}
!   \item[field]
!     The {\tt ESMF\_Field} object logged.
!   \item [{[prefix]}]
!     String to prefix the log message. Default is no prefix.
!   \item [{[logMsgFlag]}]
!     Type of log message generated. See section \ref{const:logmsgflag} for
!     a list of valid message types. Default is {\tt ESMF\_LOGMSG\_INFO}.
!   \item[{[deepFlag]}]
!     When set to {\tt .false.} (default), only log top level information about
!     the Field.
!     When set to {\tt .true.}, additionally log deep information.
!   \item[{[rc]}] 
!     Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!   \end{description}
!
!EOP
!------------------------------------------------------------------------------
    integer                       :: localrc      ! local return code
    type(ESMF_LogMsg_Flag)        :: logMsg
    character(len=:), allocatable :: prefixStr
    logical                       :: deepLog
    type(ESMF_FieldStatus_Flag)   :: fieldStatus
    type(ESMF_TypeKind_Flag)      :: typekind
    integer                       :: rank, dimCount
    character(ESMF_MAXSTR)        :: name, tempString
    character(800)                :: msgString
    type(ESMF_Array)              :: array

    ! initialize return code; assume routine not implemented
    localrc = ESMF_RC_NOT_IMPL
    if (present(rc)) rc = ESMF_RC_NOT_IMPL

    ! optional prefix
    if (present(prefix)) then
      prefixStr = trim(prefix)
    else
      prefixStr = ""
    endif

    ! deal with optional logMsgFlag
    logMsg = ESMF_LOGMSG_INFO ! default
    if (present(logMsgFlag)) logMsg = logMsgFlag

    ! deal with optional deepFlag
    deepLog = .false. ! default
    if (present(deepFlag)) deepLog = deepFlag

    call ESMF_LogWrite(ESMF_StringConcat(trim(prefixStr), &
      "--- FieldLog() start -----------------"), logMsg, rc=localrc)
    if (ESMF_LogFoundError(localrc, &
      ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return

    if (.not. ESMF_FieldIsCreated(field)) then
      call ESMF_LogWrite(ESMF_StringConcat(prefix, &
        "Field object is invalid! Not created or deleted!"), &
        logMsg, rc=localrc)
      if (ESMF_LogFoundError(localrc, &
        ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return
    else
      ! query
      call ESMF_FieldGet(field, name=name, status=fieldStatus, rc=localrc)
      if (ESMF_LogFoundError(localrc, &
        ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return

      if (fieldStatus==ESMF_FIELDSTATUS_EMPTY) then
        tempString = "ESMF_FIELDSTATUS_EMPTY"
      else if (fieldStatus==ESMF_FIELDSTATUS_GRIDSET) then
        tempString = "ESMF_FIELDSTATUS_GRIDSET"
      else if (fieldStatus==ESMF_FIELDSTATUS_COMPLETE) then
        tempString = "ESMF_FIELDSTATUS_COMPLETE"
      else
        tempString = "Out or range FIELDSTATUS!!!"
      endif

      write (msgString,'(A,A,A,A,A,A)') &
        prefix, "<name: ", trim(name), "> <fieldStatus: ", trim(tempString), ">"
      call ESMF_LogWrite(trim(msgString), logMsg, rc=localrc)
      if (ESMF_LogFoundError(localrc, &
        ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return

      call c_esmc_vmlogpointer(field, prefix, logMsg)

      if (fieldStatus == ESMF_FIELDSTATUS_COMPLETE) then
        call ESMF_FieldGet(field, typekind=typekind, rank=rank, &
          dimCount=dimCount, rc=localrc)
        if (ESMF_LogFoundError(localrc, &
          ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return

        call ESMF_TypeKindString(typekind, string=tempString, rc=localrc)
        if (ESMF_LogFoundError(localrc, &
          ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return

        write (msgString,'(A,A,A,A,A,I4,A,A,I4,A)') &
          prefix, "<typekind: ", trim(tempString), ">", &
          " <rank: ", rank, ">", " <dimCount: ", dimCount, ">"
        call ESMF_LogWrite(trim(msgString), logMsg, rc=localrc)
        if (ESMF_LogFoundError(localrc, &
          ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return

        if (deepLog) then
          call ESMF_FieldGet(field, array=array, rc=localrc)
          if (ESMF_LogFoundError(localrc, &
            ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
          call ESMF_ArrayLog(array, &
            prefix=ESMF_StringConcat(prefix, "! "), &
            logMsgFlag=logMsg, deepFlag=deepLog, rc=localrc)
          if (ESMF_LogFoundError(localrc, &
            ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
        endif

      endif
    endif

    call ESMF_LogWrite(ESMF_StringConcat(trim(prefixStr), &
      "--- FieldLog() end -------------------"), logMsg, rc=localrc)
    if (ESMF_LogFoundError(localrc, &
      ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return

    ! return successfully
    if (present(rc)) rc = ESMF_SUCCESS

  end subroutine ESMF_FieldLog
!------------------------------------------------------------------------------

end module ESMF_FieldHaloMod