Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #pragma once
11 :
12 : #include "libmesh/replicated_mesh.h"
13 :
14 : #include "MooseTypes.h"
15 :
16 : namespace MooseMeshElementConversionUtils
17 : {
18 : // Define for comparing the key value of BCTuple
19 : struct BCTupleKeyComp
20 : {
21 392694 : bool operator()(const libMesh::BoundaryInfo::BCTuple & s, dof_id_type i) const
22 : {
23 392694 : return std::get<0>(s) < i;
24 : }
25 189652 : bool operator()(dof_id_type i, const libMesh::BoundaryInfo::BCTuple & s) const
26 : {
27 189652 : return i < std::get<0>(s);
28 : }
29 : };
30 :
31 : /**
32 : * Split a HEX8 element into six TET4 elements.
33 : * @param mesh The mesh to be modified
34 : * @param bdry_side_list A list that contains the boundary information of the original mesh
35 : * @param elem_id The id of the element to be split
36 : * @param converted_elems_ids a vector to record the ids of the newly created TET4 elements
37 : */
38 : void hexElemSplitter(MeshBase & mesh,
39 : const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
40 : const dof_id_type elem_id,
41 : std::vector<dof_id_type> & converted_elems_ids);
42 :
43 : /**
44 : * Split a PYRAMID5 element into two TET4 elements.
45 : * @param mesh The mesh to be modified
46 : * @param bdry_side_list A list that contains the boundary information of the original mesh
47 : * @param elem_id The id of the element to be split
48 : * @param converted_elems_ids a vector to record the ids of the newly created TET4 elements
49 : */
50 : void pyramidElemSplitter(MeshBase & mesh,
51 : const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
52 : const dof_id_type elem_id,
53 : std::vector<dof_id_type> & converted_elems_ids);
54 :
55 : /**
56 : * Split a PRISM6 element into three TET4 elements.
57 : * @param mesh The mesh to be modified
58 : * @param bdry_side_list A list that contains the boundary information of the original mesh
59 : * @param elem_id The id of the element to be split
60 : * @param converted_elems_ids a vector to record the ids of the newly created TET4 elements
61 : */
62 : void prismElemSplitter(MeshBase & mesh,
63 : const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
64 : const dof_id_type elem_id,
65 : std::vector<dof_id_type> & converted_elems_ids);
66 :
67 : /**
68 : * Split a polyhedron element into n_sides TET4 elements.
69 : * @param mesh The mesh to be modified
70 : * @param bdry_side_list A list that contains the boundary information of the original mesh
71 : * @param elem_id The id of the element to be split
72 : * @param converted_elems_ids a vector to record the ids of the newly created TET4 elements
73 : */
74 : void polyhedronElemSplitter(MeshBase & mesh,
75 : const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
76 : const dof_id_type elem_id,
77 : std::vector<dof_id_type> & converted_elems_ids);
78 :
79 : /**
80 : * Rotate a HEX8 element's nodes to ensure that the node with the minimum id is the first node;
81 : * and the node among its three neighboring nodes with the minimum id is the second node.
82 : * @param min_id_index The index of the node with the minimum id
83 : * @param sec_min_pos The index of the node among its three neighboring nodes with the minimum
84 : * id (see comments in the function for more details about how the index is defined)
85 : * @param face_rotation A vector to record the rotation of the faces of the HEX8 element
86 : * @param node_rotation a vector of node indices that can form a HEX8 element
87 : */
88 : void nodeRotationHEX8(const unsigned int min_id_index,
89 : const unsigned int sec_min_pos,
90 : std::vector<unsigned int> & face_rotation,
91 : std::vector<unsigned int> & node_rotation);
92 :
93 : /**
94 : * Calculate the indices (within the element nodes) of the three neighboring nodes of a node in a
95 : * HEX8 element.
96 : * @param min_id_index The index of the node with the minimum id
97 : * @return a vector of the three neighboring nodes
98 : */
99 : std::vector<unsigned int> neighborNodeIndicesHEX8(unsigned int min_id_index);
100 :
101 : /**
102 : * For a vector of rotated nodes that can form a HEX8 element, create a vector of four-node sets
103 : * that can form TET4 elements to replace the original HEX8 element. All the QUAD4 faces of the
104 : * HEX8 element will be split by the diagonal line that involves the node with the minimum id of
105 : * that face.
106 : * @param hex_nodes A vector of pointers to the nodes that can form a HEX8 element
107 : * @param rotated_tet_face_indices A vector of vectors of the original face indices of the HEX8
108 : * element corresponding to the faces of the newly created TET4 elements
109 : * @param tet_nodes_list a vector of vectors of pointers to the nodes that can form TET4 elements
110 : */
111 : void hexNodesToTetNodesDeterminer(std::vector<const Node *> & hex_nodes,
112 : std::vector<std::vector<unsigned int>> & rotated_tet_face_indices,
113 : std::vector<std::vector<const Node *>> & tet_nodes_list);
114 :
115 : /**
116 : * For a HEX8 element, determine the direction of the diagonal line of each face that involves the
117 : * node with the minimum id of that face.
118 : * @param hex_nodes A vector of pointers to the nodes that can form a HEX8 element
119 : * @return a vector of boolean values indicating the direction of the diagonal line of each face
120 : */
121 : std::vector<bool> quadFaceDiagonalDirectionsHex(const std::vector<const Node *> & hex_nodes);
122 :
123 : /**
124 : * For a QUAD4 element, determine the direction of the diagonal line that involves the node with
125 : * the minimum id of that element.
126 : * @param quad_nodes A vector of pointers to the nodes that can form a QUAD4 element
127 : * @return a boolean value indicating the direction of the diagonal line
128 : */
129 : bool quadFaceDiagonalDirection(const std::vector<const Node *> & quad_nodes);
130 :
131 : /**
132 : * Creates sets of four nodes indices that can form TET4 elements to replace the original HEX8
133 : * element.
134 : * @param diagonal_directions A vector of boolean values indicating the direction of the diagonal
135 : * line of each face; true means the diagonal line is connecting node 0 and node 2, false means the
136 : * diagonal line is connecting node 1 and node 3 of that quad face
137 : * @param tet_face_indices A vector of vectors of the original face indices of the HEX8 element
138 : * corresponding to the faces of the newly created TET4 elements
139 : * @return a vector of vectors of node indices that can form TET4 elements
140 : */
141 : std::vector<std::vector<unsigned int>>
142 : tetNodesForHex(const std::vector<bool> diagonal_directions,
143 : std::vector<std::vector<unsigned int>> & tet_face_indices);
144 :
145 : /**
146 : * Rotate a PRISM6 element nodes to ensure that the node with the minimum id is the first node.
147 : * @param min_id_index The index of the node, within the prism nodes, with the minimum id
148 : * @param face_rotation A vector to record the rotation of the faces of the PRISM6 element
149 : * @param node_rotation a vector of node indices that can form a PRISM6 element
150 : */
151 : void nodeRotationPRISM6(unsigned int min_id_index,
152 : std::vector<unsigned int> & face_rotation,
153 : std::vector<unsigned int> & node_rotation);
154 :
155 : /**
156 : * For a rotated nodes that can form a PRISM6 element, create a series of four-node set that can
157 : * form TET4 elements to replace the original PRISM6 element. All the QUAD4 face of the PRISM6
158 : * element will be split by the diagonal line that involves the node with the minimum id of that
159 : * face.
160 : * @param prism_nodes A vector of pointers to the nodes that can form a PRISM6 element
161 : * @param rotated_tet_face_indices A vector of vectors of the original face indices of the PRISM6
162 : * element corresponding to the faces of the newly created TET4 elements
163 : * @param tet_nodes_list a vector of vectors of pointers to the nodes that can form TET4 elements
164 : */
165 : void
166 : prismNodesToTetNodesDeterminer(std::vector<const Node *> & prism_nodes,
167 : std::vector<std::vector<unsigned int>> & rotated_tet_face_indices,
168 : std::vector<std::vector<const Node *>> & tet_nodes_list);
169 :
170 : /**
171 : * Creates sets of four nodes indices that can form TET4 elements to replace the original PRISM6
172 : * element.
173 : * @param diagonal_direction A boolean value indicating the direction of the diagonal line of Face
174 : * 2
175 : * @param tet_face_indices A vector of vectors of the original face indices of the PRISM6 element
176 : * corresponding to the faces of the newly created TET4 elements
177 : * @return a vector of vectors of node indices that can form TET4 elements
178 : */
179 : std::vector<std::vector<unsigned int>>
180 : tetNodesForPrism(const bool diagonal_direction,
181 : std::vector<std::vector<unsigned int>> & tet_face_indices);
182 :
183 : /**
184 : * Rotate a PYRAMID5 element nodes to ensure that the node with the minimum id is the first node
185 : * for the bottom face.
186 : * @param min_id_index The index of the node, within the pyramid nodes, with the minimum id for the
187 : * bottom face
188 : * @param face_rotation A vector to record the rotation of the faces of the PYRAMID5 element
189 : * @param node_rotation a vector of node indices that can form a PYRAMID5 element
190 : */
191 : void nodeRotationPYRAMID5(unsigned int min_id_index,
192 : std::vector<unsigned int> & face_rotation,
193 : std::vector<unsigned int> & node_rotation);
194 :
195 : /**
196 : * For a rotated nodes that can form a PYRAMID5 element, create a series of four-node set that can
197 : * form TET4 elements to replace the original PYRAMID5 element. The QUAD4 face of the
198 : * PYRAMID5 element will be split by the diagonal line that involves the node with the minimum id
199 : * of that face.
200 : * @param pyramid_nodes A vector of pointers to the nodes that can form a PYRAMID5 element
201 : * @param rotated_tet_face_indices A vector of vectors of the original face indices of the
202 : * PYRAMID5 element corresponding to the faces of the newly created TET4 elements
203 : * @param tet_nodes_list a vector of vectors of pointers to the nodes that can form TET4 elements
204 : */
205 : void
206 : pyramidNodesToTetNodesDeterminer(std::vector<const Node *> & pyramid_nodes,
207 : std::vector<std::vector<unsigned int>> & rotated_tet_face_indices,
208 : std::vector<std::vector<const Node *>> & tet_nodes_list);
209 :
210 : /**
211 : * Convert all the elements in a 3D mesh, consisting of only linear elements, into TET4 elements.
212 : * @param mesh The mesh to be converted
213 : * @param elems_to_process A vector of pairs of element ids and a bool indicating whether the
214 : * element needs to be fully retained or will be further processed in the following procedures
215 : * @param converted_elems_ids_to_track A vector of element ids that need to be tracked for being
216 : * further processed in the following procedures
217 : * @param block_id_to_remove The id of a new subdomain in the mesh containing all the elements to be
218 : * removed
219 : * @param delete_block_to_remove A bool indicating whether the block to be removed will be
220 : * deleted in this method
221 : */
222 : void convert3DMeshToAllTet4(MeshBase & mesh,
223 : const std::vector<std::pair<dof_id_type, bool>> & elems_to_process,
224 : std::vector<dof_id_type> & converted_elems_ids_to_track,
225 : const subdomain_id_type block_id_to_remove,
226 : const bool delete_block_to_remove);
227 :
228 : /**
229 : * Convert all the elements in a 3D mesh consisting of only linear elements into TET4 elements.
230 : * @param mesh The mesh to be converted
231 : */
232 : void convert3DMeshToAllTet4(MeshBase & mesh);
233 :
234 : /**
235 : * Collect the boundary information of the given element in a mesh.
236 : * @param bdry_side_list A list that contains the boundary information of the mesh
237 : * @param elem_id The id of the element to be processed
238 : * @param n_elem_sides The number of sides of the element
239 : * @param elem_side_list a vector of vectors to record the boundary information of the element
240 : */
241 : void
242 : elementBoundaryInfoCollector(const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
243 : const dof_id_type elem_id,
244 : const unsigned short n_elem_sides,
245 : std::vector<std::vector<boundary_id_type>> & elem_side_list);
246 :
247 : /**
248 : * Convert the element to an element with TRI3 side-elements on the user-specified sides by
249 : * modifying the mesh.
250 : * @param mesh The mesh containing the element
251 : * @param elem_id The ID of the element to be converted
252 : * @param side_indices The indices of the sides to be converted
253 : * @param elem_side_info The boundary IDs associated with the sides of the element
254 : * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
255 : */
256 : void convertElem(MeshBase & mesh,
257 : const dof_id_type & elem_id,
258 : const std::vector<unsigned int> & side_indices,
259 : const std::vector<std::vector<boundary_id_type>> & elem_side_info,
260 : const SubdomainID & subdomain_id_shift_base);
261 :
262 : /**
263 : * Convert a HEX8 element to elements with TRI3 surfaces on the given original QUAD4 side(s).
264 : * @param mesh The mesh containing the element
265 : * @param elem_id The ID of the HEX8 element to be converted
266 : * @param side_indices The indices of the QUAD4 sides to be converted to TRI3 sides
267 : * @param elem_side_info The boundary IDs associated with the sides of the HEX8 element
268 : * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
269 : */
270 : void convertHex8Elem(MeshBase & mesh,
271 : const dof_id_type & elem_id,
272 : const std::vector<unsigned int> & side_indices,
273 : const std::vector<std::vector<boundary_id_type>> & elem_side_info,
274 : const SubdomainID & subdomain_id_shift_base);
275 :
276 : /**
277 : * Create one PYRAMID5 element based on a side and the centroid of the HEX8 element.
278 : * @param mesh The mesh containing the element
279 : * @param elem_id The ID of the HEX8 element to be converted
280 : * @param side_index The index of the side to be converted
281 : * @param new_node The new node created at the centroid of the HEX8 element
282 : * @param side_info The boundary IDs associated with the side of the HEX8 element
283 : * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
284 : */
285 : void createUnitPyramid5FromHex8(MeshBase & mesh,
286 : const dof_id_type & elem_id,
287 : const unsigned int & side_index,
288 : const Node * new_node,
289 : const std::vector<boundary_id_type> & side_info,
290 : const SubdomainID & subdomain_id_shift_base);
291 :
292 : /**
293 : * Create two TET4 elements based on a side and the centroid of the HEX8 element.
294 : * @param mesh The mesh containing the element
295 : * @param elem_id The ID of the HEX8 element to be converted
296 : * @param side_index The index of the side to be converted
297 : * @param new_node The new node created at the centroid of the HEX8 element
298 : * @param side_info The boundary IDs associated with the side of the HEX8 element
299 : * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
300 : */
301 : void createUnitTet4FromHex8(MeshBase & mesh,
302 : const dof_id_type & elem_id,
303 : const unsigned int & side_index,
304 : const Node * new_node,
305 : const std::vector<boundary_id_type> & side_info,
306 : const SubdomainID & subdomain_id_shift_base);
307 :
308 : /**
309 : * Convert a PRISM6 element to elements with TRI3 surfaces on the given original QUAD4 side(s).
310 : * @param mesh The mesh containing the element
311 : * @param elem_id The ID of the PRISM6 element to be converted
312 : * @param side_indices The indices of the QUAD sides to be converted to TRI3 sides
313 : * @param elem_side_info The boundary IDs associated with the sides of the PRISM6 element
314 : * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
315 : */
316 : void convertPrism6Elem(MeshBase & mesh,
317 : const dof_id_type & elem_id,
318 : const std::vector<unsigned int> & side_indices,
319 : const std::vector<std::vector<boundary_id_type>> & elem_side_info,
320 : const SubdomainID & subdomain_id_shift_base);
321 : /**
322 : * Create one or two TET4 elements based on a side and the centroid of the PRISM6 element.
323 : * @param mesh The mesh containing the element
324 : * @param elem_id The ID of the PRISM6 element to be converted
325 : * @param side_index The index of the side to be converted
326 : * @param new_node The new node created at the centroid of the PRISM6 element
327 : * @param side_info The boundary IDs associated with the side of the PRISM6 element
328 : * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
329 : */
330 : void createUnitTet4FromPrism6(MeshBase & mesh,
331 : const dof_id_type & elem_id,
332 : const unsigned int & side_index,
333 : const Node * new_node,
334 : const std::vector<boundary_id_type> & side_info,
335 : const SubdomainID & subdomain_id_shift_base);
336 :
337 : /**
338 : * Create a PYRAMID5 element opposite the sides converted to tets and the centroid of the PRISM6
339 : * element.
340 : * @param mesh The mesh containing the element
341 : * @param elem_id The ID of the PRISM6 element to be converted
342 : * @param side_index The index of the side to be converted
343 : * @param new_node The new node created at the centroid of the PRISM6 element
344 : * @param side_info The boundary IDs associated with the side of the PRISM6 element
345 : * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
346 : */
347 : void createUnitPyramid5FromPrism6(MeshBase & mesh,
348 : const dof_id_type & elem_id,
349 : const unsigned int & side_index,
350 : const Node * new_node,
351 : const std::vector<boundary_id_type> & side_info,
352 : const SubdomainID & subdomain_id_shift_base);
353 :
354 : /**
355 : * Convert a PYRAMID5 element to elements with TRI3 surfaces on the original QUAD4 side.
356 : * @param mesh The mesh containing the element
357 : * @param elem_id The ID of the PYRAMID5 element to be converted
358 : * @param elem_side_info The boundary IDs associated with the sides of the PYRAMID
359 : * @param subdomain_id_shift_base the reference id used to shift the subdomain ID for new elements
360 : */
361 : void convertPyramid5Elem(MeshBase & mesh,
362 : const dof_id_type & elem_id,
363 : const std::vector<std::vector<boundary_id_type>> & elem_side_info,
364 : const SubdomainID & subdomain_id_shift_base);
365 :
366 : /**
367 : * Retain the extra integer of the original element in a new element.
368 : * @param mesh The mesh containing the element
369 : * @param elem_id The ID of the original element
370 : * @param new_elem_ptr The pointer to the new element that will retain the extra integer
371 : */
372 : void retainEEID(MeshBase & mesh, const dof_id_type & elem_id, Elem * new_elem_ptr);
373 :
374 : /**
375 : * Generate a transition layer of elements with TRI3 surfaces on the given boundaries.
376 : * @param mesh The mesh to be modified
377 : * @param boundary_names A vector of boundary names on which the transition layer will be
378 : * generated
379 : * @param conversion_element_layer_number The number of element layers to be converted on the given
380 : * boundaries.
381 : * @param external_boundaries_checking Whether to check if the provided boundaries are external
382 : * boundaries
383 : */
384 : void transitionLayerGenerator(MeshBase & mesh,
385 : const std::vector<BoundaryName> & boundary_names,
386 : const unsigned int conversion_element_layer_number,
387 : const bool external_boundaries_checking);
388 :
389 : /**
390 : * Assign a subdomain name suffix to the converted elements created during transition layer
391 : * generation.
392 : * @param mesh The mesh to be modified
393 : * @param original_subdomain_ids A set of original subdomain IDs of the mesh before conversion
394 : * @param sid_shift_base The base subdomain ID to shift the original elements because of the
395 : * element type change
396 : * @param tet_suffix The suffix to be added to the subdomain names of the converted TET4 elements
397 : * @param pyramid_suffix The suffix to be added to the subdomain names of the converted PYRAMID5
398 : * elements
399 : */
400 : void assignConvertedElementsSubdomainNameSuffix(
401 : MeshBase & mesh,
402 : const std::set<subdomain_id_type> & original_subdomain_ids,
403 : const subdomain_id_type sid_shift_base,
404 : const SubdomainName & tet_suffix,
405 : const SubdomainName & pyramid_suffix);
406 : }
|