ESMF_MeshCreate1Part Function

private function ESMF_MeshCreate1Part(parametricDim, spatialDim, nodeIds, nodeCoords, nodeOwners, nodeMask, nodalDistgrid, elementIds, elementTypes, elementConn, elementMask, elementArea, elementCoords, elementDistgrid, coordSys, name, rc)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: parametricDim
integer, intent(in) :: spatialDim
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(in) :: elementIds(:)
integer, intent(in) :: elementTypes(:)
integer, intent(in) :: elementConn(:)
integer, intent(in), optional :: elementMask(:)
real(kind=ESMF_KIND_R8), intent(in), optional :: elementArea(:)
real(kind=ESMF_KIND_R8), intent(in), optional :: elementCoords(:)
type(ESMF_DistGrid), intent(in), optional :: elementDistgrid
type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys
character(len=*), intent(in), optional :: name
integer, intent(out), optional :: rc

Return Value type(ESMF_Mesh)


Source Code

    function ESMF_MeshCreate1Part(parametricDim, spatialDim, &
                   nodeIds, nodeCoords, nodeOwners, nodeMask, nodalDistgrid, &
                   elementIds, elementTypes, elementConn, &
                   elementMask, elementArea, elementCoords, &
                   elementDistgrid, coordSys, name, rc)
!
!
! !RETURN VALUE:
    type(ESMF_Mesh)                                 :: ESMF_MeshCreate1Part
! !ARGUMENTS:
    integer,                  intent(in)            :: parametricDim
    integer,                  intent(in)            :: spatialDim
    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(in)            :: elementIds(:)
    integer,                  intent(in)            :: elementTypes(:)
    integer,                  intent(in)            :: elementConn(:)
    integer,                  intent(in),  optional :: elementMask(:)
    real(ESMF_KIND_R8),       intent(in),  optional :: elementArea(:)
    real(ESMF_KIND_R8),       intent(in),  optional :: elementCoords(:)
    type(ESMF_DistGrid),      intent(in),  optional :: elementDistgrid
    type(ESMF_CoordSys_Flag), intent(in),  optional :: coordSys
    character(len=*),         intent(in),  optional :: name
    integer,                  intent(out), optional :: rc
