MOAB: Mesh Oriented datABase
(version 5.2.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 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