\chapter{Getting Mesh Into Mesquite}
\label{sec:meshes}

The application must provide Mesquite with data on which to operate.  The two
fundamental classes of information Mesquite requires are:
\begin{itemize}
\item Mesh vertex coordinates and element connectivity, and
\item Constraints on vertex movement.
\end{itemize}
In this chapter we will assume that the only constraint available for vertex movement is to flag the vertices as fixed.  More advanced constraints such as vertices following geometric curves or surfaces are discussed in the following chapter.  

The mesh data expected as input to Mesquite is a set of vertices and elements.  Each vertex has associated with it a fixed flag, a ``byte'', and x, y, and z coordinate values.  The fixed flag is used as input only.  It indicates whether or not the corresponding vertex position should be fixed (i.e., coordinates not allowed to change) during the optimization.  The ``byte'' is one byte of Mesquite-specific working data associated with each vertex (currently only used for vertex culling.)   The coordinate values for each vertex serve as both input and output: as input they are the initial positions of the vertices and as output they are the optimized positions.  

Each element of the input mesh has associated with it a type and a list of vertices.  The type is one of the values defined in \texttt{Mesquite::EntityTopology} (\texttt{Mesquite.hpp}).  It species the topology (type of shape) of the element. Currently supported element types are triangles, quadrilaterals, 
tetrahedra, hexahedra, triangular wedges, and pyramids.  The list of vertices (commonly referred to as the ``connectivity'') define the geometry (location and variation of shape) for the element.  The vertices are expected to be in a pre-defined order specific to the element topology. Mesquite uses the canonical ordering defined in the ExodusII specification\cite{exodus}.

For some more advanced capabilities, Mesquite may require the ability to attach arbitrary pieces of data (called ``tags'') to mesh elements or vertices. For more on tags see Section \ref{sec:tags_section}.


\section{The \texttt{Mesquite::Mesh} Interface} \label{sec:MeshData}

The \texttt{Mesquite::Mesh} class (\texttt{MeshInterface.hpp}) defines the interface Mesquite uses to interact with mesh data.  In C++ this means that the class defines a variety of pure virtual (or abstract) functions for accessing mesh data.  An application may implement a subclass of \texttt{Mesquite::Mesh}, providing implementations of the virtual methods that allow Mesquite direct access to the applications in-memory mesh representation.  

The \texttt{Mesquite::Mesh} interface defines functions for operations such as:
\begin{itemize}
\item Get a list of all mesh vertices.
\item Get a list of all mesh elements.
\item Get a property of a vertex (coordinates, fixed flag, etc.)
\item Set a property of a vertex (coordinates, ``byte'', etc.)
\item Get the type of an element
\item Get the vertices in an element
\end{itemize}
It also defines other operations that are only used for certain optimization algorithms:
\begin{itemize}
\item Get the list of elements for which a specific vertex occurs in the connectivity list.
\item Define a ``tag'' and use it to associate data with vertices or elements.
\end{itemize}

