ESMF_MeshCreateRedist Function

private function ESMF_MeshCreateRedist(mesh, keywordEnforcer, nodalDistgrid, elementDistgrid, vm, name, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_Mesh), intent(in) :: mesh
type(ESMF_KeywordEnforcer), optional :: keywordEnforcer
type(ESMF_DistGrid), intent(in), optional :: nodalDistgrid
type(ESMF_DistGrid), intent(in), optional :: elementDistgrid
type(ESMF_VM), intent(in), optional :: vm
character(len=*), intent(in), optional :: name
integer, intent(out), optional :: rc

Return Value type(ESMF_Mesh)


Source Code

    function ESMF_MeshCreateRedist(mesh, keywordEnforcer, nodalDistgrid, &
      elementDistgrid, vm, name, rc)
!
!
! !RETURN VALUE:
    type(ESMF_Mesh)                            :: ESMF_MeshCreateRedist

! !ARGUMENTS:
    type(ESMF_Mesh),          intent(in)            :: mesh
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
    type(ESMF_DistGrid),      intent(in),  optional :: nodalDistgrid
    type(ESMF_DistGrid),      intent(in),  optional :: elementDistgrid
    type(ESMF_VM),            intent(in),  optional :: vm
    character(len=*),         intent(in),  optional :: name
    integer,                  intent(out), optional :: rc
