MOAB: Mesh Oriented datABase  (version 5.2.1)
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[], std::vector< bool >& fixed_flag_array,
00128                                           size_t num_vtx, MsqError& err ) = 0;
00129 
00130     //! Returns true or false, indicating whether the vertex
00131     //! is a higher-order node that should be slaved to the logical
00132     //! mid-point of the element side it lies on or not, respectively.
00133     //!
00134     //! Note: This function will never be called unless this behavior is
00135     //! requested by calling:
00136     //! InstructionQueue::set_slaved_ho_node_mode( Settings::SLAVE_FLAG )
00137     virtual void vertices_get_slaved_flag( const VertexHandle vert_array[], std::vector< bool >& slaved_flag_array,
00138                                            size_t num_vtx, MsqError& err ) = 0;
00139 
00140     //! Get/set location of a vertex
00141     virtual void vertices_get_coordinates( const VertexHandle vert_array[], MsqVertex* coordinates, size_t num_vtx,
00142                                            MsqError& err )                                                 = 0;
00143     virtual void vertex_set_coordinates( VertexHandle vertex, const Vector3D& coordinates, MsqError& err ) = 0;
00144 
00145     //! Each vertex has a byte-sized flag that can be used to store
00146     //! flags.  This byte's value is neither set nor used by the mesh
00147     //! implementation.  It is intended to be used by Mesquite algorithms.
00148     //! Until a vertex's byte has been explicitly set, its value is 0.
00149     virtual void vertex_set_byte( VertexHandle vertex, unsigned char byte, MsqError& err ) = 0;
00150     virtual void vertices_set_byte( const VertexHandle* vert_array, const unsigned char* byte_array, size_t array_size,
00151                                     MsqError& err )                                        = 0;
00152 
00153     //! Retrieve the byte value for the specified vertex or vertices.
00154     //! The byte value is 0 if it has not yet been set via one of the
00155     //! *_set_byte() functions.
00156     virtual void vertex_get_byte( const VertexHandle vertex, unsigned char* byte, MsqError& err ) = 0;
00157     virtual void vertices_get_byte( const VertexHandle* vertex, unsigned char* byte_array, size_t array_size,
00158                                     MsqError& err )                                               = 0;
00159 
00160     //**************** Vertex Topology *****************
00161     /** \brief get elements adjacent to vertices
00162      *
00163      * Get adjacency data for vertices
00164      *
00165      *\param vertex_array    Array of vertex handles specifying the
00166      *                       list of vertices to retrieve adjacency
00167      *                       data for.
00168      *\param num_vertex      Number of vertex handles in #vertex_array
00169      *\param elements     The array in which to place the handles of
00170      *                       elements adjacent to the input vertices.
00171      *\param offsets    For each vertex in #vertex_array, the
00172      *                       value in the corresponding position in this
00173      *                       array is the index into #elem_array at
00174      *                       which the adjacency list begins for that
00175      *                       vertex.
00176      */
00177     virtual void vertices_get_attached_elements( const VertexHandle* vertex_array, size_t num_vertex,
00178                                                  std::vector< ElementHandle >& elements, std::vector< size_t >& offsets,
00179                                                  MsqError& err ) = 0;
00180 
00181     //*************** Element Topology *************
00182 
00183     /** \brief Get element connectivity
00184      *
00185      * Get the connectivity (ordered list of vertex handles) for
00186      * each element in the input array.
00187      *
00188      *\param elem_handles  The array of element handles for which to
00189      *                     retrieve the connectivity list.
00190      *\param num_elems     The length of #elem_handles
00191      *\param vert_handles  Array in which to place the vertex handles
00192      *                     in each elements connectivity.
00193      *\param offsets       For each element in #elem_handles, the
00194      *                     value in the same position in this array
00195      *                     is the index into #vert_handles at which
00196      *                     the connectivity list for that element begins.
00197      */
00198     virtual void elements_get_attached_vertices( const ElementHandle* elem_handles, size_t num_elems,
00199                                                  std::vector< VertexHandle >& vert_handles,
00200                                                  std::vector< size_t >& offsets, MsqError& err ) = 0;
00201 
00202     //! Returns the topologies of the given entities.  The "entity_topologies"
00203     //! array must be at least "num_elements" in size.
00204     virtual void elements_get_topologies( const ElementHandle* element_handle_array, EntityTopology* element_topologies,
00205                                           size_t num_elements, MsqError& err ) = 0;
00206 
00207     //***************  Tags  ***********
00208 
00209     /** The type of a tag */
00210     enum TagType
00211     {
00212         BYTE,
00213         BOOL,
00214         INT,
00215         DOUBLE,
00216         HANDLE
00217     };
00218 
00219     /** \brief Create a tag
00220      *
00221      * Create a user-defined data type that can be attached
00222      * to any element or vertex in the mesh.  For an opaque or
00223      * undefined type, use type=BYTE and length=sizeof(..).
00224      *
00225      * \param tag_name  A unique name for the data object
00226      * \param type      The type of the data
00227      * \param length    Number of values per entity (1->scalar, >1 ->vector)
00228      * \param default_value Default value to assign to all entities - may be NULL
00229      * \return - Handle for tag definition
00230      */
00231     virtual TagHandle tag_create( const std::string& tag_name, TagType type, unsigned length, const void* default_value,
00232                                   MsqError& err ) = 0;
00233 
00234     /** \brief Remove a tag and all corresponding data
00235      *
00236      * Delete a tag.
00237      */
00238     virtual void tag_delete( TagHandle handle, MsqError& err ) = 0;
00239 
00240     /** \brief Get handle for existing tag, by name.
00241      *
00242      * Check for the existance of a tag given it's name and
00243      * if it exists return a handle for it.  If the specified
00244      * tag does not exist, zero should be returned WITHOUT
00245      * flagging an error.
00246      */
00247     virtual TagHandle tag_get( const std::string& name, MsqError& err ) = 0;
00248 
00249     /** \brief Get properites of tag
00250      *
00251      * Get data type and number of values per entity for tag.
00252      * \param handle     Tag to get properties of.
00253      * \param name_out   Passed back tag name.
00254      * \param type_out   Passed back tag type.
00255      * \param length_out Passed back number of values per entity.
00256      */
00257     virtual void tag_properties( TagHandle handle, std::string& name_out, TagType& type_out, unsigned& length_out,
00258                                  MsqError& err ) = 0;
00259 
00260     /** \brief Set tag values on elements
00261      *
00262      * Set the value of a tag for a list of mesh elements.
00263      * \param handle     The tag
00264      * \param num_elems  Length of elem_array
00265      * \param elem_array Array of elements for which to set the tag value.
00266      * \param tag_data   Tag data for each element, contiguous in memory.
00267      *                   This data is expected to be
00268      *                   num_elems*tag_length*sizeof(tag_type) bytes.
00269      */
00270     virtual void tag_set_element_data( TagHandle handle, size_t num_elems, const ElementHandle* elem_array,
00271                                        const void* tag_data, MsqError& err ) = 0;
00272 
00273     /** \brief Set tag values on vertices
00274      *
00275      * Set the value of a tag for a list of mesh vertices.
00276      * \param handle     The tag
00277      * \param num_elems  Length of node_array
00278      * \param node_array Array of vertices for which to set the tag value.
00279      * \param tag_data   Tag data for each element, contiguous in memory.
00280      *                   This data is expected to be
00281      *                   num_elems*tag_length*sizeof(tag_type) bytes.
00282      */
00283     virtual void tag_set_vertex_data( TagHandle handle, size_t num_elems, const VertexHandle* node_array,
00284                                       const void* tag_data, MsqError& err ) = 0;
00285 
00286     /** \brief Get tag values on elements
00287      *
00288      * Get the value of a tag for a list of mesh elements.
00289      * \param handle     The tag
00290      * \param num_elems  Length of elem_array
00291      * \param elem_array Array of elements for which to get the tag value.
00292      * \param tag_data   Return buffer in which to copy tag data, contiguous
00293      *                   in memory.  This data is expected to be
00294      *                   num_elems*tag_length*sizeof(tag_type) bytes.
00295      */
00296     virtual void tag_get_element_data( TagHandle handle, size_t num_elems, const ElementHandle* elem_array,
00297                                        void* tag_data, MsqError& err ) = 0;
00298 
00299     /** \brief Get tag values on vertices.
00300      *
00301      * Get the value of a tag for a list of mesh vertices.
00302      * \param handle     The tag
00303      * \param num_elems  Length of elem_array
00304      * \param elem_array Array of vertices for which to get the tag value.
00305      * \param tag_data   Return buffer in which to copy tag data, contiguous
00306      *                   in memory.  This data is expected to be
00307      *                   num_elems*tag_length*sizeof(tag_type) bytes.
00308      */
00309     virtual void tag_get_vertex_data( TagHandle handle, size_t num_elems, const VertexHandle* node_array,
00310                                       void* tag_data, MsqError& err ) = 0;
00311 
00312     //**************** Memory Management ****************
00313     //! Tells the mesh that the client is finished with a given
00314     //! entity handle.
00315     virtual void release_entity_handles( const EntityHandle* handle_array, size_t num_handles, MsqError& err ) = 0;
00316 
00317     //! Instead of deleting a Mesh when you think you are done,
00318     //! call release().  In simple cases, the implementation could
00319     //! just call the destructor.  More sophisticated implementations
00320     //! may want to keep the Mesh object to live longer than Mesquite
00321     //! is using it.
00322     virtual void release() = 0;
00323 
00324     virtual ~Mesh() {}
00325 
00326   protected:
00327 };
00328 
00329 /*! \class EntityIterator
00330 \brief   Iterates through a set of entities.  An EntityIterator
00331 is typically obtained via Mesh::vertex_iterator() or
00332 Mesh::element_iterator().  An iterator obtained in this
00333 way iterates over the set of all vertices/elements in
00334 the Mesh from which the iterator was obtained. */
00335 class EntityIterator
00336 {
00337   public:
00338     virtual ~EntityIterator() {}
00339 
00340     //! Moves the iterator back to the first
00341     //! entity in the list.
00342     virtual void restart() = 0;
00343 
00344     //! *iterator.  Return the handle currently
00345     //! being pointed at by the iterator.
00346     virtual Mesh::EntityHandle operator*() const = 0;
00347 
00348     //! ++iterator
00349     virtual void operator++() = 0;
00350 
00351     //! Returns false until the iterator has
00352     //! been advanced PAST the last entity.
00353     //! Once is_at_end() returns true, *iterator
00354     //! returns 0.
00355     virtual bool is_at_end() const = 0;
00356 };
00357 
00358 /*! \class MeshDomain
00359     The MeshDomain class provides geometrical information concerning the Mesh.
00360     It is called during surface meshes optimization to figure out the surface normal,
00361     how to snap vertices back to the surface, etc... .
00362   */
00363 class MESQUITE_EXPORT MeshDomain
00364 {
00365   public:
00366     virtual ~MeshDomain() {}
00367 
00368     //! Modifies "coordinate" so that it lies on the
00369     //! domain to which "entity_handle" is constrained.
00370     //! The handle determines the domain.  The coordinate
00371     //! is the proposed new position on that domain.
00372     virtual void snap_to( Mesh::VertexHandle entity_handle, Vector3D& coordinate ) const = 0;
00373 
00374     //! Returns the normal of the domain to which
00375     //! "entity_handle" is constrained.  For non-planar surfaces,
00376     //! the normal is calculated at the point on the domain that
00377     //! is closest to the passed in value of "coordinate".  If the
00378     //! domain does not have a normal, or the normal cannot
00379     //! be determined, "coordinate" is set to (0,0,0).  Otherwise,
00380     //! "coordinate" is set to the domain's normal at the
00381     //! appropriate point.
00382     //! In summary, the handle determines the domain.  The coordinate
00383     //! determines the point of interest on that domain.
00384     //!
00385     //! User should see also PatchData::get_domain_normal_at_vertex and
00386     //! PatchData::get_domain_normal_at_element .
00387     virtual void vertex_normal_at( Mesh::VertexHandle entity_handle, Vector3D& coordinate ) const   = 0;
00388     virtual void element_normal_at( Mesh::ElementHandle entity_handle, Vector3D& coordinate ) const = 0;
00389 
00390     /**\brief evaluate surface normals
00391      *
00392      * Returns normals for a domain.
00393      *
00394      *\param handles       The domain evaluated is the one in which
00395      *                     this mesh entity is constrained.
00396      *\param coordinates   As input, a list of positions at which to
00397      *                     evaluate the domain.  As output, the resulting
00398      *                     domain normals.
00399      *\param count         The length of the coordinates array.
00400      */
00401     virtual void vertex_normal_at( const Mesh::VertexHandle* handles, Vector3D coordinates[], unsigned count,
00402                                    MsqError& err ) const = 0;
00403 
00404     /**\brief evaluate closest point and normal
00405      *
00406      * Given a position in space, return the closest
00407      * position in the domain and the domain normal
00408      * at that point.
00409      *
00410      *\param entity_handle Evaluate the subset of the domain contianing
00411      *                     this entity
00412      *\param position      Input position for which to evaluate
00413      *\param closest       Closest position in the domain.
00414      *\param normal        Domain normal at the location of 'closest'
00415      */
00416     virtual void closest_point( Mesh::VertexHandle handle, const Vector3D& position, Vector3D& closest,
00417                                 Vector3D& normal, MsqError& err ) const = 0;
00418 
00419     /**\brief Get degrees of freedom in vertex movement.
00420      *
00421      * Given a vertex, return how the domain constrains the
00422      * location of that vertex as the number of degrees of
00423      * freedom in the motion of the vertex.  If the domain
00424      * is a geometric domain, the degrees of freedom for a
00425      * vertex is the dimension of the geometric entity the
00426      * vertex is constrained to lie on (e.g. point = 0, curve = 1,
00427      * surface = 2, volume = 3.)
00428      */
00429     virtual void domain_DoF( const Mesh::EntityHandle* handle_array, unsigned short* dof_array, size_t num_handles,
00430                              MsqError& err ) const = 0;
00431 };
00432 
00433 /*! \class MeshDomainAssoc
00434     The MeshDomainAssoc class provides an association of a Mesh instance
00435     with a MeshDomain instance.  The mesh is checked to verify that
00436     it is compatibile with the associated MeshDomain.  If the two are
00437     not compatible, the MeshDomainAssoc instace is not created.
00438   */
00439 class MESQUITE_EXPORT MeshDomainAssoc
00440 {
00441   public:
00442     /**\brief Constructor
00443      *\param mesh                       The mesh instance being associated
00444      * param domain                     The domain being associated
00445      * param full_compatibility_check   Controls how many vertices will be checked for
00446      *                                  compatibility with the associated domain.
00447      *                                  When false, only the first vertex of the mesh
00448      *                                  is checked for compatibility.  When true, all
00449      *                                  vertices of the mesh are checked.
00450      * param proceed                    Controls what Mesquite will do if the compatibility
00451      *                                  check fails.  When false, mesquite terminates i
00452      *                                  execution.  When true, execution continues.
00453      * param skip_compatibility_checki  when true, does not perform the compatibility check.
00454      *                                  When false, the check is performed.
00455      */
00456     MeshDomainAssoc( MBMesquite::Mesh* mesh, MBMesquite::MeshDomain* domain, bool full_compatibility_check = false,
00457                      bool proceed = false, bool skip_compatibility_check = false )
00458         : mMesh( mesh ), mMeshDomain( domain ), mesh_and_domain_are_compatible( false )
00459     {
00460         // check for real instance.  If either value is NULL then it's just an
00461         // instance created to facilitate passing of just a mesh or domain
00462         // also, check if skipping the compatibility check was requested
00463         if( mesh && domain && !skip_compatibility_check )
00464         {
00465             MsqError err;
00466             double tolerance = 1.0e-3;
00467 
00468             std::vector< Mesh::VertexHandle > vert_handles;
00469             mMesh->get_all_vertices( vert_handles, err );
00470 
00471             MsqVertex mesh_vertex, domain_vertex;
00472             Vector3D normal;
00473 
00474             double distance;
00475             std::vector< int >::size_type i, times_to_loop;
00476             if( full_compatibility_check )
00477                 times_to_loop = vert_handles.size();
00478             else
00479                 times_to_loop = 1;
00480             mesh_and_domain_are_compatible = true;
00481             for( i = 0; i < times_to_loop; ++i )
00482             {
00483                 mMesh->vertices_get_coordinates( &vert_handles[i], &mesh_vertex, 1, err );
00484                 mMeshDomain->closest_point( vert_handles[i], Vector3D( mesh_vertex ), domain_vertex, normal, err );
00485 
00486                 distance = Vector3D::distance_between( mesh_vertex, domain_vertex );
00487                 if( distance > tolerance )
00488                 {
00489                     mesh_and_domain_are_compatible = false;
00490                     std::cout << "Warning: Mesh and Domain are not compatibile" << std::endl;
00491                     if( !proceed )
00492                     {
00493                         std::cout << "Terminating due to Mesh/Domain incompatibility" << std::endl;
00494                         throw "Terminating due to Mesh/Domain incompatibility";
00495                     }
00496                     break;  // exits for loop when not compatbile but should not terminate
00497                 }
00498             }
00499         }
00500     }
00501 
00502     ~MeshDomainAssoc(){};
00503 
00504     /**\brief get associated mesh
00505      *
00506      * Return the mesh associated with this instance.
00507      */
00508     MBMesquite::Mesh* get_mesh()
00509     {
00510         return mMesh;
00511     };
00512 
00513     /**\brief get associated domain
00514      *
00515      * Return the domain associated with this instance.
00516      */
00517     MBMesquite::MeshDomain* get_domain()
00518     {
00519         return mMeshDomain;
00520     };
00521 
00522   private:
00523     MBMesquite::Mesh* mMesh;
00524     MBMesquite::MeshDomain* mMeshDomain;
00525     bool mesh_and_domain_are_compatible;
00526 
00527   public:
00528     bool are_compatible()
00529     {
00530         return mesh_and_domain_are_compatible;
00531     };
00532 };
00533 }  // namespace MBMesquite
00534 
00535 inline size_t MBMesquite::vertices_in_topology( MBMesquite::EntityTopology topo )
00536 {
00537     return TopologyInfo::corners( topo );
00538 }
00539 
00540 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines