anchor.diff:  ! (File) Revision #: $Rev$
   ! URL: $HeadURL$
   !**********************************************************************************************************************************
  +!> This module contains the type definition of of ModMesh, the FAST spatial mesh structure.   
   MODULE ModMesh_Types
      USE NWTC_Num
      IMPLICIT NONE
   
  -   INTEGER, PUBLIC, PARAMETER :: COMPONENT_INPUT = 1
  -   INTEGER, PUBLIC, PARAMETER :: COMPONENT_OUTPUT = 2
  -   INTEGER, PUBLIC, PARAMETER :: COMPONENT_STATE = 3
  +   INTEGER, PUBLIC, PARAMETER :: COMPONENT_INPUT        = 1  !< parameter for "input mesh"
  +   INTEGER, PUBLIC, PARAMETER :: COMPONENT_OUTPUT       = 2  !< parameter for "output mesh"
  +   INTEGER, PUBLIC, PARAMETER :: COMPONENT_STATE        = 3  !< parameter for "state mesh" (not recommended to use)
   
   !WARNING... if you add fields here add them to the buffer size computation MeshPack too
  -   INTEGER, PUBLIC, PARAMETER :: MASKID_FORCE = 1
  -   INTEGER, PUBLIC, PARAMETER :: MASKID_MOMENT = 2
  -   INTEGER, PUBLIC, PARAMETER :: MASKID_ORIENTATION = 3
  -   INTEGER, PUBLIC, PARAMETER :: MASKID_TRANSLATIONDISP = 4
  -   INTEGER, PUBLIC, PARAMETER :: MASKID_TRANSLATIONVEL = 5
  -   INTEGER, PUBLIC, PARAMETER :: MASKID_ROTATIONVEL = 6
  -   INTEGER, PUBLIC, PARAMETER :: MASKID_TRANSLATIONACC = 7
  -   INTEGER, PUBLIC, PARAMETER :: MASKID_ROTATIONACC = 8
  -   INTEGER, PUBLIC, PARAMETER :: MASKID_SCALAR = 9
  -   INTEGER, PUBLIC, PARAMETER :: FIELDMASK_SIZE = 9
  -
  -! Format of the Int buffer
  -   INTEGER, PUBLIC, PARAMETER :: HDR_INTBUFSIZE  = 1
  -   INTEGER, PUBLIC, PARAMETER :: HDR_REALBUFSIZE = 2
  -   INTEGER, PUBLIC, PARAMETER :: HDR_DBLBUFSIZE  = 3
  -   INTEGER, PUBLIC, PARAMETER :: HDR_IOS         = 4
  -   INTEGER, PUBLIC, PARAMETER :: HDR_NUMNODES    = 5
  -   INTEGER, PUBLIC, PARAMETER :: HDR_NUMELEMREC  = 6
  -   INTEGER, PUBLIC, PARAMETER :: HDR_FIELDMASK   = 7
  -   INTEGER, PUBLIC, PARAMETER :: HDR_FIXEDLEN    = HDR_FIELDMASK+FIELDMASK_SIZE-1
  -   INTEGER, PUBLIC, PARAMETER :: HDR_FIRSTELEM   = HDR_FIXEDLEN+1
  -
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_POINT   = 1
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_LINE2   = 2
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_LINE3   = 3
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_TRI3    = 4
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_TRI6    = 5
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_QUAD4   = 6
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_QUAD8   = 7
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_TET4    = 8
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_TET10   = 9
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_HEX8    = 10
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_HEX20   = 11
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_WEDGE6  = 12
  -   INTEGER, PUBLIC, PARAMETER :: ELEMENT_WEDGE15 = 13
  -   INTEGER, PUBLIC, PARAMETER :: NELEMKINDS = 13
  +   INTEGER, PUBLIC, PARAMETER :: MASKID_FORCE           = 1  !< parameter for fields holding force
  +   INTEGER, PUBLIC, PARAMETER :: MASKID_MOMENT          = 2  !< parameter for fields holding moment
  +   INTEGER, PUBLIC, PARAMETER :: MASKID_ORIENTATION     = 3  !< parameter for fields holding orientation
  +   INTEGER, PUBLIC, PARAMETER :: MASKID_TRANSLATIONDISP = 4  !< parameter for fields holding translational displacement
  +   INTEGER, PUBLIC, PARAMETER :: MASKID_TRANSLATIONVEL  = 5  !< parameter for fields holding translational velocity
  +   INTEGER, PUBLIC, PARAMETER :: MASKID_ROTATIONVEL     = 6  !< parameter for fields holding rotational velocity
  +   INTEGER, PUBLIC, PARAMETER :: MASKID_TRANSLATIONACC  = 7  !< parameter for fields holding translational acceleration
  +   INTEGER, PUBLIC, PARAMETER :: MASKID_ROTATIONACC     = 8  !< parameter for fields holding rotational acceleration
  +   INTEGER, PUBLIC, PARAMETER :: MASKID_SCALAR          = 9  !< parameter for fields holding scalars
  +   INTEGER, PUBLIC, PARAMETER :: FIELDMASK_SIZE         = 9  !< maximum number of fields in a mesh 
  +
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_POINT          = 1  !< parameter for elements of point
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_LINE2          = 2  !< parameter for elements of 2-point lines
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_LINE3          = 3  !< parameter for elements of 3-point lines (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_TRI3           = 4  !< parameter for elements (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_TRI6           = 5  !< parameter for elements (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_QUAD4          = 6  !< parameter for elements (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_QUAD8          = 7  !< parameter for elements (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_TET4           = 8  !< parameter for elements (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_TET10          = 9  !< parameter for elements (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_HEX8           = 10 !< parameter for elements (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_HEX20          = 11 !< parameter for elements (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_WEDGE6         = 12 !< parameter for elements (currently unused)
  +   INTEGER, PUBLIC, PARAMETER :: ELEMENT_WEDGE15        = 13 !< parameter for elements (currently unused)                    
  +   INTEGER, PUBLIC, PARAMETER :: NELEMKINDS             = 13 !< parameter for maximum number of element kinds
   
      CHARACTER(*),DIMENSION(NELEMKINDS),PARAMETER::  ElemNames = (/&
          "Point  ","Line2  ","Line3  ","Tri3   ","Tri6   ",&
          "Quad4  ","Quad8  ","Tet4   ","Tet10  ","Hex8   ",&
  -       "Hex20  ","Wedge6 ","Wedge15"                   /)
  -
  -
  -   INTEGER, PUBLIC, PARAMETER :: MESH_NEWCOPY         = 1
  -   INTEGER, PUBLIC, PARAMETER :: MESH_SIBLING         = 2
  -   INTEGER, PUBLIC, PARAMETER :: MESH_UPDATECOPY      = 3
  -   INTEGER, PUBLIC, PARAMETER :: MESH_UPDATEREFERENCE = 4
  -   INTEGER, PUBLIC, PARAMETER :: MESH_COUSIN          = 5
  -
  -   INTEGER, PUBLIC, PARAMETER :: MESH_NEXT  = -2
  -   INTEGER, PUBLIC, PARAMETER :: MESH_NOMOREELEMS  = -3
  -   INTEGER, PUBLIC, PARAMETER :: MESH_NOMOREELEMENTS  = MESH_NOMOREELEMS  !synonym
  -   INTEGER, PUBLIC, PARAMETER :: MESH_NOMORE  = MESH_NOMOREELEMS          !synonym
  +       "Hex20  ","Wedge6 ","Wedge15"                   /)   !< element names
  +
  +
  +   INTEGER, PUBLIC, PARAMETER :: MESH_NEWCOPY         = 1   !< parameter for type of mesh copy: new mesh instance
  +   INTEGER, PUBLIC, PARAMETER :: MESH_SIBLING         = 2   !< parameter for type of mesh copy: new sibling (shares element and reference data; fields separate)
  +   INTEGER, PUBLIC, PARAMETER :: MESH_UPDATECOPY      = 3   !< parameter for type of mesh copy: updates fields in existing mesh
  +   INTEGER, PUBLIC, PARAMETER :: MESH_UPDATEREFERENCE = 4   !< parameter for type of mesh copy: updates reference fields in existing mesh
  +   INTEGER, PUBLIC, PARAMETER :: MESH_COUSIN          = 5   !< parameter for type of mesh copy: like sibling, but allocates memory for all data
  +
  +   INTEGER, PUBLIC, PARAMETER :: MESH_NEXT            = -2  !< parameter for next element in mesh
  +   INTEGER, PUBLIC, PARAMETER :: MESH_NOMOREELEMS     = -3  !< parameter indicating no more elements in mesh
  +   INTEGER, PUBLIC, PARAMETER :: MESH_NOMOREELEMENTS  = MESH_NOMOREELEMS  !< synonym
  +   INTEGER, PUBLIC, PARAMETER :: MESH_NOMORE          = MESH_NOMOREELEMS  !< synonym
   
      LOGICAL, PARAMETER :: mesh_debug = .FALSE.
   
  -
  -   TYPE, PUBLIC :: ElemRecType ! a particular element
  -      ! note: any fields added to this type must be copied in Mesh_MoveAlloc_ElemRecType()
  -     INTEGER                        :: Xelement      ! which kind of element
  -     INTEGER                        :: Nneighbors    ! how many neighbors
  -     REAL(ReKi)                     :: det_jac       ! determinant of the Jacobian (e.g., 1/2 the length of a line-2 element)
  -     INTEGER,           ALLOCATABLE :: ElemNodes(:)  ! the list of nodes
  +      !> element record type: fields for a particular element
  +   TYPE, PUBLIC :: ElemRecType 
  +      ! note: any fields added to this type must be copied in Mesh_MoveAlloc_ElemRecType (modmesh_types::mesh_movealloc_elemrectype)
  +     INTEGER                        :: Xelement      !< which kind of element
  +     INTEGER                        :: Nneighbors    !< how many neighbors
  +     REAL(ReKi)                     :: det_jac       !< determinant of the Jacobian (e.g., 1/2 the length of a line-2 element)
  +     INTEGER,           ALLOCATABLE :: ElemNodes(:)  !< the list of nodes
   !     TYPE(ElemRecType), POINTER     :: Neighbors(:)  ! neighbor list (cannot be allocatable because it's a subtype of itself)
      END TYPE ElemRecType
   
  -   TYPE, PUBLIC :: ElemTabType   ! table of all elements of a particular type
  -     INTEGER                     :: nelem, maxelem
  -     INTEGER                     :: Xelement               ! which kind of element
  -     TYPE(ElemRecType), POINTER  :: Elements(:) => NULL()
  +      !> table of all elements of a particular type
  +   TYPE, PUBLIC :: ElemTabType   
  +     INTEGER                     :: nelem                  !< number of elements of this type
  +     INTEGER                     :: maxelem                !< maximum elements currently allocated for this type 
  +     INTEGER                     :: Xelement               !< which kind of element
  +     TYPE(ElemRecType), POINTER  :: Elements(:) => NULL()  !< pointer to list of all elements of this type
      END TYPE ElemTabType
   
  -   TYPE, PUBLIC :: ElemListType ! all elements (may be different types, but not spatial dimensions)
  -     TYPE(ElemRecType), POINTER :: Element => NULL()                 ! bjj added initialization
  +      !> table/list of all elements (may be different types, but not spatial dimensions)
  +   TYPE, PUBLIC :: ElemListType 
  +     TYPE(ElemRecType), POINTER :: Element => NULL()        !< pointer to a particular mesh element
      END TYPE ElemListType
   
  +      !> mesh data structure
      TYPE, PUBLIC :: MeshType
  -      LOGICAL :: initialized = .FALSE.                       ! Indicate whether this mesh is initialized
  -      LOGICAL :: committed = .FALSE.                         ! Indicate whether this mesh is committed
  -      LOGICAL :: fieldmask(FIELDMASK_SIZE) = .FALSE.         ! Dimension as number of allocatable fields, below
  -      LOGICAL,POINTER :: RemapFlag  => NULL()                ! false=no action/ignore; true=remap required
  -      INTEGER :: ios                                         ! Mesh type: input (1), output(2), or state(3)
  -      INTEGER :: Nnodes = 0                                  ! Number of nodes (vertices) in mesh
  +      LOGICAL :: initialized = .FALSE.                       !< Indicate whether this mesh is initialized
  +      LOGICAL :: committed = .FALSE.                         !< Indicate whether this mesh is committed
  +      LOGICAL :: fieldmask(FIELDMASK_SIZE) = .FALSE.         !< Dimension as number of allocatable fields, below
  +      LOGICAL,POINTER :: RemapFlag  => NULL()                !< false=no action/ignore; true=remap required
  +      INTEGER :: ios                                         !< Mesh type: input (1), output(2), or state(3)
  +      INTEGER :: Nnodes = 0                                  !< Number of nodes (vertices) in mesh
   
        ! Mesh elements
  -      TYPE(ElemTabType), POINTER :: ElemTable(:) => NULL()   ! Elements in the mesh, by type
  +      TYPE(ElemTabType), POINTER :: ElemTable(:) => NULL()   !< A table of all elements in the mesh, by type
   
        ! Mesh traversal
  -      INTEGER :: nelemlist                                   ! Number of elements in the list (ElemList)
  -      INTEGER :: maxelemlist                                 ! Maximum number of elements in the list
  -      INTEGER :: nextelem                                    ! Next element in the list
  -      TYPE(ElemListType), POINTER :: ElemList(:) => NULL()   ! All of the elements in the mesh
  +      INTEGER :: nelemlist                                   !< Number of elements in the list (ElemList)
  +      INTEGER :: maxelemlist                                 !< Maximum number of elements in the list
  +      INTEGER :: nextelem                                    !< Next element in the list
  +      TYPE(ElemListType), POINTER :: ElemList(:) => NULL()   !< All of the elements in the mesh
   
        ! Node position and reference orientation, which are always allocated (and shared between siblings):
  -      REAL(ReKi), POINTER :: Position(:,:) => NULL()         ! XYZ coordinate of node (3,:)
  -      REAL(R8Ki), POINTER :: RefOrientation(:,:,:) => NULL() ! Original/reference orientation [DCM] (3,3,:)
  +      REAL(ReKi), POINTER :: Position(:,:) => NULL()         !< XYZ coordinate of node (3,:)
  +      REAL(R8Ki), POINTER :: RefOrientation(:,:,:) => NULL() !< Original/reference orientation [DCM] (3,3,:)
   
   ! Here are some built in derived data types that can represent values at the nodes
   ! the last dimension of each of these has range 1:nnodes for the mesh being represented
  
positive.code: 
     END FUNCTION HasLoadFields
  
     SUBROUTINE Mesh_MoveAlloc_ElemRecType( Src, Dest )
        TYPE(ElemRecType), INTENT(INOUT) :: Src
        TYPE(ElemRecType), INTENT(INOUT) :: Dest
     
        Dest%Xelement   = Src%Xelement
        Dest%Nneighbors = Src%Nneighbors
  
negative.code:      END SELECT
     END FUNCTION NumNodes
  
  !> This function determines if a mesh contains any motion field (translational/rotational positions, velocities, accelerations or scalars).
     LOGICAL FUNCTION HasMotionFields(Mesh)
  
        TYPE(MeshType), INTENT(IN) :: Mesh  !< mesh to query
  
        IF (     Mesh%FieldMask(MASKID_TRANSLATIONDISP)    &
            .or. Mesh%FieldMask(MASKID_ORIENTATION)        &
  