Mesh entities (vertices and elements) are referenced in the \texttt{Mesquite::Mesh} interface using `handles'.  There must be a unique handle
space for all vertices, and a separate unique handle space for all elements. 
That is, there must be a one-to-one mapping between handle values and vertices,
and a one-to-one mapping between handle values and elements.  The storage type of
the handles is specified by 
\begin{center}
\texttt{Mesquite::Mesh::VertexHandle} and \texttt{Mesquite::Mesh::ElementHandle}.
\end{center}
The handle types are of sufficient size
to hold either a pointer or an index, allowing the underlying implementation of
the \texttt{Mesquite::Mesh} interface to be either pointer-based or index-based. 
All mesh entities are referenced using handles.  For example, the
\texttt{Mesquite::Mesh} interface declares a method to retrieve the list of all
vertices as an array of handles and a method to update the coordinates of a
vertex where the vertex is specified as a handle.

It is recommended that the application invoke the Mesquite optimizer for subsets
of the mesh rather than the entire mesh whenever it makes sense to do so.  For
example, if a mesh of two geometric volumes is to be optimized and all mesh
vertices lying on geometric surfaces are constrained to be fixed (such vertices
will not be moved during the optimization) then optimizing each volume separately
will produce the same result as optimizing both together.  


\section{Accessing Mesh In Arrays} \label{sec::ArrayMesh}

One common representation of mesh in applications is composed of simple 
coordinate and index arrays.  Mesquite provides the \texttt{ArrayMesh} implementation of the \texttt{Mesquite::Mesh} interface to allow Mesquite
to access such array-based mesh definitions directly.  The mesh must be
defined as follows:
\begin{itemize}
\item Vertex coordinates must be stored in an array of double-precision
      floating-point values.  The coordinate values must be interleaved,
      meaning that the x, y, and z coordinate values for a single vertex
      are contiguous in memory.
\item The mesh must be composed of a single element type.
\item The element connectivity (vertices in each element) must be stored
      in an interleaved format as an array of long integers.  The vertices
      in each element are specified by an integer \texttt{i}, where the location       of the coordinates of the corresponding vertex is located at position
      \texttt{3*i} in the vertex coordinates array.
\item The fixed/boundary state of the vertices must be stored in an array
      of integer values, where a value of 1 indicates a fixed vertex and a 
      value of 0 indicates a free vertex.  The values in this array must
      be in the same order as the corresponding vertex coordinates in the
      coordinate array.
\end{itemize}

The following is a simple example of using the ArrayMesh object to pass
Mesquite a mesh containing four quadrilateral elements.
\begin{lstlisting}
/** define some mesh **/
    /* vertex coordinates */
  double coords[] = { 0, 0, 0,
                      1, 0, 0,
                      2, 0, 0,
                      0, 1, 0,
                     .5,.5, 0,
                      2, 1, 0,
                      0, 2, 0,
                      1, 2, 0,
                      2, 2, 0 };
    /* quadrilateral element connectivity (vertices) */
  long quads[] = { 0, 1, 4, 3,
                   1, 2, 5, 4,
                   3, 4, 7, 6,
                   4, 5, 8, 7 };
    /* all vertices except the center one are fixed */
  int fixed[] = { 1, 1, 1,
                  1, 0, 1,
                  1, 1, 1 };
  
/** create an ArrayMesh to pass the above mesh into Mesquite **/
  
  ArrayMesh mesh( 
      3,            /* 3D mesh (three coord values per vertex) */
      9,            /* nine vertices */
      coords,       /* the vertex coordinates */ 
      fixed,        /* the vertex fixed flags */
      4,            /* four elements */
      QUADRILATERAL,/* elements are quadrilaterals */
      quads );      /* element connectivity */
  
/** smooth the mesh **/
  
    /* Need surface to constrain 2D elements to */
  PlanarDomain domain( PlanarDomain::XY );

  MsqError err;
  ShapeImprover shape_wrapper;
  if (err) {
    std::cout << err << std::endl;
    exit (2);
  }
  

  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain);
  shape_wrapper.run_instructions( &mesh_and_domain, err );
  if (err) {
    std::cout << "Error smoothing mesh:" << std::endl
              << err << std::endl;
  }
  
/** Output the new location of the center vertex **/
  std::cout << "New vertex location: ( "
            << coords[12] << ", " 
            << coords[13] << ", " 
            << coords[14] << " )" << std::endl;
\end{lstlisting}

NOTE:  When using the \texttt{ArrayMesh} interface, the application is responsible for managing the storage of the mesh data.  The \texttt{ArrayMesh}
 does NOT copy the input mesh.  

 
\section{Reading Mesh From Files} \label{sec:meshFiles}

\subsection{VTK and ExodusII Files}

Mesquite provides a concrete implementation of the \texttt{Mesquite::Mesh} named
\texttt{Mesquite::MeshImpl}.  This implementation is capable of reading mesh from
VTK\cite{VTKbook, VTKuml} and optionally ExodusII files. See Sections 
\ref{sec:depends} and \ref{sec:compiling} for more 
information regarding the optional support for ExodusII files.

\subsection{Reading and Writing VTK Files}

VTK files can be read into Mesquite via the MeshImpl::read\_vtk(...) method.  VTK files can be written using the MeshImpl::write\_vtk(...) method. 
 The current implementation writes version 3.0 of the VTK file format
and is capable of reading any version of the file format up to 3.0. Mesquite only supports the legacy VTK file format; it does not support XML format.  The capibilities and limitations of Mesquite VTK file processing is as follows:
\begin{itemize}
\item cannot read binary files
\item can read the following Dataset types:
\begin {verbatim}
     "STRUCTURED_POINTS",
     "STRUCTURED_GRID",
     "UNSTRUCTURED_GRID",
     "POLYDATA",
     "RECTILINEAR_GRID",
     "FIELD"
\end{verbatim}
\item can only write "UNSTRUCTURED\_GRID" Dataset type
\item cannot read triangle strips
\item can read/write following VTK attribute data:
\begin {verbatim}
     "SCALARS",
     "COLOR_SCALARS",
     "VECTORS",
     "NORMALS",
     "TEXTURE_COORDINATES",
     "TENSORS",
     "FIELD"
\end{verbatim}
\item will accept either "FIELD" or "DATASET FIELD" for block name value
\item polygonal meshes can be read and written by Mesquite using VTK format.  However, only the LaplaceSmoother and the SmartLaplaceSmoother are currently able to work with this mesh type.
\item supports fixed and slaved POINT Dataset Attributes with dataNames of "fixed" and "slaved".  These are used to specify which nodes are to be considered fixed and slaved.
\end{itemize}

The `fixed' flag for vertices can be specified in VTK files by defining a
SCALAR POINT\_DATA attribute with values of 0 or 1, where 1 indicates that the
corresponding vertex is fixed.  The \texttt{Mesquite::MeshImpl} class is capable
of reading and storing tag data (see Section \ref{sec:tags_section}) using VTK attributes and field data. A example of a Mesquite compatible VTK file can be found in Section \ref{sec:slaved_vertices}. 

