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