ESMF_MeshMatch Function

public function ESMF_MeshMatch(mesh1, mesh2, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_Mesh), intent(in) :: mesh1
type(ESMF_Mesh), intent(in) :: mesh2
integer, intent(out), optional :: rc

Return Value logical


Source Code

  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