!
! !DESCRIPTION:
!   Create a Mesh object in one step. After this call the Mesh is usable, for
!   example, a Field may be built on the created Mesh object and
!   this Field may be used in a {\tt ESMF\_FieldRegridStore()} call.
!
!   This call sets the dimension of the elements in the mesh
!   ({\tt parametricDim}) and the number of coordinate dimensions in the mesh
!   ({\tt spatialDim}). It then creates the nodes, and
!   then creates the elements by connecting together the nodes.
!
!   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$.
!
!   The parameters to this call {\tt elementIds}, {\tt elementTypes}, and
!   {\tt elementConn} describe the elements to be created. The description
!   for a particular element lies at the same index location in {\tt elementIds}
!   and {\tt elementTypes}. Each entry in {\tt elementConn} consists of the list of
!   nodes used to create that element, so the connections for element $e$ in the
!   {\tt elementIds} array will start at $number\_of\_nodes\_in\_element(1) + number\_of\_nodes\_in\_element(2) +
!   \cdots + number\_of\_nodes\_in\_element(e-1) + 1$ in {\tt elementConn}.
!
!   This call is {\em collective} across the current VM.
!
!   \begin{description}
!   \item [parametricDim]
!         Dimension of the topology of the Mesh. (E.g. a mesh constructed of squares would
!         have a parametric dimension of 2, whereas a Mesh constructed of cubes would have one
!         of 3.)
!   \item[spatialDim]
!         The number of coordinate dimensions needed to describe the locations of the nodes
!         making up the Mesh. For a manifold, the spatial dimension can be larger than the
!         parametric dim (e.g. the 2D surface of a sphere in 3D space), but it can't be smaller.
!   \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 [elementIds]
!          An array containing the global ids of the elements to be created on this PET.
!          This input consists of a 1D array the size of the number of elements on this PET.
!          Each element id must be a number equal to or greater than 1. An id should be
!          unique in the sense that different elements must have different ids (the same element
!          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[elementTypes]
!          An array containing the types of the elements to be created on this PET. The types used
!          must be appropriate for the parametric dimension of the Mesh. Please see
!          Section~\ref{const:meshelemtype} for the list of options. This input consists of
!          a 1D array the size of the number of elements on this PET.
!   \item[elementConn]
!         An array containing the indexes of the sets of nodes to be connected together to form the
!         elements to be created on this PET. The entries in this list are NOT node global ids,
!         but rather each entry is a local index (1 based) into the list of nodes to be
!         created on this PET by this call.
!         In other words, an entry of 1 indicates that this element contains the node
!         described by {\tt nodeIds(1)}, {\tt nodeCoords(1)}, etc. on this PET. It is also
!         important to note that the order of the nodes in an element connectivity list
!         matters. Please see Section~\ref{const:meshelemtype} for diagrams illustrating
!         the correct order of nodes in a element. This input consists of a 1D array with
!         a total size equal to the sum of the number of nodes contained in each element on
!         this PET. The number of nodes in each element is implied by its element type in
!         {\tt elementTypes}. The nodes for each element
!         are in sequence in this array (e.g. the nodes for element 1 are elementConn(1),
!         elementConn(2), etc.).
!   \item [{[elementMask]}]
!          An array containing values which can be used for element 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 elements on this PET.
!   \item [{[elementArea]}]
!          An array containing element areas. If not specified, the element areas are internally calculated.
!          This input consists of a 1D array the size of the number of elements on this PET.
!          {\bf NOTE:} ESMF doesn't currently do unit conversion on areas. If these areas are going to be used
!                in a process that also involves the areas of another Grid or Mesh (e.g. conservative regridding), then
!                it is the user's responsibility to make sure that the area units are consistent between the two sides.
!                If ESMF calculates an area on the surface of a sphere, then it is in units of square radians. If
!                it calculates the area for a Cartesian grid, then it is in the same units as the coordinates, but squared.
!   \item[{[elementCoords]}]
!          An array containing the physical coordinates of the elements to be created on this
!          PET. This input consists of a 1D array the size of the number of elements on this PET times the Mesh's
!          spatial dimension ({\tt spatialDim}). The coordinates in this array are ordered
!          so that the coordinates for an element lie in sequence in memory. (e.g. for a
!          Mesh with spatial dimension 2, the coordinates for element 1 are in elementCoords(1) and
!          elementCoords(2), the coordinates for element 2 are in elementCoords(3) and elementCoords(4),
!          etc.).
!   \item [{[elementDistgrid]}]
!          If present, use this as the element Distgrid for the Mesh.
!          The passed in Distgrid
!          needs to contain a local set of sequence indices matching the set of local element ids (i.e. those in {\tt elementIds}).
!          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[{[coordSys]}]
!         The coordinate system of the grid coordinate data.
!         For a full list of options, please see Section~\ref{const:coordsys}.
!         If not specified then defaults to ESMF\_COORDSYS\_SPH\_DEG.
!   \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
    integer :: numNode, numElem
    integer :: num_nodes
    integer :: num_elems, num_elementConn
    type(ESMF_InterArray) :: elementMaskII, nodeMaskII
    type(ESMF_InterArray) :: nodeOwnersII
    real(ESMF_KIND_R8) :: tmpArea(2)
    integer :: areaPresent
    real(ESMF_KIND_R8) :: tmpCoords(2)
    integer :: coordsPresent
    type(ESMF_CoordSys_Flag) :: coordSysLocal

    ! initialize return code; assume routine not implemented
    localrc = ESMF_RC_NOT_IMPL
    if (present(rc)) rc = ESMF_RC_NOT_IMPL

    ESMF_MeshCreate1Part%this = ESMF_NULL_POINTER

    ! Check init status of arguments
    ESMF_INIT_CHECK_DEEP(ESMF_DistgridGetInit, nodalDistgrid, rc)
    ESMF_INIT_CHECK_DEEP(ESMF_DistgridGetInit, elementDistgrid, rc)

   ! Set Default coordSys
   if (present(coordSys)) then
      coordSysLocal=coordSys
   else
      coordSysLocal=ESMF_COORDSYS_SPH_DEG
   endif

    ! Create C++ Mesh
    ! Optional name argument requires separate calls into C++
    if (present(name)) then
      call C_ESMC_MeshCreate(ESMF_MeshCreate1Part%this, parametricDim, spatialDim, &
                             coordSyslocal, name, localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return
    else
      call C_ESMC_MeshCreate(ESMF_MeshCreate1Part%this, parametricDim, spatialDim, &
                             coordSyslocal, "", localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT, rcToReturn=rc)) return
    endif

    ! Set init status of arguments
    ESMF_INIT_SET_CREATED(ESMF_MeshCreate1Part)


   ! 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 node mask
   nodeMaskII = ESMF_InterArrayCreate(nodeMask, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
         ESMF_CONTEXT, rcToReturn=rc)) return


    ! Add the nodes
    num_nodes = size(nodeIds)
    call C_ESMC_MeshAddNodes(ESMF_MeshCreate1Part%this, num_nodes, nodeIds, nodeCoords, &
                             nodeOwnersII, nodeMaskII, &
                             coordSysLocal, spatialDim, 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


   ! Create interface int to wrap optional element mask
   elementMaskII = ESMF_InterArrayCreate(elementMask, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
         ESMF_CONTEXT, rcToReturn=rc)) return


    ! get sizes of lists
    num_elems = size(elementIds)
    num_elementConn = size(elementConn)


    ! If present make sure that elementCoords has the correct size
    if (present(elementCoords)) then
       if (size(elementCoords) .ne. &
            spatialDim*num_elems) then
          call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, &
               msg="- elementCoords input array is the wrong size.", &
               ESMF_CONTEXT, rcToReturn=rc)
          return
       endif
    endif