\subsection{VTK Cell Types}
VTK files can contain the following types of cells:

\begin{verbatim}
   1. VTK_VERTEX 
   2. VTK_POLY_VERTEX 
   3. VTK_LINE 
   4. VTK_POLY_LINE 
   5. VTK_TRIANGLE
   6. VTK_TRIANGLE_STRIP 
   7. VTK_POLYGON 
   8. VTK_PIXEL 
   9. VTK_QUAD 
  10. VTK_TETRA 
  11. VTK_VOXEL 
  12. VTK_HEXAHEDRON 
  13. VTK_WEDGE 
  14. VTK_PYRAMID 
  15. VTK_PENTAGONAL_PRISM 
  16. VTK_HEXAGONAL_PRISM 
  21. VTK_QUADRATIC_EDGE 
  22. VTK_QUADRATIC_TRIANGLE 
  23. VTK_QUADRATIC_QUAD 
  24. VTK_QUADRATIC_TETRA 
  25. VTK_QUADRATIC_HEXAHEDRON 
  26. VTK_QUADRATIC_WEDGE 
  27. VTK_QUADRATIC_PYRAMID 
  28. VTK_BI_QUADRATIC_QUAD 
  29. VTK_TRI_QUADRATIC_HEXAHEDRON 
  30. VTK_QUADRATIC_LINEAR_QUAD 
  31. VTK_QUADRATIC_LINEAR_WEDGE 
  32. VTK_QUADRATIC_WEDGE 
  33. VTK_QUADRATIC_WEDGE 
  34. VTK_BI_QUADRATIC_HEXAHEDRON 
\end{verbatim}

Mesquite supports the following VTK cell types (followed by the VTK Cell Types number):

\begin{itemize}
\item  TRIANGLE (5, 22)
\item  QUADRILATERAL (9, 23, 28)
\item  POLYGON (7)
\item  TETRAHEDRON (10, 24)
\item  HEXAHEDRON (12, 25, 29)
\item PRISM (13, 26)
\item  PYRAMID (14, 27)
\end{itemize}

\section{ITAPS iMesh Interface}

\subsection{Introduction}

The ITAPS Working Group has defined a standard API for exchange of mesh data between applications.  The iMesh interface\cite{imesh} defines a superset of the functionality required for the \texttt{Mesquite::Mesh} interface.  Mesquite can access mesh through an iMesh interface using the \texttt{Mesquite::MsqIMesh} class declared in \texttt{MsqIMesh.hpp}.  This class is an ``adaptor'':  it presents the iMesh interface as the \texttt{Mesquite::Mesh} interface.  

The primary advantage of this method of providing mesh data to mesquite is that it is designed for interoperability.  The same API can be used to provide other tools and services access to the mesh data.  And there are stand-alone mesh data base libraries that already implement this API such as MOAB\cite{MOAB-webpage} and FMDB\cite{FMDB-webpage}.  It is also possible to implement the iMesh interface in Fortran.

\subsection{Overview}

A \texttt{Mesquite::MsqIMesh} instance must be provided with at least two pieces of information: The \texttt{iMesh\_Instance} handle and an \texttt{iBase\_EntitySetHandle}.  The optional \texttt{iBase\_TagHandle} for the ``fixed tag'' must frequently be provided as well.  The \texttt{iMesh\_Instance} specifies the instance of the database containing the mesh.  The \texttt{iBase\_EntitySetHandle} handle specifies the subset of that mesh that is to be optimized by Mesquite.  If the entire mesh is to be optimized then the ``root set'' should be specified for this argument.  The quality of all elements in this set will be used to drive the mesh optimization.  All vertices adjacent to any elements in the set will be moved as a part of the optimization unless they are explicitly designated as fixed.  The ``fixed tag'' is used to indicate such vertices.  Every vertex adjacent to the input elements should be tagged with a single integer value of either zero or one for the ``fixed tag''.  A value of one indicates that the vertex is fixed while a value of zero indicates that the vertex location is to be optimized by Mesquite.

The boundary of the mesh must always be constrained in some way for the mesh optimization to produce valid results.  For a volume mesh this can be accomplished by either designating the vertices on the mesh boundary as fixed or by specifying a geometric domain (e.g. surfaces, curves, etc) that the boundary vertices are constrained to lie on.  For a surface mesh some geometric domain must always be specified (e.g. a surface) and it is still necessary to specify which vertices are fixed unless the geometric domain also includes the bounding geometric curves constraining the movement of the boundary mesh vertices\footnote{A surface mesh that forms a topological sphere has no boundary and therefore need not have vertices designated as fixed or otherwise constrained as long as the entire geometric domain is continuous.}.  Geometric domains are the topic of Chapter \ref{sec:geom}.  Further discussion and examples in this section will be limited to volume meshes and true 2D meshes, both with the boundary vertices designated as fixed via the ``fixed tag''. 

