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