#if 0
    call C_ESMC_MeshAddElements(ESMF_MeshCreate1Part%this,
num_elems, &
                             elementIds, elementTypes, elementMaskII, &
                             num_elementConn, elementConn, &
                             localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return
#endif


    ! set element area if it's present.
    if (present(elementCoords)) then
       if (present(elementArea)) then
          areaPresent=1
          coordsPresent=1
          call C_ESMC_MeshAddElements(ESMF_MeshCreate1Part%this, &
               num_elems, &
               elementIds, elementTypes, elementMaskII, &
               areaPresent, elementArea, &
               coordsPresent, elementCoords, &
               num_elementConn, elementConn, &
               coordSysLocal, spatialDim, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
       else
          areaPresent=0
          coordsPresent=1
          call C_ESMC_MeshAddElements(ESMF_MeshCreate1Part%this, &
               num_elems, &
               elementIds, elementTypes, elementMaskII, &
               areaPresent, tmpArea, &
               coordsPresent, elementCoords, &
               num_elementConn, elementConn, &
               coordSysLocal, spatialDim, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
       endif
    else
       if (present(elementArea)) then
          areaPresent=1
          coordsPresent=0
          call C_ESMC_MeshAddElements(ESMF_MeshCreate1Part%this, &
               num_elems, &
               elementIds, elementTypes, elementMaskII, &
               areaPresent, elementArea, &
               coordsPresent, tmpCoords, &
               num_elementConn, elementConn, &
               coordSysLocal, spatialDim, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
       else
          areaPresent=0
          coordsPresent=0
          call C_ESMC_MeshAddElements(ESMF_MeshCreate1Part%this, &
               num_elems, &
               elementIds, elementTypes, elementMaskII, &
               areaPresent, tmpArea, &
               coordsPresent, tmpCoords, &
               num_elementConn, elementConn, &
               coordSysLocal, spatialDim, localrc)
          if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
               ESMF_CONTEXT, rcToReturn=rc)) return
       endif
    endif

    ! Create two distgrids, one for nodes and one for elements
    if (present(nodalDistgrid)) then
      call c_ESMC_MeshSetNodeDistGrid(ESMF_MeshCreate1Part, nodalDistgrid, localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return
    else
      call C_ESMC_MeshCreateNodeDistGrid(ESMF_MeshCreate1Part, localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return
    endif

    if (present(elementDistgrid)) then
      call c_ESMC_MeshSetElemDistGrid(ESMF_MeshCreate1Part, elementDistgrid, localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return
    else
      call C_ESMC_MeshCreateElemDistGrid(ESMF_MeshCreate1Part, localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return
    endif

    ! Get rid of interface Int wrapper
    call ESMF_InterArrayDestroy(elementMaskII, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
         ESMF_CONTEXT, rcToReturn=rc)) return

    ! Set Status
    call C_ESMC_MeshSetStatus(ESMF_MeshCreate1Part, ESMF_MESHSTATUS_COMPLETE)

    if (present (rc)) rc = localrc

  end function ESMF_MeshCreate1Part