Designating vertices as fixed is the responsibility of the application using Mesquite.  This responsibility is left to the application (as opposed to providing some utility in Mesquite to find the ``skin'' of a mesh) for several reasons.  An application can often obtain the set of vertices bounding a region of mesh directly through data not available to Mesquite.  For example if the application has a B-rep solid model for which the mesh is a discretization then it typically can obtain the bounding vertices as the set of vertices associated with the bounding geometric entities.  Further, there exist cases where the fixed vertices are more than just those on the topological boundary of the mesh.  For example, consider the mesh of a conic surface that includes a vertex at the apex of the cone.  Such a vertex must be designated as fixed because the lack of a valid surface normal at that point will interfere with the correct functioning of Mesquite.  Such a vertex cannot be reliably identified given only the mesh.  However, identifying such vertices typically happens naturally when obtaining the set of fixed vertices from the association with bounding geometric entities.  Finally, the optimal implementation of a ``skinning'' operation depends greatly on details of the mesh representation that Mesquite is not aware of and is not otherwise concerned with.

\subsection{Practical Details}

The \texttt{Mesquite::MsqIMesh} class caches data related to the input \texttt{iBase\_EntitySetHandle} upon construction.  If the contents of the referenced entity set change, or the vertices associated with elements contained in that set change, then the application should either re-create the \texttt{Mesquite::MsqIMesh} instance or notify an existing instance of the change by calling the \texttt{set\_active\_set} member function.  Similarly, while the implementation does not at the time of this writing cache data related to the ``fixed tag'', it may do so in the future.  For forward compatibility the application should consider calling the \texttt{set\_fixed\_tag} method of \texttt{Mesquite::MsqIMesh} to notify the instance that the value of the tag may have changed for some mesh vertices.

The current version of Mesquite uses the following functions from the iMesh interface:
\begin{itemize}
\item \texttt{iMesh\_getRootSet}
\item \texttt{iMesh\_getGeometricDimension}
\item \texttt{iMesh\_getEntities}
\item \texttt{iMesh\_getNumOfType}
\item \texttt{iMesh\_isEntContained}
\item \texttt{iMesh\_getEntArrTopo}
\item \texttt{iMesh\_getEntArrAdj}
\item \texttt{iMesh\_getVtxArrCoords}
\item \texttt{iMesh\_setVtxCoord}
\item \texttt{iMesh\_createTag}
\item \texttt{iMesh\_destroyTag}
\item \texttt{iMesh\_getTagName}
\item \texttt{iMesh\_getTagSizeBytes}
\item \texttt{iMesh\_getTagType}
\item \texttt{iMesh\_getTagHandle}
\item \texttt{iMesh\_getIntArrData}
\item \texttt{iMesh\_getIntData}
\item \texttt{iMesh\_getArrData}
\item \texttt{iMesh\_setArrData}
\item \texttt{iMesh\_setIntData}
\item \texttt{iMesh\_setIntArrData}
\end{itemize}

An implementation should provide complete implementations of all of these methods to guarantee compatibility with all possible Mesquite algorithms. 

\subsection{Volume Example}

The following example demonstrates the use of the \texttt{ShapeImprover} wrapper with an implementation of the iMesh interface.  It is assumed that the application has implemented the iMesh interface to provide access to its own data or is using an existing implementation of the iMesh interface to store its mesh data.  The example illustrates the setup necessary to correctly pass a subset of a mesh to mesquite and how to designate boundary vertices as fixed using the ``fixed tag''.  The input to the example function is the \texttt{iMesh\_Instance} handle and an \texttt{iBase\_EntitySetHandle} specifying both the elements for which to improve the quality and the free vertices.  The example code uses this application-supplied designation of which vertices are fixed to initialize the ``fixed tag''.

\begin{lstlisting}

#include <MsqError.hpp>
#include <ShapeImprover.hpp>
#include <MsqIMesh.hpp>
#include <vector>
#include <iostream>
#include <iMesh.h>

using namespace Mesquite;

/**\brief Call Mesquite ShapeImprover wrapper for volume mesh
 *
 * Smooth mesh accessed through ITAPS APIs using Mesquite
 * ShapeImprover.
 *
 *\param mesh_instance iMesh API instance
 *\param mesh A set defined in 'mesh_instance' that contains
 *            *both* the set of elements to smooth *and* the
 *            set of interior vertices that are to be moved
 *            to improve the quality of the mesh.  This set
 *            must *not* contain vertices on the boundary of
 *            the volume mesh.
 *\return mesquite error code or imesh error code
 *        (0 for success in all cases.)
 */
