subroutine ESMF_MeshAddNodes(mesh, nodeIds, nodeCoords, nodeOwners, &
nodeMask, nodalDistgrid, rc)
!
! !ARGUMENTS:
type(ESMF_Mesh), intent(inout) :: mesh
integer, intent(in) :: nodeIds(:)
real(ESMF_KIND_R8), intent(in) :: nodeCoords(:)
integer, intent(in), optional :: nodeOwners(:)
integer, intent(in), optional :: nodeMask(:)
type(ESMF_DistGrid), intent(in), optional :: nodalDistgrid
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
! This call is the second part of the three part mesh create
! sequence and should be called after the mesh's dimensions are set
! using {\tt ESMF\_MeshCreate()} (\ref{sec:mesh:api:meshcreate}).
! This call adds the nodes to the
! mesh. The next step is to call {\tt ESMF\_MeshAddElements()} (\ref{sec:mesh:api:meshaddelements}).
!
! The parameters to this call {\tt nodeIds}, {\tt nodeCoords}, and
! {\tt nodeOwners} describe the nodes to be created on this PET.
! The description for a particular node lies at the same index location in
! {\tt nodeIds} and {\tt nodeOwners}. Each entry
! in {\tt nodeCoords} consists of spatial dimension coordinates, so the coordinates
! for node $n$ in the {\tt nodeIds} array will start at $(n-1)*spatialDim+1$.
!
! \begin{description}
! \item [nodeIds]
! An array containing the global ids of the nodes to be created on this PET.
! This input consists of a 1D array the size of the number of nodes on this PET.
! Each node id must be a number equal to or greater than 1. An id should be
! unique in the sense that different nodes must have different ids (the same node
! that appears on different processors must have the same id). There may be gaps in the sequence
! of ids, but if these gaps are the same scale as the length of the sequence it can lead to
! inefficiencies when the Mesh is used (e.g. in {\tt ESMF\_FieldRegridStore()}).
! \item[nodeCoords]
! An array containing the physical coordinates of the nodes to be created on this
! PET. This input consists of a 1D array the size of the number of nodes on this PET times the Mesh's
! spatial dimension ({\tt spatialDim}). The coordinates in this array are ordered
! so that the coordinates for a node lie in sequence in memory. (e.g. for a
! Mesh with spatial dimension 2, the coordinates for node 1 are in nodeCoords(1) and
! nodeCoords(2), the coordinates for node 2 are in nodeCoords(3) and nodeCoords(4),
! etc.).
! \item[{[nodeOwners]}]
! An array containing the PETs that own the nodes to be created on this PET.
! If the node is shared with another PET, the value
! may be a PET other than the current one. Only nodes owned by this PET
! will have PET local entries in a Field created on the Mesh. This input consists of
! a 1D array the size of the number of nodes on this PET. If not provided by the user,
! then ESMF will calculate node ownership.
! \item [{[nodeMask]}]
! An array containing values which can be used for node masking. Which values indicate
! masking are chosen via the {\tt srcMaskValues} or {\tt dstMaskValues} arguments to
! {\tt ESMF\_FieldRegridStore()} call. This input consists of a 1D array the
! size of the number of nodes on this PET.
! \item [{[nodalDistgrid]}]
! If present, use this as the node Distgrid for the Mesh.
! The passed in Distgrid
! needs to contain a local set of sequence indices matching the set of local node ids (i.e. the ids in
! {\tt nodeIds} with {\tt nodeOwners} equal to the current PET).
! However, specifying an externally created Distgrid gives the user more control over aspects of
! the Distgrid containing those sequence indices (e.g. how they are broken into DEs).
! If not present, a 1D Distgrid will be created internally consisting of one DE per PET.
! \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 :: num_nodes
integer :: sdim, pdim, numNode
type(ESMF_CoordSys_Flag):: coordSys
type(ESMF_InterArray) :: nodeMaskII, nodeOwnersII
! 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_MeshGetInit, mesh, rc)
ESMF_INIT_CHECK_DEEP(ESMF_DistgridGetInit, nodalDistgrid, rc)
call C_ESMC_MeshGetIsFree(mesh, isfree)
if (isfree == ESMF_TRUE) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_WRONG, &
msg="- the mesh internals have been freed", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
! If we're at the wrong stage then complain
call C_ESMC_MeshGetStatus(mesh, status)
if (status .ne. ESMF_MESHSTATUS_STRUCTCREATED) then
call ESMF_LogSetError(rcToCheck=ESMF_RC_OBJ_WRONG, &
msg="- MeshCreate() should be called before this", &
ESMF_CONTEXT, rcToReturn=rc)
return
endif
call C_ESMC_MeshGetDimensions(mesh, sdim, pdim, coordSys, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Create interface int to wrap optional node owners
nodeOwnersII = ESMF_InterArrayCreate(nodeOwners, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Create interface int to wrap optional element mask
nodeMaskII = ESMF_InterArrayCreate(nodeMask, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
num_nodes = size(nodeIds)
call C_ESMC_MeshAddNodes(mesh%this, num_nodes, nodeIds, nodeCoords, &
nodeOwnersII, nodeMaskII, &
coordSys, sdim, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Get rid of interface Int wrappers
call ESMF_InterArrayDestroy(nodeOwnersII, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_InterArrayDestroy(nodeMaskII, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Set distgrid if was passed in
if (present(nodalDistgrid)) then
call c_ESMC_MeshSetNodeDistGrid(mesh, nodalDistgrid, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
! Change status
call C_ESMC_MeshSetStatus(mesh, ESMF_MESHSTATUS_NODESADDED)
if (present (rc)) rc = localrc
end subroutine ESMF_MeshAddNodes