ESMF_MeshAddNodes Subroutine

public subroutine ESMF_MeshAddNodes(mesh, nodeIds, nodeCoords, nodeOwners, nodeMask, nodalDistgrid, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_Mesh), intent(inout) :: mesh
integer, intent(in) :: nodeIds(:)
real(kind=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

Source Code

    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