int shape_improve_volume( iMesh_Instance mesh_instance,
                          iBase_EntitySetHandle mesh )
{
  MsqPrintError err(std::cerr);
  int ierr;
  iBase_EntityHandle *ptr1, *ptr2;
  int *ptr3, *ptr4;
  int i5, i6, i7, i8, i9, i10, i11;
  \<const int elem_dim = 3;\>
  \<const int max_vtx_per_elem = 8;\>
  
    // create adapter (should also create fixed tag)
  MsqIMesh mesh_adapter( mesh_instance, mesh, elem_dim, err );
  if (err) return err.error_code();

    // get tag for marking vertices as fixed
    // Note: we assume here that the tag has already been created.
  iBase_TagHandle fixed_tag = 0;
  iMesh_getTagHandle( mesh_instance,
                      "fixed",
                      &fixed_tag,
                      &ierr,
                      strlen("fixed") );
  if (iBase_SUCCESS != ierr) return ierr;

    // get all vertices in mesh
  int count, num_vtx;
  iMesh_getNumOfType( mesh_instance, mesh, elem_dim, &count, &ierr );
  if (iBase_SUCCESS != ierr) return ierr;
  std::vector<iBase_EntityHandle> elems(count), verts(max_vtx_per_elem*count);
  std::vector<int> indices(max_vtx_per_elem*count), offsets(count+1);
  ptr1 = &elems[0];
  ptr2 = &verts[0];
  ptr3 = &indices[0];
  ptr4 = &offsets[0];
  i5 = elems.size();
  i7 = verts.size();
  i8 = indices.size();
  i10 = offsets.size();
  iMesh_getAdjEntIndices( mesh_instance, mesh, 
                          elem_dim, iMesh_ALL_TOPOLOGIES, iBase_VERTEX,
                          &ptr1, &i5, &i6,
                          &ptr2, &i7, &num_vtx,
                          &ptr3, &i8, &i9,
                          &ptr4, &i10, &i11, &ierr );
  if (iBase_SUCCESS != ierr) return ierr;
  verts.resize( num_vtx );

    // set fixed flag on all vertices
  std::vector<int> tag_data(num_vtx, 1);
  iMesh_setIntArrData( mesh_instance, &verts[0], verts.size(), 
                       fixed_tag, &tag_data[0], tag_data.size(), &ierr );
  if (iBase_SUCCESS != ierr) return ierr;

    // clear fixed flag for vertices contained directly in set
  iMesh_getNumOfType( mesh_instance, mesh, iBase_VERTEX, &count, &ierr );
  if (iBase_SUCCESS != ierr) return ierr;
  verts.resize( count );
  ptr1 = &verts[0];
  i5 = verts.size();
  iMesh_getEntities( mesh_instance, mesh, iBase_VERTEX, iMesh_ALL_TOPOLOGIES,
                     &ptr1, &i5, &i6, &ierr );
  if (iBase_SUCCESS != ierr) return ierr;
  tag_data.clear();
  tag_data.resize( verts.size(), 0 );
  iMesh_setIntArrData( mesh_instance, &verts[0], verts.size(), 
                       fixed_tag, &tag_data[0], tag_data.size(), &ierr );
  if (iBase_SUCCESS != ierr) return ierr;

    // Finally, smooth the mesh
  ShapeImprover smoother;
  \<smoother.run_instructions( &mesh_adapter, err );\>
  if (err) return err.error_code();

  return 0;
}
\end{lstlisting}

\subsection{Two-dimensional Example}

This section presents an example of how to use Mesquite to optimize a 2D mesh.  It is a modification of the example from the previous section with changes shown in blue.  As Mesquite operates only on 3D meshes (either volume or surface), a 2D mesh is optimized by treating it as a surface mesh constrained to the XY plane.


\begin{lstlisting}

#include <MsqError.hpp>
#include <ShapeImprover.hpp>
#include <MsqIMesh.hpp>
\<#include <PlanarDomain.hpp>\>
#include <vector>
#include <iostream>
#include <iMesh.h>

using namespace Mesquite;

/**\brief Call Mesquite ShapeImprover wrapper for 2D mesh
 *
 * Smooth mesh accessed through ITAPS APIs using Mesquite
 * ShapeImprover.
 *
 *\param mesh_instance iMesh API instance
 *\param mesh A set defined in 'mesh_instance' that contains
 *            *both* the set of elements to smooth *and* the
 *            set of interior vertices that are to be moved
 *            to improve the quality of the mesh.  This set
 *            must *not* contain vertices on the boundary of
 *            the mesh.
 *\return mesquite error code or imesh error code
 *        (0 for success in all cases.)
 */
int shape_improve_2D( iMesh_Instance mesh_instance,
                      iBase_EntitySetHandle mesh )
{
  MsqPrintError err(std::cerr);
  int ierr;
  iBase_EntityHandle *ptr1, *ptr2;
  int *ptr3, *ptr4;
  int i5, i6, i7, i8, i9, i10, i11;
  \<const int elem_dim = 2;\>
  \<const int max_vertex_per_elem = 4;\>
  
    // create adapter (should also create fixed tag)
  MsqIMesh mesh_adapter( mesh_instance, mesh, elem_dim, err );
  if (err) return err.error_code();

    // get tag for marking vertices as fixed
    // Note: we assume here that the tag has already been created.
  iBase_TagHandle fixed_tag = 0;
  iMesh_getTagHandle( mesh_instance,
                      "fixed",
                      &fixed_tag,
                      &ierr,
                      strlen("fixed") );
  if (iBase_SUCCESS != ierr) return ierr;

    // get all vertices in mesh
  int count, num_vtx;
  iMesh_getNumOfType( mesh_instance, mesh, elem_dim, &count, &ierr );
  if (iBase_SUCCESS != ierr) return ierr;
  std::vector<iBase_EntityHandle> elems(count), verts(max_vtx_per_elem*count);
  std::vector<int> indices(max_vtx_per_elem*count), offsets(count+1);
  ptr1 = &elems[0];
  ptr2 = &verts[0];
  ptr3 = &indices[0];
  ptr4 = &offsets[0];
  i5 = elems.size();
  i7 = verts.size();
  i8 = indices.size();
  i10 = offsets.size();
  iMesh_getAdjEntIndices( mesh_instance, mesh, 
                          elem_dim, iMesh_ALL_TOPOLOGIES, iBase_VERTEX,
                          &ptr1, &i5, &i6,
                          &ptr2, &i7, &num_vtx,
                          &ptr3, &i8, &i9,
                          &ptr4, &i10, &i11, &ierr );
  if (iBase_SUCCESS != ierr) return ierr;
  verts.resize( num_vtx );

    // set fixed flag on all vertices
  std::vector<int> tag_data(num_vtx, 1);
  iMesh_setIntArrData( mesh_instance, &verts[0], verts.size(), 
                       fixed_tag, &tag_data[0], tag_data.size(), &ierr );
  if (iBase_SUCCESS != ierr) return ierr;

    // clear fixed flag for vertices contained directly in set
  iMesh_getNumOfType( mesh_instance, mesh, iBase_VERTEX, &count, &ierr );
  if (iBase_SUCCESS != ierr) return ierr;
  verts.resize( count );
  ptr1 = &verts[0];
  i5 = verts.size();
  iMesh_getEntities( mesh_instance, mesh, iBase_VERTEX, iMesh_ALL_TOPOLOGIES,
                     &ptr1, &i5, &i6, &ierr );
  if (iBase_SUCCESS != ierr) return ierr;
  tag_data.clear();
  tag_data.resize( verts.size(), 0 );
  iMesh_setIntArrData( mesh_instance, &verts[0], verts.size(), 
                       fixed_tag, &tag_data[0], tag_data.size(), &ierr );
  if (iBase_SUCCESS != ierr) return ierr;

    // Finally, smooth the mesh
  ShapeImprover smoother;
  \<PlanarDomain xyplane(PlanarDomain::XY);\>
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh_adapter, &xyplane);
  \<smoother.run_instructions( &mesh_and_domain, err );\>
  if (err) return err.error_code();

  return 0;
}
\end{lstlisting}

\section{Tags} \label{sec:tags_section}

\subsection{Using Tags}

Mesquite has the ability to attach arbitrary pieces of data to mesh elements or vertices via the use of tags.  Assigning tag data to a vertex or element is a two step process.  First, the tag itself is created to describe the tag name, type, and size.  Second, the actual data value is associated with the vertex or element using the tag as a descriptor.

When a tag itself is created, it is given a name and associated data type.  Valid Mesquite Tag Types are: BYTE, BOOL, INT, DOUBLE, and HANDLE. Tags are created using the method MeshImpl::tag\_create() or one of it derived forms.

Mesquite can also handle VTK tags.  Valid VTK Tag Types are: SCALAR, COLOR, VECTOR, NORMAL, TEXTURE, TENSOR, and FIELD. VTK tags and data are assigned as part of the reading a VTK file operation and can be created and manipulated from within Mesquite.  The VTK tags and data are persistent for the VTK entitles within Mesquite including when they are written back to a file.

Once the tag is created, it is used to associate data to a vertex or element mesh entity using the methods MeshImpl::tag\_set\_vertex\_data() or MeshImpl::tag\_set\_element\_data().  Tagged data is recovered via MeshImpl::tag\_get\_vertex\_data() or MeshImpl::tag\_get\_element\_data().


\subsection{Vector Example}

The following is a simple example of using tags to associate vectors with elements of a mesh. It creates a simple mesh of two quads then creates a single tag consisting of 3 doubles to represent the vector. After creating the values for the two vectors, it associates the vectors with the elements of the mesh via a call to tag\_set\_element\_data().

