Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain 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 */ 00015 00016 #ifndef MOAB_DUAL_TOOL_HPP 00017 #define MOAB_DUAL_TOOL_HPP 00018 00019 #include "moab/Forward.hpp" 00020 00021 #include "moab/win32_config.h" 00022 00023 namespace moab 00024 { 00025 00026 /*! 00027 * \authors Tim Tautges 00028 * \date 2/04 00029 * \brief Tools for constructing and working with mesh duals (both tet- and hex-based, 00030 * though some functions may not make sense for tet duals) 00031 * 00032 */ 00033 class DualTool 00034 { 00035 public: 00036 //! tag name for dual surfaces 00037 static MOAB_EXPORT const char* DUAL_SURFACE_TAG_NAME; 00038 00039 //! tag name for dual curves 00040 static MOAB_EXPORT const char* DUAL_CURVE_TAG_NAME; 00041 00042 //! tag name for dual cells 00043 static const char* IS_DUAL_CELL_TAG_NAME; 00044 00045 //! tag name for dual entitys 00046 static const char* DUAL_ENTITY_TAG_NAME; 00047 00048 //! tag name for dual entitys 00049 static const char* EXTRA_DUAL_ENTITY_TAG_NAME; 00050 00051 //! tag name for dual entitys 00052 static const char* DUAL_GRAPHICS_POINT_TAG_NAME; 00053 00054 //! struct for storing a graphics pt 00055 class GraphicsPoint 00056 { 00057 public: 00058 GraphicsPoint() 00059 { 00060 xyz[0] = 0.0; 00061 xyz[1] = 0.0; 00062 xyz[2] = 0.0; 00063 id = -1; 00064 } 00065 00066 GraphicsPoint( float xi, float yi, float zi, int idi ) 00067 { 00068 xyz[0] = xi; 00069 xyz[1] = yi; 00070 xyz[2] = zi; 00071 id = idi; 00072 } 00073 00074 GraphicsPoint( float xyzi[3], int idi ) 00075 { 00076 xyz[0] = xyzi[0]; 00077 xyz[1] = xyzi[1]; 00078 xyz[2] = xyzi[2]; 00079 id = idi; 00080 } 00081 00082 GraphicsPoint( double xyzi[3], int idi ) 00083 { 00084 xyz[0] = xyzi[0]; 00085 xyz[1] = xyzi[1]; 00086 xyz[2] = xyzi[2]; 00087 id = idi; 00088 } 00089 00090 GraphicsPoint( const GraphicsPoint& gp ) 00091 { 00092 xyz[0] = gp.xyz[0]; 00093 xyz[1] = gp.xyz[1]; 00094 xyz[2] = gp.xyz[2]; 00095 id = gp.id; 00096 } 00097 00098 GraphicsPoint& operator=( GraphicsPoint const& gp ) 00099 { 00100 for( unsigned i = 0; i < 3; ++i ) 00101 xyz[i] = gp.xyz[i]; 00102 id = gp.id; 00103 return *this; 00104 } 00105 00106 float xyz[3]; 00107 int id; 00108 }; 00109 00110 DualTool( Interface* impl ); 00111 00112 ~DualTool(); 00113 00114 //! construct the dual entities for the entire mesh 00115 ErrorCode construct_dual( EntityHandle* entities, const int num_entities ); 00116 00117 //! construct the dual entities for a hex mesh, including dual surfaces & curves 00118 ErrorCode construct_hex_dual( EntityHandle* entities, const int num_entities ); 00119 00120 //! construct the dual entities for a hex mesh, including dual surfaces & curves 00121 ErrorCode construct_hex_dual( Range& entities ); 00122 00123 //! get the dual entities; if non-null, only dual of entities passed in are returned 00124 ErrorCode get_dual_entities( const int dim, EntityHandle* entities, const int num_entities, Range& dual_ents ); 00125 00126 //! get the dual entities; if non-null, only dual of entities passed in are returned 00127 ErrorCode get_dual_entities( const int dim, 00128 EntityHandle* entities, 00129 const int num_entities, 00130 std::vector< EntityHandle >& dual_ents ); 00131 00132 //! return the corresponding dual entity 00133 EntityHandle get_dual_entity( const EntityHandle this_ent ) const; 00134 00135 //! return the corresponding extra dual entity 00136 EntityHandle get_extra_dual_entity( const EntityHandle this_ent ); 00137 00138 //! get the d-dimensional hyperplane sets; static 'cuz it's easy to do without an active 00139 //! dualtool 00140 static ErrorCode get_dual_hyperplanes( const Interface* impl, const int dim, Range& dual_ents ); 00141 00142 //! get the graphics points for single entity (dual_ent CAN'T be a set); 00143 //! returns multiple facets, each with npts[i] points 00144 ErrorCode get_graphics_points( EntityHandle dual_ent, 00145 std::vector< int >& npts, 00146 std::vector< GraphicsPoint >& gpoints ); 00147 00148 //! get the graphics points for a range of entities or sets (if set, the 00149 //! entities in those sets); optionally reset ids on points 00150 ErrorCode get_graphics_points( const Range& in_range, 00151 std::vector< GraphicsPoint >& gpoints, 00152 const bool assign_ids = false, 00153 const int start_id = 0 ); 00154 00155 //! given a last_v (possibly zero) and this_v, find the next loop vertex on 00156 //! this dual surface 00157 EntityHandle next_loop_vertex( const EntityHandle last_v, const EntityHandle this_v, const EntityHandle dual_surf ); 00158 00159 //! get/set the tag for dual surfaces 00160 Tag dualSurface_tag() const; 00161 ErrorCode dualSurface_tag( const Tag tag ); 00162 00163 //! get/set the tag for dual curves 00164 Tag dualCurve_tag() const; 00165 ErrorCode dualCurve_tag( const Tag tag ); 00166 00167 //! get/set the tag for dual cells 00168 Tag isDualCell_tag() const; 00169 ErrorCode isDualCell_tag( const Tag tag ); 00170 00171 //! get/set the tag for dual entities 00172 Tag dualEntity_tag() const; 00173 ErrorCode dualEntity_tag( const Tag tag ); 00174 00175 //! get/set the tag for dual entities 00176 Tag extraDualEntity_tag() const; 00177 ErrorCode extraDualEntity_tag( const Tag tag ); 00178 00179 //! get/set the tag for dual entities 00180 Tag dualGraphicsPoint_tag() const; 00181 ErrorCode dualGraphicsPoint_tag( const Tag tag ); 00182 00183 //! get/set the global id tag 00184 Tag globalId_tag() const; 00185 ErrorCode globalId_tag( const Tag tag ); 00186 00187 //! given an entity, return any dual surface or curve it's in 00188 EntityHandle get_dual_hyperplane( const EntityHandle ncell ); 00189 00190 //! returns true if first & last vertices are dual to hexes (not faces) 00191 bool is_blind( const EntityHandle chord ); 00192 00193 //! set the dual surface or curve for an entity 00194 ErrorCode set_dual_surface_or_curve( EntityHandle entity, const EntityHandle dual_hyperplane, const int dimension ); 00195 00196 //! effect atomic pillow operation 00197 ErrorCode atomic_pillow( EntityHandle odedge, EntityHandle& quad1, EntityHandle& quad2 ); 00198 00199 //! effect reverse atomic pillow operation 00200 ErrorCode rev_atomic_pillow( EntityHandle pillow, Range& chords ); 00201 00202 //! effect face shrink operation 00203 ErrorCode face_shrink( EntityHandle odedge ); 00204 00205 //! effect reverse atomic pillow operation 00206 ErrorCode rev_face_shrink( EntityHandle edge ); 00207 00208 //! effect a face open-collapse operation 00209 ErrorCode face_open_collapse( EntityHandle ocl, EntityHandle ocr ); 00210 00211 //! given the two 1-cells involved in the foc, get entities associated with 00212 //! the quads being opened/collapsed; see implementation for more details 00213 ErrorCode foc_get_ents( EntityHandle ocl, 00214 EntityHandle ocr, 00215 EntityHandle* quads, 00216 EntityHandle* split_edges, 00217 EntityHandle* split_nodes, 00218 Range& hexes, 00219 EntityHandle* other_edges, 00220 EntityHandle* other_nodes ); 00221 00222 //! given a 1-cell and a chord, return the neighboring vertices on the 00223 //! chord, in the same order as the 1-cell's vertices 00224 ErrorCode get_opposite_verts( const EntityHandle middle_edge, const EntityHandle chord, EntityHandle* verts ); 00225 00226 //! given a dual surface or curve, return the 2-cells, 1-cells, 0-cells, and 00227 //! loop 0/1-cells, if requested; any of those range pointers can be NULL, 00228 //! in which case that range isn't returned 00229 ErrorCode get_dual_entities( const EntityHandle dual_ent, 00230 Range* dcells, 00231 Range* dedges, 00232 Range* dverts, 00233 Range* dverts_loop, 00234 Range* dedges_loop ); 00235 00236 ErrorCode list_entities( const Range& entities ) const; 00237 ErrorCode list_entities( const EntityHandle* entities, const int num_entities ) const; 00238 00239 //! delete all the dual data 00240 ErrorCode delete_whole_dual(); 00241 00242 //! check dual-primal adjacencies 00243 ErrorCode check_dual_adjs(); 00244 00245 private: 00246 //! construct dual vertices for specified regions 00247 ErrorCode construct_dual_vertices( const Range& all_regions, Range& new_dual_ents ); 00248 00249 //! construct dual edges for specified faces 00250 ErrorCode construct_dual_edges( const Range& all_faces, Range& new_dual_ents ); 00251 00252 //! construct dual faces for specified edges 00253 ErrorCode construct_dual_faces( const Range& all_edges, Range& new_dual_ents ); 00254 00255 //! construct dual cells for specified vertices 00256 ErrorCode construct_dual_cells( const Range& all_verts, Range& new_dual_ents ); 00257 00258 //! traverse dual faces of input dimension, constructing 00259 //! dual hyperplanes of them in sets as it goes 00260 ErrorCode construct_dual_hyperplanes( const int dim, EntityHandle* entities, const int num_entities ); 00261 00262 //! order 1cells on a chord 00263 ErrorCode order_chord( EntityHandle chord_set ); 00264 00265 //! make a new dual hyperplane with the specified id; if the id specified is -1, 00266 //! set the new one's id to the max found 00267 ErrorCode construct_new_hyperplane( const int dim, EntityHandle& new_hyperplane, int& id ); 00268 00269 //! traverse the cells of a dual hyperplane, starting with this_ent (dimension 00270 //! of this_ent determines hyperplane dimension) 00271 //! simpler method for traversing hyperplane, using same basic algorithm but 00272 //! using MeshTopoUtil::get_bridge_adjacencies 00273 ErrorCode traverse_hyperplane( const Tag hp_tag, EntityHandle& this_hp, EntityHandle this_ent ); 00274 00275 //! connect dual surfaces with dual curves using parent/child connections 00276 ErrorCode construct_hp_parent_child(); 00277 00278 //! given an edge handle, return a list of dual vertices in radial order 00279 //! around the edge; also returns whether this edge is on the boundary 00280 ErrorCode get_radial_dverts( const EntityHandle edge, std::vector< EntityHandle >& rad_verts, bool& bdy_edge ); 00281 00282 ErrorCode construct_dual_vertex( EntityHandle entity, 00283 EntityHandle& dual_ent, 00284 const bool extra = false, 00285 const bool add_graphics_pt = true ); 00286 00287 //! add a graphics point to an entity (on a tag) 00288 ErrorCode add_graphics_point( EntityHandle entity, double* avg_pos = NULL ); 00289 00290 //! get points defining facets of a 2cell 00291 ErrorCode get_cell_points( EntityHandle dual_ent, std::vector< int >& npts, std::vector< GraphicsPoint >& points ); 00292 00293 //! if this_ent is an edge, is a dual entity, and has quads as 00294 //! its vertices' dual entities, return true, otherwise false 00295 bool check_1d_loop_edge( EntityHandle this_ent ); 00296 00297 //! go through potential dual equivalent edges (edges whose nodes define 00298 //! multiple edges), and add explicit adjacencies to corrent 2cells 00299 ErrorCode check_dual_equiv_edges( Range& dual_edges ); 00300 00301 //! delete a dual entity; updates primal to no longer point to it 00302 ErrorCode delete_dual_entities( EntityHandle* entities, const int num_entities ); 00303 00304 //! delete a range of dual entities; updates primal to no longer point to them 00305 ErrorCode delete_dual_entities( Range& entities ); 00306 00307 //! check sense of connect arrays, and reverse/rotate if necessary 00308 ErrorCode fs_check_quad_sense( EntityHandle hex0, EntityHandle quad0, std::vector< EntityHandle >* connects ); 00309 00310 //! get the three quads for a face shrink, the two hexes, and the connectivity 00311 //! of the three quads 00312 ErrorCode fs_get_quads( EntityHandle odedge, 00313 EntityHandle* quads, 00314 EntityHandle* hexes, 00315 std::vector< EntityHandle >* connects ); 00316 00317 //! get loops of quads around 2 hexes, ordered similarly to vertex loops 00318 ErrorCode fs_get_quad_loops( EntityHandle* hexes, 00319 std::vector< EntityHandle >* connects, 00320 std::vector< EntityHandle >* side_quads ); 00321 00322 //! given connectivity of first 3 quads for reverse face shrink, 00323 //! get fourth (outer 4 verts to be shared by two inner hexes) and quads 00324 //! around the side of the structure 00325 ErrorCode fsr_get_fourth_quad( std::vector< EntityHandle >* connects, std::vector< EntityHandle >* side_quads ); 00326 00327 /* 00328 //! get pairs of entities to be merged as part of foc operation 00329 ErrorCode foc_get_merge_ents(EntityHandle *quads, EntityHandle *new_quads, 00330 Range &edge, Range &new_edge, 00331 std::vector<EntityHandle> &merge_ents); 00332 */ 00333 00334 //! function for deleting dual prior to foc operation; special because in 00335 //! many cases need to delete a sheet in preparation for merging onto another 00336 ErrorCode foc_delete_dual( EntityHandle* split_quads, EntityHandle* split_edges, Range& hexes ); 00337 00338 //! split a pair of quads and the edge(s) shared by them 00339 ErrorCode split_pair_nonmanifold( EntityHandle* split_quads, 00340 EntityHandle* split_edges, 00341 EntityHandle* split_nodes, 00342 std::vector< EntityHandle >* star_dp1, 00343 std::vector< EntityHandle >* star_dp2, 00344 EntityHandle* other_edges, 00345 EntityHandle* other_nodes, 00346 EntityHandle* new_quads, 00347 EntityHandle* new_edges, 00348 EntityHandle* new_nodes ); 00349 00350 //! for foc's splitting two shared edges, there might be additional entities 00351 //! connected to the split node that also have to be updated 00352 ErrorCode foc_get_addl_ents( std::vector< EntityHandle >* star_dp1, 00353 std::vector< EntityHandle >* star_dp2, 00354 EntityHandle* split_edges, 00355 EntityHandle split_node, 00356 Range* addl_ents ); 00357 00358 //! given the split quads and edges, get the face and hex stars around the 00359 //! edge(s), separated into halves, each of which goes with the new or old entities 00360 //! after the split 00361 ErrorCode foc_get_stars( EntityHandle* split_quads, 00362 EntityHandle* split_edges, 00363 std::vector< EntityHandle >* star_dp1, 00364 std::vector< EntityHandle >* star_dp2 ); 00365 00366 void print_cell( EntityHandle cell ); 00367 00368 //! private copy of interface * 00369 Interface* mbImpl; 00370 00371 //! static constant number of points bounding any cell 00372 enum 00373 { 00374 GP_SIZE = 20 00375 }; 00376 00377 //! tags used for dual surfaces, curves, cells, entities 00378 Tag dualCurveTag; 00379 Tag dualSurfaceTag; 00380 Tag isDualCellTag; 00381 Tag dualEntityTag; 00382 Tag extraDualEntityTag; 00383 Tag dualGraphicsPointTag; 00384 Tag categoryTag; 00385 Tag globalIdTag; 00386 00387 int maxHexId; 00388 }; 00389 00390 inline Tag DualTool::dualSurface_tag() const 00391 { 00392 return dualSurfaceTag; 00393 } 00394 00395 inline Tag DualTool::dualCurve_tag() const 00396 { 00397 return dualCurveTag; 00398 } 00399 00400 inline Tag DualTool::isDualCell_tag() const 00401 { 00402 return isDualCellTag; 00403 } 00404 00405 inline Tag DualTool::dualEntity_tag() const 00406 { 00407 return dualEntityTag; 00408 } 00409 00410 inline Tag DualTool::extraDualEntity_tag() const 00411 { 00412 return extraDualEntityTag; 00413 } 00414 00415 inline Tag DualTool::dualGraphicsPoint_tag() const 00416 { 00417 return dualGraphicsPointTag; 00418 } 00419 00420 inline Tag DualTool::globalId_tag() const 00421 { 00422 return globalIdTag; 00423 } 00424 00425 //! get/set the tag for dual surfaces 00426 inline ErrorCode DualTool::dualSurface_tag( const Tag tag ) 00427 { 00428 ErrorCode result = MB_FAILURE; 00429 if( ( 0 == dualSurfaceTag && tag ) || dualSurfaceTag != tag ) 00430 { 00431 dualSurfaceTag = tag; 00432 result = MB_SUCCESS; 00433 } 00434 00435 return result; 00436 } 00437 00438 //! get/set the tag for dual curves 00439 inline ErrorCode DualTool::dualCurve_tag( const Tag tag ) 00440 { 00441 ErrorCode result = MB_FAILURE; 00442 if( ( 0 == dualCurveTag && tag ) || dualCurveTag != tag ) 00443 { 00444 dualCurveTag = tag; 00445 result = MB_SUCCESS; 00446 } 00447 00448 return result; 00449 } 00450 00451 //! get/set the tag for dual cells 00452 inline ErrorCode DualTool::isDualCell_tag( const Tag tag ) 00453 { 00454 ErrorCode result = MB_FAILURE; 00455 if( ( 0 == isDualCellTag && tag ) || isDualCellTag != tag ) 00456 { 00457 isDualCellTag = tag; 00458 result = MB_SUCCESS; 00459 } 00460 00461 return result; 00462 } 00463 00464 //! get/set the tag for dual entities 00465 inline ErrorCode DualTool::dualEntity_tag( const Tag tag ) 00466 { 00467 ErrorCode result = MB_FAILURE; 00468 if( ( 0 == dualEntityTag && tag ) || dualEntityTag != tag ) 00469 { 00470 dualEntityTag = tag; 00471 result = MB_SUCCESS; 00472 } 00473 00474 return result; 00475 } 00476 00477 //! get/set the tag for dual entities 00478 inline ErrorCode DualTool::extraDualEntity_tag( const Tag tag ) 00479 { 00480 ErrorCode result = MB_FAILURE; 00481 if( ( 0 == extraDualEntityTag && tag ) || extraDualEntityTag != tag ) 00482 { 00483 extraDualEntityTag = tag; 00484 result = MB_SUCCESS; 00485 } 00486 00487 return result; 00488 } 00489 00490 //! get/set the tag for dual entities 00491 inline ErrorCode DualTool::dualGraphicsPoint_tag( const Tag tag ) 00492 { 00493 ErrorCode result = MB_FAILURE; 00494 if( ( 0 == dualGraphicsPointTag && tag ) || dualGraphicsPointTag != tag ) 00495 { 00496 dualGraphicsPointTag = tag; 00497 result = MB_SUCCESS; 00498 } 00499 00500 return result; 00501 } 00502 00503 //! get/set the tag for dual entities 00504 inline ErrorCode DualTool::globalId_tag( const Tag tag ) 00505 { 00506 ErrorCode result = MB_FAILURE; 00507 if( ( 0 == globalIdTag && tag ) || globalIdTag != tag ) 00508 { 00509 globalIdTag = tag; 00510 result = MB_SUCCESS; 00511 } 00512 00513 return result; 00514 } 00515 00516 } // namespace moab 00517 00518 #endif