MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 [email protected], [email protected], [email protected], 00024 [email protected], [email protected], [email protected], 00025 [email protected] 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