\begin{lstlisting}
#include "Mesquite.hpp"
#include "MeshImpl.hpp"
#include "MsqError.hpp"

int main(int argc, char* argv[])
{

  const double vertices[] = { 0, 0, 0,
                              0, 1, 0,
                              1, 0, 0,
                              1, 1, 0,
                              2, 1, 0,
                              2, 0, 0};
  const int conn[] = {0, 1, 3, 2, 1, 5, 4, 3 };

  bool fixed[] = {true, true, true, true, true, true};
  Mesquite::MsqError err;
  std::vector<Mesquite::Mesh::ElementHandle>elements;

    // Create the mesh
  Mesquite::MeshImpl mesh(6, 2, Mesquite::QUADRILATERAL, fixed, vertices, conn);
  mesh.get_all_elements(elements, err);

  std::vector<double> v_tags(elements.size() * 3);

    // Create tag
  Mesquite::TagHandle v_tag = 
                mesh.tag_create("VECTOR", Mesquite::Mesh::DOUBLE, 3, NULL, err);

  std::vector<double> v_coords(6);
  v_coords[0] = 0.0;
  v_coords[1] = 0.0;
  v_coords[2] = -1.0;
  v_coords[3] = 0.0;
  v_coords[4] = 0.0;
  v_coords[5] = 1.0;

     // Associate vectors with elements
  mesh.tag_set_element_data(v_tag, elements.size(), 
                   mesquite::arrptr(elements), Mesquite::arrptr(v_coords) ,err);
  return 0;
}
\end{lstlisting}

\subsection{2x2 Matrix on vertices using Tags Example}

The follow code example shows another way tags can be used in Mesquite.  It attaches a 2x2 matrix to each vertex in a mesh by creating four tags and four arrays of doubles. The value for the matrices are stored in the arrays with each array representing one value of the matrix. Then the four tags are associated with the four arrays to create tagged data for each vertex representing the 2x2 matrix for it.


