Branch data Line data Source code
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
47 : : Interface* thisMB;
48 : :
49 : : Tag mDeletableMBTag;
50 : : Tag mAdjTag;
51 : : int mTargetDim;
52 : :
53 : : public:
54 : : //! constructor, takes mdb instance
55 : 38 : 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, const Range& entities, bool get_vertices, Range& output_handles,
79 : : Range* output_reverse_handles = 0, bool create_vert_elem_adjs = false,
80 : : bool create_skin_elements = true, bool look_for_scd = false );
81 : :
82 : : /**\brief will accept entities all of one dimension and
83 : : * return entities of n-1 dimension; NOTE: get_vertices argument controls whether
84 : : * vertices or entities of n-1 dimension are returned, and only one of these is allowed
85 : : * (i.e. this function returns only vertices or (n-1)-dimensional entities, but not both)
86 : : * \param entities Pointer to elements for which to find the skin
87 : : * \param num_entities Number of entities in vector
88 : : * \param get_vertices If true, vertices on the skin are returned
89 : : * in the range, otherwise elements are returned
90 : : * \param output_handles Range holding skin entities returned
91 : : * \param output_reverse_handles Range holding entities on skin which
92 : : * are reversed wrt entities
93 : : * \param create_vert_elem_adjs If true, this function will cause
94 : : * vertex-element adjacencies to be generated
95 : : * \param create_skin_elements If true, this function will cause creation
96 : : * of skin entities, otherwise only skin entities already extant
97 : : * will be returned
98 : : */
99 : : ErrorCode find_skin( const EntityHandle this_set, const EntityHandle* entities, int num_entities, bool get_vertices,
100 : : Range& output_handles, Range* output_reverse_handles = 0, bool create_vert_elem_adjs = false,
101 : : bool create_skin_elements = true, bool look_for_scd = false );
102 : :
103 : : /**\brief get skin entities of prescribed dimension
104 : : * \param entities The elements for which to find the skin
105 : : * \param dim Dimension of skin entities requested
106 : : * \param skin_entities Range holding skin entities returned
107 : : * \param create_vert_elem_adjs If true, this function will cause
108 : : * vertex-element adjacencies to be generated
109 : : */
110 : : ErrorCode find_skin( const EntityHandle this_set, const Range& entities, int dim, Range& skin_entities,
111 : : bool create_vert_elem_adjs = false, bool create_skin_elements = true );
112 : :
113 : : ErrorCode classify_2d_boundary( const Range& boundary, const Range& bar_elements, EntityHandle boundary_edges,
114 : : EntityHandle inferred_edges, EntityHandle non_manifold_edges,
115 : : EntityHandle other_edges, int& number_boundary_nodes );
116 : :
117 : : //! given a skin of dimension 2, will classify and return edges
118 : : //! as boundary, inferred, and non-manifold, and the rest (other)
119 : : ErrorCode classify_2d_boundary( const Range& boundary, const Range& mesh_1d_elements, Range& boundary_edges,
120 : : Range& inferred_edges, Range& non_manifold_edges, Range& other_edges,
121 : : int& number_boundary_nodes );
122 : :
123 : : protected:
124 : : ErrorCode initialize();
125 : :
126 : : ErrorCode deinitialize();
127 : :
128 : : ErrorCode find_skin_noadj( const Range& source_entities, Range& forward_target_entities,
129 : : Range& reverse_target_entities );
130 : :
131 : : ErrorCode add_adjacency( EntityHandle entity );
132 : :
133 : : void add_adjacency( EntityHandle entity, const EntityHandle* conn, const int num_nodes );
134 : :
135 : : ErrorCode remove_adjacency( EntityHandle entity );
136 : :
137 : : bool entity_deletable( EntityHandle entity );
138 : :
139 : : void find_match( EntityType type, const EntityHandle* conn, const int num_nodes, EntityHandle& match,
140 : : Skinner::direction& direct );
141 : :
142 : : bool connectivity_match( const EntityHandle* conn1, const EntityHandle* conn2, const int num_verts,
143 : : Skinner::direction& direct );
144 : :
145 : : void find_inferred_edges( Range& skin_boundary, Range& candidate_edges, Range& inferred_edges,
146 : : double reference_angle_degrees );
147 : :
148 : : bool has_larger_angle( EntityHandle& entity1, EntityHandle& entity2, double reference_angle_cosine );
149 : :
150 : : /**\brief Find vertices on the skin of a set of mesh entities.
151 : : *\param entities The elements for which to find the skin. Range
152 : : * may NOT contain vertices, polyhedra, or entity sets.
153 : : * All elements in range must be of the same dimension.
154 : : *\param skin_verts Output: the vertices on the skin.
155 : : *\param skin_elems Optional output: elements representing sides of entities
156 : : * that are on the skin
157 : : *\param create_if_missing If skin_elemts is non-null and this is true,
158 : : * create new elements representing the sides of
159 : : * entities on the skin. If this is false, skin_elems
160 : : * will contain only those skin elements that already
161 : : * exist.
162 : : */
163 : : ErrorCode find_skin_vertices( const EntityHandle this_set, const Range& entities, Range* skin_verts = 0,
164 : : Range* skin_elems = 0, Range* rev_elems = 0, bool create_if_missing = true,
165 : : bool corners_only = false );
166 : :
167 : : /**\brief Skin edges
168 : : *
169 : : * Return any vertices adjacent to exactly one of the input edges.
170 : : */
171 : : ErrorCode find_skin_vertices_1D( Tag tag, const Range& edges, Range& skin_verts );
172 : :
173 : : /**\brief Skin faces
174 : : *
175 : : * For the set of face sides (logical edges), return
176 : : * vertices on such sides and/or edges equivalent to such sides.
177 : : *\param faces Set of toplogically 2D entities to skin.
178 : : *\param skin_verts If non-NULL, skin vertices will be added to this container.
179 : : *\param skin_edges If non-NULL, skin edges will be added to this container
180 : : *\param reverse_edges If skin_edges is not NULL and this is not NULL, then
181 : : * any existing skin edges that are reversed with respect
182 : : * to the skin side will be placed in this range instead of
183 : : * skin_edges. Note: this argument is ignored if skin_edges
184 : : * is NULL.
185 : : *\param create_edges If true, edges equivalent to face sides on the skin
186 : : * that don't already exist will be created. Note: this
187 : : * parameter is honored regardless of whether or not skin
188 : : * edges or vertices are returned.
189 : : *\param corners_only If true, only skin vertices that correspond to the
190 : : * corners of sides will be returned (i.e. no higher-order
191 : : * nodes.) This argument is ignored if skin_verts is NULL.
192 : : */
193 : : ErrorCode find_skin_vertices_2D( const EntityHandle this_set, Tag tag, const Range& faces, Range* skin_verts = 0,
194 : : Range* skin_edges = 0, Range* reverse_edges = 0, bool create_edges = false,
195 : : bool corners_only = false );
196 : :
197 : : /**\brief Skin volume mesh
198 : : *
199 : : * For the set of element sides (logical faces), return
200 : : * vertices on such sides and/or faces equivalent to such sides.
201 : : *\param entities Set of toplogically 3D entities to skin.
202 : : *\param skin_verts If non-NULL, skin vertices will be added to this container.
203 : : *\param skin_faces If non-NULL, skin faces will be added to this container
204 : : *\param reverse_faces If skin_faces is not NULL and this is not NULL, then
205 : : * any existing skin faces that are reversed with respect
206 : : * to the skin side will be placed in this range instead of
207 : : * skin_faces. Note: this argument is ignored if skin_faces
208 : : * is NULL.
209 : : *\param create_faces If true, face equivalent to sides on the skin
210 : : * that don't already exist will be created. Note: this
211 : : * parameter is honored regardless of whether or not skin
212 : : * faces or vertices are returned.
213 : : *\param corners_only If true, only skin vertices that correspond to the
214 : : * corners of sides will be returned (i.e. no higher-order
215 : : * nodes.) This argument is ignored if skin_verts is NULL.
216 : : */
217 : : ErrorCode find_skin_vertices_3D( const EntityHandle this_set, Tag tag, const Range& entities, Range* skin_verts = 0,
218 : : Range* skin_faces = 0, Range* reverse_faces = 0, bool create_faces = false,
219 : : bool corners_only = false );
220 : :
221 : : ErrorCode create_side( const EntityHandle this_set, EntityHandle element, EntityType side_type,
222 : : const EntityHandle* side_corners, EntityHandle& side_elem_handle_out );
223 : :
224 : : bool edge_reversed( EntityHandle face, const EntityHandle edge_ends[2] );
225 : : bool face_reversed( EntityHandle region, const EntityHandle* face_conn, EntityType face_type );
226 : :
227 : : //! look for structured box comprising source_entities, and if one is found use
228 : : //! structured information to find the skin
229 : : ErrorCode find_skin_scd( const Range& source_entities, bool get_vertices, Range& output_handles,
230 : : bool create_skin_elements );
231 : :
232 : : //! skin a structured box, taking advantage of structured information
233 : : ErrorCode skin_box( ScdBox* box, bool get_vertices, Range& output_handles, bool create_skin_elements );
234 : : };
235 : :
236 : : inline ErrorCode Skinner::find_skin( const EntityHandle this_set, const EntityHandle* entities, int num_entities,
237 : : bool get_vertices, Range& output_handles, Range* output_reverse_handles,
238 : : bool create_vert_elem_adjs, bool create_skin_elements, bool look_for_scd )
239 : : {
240 : : Range ents;
241 : : std::copy( entities, entities + num_entities, range_inserter( ents ) );
242 : : return find_skin( this_set, ents, get_vertices, output_handles, output_reverse_handles, create_vert_elem_adjs,
243 : : create_skin_elements, look_for_scd );
244 : : }
245 : :
246 : : } // namespace moab
247 : :
248 : : #endif
|