Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
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
56  {
57  public:
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 
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 
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
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,
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
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
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
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
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
198 
199  //! effect reverse atomic pillow operation
200  ErrorCode rev_atomic_pillow( EntityHandle pillow, Range& chords );
201 
202  //! effect face shrink operation
204 
205  //! effect reverse atomic pillow operation
207 
208  //! effect a face open-collapse operation
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
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
241 
242  //! check dual-primal adjacencies
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
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 
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
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
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
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
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 *
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
386 
387  int maxHexId;
388 };
389 
391 {
392  return dualSurfaceTag;
393 }
394 
396 {
397  return dualCurveTag;
398 }
399 
401 {
402  return isDualCellTag;
403 }
404 
406 {
407  return dualEntityTag;
408 }
409 
411 {
412  return extraDualEntityTag;
413 }
414 
416 {
417  return dualGraphicsPointTag;
418 }
419 
421 {
422  return globalIdTag;
423 }
424 
425 //! get/set the tag for dual surfaces
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
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
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
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
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
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
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