\begin{lstlisting}
int main(int argc, char* argv[])
{
  //  2 +-----+ 3
  //    |\    |
  //    | \   |
  //    |  \  |
  //    |   \ |
  //    |    \|
  //  0 +-----+ 1
 double tri_verts[] = { 0.0, 0.0, 0.0,
                        1.0, 0.0, 0.0,
                        0.0, 1.0, 0.0,
                        1.0, 1.0, 0.0 };

  const int tri_elems[] = { 0, 1, 2,
                            3, 2, 1 };

  bool fixed[] = {true, true, true, true};
  Mesquite::MsqError err;
  std::vector<Mesquite::Mesh::ElementHandle>elements;

    // Create the mesh
  Mesquite::MeshImpl mesh(4, 2, Mesquite::TRIANGLE, fixed, tri_verts, tri_elems);
  mesh.get_all_elements(elements, err);

  std::vector<double> lid1(elements.size());
  std::vector<double> lid2(elements.size());
  std::vector<double> lid3(elements.size());
  std::vector<double> lid4(elements.size());

  double adTestOri[4] = {0.0,0.0,0.0,0.0};
  for (unsigned int i=0; i < elements.size(); i++)
  {
    /****************************************************************
     Compute eigenvectors and eigenvalues to be used to set the Target
     (actual steps left out for simplicity of example)
    ****************************************************************/

    if (adTestOri[1]*adTestOri[1]+adTestOri[3]*adTestOri[3] >
        adTestOri[0]*adTestOri[0]+adTestOri[2]*adTestOri[2])
          {
      lid1[i] = -adTestOri[1];
      lid2[i] = adTestOri[0];
      lid3[i] = -adTestOri[3];
      lid4[i] = adTestOri[2];
    }
    else
    {
      lid1[i] = adTestOri[0];
      lid2[i] = adTestOri[1];
      lid3[i] = adTestOri[2];
      lid4[i] = adTestOri[3];
    }
  }

  const char LOCAL_ID_NAME1[] = "LOCAL_ID1";
  const char LOCAL_ID_NAME2[] = "LOCAL_ID2";
  const char LOCAL_ID_NAME3[] = "LOCAL_ID3";
  const char LOCAL_ID_NAME4[] = "LOCAL_ID4";

    // Create tags
  Mesquite::TagHandle lid_tag1 =
        mesh.tag_create(LOCAL_ID_NAME1, Mesquite::Mesh::DOUBLE, 1, NULL, err);
  Mesquite::TagHandle lid_tag2 =
        mesh.tag_create(LOCAL_ID_NAME2, Mesquite::Mesh::DOUBLE, 1, NULL, err);
  Mesquite::TagHandle lid_tag3 =
        mesh.tag_create(LOCAL_ID_NAME3, Mesquite::Mesh::DOUBLE, 1, NULL, err);
  Mesquite::TagHandle lid_tag4 =
        mesh.tag_create(LOCAL_ID_NAME4, Mesquite::Mesh::DOUBLE, 1, NULL, err);
  size_t num_cells=(elements.size());

    // Associate arrays representing 2x2 matricies to verticies
  mesh.tag_set_vertex_data(
      lid_tag1,num_cells,Mesquite::arrptr(elements),Mesquite::arrptr(lid1),err);
  mesh.tag_set_vertex_data(
      lid_tag2,num_cells,Mesquite::arrptr(elements),Mesquite::arrptr(lid2),err);
  mesh.tag_set_vertex_data(
      lid_tag3,num_cells,Mesquite::arrptr(elements),Mesquite::arrptr(lid3),err);
  mesh.tag_set_vertex_data(
      lid_tag4,num_cells,Mesquite::arrptr(elements),Mesquite::arrptr(lid4),err);

  return 0;
\end{lstlisting}

\section{Slaved Verticies} \label{sec:slaved_vertices}

Mesquite supports three types of vertices: fixed, free, and slaved.  Fixed vertices cannot be moved by optimization routines, free vertices are eligible to be moved, and slaved vertices are handled in a specific manner as described in this section.

Slaved vertices are used primarily with a mesh that contains higher order elements.  They are typically vertices at edge or face centers as well as element centers.  In the cases where these higher order nodes cannot or should not be used in an optimization or quality metric evaluation, they are marked as slaved.  This allows the operations to proceed as if those nodes were not present in the mesh but the slaved nodes can still be moved to retain the proper spatial relationship with any free nodes that were moved by the optimization.

How vertices can be moved by optimization routines is controlled by two flags in the MeshImplData class: fixed and slaved.  When the fixed flag is false the vertex is considered to be free, true signifies a fixed vertex.  True for the slaved flag marks the vertex as slaved.  The combination of fixed=true and slaved=true is not valid and will result in failures during processing of the mesh containing the vertices.


There are three ways in Mesquite to mark vertices as slaved:

1. When reading in a mesh from a VTK file, a dataset attribute of 'slaved' can be used to define which of the points in the mesh are slaved.  The following VTK input file describes a very contrived mesh of a single quad with four fixed vertices at the corners and a slaved vertex at the mid-point of each edge.  In the input file, the first four points defined are the corners, the next for are the mid-point nodes.



\begin{verbatim}
# vtk DataFile Version 3.0
Mesquite Mesh
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 8 double
0 0 0
1 0 0
1 1 0
0 1 0
0.5 0 0
1 0.5 0
0.5 1 0
0 0.5 0
CELLS 1 9
8 0 1 2 3 4 5 6 7
CELL_TYPES 1
23
POINT_DATA 8
SCALARS fixed int
LOOKUP_TABLE default
1
1
1
1
0
0
0
0
SCALARS GLOBAL_ID int 1
LOOKUP_TABLE default
1
2
3
4
5
6
7
8
SCALARS slaved int 1
LOOKUP_TABLE default
0
0
0
0
1
1
1
1
CELL_DATA 1
SCALARS GLOBAL_ID int 1
LOOKUP_TABLE default
1
\end{verbatim}


2. A vertex can be marked as slaved by calling the method

 \texttt{MeshImplData::slave\_vertex(size\_t index, bool flag, MsqError\& err)} with the parameter 'flag' being "true" to signify slaved, "false" for not slaved.

3. The VertexBoundarySlaver class can be inserted in the instruction queue before any optimization to determine which higher-order nodes are slaved as a function of their distance from the boundary of the mesh.  It will attempt to automatically mark vertices as slaved according to the input parameters 'depth' and 'max\_boundary\_domain\_dimension'.  'depth' is the number of elements inwards from the boundary for which all contained higher-order nodes will be free variables in the optimization.  Any vertex further from the boundary will be slaved.  A depth of zero will result in all higher-order nodes being slaved except free nodes on the boundary.  'max\_boundary\_domain\_dimension' specifies the definition of "boundary".  If greater than or equal to 4, then the set of all fixed vertices is assumed to be the boundary.  If less than four, then all vertices constrained to a domain with the specified number of fewer degrees of freedom (constrained to a geometric entity with an equal or smaller topological dimension) will be considered to be the boundary.  If not specified, the boundary will be assumed to be indicated by fixed vertices.

Assuming a mesh has already been created, the following code snippet calls the VertexBoundarySlaver class to determine which vertices are to be slaved:

\begin{lstlisting}
  unsigned depth = 1;
  unsigned boundary = 2;
  Settings settings;
  settings.set_slaved_ho_node_mode( Settings::SLAVE_CALCULATED );
  SlaveBoundaryVertices determine_slaved_verts( depth, boundary );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain);
  determine_slaved_verts.loop_over_mesh( &mesh_and_domain, &settings, err );
\end{lstlisting}

