Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DualTool.hpp
Go to the documentation of this file.
1 /** 2  * MOAB, a Mesh-Oriented datABase, is a software component for creating, 3  * storing and accessing finite element mesh data. 4  * 5  * Copyright 2004 Sandia Corporation. Under the terms of Contract 6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 7  * retains certain rights in this software. 8  * 9  * This library is free software; you can redistribute it and/or 10  * modify it under the terms of the GNU Lesser General Public 11  * License as published by the Free Software Foundation; either 12  * version 2.1 of the License, or (at your option) any later version. 13  * 14  */ 15  16 #ifndef MOAB_DUAL_TOOL_HPP 17 #define MOAB_DUAL_TOOL_HPP 18  19 #include "moab/Forward.hpp" 20  21 #include "moab/win32_config.h" 22  23 namespace moab 24 { 25  26 /*! 27  * \authors Tim Tautges 28  * \date 2/04 29  * \brief Tools for constructing and working with mesh duals (both tet- and hex-based, 30  * though some functions may not make sense for tet duals) 31  * 32  */ 33 class DualTool 34 { 35  public: 36  //! tag name for dual surfaces 37  static MOAB_EXPORT const char* DUAL_SURFACE_TAG_NAME; 38  39  //! tag name for dual curves 40  static MOAB_EXPORT const char* DUAL_CURVE_TAG_NAME; 41  42  //! tag name for dual cells 43  static const char* IS_DUAL_CELL_TAG_NAME; 44  45  //! tag name for dual entitys 46  static const char* DUAL_ENTITY_TAG_NAME; 47  48  //! tag name for dual entitys 49  static const char* EXTRA_DUAL_ENTITY_TAG_NAME; 50  51  //! tag name for dual entitys 52  static const char* DUAL_GRAPHICS_POINT_TAG_NAME; 53  54  //! struct for storing a graphics pt 55  class GraphicsPoint 56  { 57  public: 58  GraphicsPoint() 59  { 60  xyz[0] = 0.0; 61  xyz[1] = 0.0; 62  xyz[2] = 0.0; 63  id = -1; 64  } 65  66  GraphicsPoint( float xi, float yi, float zi, int idi ) 67  { 68  xyz[0] = xi; 69  xyz[1] = yi; 70  xyz[2] = zi; 71  id = idi; 72  } 73  74  GraphicsPoint( float xyzi[3], int idi ) 75  { 76  xyz[0] = xyzi[0]; 77  xyz[1] = xyzi[1]; 78  xyz[2] = xyzi[2]; 79  id = idi; 80  } 81  82  GraphicsPoint( double xyzi[3], int idi ) 83  { 84  xyz[0] = xyzi[0]; 85  xyz[1] = xyzi[1]; 86  xyz[2] = xyzi[2]; 87  id = idi; 88  } 89  90  GraphicsPoint( const GraphicsPoint& gp ) 91  { 92  xyz[0] = gp.xyz[0]; 93  xyz[1] = gp.xyz[1]; 94  xyz[2] = gp.xyz[2]; 95  id = gp.id; 96  } 97  98  GraphicsPoint& operator=( GraphicsPoint const& gp ) 99  { 100  for( unsigned i = 0; i < 3; ++i ) 101  xyz[i] = gp.xyz[i]; 102  id = gp.id; 103  return *this; 104  } 105  106  float xyz[3]; 107  int id; 108  }; 109  110  DualTool( Interface* impl ); 111  112  ~DualTool(); 113  114  //! construct the dual entities for the entire mesh 115  ErrorCode construct_dual( EntityHandle* entities, const int num_entities ); 116  117  //! construct the dual entities for a hex mesh, including dual surfaces & curves 118  ErrorCode construct_hex_dual( EntityHandle* entities, const int num_entities ); 119  120  //! construct the dual entities for a hex mesh, including dual surfaces & curves 121  ErrorCode construct_hex_dual( Range& entities ); 122  123  //! get the dual entities; if non-null, only dual of entities passed in are returned 124  ErrorCode get_dual_entities( const int dim, EntityHandle* entities, const int num_entities, Range& dual_ents ); 125  126  //! get the dual entities; if non-null, only dual of entities passed in are returned 127  ErrorCode get_dual_entities( const int dim, 128  EntityHandle* entities, 129  const int num_entities, 130  std::vector< EntityHandle >& dual_ents ); 131  132  //! return the corresponding dual entity 133  EntityHandle get_dual_entity( const EntityHandle this_ent ) const; 134  135  //! return the corresponding extra dual entity 136  EntityHandle get_extra_dual_entity( const EntityHandle this_ent ); 137  138  //! get the d-dimensional hyperplane sets; static 'cuz it's easy to do without an active 139  //! dualtool 140  static ErrorCode get_dual_hyperplanes( const Interface* impl, const int dim, Range& dual_ents ); 141  142  //! get the graphics points for single entity (dual_ent CAN'T be a set); 143  //! returns multiple facets, each with npts[i] points 144  ErrorCode get_graphics_points( EntityHandle dual_ent, 145  std::vector< int >& npts, 146  std::vector< GraphicsPoint >& gpoints ); 147  148  //! get the graphics points for a range of entities or sets (if set, the 149  //! entities in those sets); optionally reset ids on points 150  ErrorCode get_graphics_points( const Range& in_range, 151  std::vector< GraphicsPoint >& gpoints, 152  const bool assign_ids = false, 153  const int start_id = 0 ); 154  155  //! given a last_v (possibly zero) and this_v, find the next loop vertex on 156  //! this dual surface 157  EntityHandle next_loop_vertex( const EntityHandle last_v, const EntityHandle this_v, const EntityHandle dual_surf ); 158  159  //! get/set the tag for dual surfaces 160  Tag dualSurface_tag() const; 161  ErrorCode dualSurface_tag( const Tag tag ); 162  163  //! get/set the tag for dual curves 164  Tag dualCurve_tag() const; 165  ErrorCode dualCurve_tag( const Tag tag ); 166  167  //! get/set the tag for dual cells 168  Tag isDualCell_tag() const; 169  ErrorCode isDualCell_tag( const Tag tag ); 170  171  //! get/set the tag for dual entities 172  Tag dualEntity_tag() const; 173  ErrorCode dualEntity_tag( const Tag tag ); 174  175  //! get/set the tag for dual entities 176  Tag extraDualEntity_tag() const; 177  ErrorCode extraDualEntity_tag( const Tag tag ); 178  179  //! get/set the tag for dual entities 180  Tag dualGraphicsPoint_tag() const; 181  ErrorCode dualGraphicsPoint_tag( const Tag tag ); 182  183  //! get/set the global id tag 184  Tag globalId_tag() const; 185  ErrorCode globalId_tag( const Tag tag ); 186  187  //! given an entity, return any dual surface or curve it's in 188  EntityHandle get_dual_hyperplane( const EntityHandle ncell ); 189  190  //! returns true if first & last vertices are dual to hexes (not faces) 191  bool is_blind( const EntityHandle chord ); 192  193  //! set the dual surface or curve for an entity 194  ErrorCode set_dual_surface_or_curve( EntityHandle entity, const EntityHandle dual_hyperplane, const int dimension ); 195  196  //! effect atomic pillow operation 197  ErrorCode atomic_pillow( EntityHandle odedge, EntityHandle& quad1, EntityHandle& quad2 ); 198  199  //! effect reverse atomic pillow operation 200  ErrorCode rev_atomic_pillow( EntityHandle pillow, Range& chords ); 201  202  //! effect face shrink operation 203  ErrorCode face_shrink( EntityHandle odedge ); 204  205  //! effect reverse atomic pillow operation 206  ErrorCode rev_face_shrink( EntityHandle edge ); 207  208  //! effect a face open-collapse operation 209  ErrorCode face_open_collapse( EntityHandle ocl, EntityHandle ocr ); 210  211  //! given the two 1-cells involved in the foc, get entities associated with 212  //! the quads being opened/collapsed; see implementation for more details 213  ErrorCode foc_get_ents( EntityHandle ocl, 214  EntityHandle ocr, 215  EntityHandle* quads, 216  EntityHandle* split_edges, 217  EntityHandle* split_nodes, 218  Range& hexes, 219  EntityHandle* other_edges, 220  EntityHandle* other_nodes ); 221  222  //! given a 1-cell and a chord, return the neighboring vertices on the 223  //! chord, in the same order as the 1-cell's vertices 224  ErrorCode get_opposite_verts( const EntityHandle middle_edge, const EntityHandle chord, EntityHandle* verts ); 225  226  //! given a dual surface or curve, return the 2-cells, 1-cells, 0-cells, and 227  //! loop 0/1-cells, if requested; any of those range pointers can be NULL, 228  //! in which case that range isn't returned 229  ErrorCode get_dual_entities( const EntityHandle dual_ent, 230  Range* dcells, 231  Range* dedges, 232  Range* dverts, 233  Range* dverts_loop, 234  Range* dedges_loop ); 235  236  ErrorCode list_entities( const Range& entities ) const; 237  ErrorCode list_entities( const EntityHandle* entities, const int num_entities ) const; 238  239  //! delete all the dual data 240  ErrorCode delete_whole_dual(); 241  242  //! check dual-primal adjacencies 243  ErrorCode check_dual_adjs(); 244  245  private: 246  //! construct dual vertices for specified regions 247  ErrorCode construct_dual_vertices( const Range& all_regions, Range& new_dual_ents ); 248  249  //! construct dual edges for specified faces 250  ErrorCode construct_dual_edges( const Range& all_faces, Range& new_dual_ents ); 251  252  //! construct dual faces for specified edges 253  ErrorCode construct_dual_faces( const Range& all_edges, Range& new_dual_ents ); 254  255  //! construct dual cells for specified vertices 256  ErrorCode construct_dual_cells( const Range& all_verts, Range& new_dual_ents ); 257  258  //! traverse dual faces of input dimension, constructing 259  //! dual hyperplanes of them in sets as it goes 260  ErrorCode construct_dual_hyperplanes( const int dim, EntityHandle* entities, const int num_entities ); 261  262  //! order 1cells on a chord 263  ErrorCode order_chord( EntityHandle chord_set ); 264  265  //! make a new dual hyperplane with the specified id; if the id specified is -1, 266  //! set the new one's id to the max found 267  ErrorCode construct_new_hyperplane( const int dim, EntityHandle& new_hyperplane, int& id ); 268  269  //! traverse the cells of a dual hyperplane, starting with this_ent (dimension 270  //! of this_ent determines hyperplane dimension) 271  //! simpler method for traversing hyperplane, using same basic algorithm but 272  //! using MeshTopoUtil::get_bridge_adjacencies 273  ErrorCode traverse_hyperplane( const Tag hp_tag, EntityHandle& this_hp, EntityHandle this_ent ); 274  275  //! connect dual surfaces with dual curves using parent/child connections 276  ErrorCode construct_hp_parent_child(); 277  278  //! given an edge handle, return a list of dual vertices in radial order 279  //! around the edge; also returns whether this edge is on the boundary 280  ErrorCode get_radial_dverts( const EntityHandle edge, std::vector< EntityHandle >& rad_verts, bool& bdy_edge ); 281  282  ErrorCode construct_dual_vertex( EntityHandle entity, 283  EntityHandle& dual_ent, 284  const bool extra = false, 285  const bool add_graphics_pt = true ); 286  287  //! add a graphics point to an entity (on a tag) 288  ErrorCode add_graphics_point( EntityHandle entity, double* avg_pos = NULL ); 289  290  //! get points defining facets of a 2cell 291  ErrorCode get_cell_points( EntityHandle dual_ent, std::vector< int >& npts, std::vector< GraphicsPoint >& points ); 292  293  //! if this_ent is an edge, is a dual entity, and has quads as 294  //! its vertices' dual entities, return true, otherwise false 295  bool check_1d_loop_edge( EntityHandle this_ent ); 296  297  //! go through potential dual equivalent edges (edges whose nodes define 298  //! multiple edges), and add explicit adjacencies to corrent 2cells 299  ErrorCode check_dual_equiv_edges( Range& dual_edges ); 300  301  //! delete a dual entity; updates primal to no longer point to it 302  ErrorCode delete_dual_entities( EntityHandle* entities, const int num_entities ); 303  304  //! delete a range of dual entities; updates primal to no longer point to them 305  ErrorCode delete_dual_entities( Range& entities ); 306  307  //! check sense of connect arrays, and reverse/rotate if necessary 308  ErrorCode fs_check_quad_sense( EntityHandle hex0, EntityHandle quad0, std::vector< EntityHandle >* connects ); 309  310  //! get the three quads for a face shrink, the two hexes, and the connectivity 311  //! of the three quads 312  ErrorCode fs_get_quads( EntityHandle odedge, 313  EntityHandle* quads, 314  EntityHandle* hexes, 315  std::vector< EntityHandle >* connects ); 316  317  //! get loops of quads around 2 hexes, ordered similarly to vertex loops 318  ErrorCode fs_get_quad_loops( EntityHandle* hexes, 319  std::vector< EntityHandle >* connects, 320  std::vector< EntityHandle >* side_quads ); 321  322  //! given connectivity of first 3 quads for reverse face shrink, 323  //! get fourth (outer 4 verts to be shared by two inner hexes) and quads 324  //! around the side of the structure 325  ErrorCode fsr_get_fourth_quad( std::vector< EntityHandle >* connects, std::vector< EntityHandle >* side_quads ); 326  327  /* 328  //! get pairs of entities to be merged as part of foc operation 329  ErrorCode foc_get_merge_ents(EntityHandle *quads, EntityHandle *new_quads, 330  Range &edge, Range &new_edge, 331  std::vector<EntityHandle> &merge_ents); 332  */ 333  334  //! function for deleting dual prior to foc operation; special because in 335  //! many cases need to delete a sheet in preparation for merging onto another 336  ErrorCode foc_delete_dual( EntityHandle* split_quads, EntityHandle* split_edges, Range& hexes ); 337  338  //! split a pair of quads and the edge(s) shared by them 339  ErrorCode split_pair_nonmanifold( EntityHandle* split_quads, 340  EntityHandle* split_edges, 341  EntityHandle* split_nodes, 342  std::vector< EntityHandle >* star_dp1, 343  std::vector< EntityHandle >* star_dp2, 344  EntityHandle* other_edges, 345  EntityHandle* other_nodes, 346  EntityHandle* new_quads, 347  EntityHandle* new_edges, 348  EntityHandle* new_nodes ); 349  350  //! for foc's splitting two shared edges, there might be additional entities 351  //! connected to the split node that also have to be updated 352  ErrorCode foc_get_addl_ents( std::vector< EntityHandle >* star_dp1, 353  std::vector< EntityHandle >* star_dp2, 354  EntityHandle* split_edges, 355  EntityHandle split_node, 356  Range* addl_ents ); 357  358  //! given the split quads and edges, get the face and hex stars around the 359  //! edge(s), separated into halves, each of which goes with the new or old entities 360  //! after the split 361  ErrorCode foc_get_stars( EntityHandle* split_quads, 362  EntityHandle* split_edges, 363  std::vector< EntityHandle >* star_dp1, 364  std::vector< EntityHandle >* star_dp2 ); 365  366  void print_cell( EntityHandle cell ); 367  368  //! private copy of interface * 369  Interface* mbImpl; 370  371  //! static constant number of points bounding any cell 372  enum 373  { 374  GP_SIZE = 20 375  }; 376  377  //! tags used for dual surfaces, curves, cells, entities 378  Tag dualCurveTag; 379  Tag dualSurfaceTag; 380  Tag isDualCellTag; 381  Tag dualEntityTag; 382  Tag extraDualEntityTag; 383  Tag dualGraphicsPointTag; 384  Tag categoryTag; 385  Tag globalIdTag; 386  387  int maxHexId; 388 }; 389  390 inline Tag DualTool::dualSurface_tag() const 391 { 392  return dualSurfaceTag; 393 } 394  395 inline Tag DualTool::dualCurve_tag() const 396 { 397  return dualCurveTag; 398 } 399  400 inline Tag DualTool::isDualCell_tag() const 401 { 402  return isDualCellTag; 403 } 404  405 inline Tag DualTool::dualEntity_tag() const 406 { 407  return dualEntityTag; 408 } 409  410 inline Tag DualTool::extraDualEntity_tag() const 411 { 412  return extraDualEntityTag; 413 } 414  415 inline Tag DualTool::dualGraphicsPoint_tag() const 416 { 417  return dualGraphicsPointTag; 418 } 419  420 inline Tag DualTool::globalId_tag() const 421 { 422  return globalIdTag; 423 } 424  425 //! get/set the tag for dual surfaces 426 inline ErrorCode DualTool::dualSurface_tag( const Tag tag ) 427 { 428  ErrorCode result = MB_FAILURE; 429  if( ( 0 == dualSurfaceTag && tag ) || dualSurfaceTag != tag ) 430  { 431  dualSurfaceTag = tag; 432  result = MB_SUCCESS; 433  } 434  435  return result; 436 } 437  438 //! get/set the tag for dual curves 439 inline ErrorCode DualTool::dualCurve_tag( const Tag tag ) 440 { 441  ErrorCode result = MB_FAILURE; 442  if( ( 0 == dualCurveTag && tag ) || dualCurveTag != tag ) 443  { 444  dualCurveTag = tag; 445  result = MB_SUCCESS; 446  } 447  448  return result; 449 } 450  451 //! get/set the tag for dual cells 452 inline ErrorCode DualTool::isDualCell_tag( const Tag tag ) 453 { 454  ErrorCode result = MB_FAILURE; 455  if( ( 0 == isDualCellTag && tag ) || isDualCellTag != tag ) 456  { 457  isDualCellTag = tag; 458  result = MB_SUCCESS; 459  } 460  461  return result; 462 } 463  464 //! get/set the tag for dual entities 465 inline ErrorCode DualTool::dualEntity_tag( const Tag tag ) 466 { 467  ErrorCode result = MB_FAILURE; 468  if( ( 0 == dualEntityTag && tag ) || dualEntityTag != tag ) 469  { 470  dualEntityTag = tag; 471  result = MB_SUCCESS; 472  } 473  474  return result; 475 } 476  477 //! get/set the tag for dual entities 478 inline ErrorCode DualTool::extraDualEntity_tag( const Tag tag ) 479 { 480  ErrorCode result = MB_FAILURE; 481  if( ( 0 == extraDualEntityTag && tag ) || extraDualEntityTag != tag ) 482  { 483  extraDualEntityTag = tag; 484  result = MB_SUCCESS; 485  } 486  487  return result; 488 } 489  490 //! get/set the tag for dual entities 491 inline ErrorCode DualTool::dualGraphicsPoint_tag( const Tag tag ) 492 { 493  ErrorCode result = MB_FAILURE; 494  if( ( 0 == dualGraphicsPointTag && tag ) || dualGraphicsPointTag != tag ) 495  { 496  dualGraphicsPointTag = tag; 497  result = MB_SUCCESS; 498  } 499  500  return result; 501 } 502  503 //! get/set the tag for dual entities 504 inline ErrorCode DualTool::globalId_tag( const Tag tag ) 505 { 506  ErrorCode result = MB_FAILURE; 507  if( ( 0 == globalIdTag && tag ) || globalIdTag != tag ) 508  { 509  globalIdTag = tag; 510  result = MB_SUCCESS; 511  } 512  513  return result; 514 } 515  516 } // namespace moab 517  518 #endif