MOAB: Mesh Oriented datABase  (version 5.4.0)
MeshInterface.hpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2004 Sandia Corporation and Argonne National
00005     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
00006     with Sandia Corporation, the U.S. Government retains certain
00007     rights in this software.
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Lesser General Public
00011     License as published by the Free Software Foundation; either
00012     version 2.1 of the License, or (at your option) any later version.
00013 
00014     This library is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017     Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     (lgpl.txt) along with this library; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023     diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov,
00024     pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov,
00025     kraftche@cae.wisc.edu
00026 
00027   ***************************************************************** */
00028 /*!
00029   \file   MeshInterface.hpp
00030   \brief  This file contains the Mesquite mesh interface.
00031           Many users will want to implement a concrete class derived from
00032           the MeshInterface class to access their mesh.
00033 
00034 
00035   \author Darryl Melander
00036   \author Thomas Leurent
00037   \date   2003-04-17
00038 */
00039 #ifndef MESQUITE_INTERFACE_HPP
00040 #define MESQUITE_INTERFACE_HPP
00041 
00042 #include "Mesquite.hpp"
00043 #include "TopologyInfo.hpp"
00044 
00045 #include "MsqError.hpp"
00046 #include "MsqVertex.hpp"
00047 
00048 #include "moab/EntityHandle.hpp"
00049 
00050 #include <vector>
00051 #include <cstddef>
00052 #include <string>
00053 #include <iostream>
00054 
00055 namespace MBMesquite
00056 {
00057 class EntityIterator;
00058 class MsqError;
00059 class MsqVertex;
00060 class Vector3D;
00061 class SphericalDomain;
00062 typedef EntityIterator VertexIterator;
00063 typedef EntityIterator ElementIterator;
00064 
00065 /** Type used to refer to a tag defintion */
00066 typedef void* TagHandle;
00067 
00068 inline size_t vertices_in_topology( EntityTopology );
00069 
00070 /*! \class Mesh
00071    \brief  A MBMesquite::Mesh is a collection of mesh elements which are
00072    composed of mesh vertices.  Intermediate objects are not accessible
00073    through this interface (where intermediate objects include things
00074    like the faces of a hex, or an element's edges).
00075 */
00076 class MESQUITE_EXPORT Mesh
00077 {
00078   public:
00079     //************ Type Definitions **************
00080     //! Opaque EntityHandle type and tag type.
00081     typedef void* EntityHandle;
00082     // typedef moab::EntityHandle EntityHandle;
00083 
00084     // We typedef specific types of EntityHandles just
00085     // to make it clear what kind of entity is to be
00086     // returned or used as a function parameter, but the
00087     // different handle types are not actually distinct.
00088     typedef EntityHandle VertexHandle;
00089     typedef EntityHandle ElementHandle;
00090 
00091     //************ Operations on entire mesh ****************
00092     //! Returns whether this mesh lies in a 2D or 3D coordinate system.
00093     virtual int get_geometric_dimension( MsqError& err ) = 0;
00094 
00095     /** \brief Get all elements in mesh
00096      *
00097      * Get the handles of every element in the active mesh.
00098      */
00099     virtual void get_all_elements( std::vector< ElementHandle >& elements, MsqError& err ) = 0;
00100 
00101     /** \brief Get all vertices in mesh
00102      *
00103      * Get the handles of every vertex in the active mesh
00104      */
00105     virtual void get_all_vertices( std::vector< VertexHandle >& vertices, MsqError& err ) = 0;
00106 
00107     //! Returns a pointer to an iterator that iterates over the
00108     //! set of all vertices in this mesh.  The calling code should
00109     //! delete the returned iterator when it is finished with it.
00110     //! If vertices are added or removed from the Mesh after obtaining
00111     //! an iterator, the behavior of that iterator is undefined.
00112     //    virtual VertexIterator* vertex_iterator(MsqError &err) = 0;
00113 
00114     //! Returns a pointer to an iterator that iterates over the
00115     //! set of all top-level elements in this mesh.  The calling code should
00116     //! delete the returned iterator when it is finished with it.
00117     //! If elements are added or removed from the Mesh after obtaining
00118     //! an iterator, the behavior of that iterator is undefined.
00119     //    virtual ElementIterator* element_iterator(MsqError &err) = 0;
00120 
00121     //************ Vertex Properties ********************
00122     //! Returns true or false, indicating whether the vertex
00123     //! is allowed to be repositioned.  True indicates that the vertex
00124     //! is fixed and cannot be moved.  Note that this is a read-only
00125     //! property; this flag can't be modified by users of the
00126     //! MBMesquite::Mesh interface.
00127     virtual void vertices_get_fixed_flag( const VertexHandle vert_array[],
00128                                           std::vector< bool >& fixed_flag_array,
00129                                           size_t num_vtx,
00130                                           MsqError& err ) = 0;
00131 
00132     //! Returns true or false, indicating whether the vertex
00133     //! is a higher-order node that should be slaved to the logical
00134     //! mid-point of the element side it lies on or not, respectively.
00135     //!
00136     //! Note: This function will never be called unless this behavior is
00137     //! requested by calling:
00138     //! InstructionQueue::set_slaved_ho_node_mode( Settings::SLAVE_FLAG )
00139     virtual void vertices_get_slaved_flag( const VertexHandle vert_array[],
00140                                            std::vector< bool >& slaved_flag_array,
00141                                            size_t num_vtx,
00142                                            MsqError& err ) = 0;
00143 
00144     //! Get/set location of a vertex
00145     virtual void vertices_get_coordinates( const VertexHandle vert_array[],
00146                                            MsqVertex* coordinates,
00147                                            size_t num_vtx,
00148                                            MsqError& err )                                                 = 0;
00149     virtual void vertex_set_coordinates( VertexHandle vertex, const Vector3D& coordinates, MsqError& err ) = 0;
00150 
00151     //! Each vertex has a byte-sized flag that can be used to store
00152     //! flags.  This byte's value is neither set nor used by the mesh
00153     //! implementation.  It is intended to be used by Mesquite algorithms.
00154     //! Until a vertex's byte has been explicitly set, its value is 0.
00155     virtual void vertex_set_byte( VertexHandle vertex, unsigned char byte, MsqError& err ) = 0;
00156     virtual void vertices_set_byte( const VertexHandle* vert_array,
00157                                     const unsigned char* byte_array,
00158                                     size_t array_size,
00159                                     MsqError& err )                                        = 0;
00160 
00161     //! Retrieve the byte value for the specified vertex or vertices.
00162     //! The byte value is 0 if it has not yet been set via one of the
00163     //! *_set_byte() functions.
00164     virtual void vertex_get_byte( const VertexHandle vertex, unsigned char* byte, MsqError& err ) = 0;
00165     virtual void vertices_get_byte( const VertexHandle* vertex,
00166                                     unsigned char* byte_array,
00167                                     size_t array_size,
00168                                     MsqError& err )                                               = 0;
00169 
00170     //**************** Vertex Topology *****************
00171     /** \brief get elements adjacent to vertices
00172      *
00173      * Get adjacency data for vertices
00174      *
00175      *\param vertex_array    Array of vertex handles specifying the
00176      *                       list of vertices to retrieve adjacency
00177      *                       data for.
00178      *\param num_vertex      Number of vertex handles in #vertex_array
00179      *\param elements     The array in which to place the handles of
00180      *                       elements adjacent to the input vertices.
00181      *\param offsets    For each vertex in #vertex_array, the
00182      *                       value in the corresponding position in this
00183      *                       array is the index into #elem_array at
00184      *                       which the adjacency list begins for that
00185      *                       vertex.
00186      */
00187     virtual void vertices_get_attached_elements( const VertexHandle* vertex_array,
00188                                                  size_t num_vertex,
00189                                                  std::vector< ElementHandle >& elements,
00190                                                  std::vector< size_t >& offsets,
00191                                                  MsqError& err ) = 0;
00192 
00193     //*************** Element Topology *************
00194 
00195     /** \brief Get element connectivity
00196      *
00197      * Get the connectivity (ordered list of vertex handles) for
00198      * each element in the input array.
00199      *
00200      *\param elem_handles  The array of element handles for which to
00201      *                     retrieve the connectivity list.
00202      *\param num_elems     The length of #elem_handles
00203      *\param vert_handles  Array in which to place the vertex handles
00204      *                     in each elements connectivity.
00205      *\param offsets       For each element in #elem_handles, the
00206      *                     value in the same position in this array
00207      *                     is the index into #vert_handles at which
00208      *                     the connectivity list for that element begins.
00209      */
00210     virtual void elements_get_attached_vertices( const ElementHandle* elem_handles,
00211                                                  size_t num_elems,
00212                                                  std::vector< VertexHandle >& vert_handles,
00213                                                  std::vector< size_t >& offsets,
00214                                                  MsqError& err ) = 0;
00215 
00216     //! Returns the topologies of the given entities.  The "entity_topologies"
00217     //! array must be at least "num_elements" in size.
00218     virtual void elements_get_topologies( const ElementHandle* element_handle_array,
00219                                           EntityTopology* element_topologies,
00220                                           size_t num_elements,
00221                                           MsqError& err ) = 0;
00222 
00223     //***************  Tags  ***********
00224 
00225     /** The type of a tag */
00226     enum TagType
00227     {
00228         BYTE,
00229         BOOL,
00230         INT,
00231         DOUBLE,
00232         HANDLE
00233     };
00234 
00235     /** \brief Create a tag
00236      *
00237      * Create a user-defined data type that can be attached
00238      * to any element or vertex in the mesh.  For an opaque or
00239      * undefined type, use type=BYTE and length=sizeof(..).
00240      *
00241      * \param tag_name  A unique name for the data object
00242      * \param type      The type of the data
00243      * \param length    Number of values per entity (1->scalar, >1 ->vector)
00244      * \param default_value Default value to assign to all entities - may be NULL
00245      * \return - Handle for tag definition
00246      */
00247     virtual TagHandle tag_create( const std::string& tag_name,
00248                                   TagType type,
00249                                   unsigned length,
00250                                   const void* default_value,
00251                                   MsqError& err ) = 0;
00252 
00253     /** \brief Remove a tag and all corresponding data
00254      *
00255      * Delete a tag.
00256      */
00257     virtual void tag_delete( TagHandle handle, MsqError& err ) = 0;
00258 
00259     /** \brief Get handle for existing tag, by name.
00260      *
00261      * Check for the existance of a tag given it's name and
00262      * if it exists return a handle for it.  If the specified
00263      * tag does not exist, zero should be returned WITHOUT
00264      * flagging an error.
00265      */
00266     virtual TagHandle tag_get( const std::string& name, MsqError& err ) = 0;
00267 
00268     /** \brief Get properites of tag
00269      *
00270      * Get data type and number of values per entity for tag.
00271      * \param handle     Tag to get properties of.
00272      * \param name_out   Passed back tag name.
00273      * \param type_out   Passed back tag type.
00274      * \param length_out Passed back number of values per entity.
00275      */
00276     virtual void tag_properties( TagHandle handle,
00277                                  std::string& name_out,
00278                                  TagType& type_out,
00279                                  unsigned& length_out,
00280                                  MsqError& err ) = 0;
00281 
00282     /** \brief Set tag values on elements
00283      *
00284      * Set the value of a tag for a list of mesh elements.
00285      * \param handle     The tag
00286      * \param num_elems  Length of elem_array
00287      * \param elem_array Array of elements for which to set the tag value.
00288      * \param tag_data   Tag data for each element, contiguous in memory.
00289      *                   This data is expected to be
00290      *                   num_elems*tag_length*sizeof(tag_type) bytes.
00291      */
00292     virtual void tag_set_element_data( TagHandle handle,
00293                                        size_t num_elems,
00294                                        const ElementHandle* elem_array,
00295                                        const void* tag_data,
00296                                        MsqError& err ) = 0;
00297 
00298     /** \brief Set tag values on vertices
00299      *
00300      * Set the value of a tag for a list of mesh vertices.
00301      * \param handle     The tag
00302      * \param num_elems  Length of node_array
00303      * \param node_array Array of vertices for which to set the tag value.
00304      * \param tag_data   Tag data for each element, contiguous in memory.
00305      *                   This data is expected to be
00306      *                   num_elems*tag_length*sizeof(tag_type) bytes.
00307      */
00308     virtual void tag_set_vertex_data( TagHandle handle,
00309                                       size_t num_elems,
00310                                       const VertexHandle* node_array,
00311                                       const void* tag_data,
00312                                       MsqError& err ) = 0;
00313 
00314     /** \brief Get tag values on elements
00315      *
00316      * Get the value of a tag for a list of mesh elements.
00317      * \param handle     The tag
00318      * \param num_elems  Length of elem_array
00319      * \param elem_array Array of elements for which to get the tag value.
00320      * \param tag_data   Return buffer in which to copy tag data, contiguous
00321      *                   in memory.  This data is expected to be
00322      *                   num_elems*tag_length*sizeof(tag_type) bytes.
00323      */
00324     virtual void tag_get_element_data( TagHandle handle,
00325                                        size_t num_elems,
00326                                        const ElementHandle* elem_array,
00327                                        void* tag_data,
00328                                        MsqError& err ) = 0;
00329 
00330     /** \brief Get tag values on vertices.
00331      *
00332      * Get the value of a tag for a list of mesh vertices.
00333      * \param handle     The tag
00334      * \param num_elems  Length of elem_array
00335      * \param elem_array Array of vertices for which to get the tag value.
00336      * \param tag_data   Return buffer in which to copy tag data, contiguous
00337      *                   in memory.  This data is expected to be
00338      *                   num_elems*tag_length*sizeof(tag_type) bytes.
00339      */
00340     virtual void tag_get_vertex_data( TagHandle handle,
00341                                       size_t num_elems,
00342                                       const VertexHandle* node_array,
00343                                       void* tag_data,
00344                                       MsqError& err ) = 0;
00345 
00346     //**************** Memory Management ****************
00347     //! Tells the mesh that the client is finished with a given
00348     //! entity handle.
00349     virtual void release_entity_handles( const EntityHandle* handle_array, size_t num_handles, MsqError& err ) = 0;
00350 
00351     //! Instead of deleting a Mesh when you think you are done,
00352     //! call release().  In simple cases, the implementation could
00353     //! just call the destructor.  More sophisticated implementations
00354     //! may want to keep the Mesh object to live longer than Mesquite
00355     //! is using it.
00356     virtual void release() = 0;
00357 
00358     virtual ~Mesh() {}
00359 
00360   protected:
00361 };
00362 
00363 /*! \class EntityIterator
00364 \brief   Iterates through a set of entities.  An EntityIterator
00365 is typically obtained via Mesh::vertex_iterator() or
00366 Mesh::element_iterator().  An iterator obtained in this
00367 way iterates over the set of all vertices/elements in
00368 the Mesh from which the iterator was obtained. */
00369 class EntityIterator
00370 {
00371   public:
00372     virtual ~EntityIterator() {}
00373 
00374     //! Moves the iterator back to the first
00375     //! entity in the list.
00376     virtual void restart() = 0;
00377 
00378     //! *iterator.  Return the handle currently
00379     //! being pointed at by the iterator.
00380     virtual Mesh::EntityHandle operator*() const = 0;
00381 
00382     //! ++iterator
00383     virtual void operator++() = 0;
00384 
00385     //! Returns false until the iterator has
00386     //! been advanced PAST the last entity.
00387     //! Once is_at_end() returns true, *iterator
00388     //! returns 0.
00389     virtual bool is_at_end() const = 0;
00390 };
00391 
00392 /*! \class MeshDomain
00393     The MeshDomain class provides geometrical information concerning the Mesh.
00394     It is called during surface meshes optimization to figure out the surface normal,
00395     how to snap vertices back to the surface, etc... .
00396   */
00397 class MESQUITE_EXPORT MeshDomain
00398 {
00399   public:
00400     virtual ~MeshDomain() {}
00401 
00402     //! Modifies "coordinate" so that it lies on the
00403     //! domain to which "entity_handle" is constrained.
00404     //! The handle determines the domain.  The coordinate
00405     //! is the proposed new position on that domain.
00406     virtual void snap_to( Mesh::VertexHandle entity_handle, Vector3D& coordinate ) const = 0;
00407 
00408     //! Returns the normal of the domain to which
00409     //! "entity_handle" is constrained.  For non-planar surfaces,
00410     //! the normal is calculated at the point on the domain that
00411     //! is closest to the passed in value of "coordinate".  If the
00412     //! domain does not have a normal, or the normal cannot
00413     //! be determined, "coordinate" is set to (0,0,0).  Otherwise,
00414     //! "coordinate" is set to the domain's normal at the
00415     //! appropriate point.
00416     //! In summary, the handle determines the domain.  The coordinate
00417     //! determines the point of interest on that domain.
00418     //!
00419     //! User should see also PatchData::get_domain_normal_at_vertex and
00420     //! PatchData::get_domain_normal_at_element .
00421     virtual void vertex_normal_at( Mesh::VertexHandle entity_handle, Vector3D& coordinate ) const   = 0;
00422     virtual void element_normal_at( Mesh::ElementHandle entity_handle, Vector3D& coordinate ) const = 0;
00423 
00424     /**\brief evaluate surface normals
00425      *
00426      * Returns normals for a domain.
00427      *
00428      *\param handles       The domain evaluated is the one in which
00429      *                     this mesh entity is constrained.
00430      *\param coordinates   As input, a list of positions at which to
00431      *                     evaluate the domain.  As output, the resulting
00432      *                     domain normals.
00433      *\param count         The length of the coordinates array.
00434      */
00435     virtual void vertex_normal_at( const Mesh::VertexHandle* handles,
00436                                    Vector3D coordinates[],
00437                                    unsigned count,
00438                                    MsqError& err ) const = 0;
00439 
00440     /**\brief evaluate closest point and normal
00441      *
00442      * Given a position in space, return the closest
00443      * position in the domain and the domain normal
00444      * at that point.
00445      *
00446      *\param entity_handle Evaluate the subset of the domain contianing
00447      *                     this entity
00448      *\param position      Input position for which to evaluate
00449      *\param closest       Closest position in the domain.
00450      *\param normal        Domain normal at the location of 'closest'
00451      */
00452     virtual void closest_point( Mesh::VertexHandle handle,
00453                                 const Vector3D& position,
00454                                 Vector3D& closest,
00455                                 Vector3D& normal,
00456                                 MsqError& err ) const = 0;
00457 
00458     /**\brief Get degrees of freedom in vertex movement.
00459      *
00460      * Given a vertex, return how the domain constrains the
00461      * location of that vertex as the number of degrees of
00462      * freedom in the motion of the vertex.  If the domain
00463      * is a geometric domain, the degrees of freedom for a
00464      * vertex is the dimension of the geometric entity the
00465      * vertex is constrained to lie on (e.g. point = 0, curve = 1,
00466      * surface = 2, volume = 3.)
00467      */
00468     virtual void domain_DoF( const Mesh::EntityHandle* handle_array,
00469                              unsigned short* dof_array,
00470                              size_t num_handles,
00471                              MsqError& err ) const = 0;
00472 };
00473 
00474 /*! \class MeshDomainAssoc
00475     The MeshDomainAssoc class provides an association of a Mesh instance
00476     with a MeshDomain instance.  The mesh is checked to verify that
00477     it is compatibile with the associated MeshDomain.  If the two are
00478     not compatible, the MeshDomainAssoc instace is not created.
00479   */
00480 class MESQUITE_EXPORT MeshDomainAssoc
00481 {
00482   public:
00483     /**\brief Constructor
00484      *\param mesh                       The mesh instance being associated
00485      * param domain                     The domain being associated
00486      * param full_compatibility_check   Controls how many vertices will be checked for
00487      *                                  compatibility with the associated domain.
00488      *                                  When false, only the first vertex of the mesh
00489      *                                  is checked for compatibility.  When true, all
00490      *                                  vertices of the mesh are checked.
00491      * param proceed                    Controls what Mesquite will do if the compatibility
00492      *                                  check fails.  When false, mesquite terminates i
00493      *                                  execution.  When true, execution continues.
00494      * param skip_compatibility_checki  when true, does not perform the compatibility check.
00495      *                                  When false, the check is performed.
00496      */
00497     MeshDomainAssoc( MBMesquite::Mesh* mesh,
00498                      MBMesquite::MeshDomain* domain,
00499                      bool full_compatibility_check = false,
00500                      bool proceed                  = false,
00501                      bool skip_compatibility_check = false )
00502         : mMesh( mesh ), mMeshDomain( domain ), mesh_and_domain_are_compatible( false )
00503     {
00504         // check for real instance.  If either value is NULL then it's just an
00505         // instance created to facilitate passing of just a mesh or domain
00506         // also, check if skipping the compatibility check was requested
00507         if( mesh && domain && !skip_compatibility_check )
00508         {
00509             MsqError err;
00510             double tolerance = 1.0e-3;
00511 
00512             std::vector< Mesh::VertexHandle > vert_handles;
00513             mMesh->get_all_vertices( vert_handles, err );
00514 
00515             MsqVertex mesh_vertex, domain_vertex;
00516             Vector3D normal;
00517 
00518             double distance;
00519             std::vector< int >::size_type i, times_to_loop;
00520             if( full_compatibility_check )
00521                 times_to_loop = vert_handles.size();
00522             else
00523                 times_to_loop = 1;
00524             mesh_and_domain_are_compatible = true;
00525             for( i = 0; i < times_to_loop; ++i )
00526             {
00527                 mMesh->vertices_get_coordinates( &vert_handles[i], &mesh_vertex, 1, err );
00528                 mMeshDomain->closest_point( vert_handles[i], Vector3D( mesh_vertex ), domain_vertex, normal, err );
00529 
00530                 distance = Vector3D::distance_between( mesh_vertex, domain_vertex );
00531                 if( distance > tolerance )
00532                 {
00533                     mesh_and_domain_are_compatible = false;
00534                     std::cout << "Warning: Mesh and Domain are not compatibile" << std::endl;
00535                     if( !proceed )
00536                     {
00537                         std::cout << "Terminating due to Mesh/Domain incompatibility" << std::endl;
00538                         throw "Terminating due to Mesh/Domain incompatibility";
00539                     }
00540                     break;  // exits for loop when not compatbile but should not terminate
00541                 }
00542             }
00543         }
00544     }
00545 
00546     ~MeshDomainAssoc(){};
00547 
00548     /**\brief get associated mesh
00549      *
00550      * Return the mesh associated with this instance.
00551      */
00552     MBMesquite::Mesh* get_mesh()
00553     {
00554         return mMesh;
00555     };
00556 
00557     /**\brief get associated domain
00558      *
00559      * Return the domain associated with this instance.
00560      */
00561     MBMesquite::MeshDomain* get_domain()
00562     {
00563         return mMeshDomain;
00564     };
00565 
00566   private:
00567     MBMesquite::Mesh* mMesh;
00568     MBMesquite::MeshDomain* mMeshDomain;
00569     bool mesh_and_domain_are_compatible;
00570 
00571   public:
00572     bool are_compatible()
00573     {
00574         return mesh_and_domain_are_compatible;
00575     };
00576 };
00577 }  // namespace MBMesquite
00578 
00579 inline size_t MBMesquite::vertices_in_topology( MBMesquite::EntityTopology topo )
00580 {
00581     return TopologyInfo::corners( topo );
00582 }
00583 
00584 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines