Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
Skinner.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_SKINNER_HPP
17 #define MOAB_SKINNER_HPP
18 
19 #include "moab/Forward.hpp"
20 #include "moab/Range.hpp"
21 #include <vector>
22 
23 namespace moab
24 {
25 
26 class ScdBox;
27 
28 /** \class Skinner
29  * \brief Class for constructing and querying skin of a mesh
30  * Class for constructing and querying skin of a mesh, defined as the outside lower-dimensional
31  * boundary of a mesh or a given set of entities. This class provides options for finding the
32  * forward- and reverse-oriented members of the skin. Several methods are available for computing
33  * the skin, e.g. using geometric topology sets, vertex-entity adjacencies, or directly from
34  * (n-1)-dimensional entities.
35  */
36 class Skinner
37 {
38 
39  enum direction
40  {
41  FORWARD = 1,
42  REVERSE = -1
43  };
44 
45  protected:
46  //! the MB instance that this works with
48 
52 
53  public:
54  //! constructor, takes mdb instance
55  Skinner( Interface* mdb ) : thisMB( mdb ), mDeletableMBTag( 0 ), mAdjTag( 0 ), mTargetDim( 0 ) {}
56 
57  //! destructor
58  ~Skinner();
59 
60  ErrorCode find_geometric_skin( const EntityHandle meshset, Range& forward_target_entities );
61 
62  /**\brief will accept entities all of one dimension and
63  * return entities of n-1 dimension; NOTE: get_vertices argument controls whether
64  * vertices or entities of n-1 dimension are returned, and only one of these is allowed
65  * (i.e. this function returns only vertices or (n-1)-dimensional entities, but not both)
66  * \param entities The elements for which to find the skin
67  * \param get_vertices If true, vertices on the skin are returned
68  * in the range, otherwise elements are returned
69  * \param output_handles Range holding skin entities returned
70  * \param output_reverse_handles Range holding entities on skin which
71  * are reversed wrt entities
72  * \param create_vert_elem_adjs If true, this function will cause
73  * vertex-element adjacencies to be generated
74  * \param create_skin_elements If true, this function will cause creation
75  * of skin entities, otherwise only skin entities already extant
76  * will be returned
77  */
78  ErrorCode find_skin( const EntityHandle meshset,
79  const Range& entities,
80  bool get_vertices,
81  Range& output_handles,
82  Range* output_reverse_handles = 0,
83  bool create_vert_elem_adjs = false,
84  bool create_skin_elements = true,
85  bool look_for_scd = false );
86 
87  /**\brief will accept entities all of one dimension and
88  * return entities of n-1 dimension; NOTE: get_vertices argument controls whether
89  * vertices or entities of n-1 dimension are returned, and only one of these is allowed
90  * (i.e. this function returns only vertices or (n-1)-dimensional entities, but not both)
91  * \param entities Pointer to elements for which to find the skin
92  * \param num_entities Number of entities in vector
93  * \param get_vertices If true, vertices on the skin are returned
94  * in the range, otherwise elements are returned
95  * \param output_handles Range holding skin entities returned
96  * \param output_reverse_handles Range holding entities on skin which
97  * are reversed wrt entities
98  * \param create_vert_elem_adjs If true, this function will cause
99  * vertex-element adjacencies to be generated
100  * \param create_skin_elements If true, this function will cause creation
101  * of skin entities, otherwise only skin entities already extant
102  * will be returned
103  */
104  ErrorCode find_skin( const EntityHandle this_set,
105  const EntityHandle* entities,
106  int num_entities,
107  bool get_vertices,
108  Range& output_handles,
109  Range* output_reverse_handles = 0,
110  bool create_vert_elem_adjs = false,
111  bool create_skin_elements = true,
112  bool look_for_scd = false );
113 
114  /**\brief get skin entities of prescribed dimension
115  * \param entities The elements for which to find the skin
116  * \param dim Dimension of skin entities requested
117  * \param skin_entities Range holding skin entities returned
118  * \param create_vert_elem_adjs If true, this function will cause
119  * vertex-element adjacencies to be generated
120  */
121  ErrorCode find_skin( const EntityHandle this_set,
122  const Range& entities,
123  int dim,
124  Range& skin_entities,
125  bool create_vert_elem_adjs = false,
126  bool create_skin_elements = true );
127 
128  ErrorCode classify_2d_boundary( const Range& boundary,
129  const Range& bar_elements,
130  EntityHandle boundary_edges,
131  EntityHandle inferred_edges,
132  EntityHandle non_manifold_edges,
133  EntityHandle other_edges,
134  int& number_boundary_nodes );
135 
136  //! given a skin of dimension 2, will classify and return edges
137  //! as boundary, inferred, and non-manifold, and the rest (other)
138  ErrorCode classify_2d_boundary( const Range& boundary,
139  const Range& mesh_1d_elements,
140  Range& boundary_edges,
141  Range& inferred_edges,
142  Range& non_manifold_edges,
143  Range& other_edges,
144  int& number_boundary_nodes );
145 
146  protected:
148 
150 
151  ErrorCode find_skin_noadj( const Range& source_entities,
152  Range& forward_target_entities,
153  Range& reverse_target_entities );
154 
156 
157  void add_adjacency( EntityHandle entity, const EntityHandle* conn, const int num_nodes );
158 
160 
161  bool entity_deletable( EntityHandle entity );
162 
163  void find_match( EntityType type,
164  const EntityHandle* conn,
165  const int num_nodes,
166  EntityHandle& match,
167  Skinner::direction& direct );
168 
169  bool connectivity_match( const EntityHandle* conn1,
170  const EntityHandle* conn2,
171  const int num_verts,
172  Skinner::direction& direct );
173 
174  void find_inferred_edges( Range& skin_boundary,
175  Range& candidate_edges,
176  Range& inferred_edges,
177  double reference_angle_degrees );
178 
179  bool has_larger_angle( EntityHandle& entity1, EntityHandle& entity2, double reference_angle_cosine );
180 
181  /**\brief Find vertices on the skin of a set of mesh entities.
182  *\param entities The elements for which to find the skin. Range
183  * may NOT contain vertices, polyhedra, or entity sets.
184  * All elements in range must be of the same dimension.
185  *\param skin_verts Output: the vertices on the skin.
186  *\param skin_elems Optional output: elements representing sides of entities
187  * that are on the skin
188  *\param create_if_missing If skin_elemts is non-null and this is true,
189  * create new elements representing the sides of
190  * entities on the skin. If this is false, skin_elems
191  * will contain only those skin elements that already
192  * exist.
193  */
194  ErrorCode find_skin_vertices( const EntityHandle this_set,
195  const Range& entities,
196  Range* skin_verts = 0,
197  Range* skin_elems = 0,
198  Range* rev_elems = 0,
199  bool create_if_missing = true,
200  bool corners_only = false );
201 
202  /**\brief Skin edges
203  *
204  * Return any vertices adjacent to exactly one of the input edges.
205  */
206  ErrorCode find_skin_vertices_1D( Tag tag, const Range& edges, Range& skin_verts );
207 
208  /**\brief Skin faces
209  *
210  * For the set of face sides (logical edges), return
211  * vertices on such sides and/or edges equivalent to such sides.
212  *\param faces Set of toplogically 2D entities to skin.
213  *\param skin_verts If non-NULL, skin vertices will be added to this container.
214  *\param skin_edges If non-NULL, skin edges will be added to this container
215  *\param reverse_edges If skin_edges is not NULL and this is not NULL, then
216  * any existing skin edges that are reversed with respect
217  * to the skin side will be placed in this range instead of
218  * skin_edges. Note: this argument is ignored if skin_edges
219  * is NULL.
220  *\param create_edges If true, edges equivalent to face sides on the skin
221  * that don't already exist will be created. Note: this
222  * parameter is honored regardless of whether or not skin
223  * edges or vertices are returned.
224  *\param corners_only If true, only skin vertices that correspond to the
225  * corners of sides will be returned (i.e. no higher-order
226  * nodes.) This argument is ignored if skin_verts is NULL.
227  */
229  Tag tag,
230  const Range& faces,
231  Range* skin_verts = 0,
232  Range* skin_edges = 0,
233  Range* reverse_edges = 0,
234  bool create_edges = false,
235  bool corners_only = false );
236 
237  /**\brief Skin volume mesh
238  *
239  * For the set of element sides (logical faces), return
240  * vertices on such sides and/or faces equivalent to such sides.
241  *\param entities Set of toplogically 3D entities to skin.
242  *\param skin_verts If non-NULL, skin vertices will be added to this container.
243  *\param skin_faces If non-NULL, skin faces will be added to this container
244  *\param reverse_faces If skin_faces is not NULL and this is not NULL, then
245  * any existing skin faces that are reversed with respect
246  * to the skin side will be placed in this range instead of
247  * skin_faces. Note: this argument is ignored if skin_faces
248  * is NULL.
249  *\param create_faces If true, face equivalent to sides on the skin
250  * that don't already exist will be created. Note: this
251  * parameter is honored regardless of whether or not skin
252  * faces or vertices are returned.
253  *\param corners_only If true, only skin vertices that correspond to the
254  * corners of sides will be returned (i.e. no higher-order
255  * nodes.) This argument is ignored if skin_verts is NULL.
256  */
258  Tag tag,
259  const Range& entities,
260  Range* skin_verts = 0,
261  Range* skin_faces = 0,
262  Range* reverse_faces = 0,
263  bool create_faces = false,
264  bool corners_only = false );
265 
266  ErrorCode create_side( const EntityHandle this_set,
267  EntityHandle element,
268  EntityType side_type,
269  const EntityHandle* side_corners,
270  EntityHandle& side_elem_handle_out );
271 
272  bool edge_reversed( EntityHandle face, const EntityHandle edge_ends[2] );
273  bool face_reversed( EntityHandle region, const EntityHandle* face_conn, EntityType face_type );
274 
275  //! look for structured box comprising source_entities, and if one is found use
276  //! structured information to find the skin
277  ErrorCode find_skin_scd( const Range& source_entities,
278  bool get_vertices,
279  Range& output_handles,
280  bool create_skin_elements );
281 
282  //! skin a structured box, taking advantage of structured information
283  ErrorCode skin_box( ScdBox* box, bool get_vertices, Range& output_handles, bool create_skin_elements );
284 };
285 
287  const EntityHandle* entities,
288  int num_entities,
289  bool get_vertices,
290  Range& output_handles,
291  Range* output_reverse_handles,
292  bool create_vert_elem_adjs,
293  bool create_skin_elements,
294  bool look_for_scd )
295 {
296  Range ents;
297  std::copy( entities, entities + num_entities, range_inserter( ents ) );
298  return find_skin( this_set, ents, get_vertices, output_handles, output_reverse_handles, create_vert_elem_adjs,
299  create_skin_elements, look_for_scd );
300 }
301 
302 } // namespace moab
303 
304 #endif