!
! !DESCRIPTION:
!  Create a copy of an existing Mesh with a new distribution. Information
! in the Mesh such as connections, coordinates, areas, masks, etc. are
! automatically redistributed to the new Mesh. To redistribute
! data in Fields built on the original Mesh create a Field on the new Mesh
!  and then use the Field redistribution functionality
! ({\tt ESMF\_FieldRedistStore()}, etc.). The equivalent methods
! can also be used for data in FieldBundles.
!
! \begin{description}
!  \item [mesh]
!         The source Mesh to be redistributed.
!  \item [{[nodalDistgrid]}]
!         A Distgrid describing the new distribution of
!         the nodes across the PETs.
!  \item [{[elementDistgrid]}]
!         A Distgrid describing the new distribution of
!         the elements across the PETs.
!  \item[{[vm]}]
!         If present, the Mesh object is created on the specified
!         {\tt ESMF\_VM} object. The default is to create on the VM of the
!         current context.
!   \item [{[name]}]
!         The name of the Mesh.
!  \item [{[rc]}]
!         Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!  \end{description}
!
!EOP
!------------------------------------------------------------------------------
    integer :: localrc
    type(ESMF_Logical) :: isfree
    type(ESMF_MeshStatus_Flag) :: status
    integer :: numNode, numElem
    integer :: numNodeIds, numElemIds
    integer, allocatable :: nodeIds(:), elemIds(:)
    type(ESMF_DELayout) :: delayout
    integer             :: localDeCount
    type(ESMF_DistGrid) :: nodeDistGrid, elemDistGrid

    type(ESMF_VM) :: lvm
    integer :: localPet
    
    ! Init localrc
    localrc = ESMF_SUCCESS

    call ESMF_VMGetCurrent(lvm, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
              ESMF_CONTEXT, rcToReturn=rc)) return
    
    ! set up local pet info
    call ESMF_VMGet(lvm, localPet=localPet, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
              ESMF_CONTEXT, rcToReturn=rc)) return

    ! Check input classes
    ESMF_INIT_CHECK_DEEP(ESMF_MeshGetInit, mesh, rc)
    ESMF_INIT_CHECK_DEEP(ESMF_DistGridGetInit, nodalDistgrid, rc)
    ESMF_INIT_CHECK_DEEP(ESMF_DistGridGetInit, elementDistgrid, rc)

    ! If mesh has not been fully created
    call C_ESMC_MeshGetStatus(mesh, status)
    if (status .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

    !!! OPERATE BASED ON PRESENCE OF DISTGRIDS  !!!
    if (present(nodalDistgrid)) then

      !! NODE AND ELEMENT DISTGRID BOTH PRESENT !!
      if (present(elementDistgrid)) then
          ! Get number of node Ids
          call ESMF_DistGridGetNumIds(nodalDistgrid, &
               numNodeIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! Get number of element Ids
          call ESMF_DistGridGetNumIds(elementDistgrid, &
               numElemIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! If the C side doesn't exist, then don't need to redist, so exit
          call C_ESMC_MeshGetIsFree(mesh, isfree)
          if (isfree == ESMF_TRUE) then
             ESMF_INIT_SET_CREATED(ESMF_MeshCreateRedist)
             if (present(rc)) rc=ESMF_SUCCESS
             return
          endif

          ! Allocate space for node Ids
          allocate(nodeIds(numNodeIds))

          ! Get node Ids
          call ESMF_DistGridGetIds(nodalDistgrid, &
               nodeIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! Allocate space for element Ids
          allocate(elemIds(numElemIds))

          ! Get element Ids
          call ESMF_DistGridGetIds(elementDistgrid,&
               elemIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return


          ! Call into C
          call C_ESMC_MeshCreateRedist(mesh,                  &
               numNodeIds, nodeIds,   &
               numElemIds, elemIds,   &
               ESMF_MeshCreateRedist, &
               localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! Deallocate gid arrays
          deallocate(nodeIds)
          deallocate(elemIds)

          call C_ESMC_MeshSetNodeDistGrid(ESMF_MeshCreateRedist, nodalDistgrid, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
          
          call C_ESMC_MeshSetElemDistGrid(ESMF_MeshCreateRedist, elementDistgrid, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

      else  !! JUST NODE DISTGRID PRESENT !!
          call ESMF_DistGridGetNumIds(nodalDistgrid, numNodeIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! If the C side doesn't exist, then return an error
          ! because I don't know how to distribute nodes without elem info
          call C_ESMC_MeshGetIsFree(mesh, isfree)
          if (isfree == ESMF_TRUE) then
             call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_WRONG, &
             msg="- method does not work if the input Mesh has no " // &
             "C Mesh attached and just the nodeDistgrid is specified", &
                  ESMF_CONTEXT, rcToReturn=rc)
             return
          endif

          ! Allocate space for node Ids
          allocate(nodeIds(numNodeIds))

          ! Get node Ids
          call ESMF_DistGridGetIds(nodalDistgrid, &
               nodeIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return


          ! Call into C
          call C_ESMC_MeshCreateRedistNodes(mesh,                  &
               numNodeIds, nodeIds,   &
               ESMF_MeshCreateRedist, &
               localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          call C_ESMC_MeshSetNodeDistGrid(ESMF_MeshCreateRedist, nodalDistgrid, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
          
          ! Deallocate gid arrays
          deallocate(nodeIds)

           ! Create elem distgrid
          call C_ESMC_MeshCreateElemDistGrid(ESMF_MeshCreateRedist, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
      endif
    else
        !! JUST ELEMENT DISTGRID PRESENT !!
        if (present(elementDistgrid)) then

          call ESMF_DistGridGetNumIds(elementDistgrid, numElemIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! If the C side doesn't exist, then return an error
          ! because I don't know how to distribute nodes without elem info
          call C_ESMC_MeshGetIsFree(mesh, isfree)
          if (isfree == ESMF_TRUE) then
             call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_WRONG, &
   msg="- method does not work if the input Mesh has no " // &
       "C Mesh attached and just the elemDistgrid is specified", &
                  ESMF_CONTEXT, rcToReturn=rc)
             return
          endif

          ! Allocate space for element Ids
          allocate(elemIds(numElemIds))

          ! Get element Ids
          call ESMF_DistGridGetIds(elementDistgrid, &
                 elemIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! Call into C
          call C_ESMC_MeshCreateRedistElems(mesh,                  &
               numElemIds, elemIds,   &
               ESMF_MeshCreateRedist, &
               localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! Deallocate gid arrays
          deallocate(elemIds)

          call C_ESMC_MeshSetElemDistGrid(ESMF_MeshCreateRedist, elementDistgrid, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

           ! Create node distgrid and get number of nodes
          call C_ESMC_MeshCreateNodeDistGrid(ESMF_MeshCreateRedist, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

       else !! NO DISTGRIDs PRESENT -> make new mesh a copy of the old w/ new distgrids !!

          ! Need to get the distgrids first
          call c_ESMC_MeshGetNodeDistGrid(mesh, nodeDistGrid, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
          
          ! Set init code for deep C++ DistGrid object
          call ESMF_DistGridSetInitCreated(nodeDistGrid, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
            
          call c_ESMC_MeshGetElemDistGrid(mesh, elemDistGrid, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
          
          ! Set init code for deep C++ DistGrid object
          call ESMF_DistGridSetInitCreated(elemDistGrid, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
            
          ! Get number of node Ids
          call ESMF_DistGridGetNumIds(nodeDistGrid, numNodeIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! Get number of element Ids
          call ESMF_DistGridGetNumIds(elemDistGrid, numElemIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! If the C side doesn't exist, then don't need to redist, so exit
          call C_ESMC_MeshGetIsFree(mesh, isfree)
          if (isfree == ESMF_TRUE) then
             ESMF_INIT_SET_CREATED(ESMF_MeshCreateRedist)

             if (present(rc)) rc=ESMF_SUCCESS
             return
          endif

          ! Allocate space for node Ids
          allocate(nodeIds(numNodeIds))

          ! Get node Ids
          call ESMF_DistGridGetIds(nodeDistGrid, nodeIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! Allocate space for element Ids
          allocate(elemIds(numElemIds))

          ! Get element Ids
          call ESMF_DistGridGetIds(elemDistGrid, elemIds, rc=localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return


          ! Call into C
          call C_ESMC_MeshCreateRedist(mesh,                  &
               numNodeIds, nodeIds,   &
               numElemIds, elemIds,   &
               ESMF_MeshCreateRedist, &
               localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

          ! Deallocate gid arrays
          deallocate(nodeIds)
          deallocate(elemIds)

           ! Create node distgrid and get number of nodes
          call C_ESMC_MeshCreateNodeDistGrid(ESMF_MeshCreateRedist, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return

           ! Create elem distgrid and get number of elems
          call C_ESMC_MeshCreateElemDistGrid(ESMF_MeshCreateRedist, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
       endif
    endif

    ! If vm is present, change new mesh to exist just on that VM
    if (present(vm)) then
       call C_ESMC_MeshFitOnVM(ESMF_MeshCreateRedist, &
            vm, localrc)
       if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT, rcToReturn=rc)) return
    endif

    ! Set the name in Base object
    if (present(name)) then
      call c_ESMC_SetName(ESMF_MeshCreateRedist, "Mesh", name, localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return
    endif

    ! Set as created
    ESMF_INIT_SET_CREATED(ESMF_MeshCreateRedist)

    if (present(rc)) rc=ESMF_SUCCESS
    return

end function ESMF_MeshCreateRedist