function ESMF_MeshMatch(mesh1, mesh2, rc)
!
! !RETURN VALUE:
logical :: ESMF_MeshMatch
! !ARGUMENTS:
type(ESMF_Mesh), intent(in) :: mesh1
type(ESMF_Mesh), intent(in) :: mesh2
integer, intent(out), optional :: rc
!
!
! !DESCRIPTION:
! Check if {\tt mesh1} and {\tt mesh2} match. Returns
! .true. if Mesh objects match, .false. otherwise. This
! method current just checks if mesh1 and mesh2s distgrids match,
! future work will do a more complex check.
!
! The arguments are:
! \begin{description}
! \item[mesh1]
! {\tt ESMF\_Mesh} object.
! \item[mesh2]
! {\tt ESMF\_Mesh} object.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOPI
!------------------------------------------------------------------------------
integer :: i, localrc
type(ESMF_MeshStatus_Flag) :: status1, status2
integer :: mesh1sdim, mesh1pdim, mesh2sdim, mesh2pdim
integer :: mesh1numNode, mesh1numElem, mesh2numNode, mesh2numElem
type(ESMF_CoordSys_Flag) :: mesh1coordSys, mesh2coordSys
type(ESMF_DistGridMatch_Flag) :: matchResultNode, matchResultElem
type(ESMF_DistGrid) :: nodeDistGrid1, nodeDistGrid2, &
elemDistGrid1, elemDistGrid2
real(ESMF_KIND_R8), pointer :: area1(:), area2(:)
real(ESMF_KIND_R8), allocatable :: coord1(:), coord2(:)
integer :: nOwnedNodes1, nOwnedElems1
integer :: nOwnedNodes2, nOwnedElems2
! initialize return code; assume routine not implemented
localrc = ESMF_RC_NOT_IMPL
if (present(rc)) rc = ESMF_RC_NOT_IMPL
! init to one setting in case of error
ESMF_MeshMatch = .false.
! Check init status of arguments
ESMF_INIT_CHECK_DEEP(ESMF_MeshGetInit, mesh1, rc)
ESMF_INIT_CHECK_DEEP(ESMF_MeshGetInit, mesh2, rc)
! If meshes have not been fully created
call C_ESMC_MeshGetStatus(mesh1, status1)
if (status1 .ne. ESMF_MESHSTATUS_COMPLETE) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_WRONG, &
msg="- the mesh has not been fully created", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
call C_ESMC_MeshGetStatus(mesh2, status2)
if (status2 .ne. ESMF_MESHSTATUS_COMPLETE) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_WRONG, &
msg="- the mesh has not been fully created", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
call C_ESMC_MeshGetDimensions(mesh1, mesh1sdim, mesh1pdim, &
mesh1coordSys, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call C_ESMC_MeshGetDimensions(mesh2, mesh2sdim, mesh2pdim, &
mesh2coordSys, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call C_ESMC_MeshGetOwnedNodeCount(mesh1, mesh1numNode, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call C_ESMC_MeshGetOwnedElemCount(mesh1, mesh1numElem, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call C_ESMC_MeshGetOwnedNodeCount(mesh2, mesh2numNode, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call C_ESMC_MeshGetOwnedElemCount(mesh2, mesh2numElem, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call c_ESMC_MeshGetNodeDistGrid(mesh1, nodeDistGrid1, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Set init code for deep C++ DistGrid object
call ESMF_DistGridSetInitCreated(nodeDistGrid1, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call c_ESMC_MeshGetNodeDistGrid(mesh2, nodeDistGrid2, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Set init code for deep C++ DistGrid object
call ESMF_DistGridSetInitCreated(nodeDistGrid2, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call c_ESMC_MeshGetElemDistGrid(mesh1, elemDistGrid1, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Set init code for deep C++ DistGrid object
call ESMF_DistGridSetInitCreated(elemDistGrid1, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call c_ESMC_MeshGetElemDistGrid(mesh2, elemDistGrid2, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Set init code for deep C++ DistGrid object
call ESMF_DistGridSetInitCreated(elemDistGrid2, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! For now just make match to mean that the Mesh's have the same distgrids because that's
! all the fields care about
matchResultNode=ESMF_DistGridMatch(nodeDistGrid1, nodeDistGrid2, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
matchResultElem=ESMF_DistGridMatch(elemDistGrid1, elemDistGrid2, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! return successfully
if ((matchResultNode >= ESMF_DISTGRIDMATCH_EXACT) .and. &
(matchResultElem >= ESMF_DISTGRIDMATCH_EXACT)) then
ESMF_MeshMatch = .true.
else
ESMF_MeshMatch = .false.
return
endif
! check area
allocate(area1(mesh1numElem), area2(mesh2numElem), stat=localrc)
if (ESMF_LogFoundAllocError(localrc, &
msg="- MeshMatch: Allocating area1 and area2 failed ", &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_MeshGetElemArea(mesh1, area1, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_MeshGetElemArea(mesh2, area2, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
do i = 1, mesh1numElem
if(area1(i) /= area2(i)) then
ESMF_MeshMatch = .false.
deallocate(area1, area2)
return
endif
enddo
deallocate(area1, area2)
#if 0
! check nodal coordinates
if(mesh1sdim /= mesh2sdim) then
ESMF_MeshMatch = .false.
return
endif
if(mesh1numNode /= mesh2numNode) then
ESMF_MeshMatch = .false.
return
endif
call ESMF_MeshGet(mesh1, numOwnedNodes=nOwnedNodes1, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_MeshGet(mesh2, numOwnedNodes=nOwnedNodes2, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if(nOwnedNodes1 /= nOwnedNodes2) then
ESMF_MeshMatch = .false.
return
endif
allocate(coord1(nOwnedNodes1*mesh1sdim), &
coord2(nOwnedNodes2*mesh2sdim), stat=localrc)
if (ESMF_LogFoundAllocError(localrc, &
msg="- MeshMatch: Allocating coord1 and coord2 failed ", &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_MeshGet(mesh1, ownedNodeCoords=coord1, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_MeshGet(mesh2, ownedNodeCoords=coord2, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
do i = 1, nOwnedNodes1
if(coord1(i) /= coord2(i)) then
ESMF_MeshMatch = .false.
deallocate(coord1, coord2)
return
endif
enddo
! check element coordinates
! Currently mesh element coordinates are not required
if(mesh1numElem /= mesh2numElem) then
ESMF_MeshMatch = .false.
return
endif
nCoord = mesh1numElem * mesh1sdim
allocate(coord1(nCoord), coord2(mesh2numElem), stat=localrc)
if (ESMF_LogFoundAllocError(localrc, &
msg="- MeshMatch: Allocating coord1 and coord2 failed ", &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_MeshGet(mesh1, ownedElemCoords=coord1, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_MeshGet(mesh2, ownedElemCoords=coord2, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
do i = 1, mesh1numElem
if(coord1(i) /= coord2(i)) then
ESMF_MeshMatch = .false.
deallocate(coord1, coord2)
return
endif
enddo
deallocate(coord1, coord2)
#endif
if (present(rc)) rc = ESMF_SUCCESS
end function ESMF_MeshMatch