13 #include "libmesh/cell_prism6.h" 14 #include "libmesh/cell_prism15.h" 15 #include "libmesh/cell_prism18.h" 16 #include "libmesh/cell_prism21.h" 17 #include "libmesh/cell_pyramid5.h" 18 #include "libmesh/cell_pyramid13.h" 19 #include "libmesh/cell_pyramid14.h" 20 #include "libmesh/cell_pyramid18.h" 21 #include "libmesh/cell_tet4.h" 22 #include "libmesh/cell_tet10.h" 23 #include "libmesh/cell_tet14.h" 24 #include "libmesh/cell_hex8.h" 25 #include "libmesh/cell_hex20.h" 26 #include "libmesh/cell_hex27.h" 27 #include "libmesh/face_tri3.h" 28 #include "libmesh/face_tri7.h" 29 #include "libmesh/face_quad4.h" 30 #include "libmesh/face_quad9.h" 31 #include "libmesh/point.h" 32 #include "libmesh/mesh_tools.h" 45 params.
addClassDescription(
"This RevolveGenerator object is designed to revolve a 1D mesh into " 46 "2D, or a 2D mesh into 3D based on an axis.");
56 "revolving_angles<=360.0 & revolving_angles>0.0",
57 "The angles delineating each azimuthal section of revolution around the axis in degrees");
59 params.
addParam<std::vector<std::vector<subdomain_id_type>>>(
62 "For each row, every two entries are interpreted as a pair of " 63 "'from' and 'to' to remap the subdomains for that azimuthal section");
65 params.
addParam<std::vector<std::vector<boundary_id_type>>>(
68 "For each row, every two entries are interpreted as a pair of " 69 "'from' and 'to' to remap the boundaries for that elevation");
71 params.
addParam<std::vector<std::string>>(
72 "elem_integer_names_to_swap",
74 "Array of element extra integer names that need to be swapped during revolving.");
76 params.
addParam<std::vector<std::vector<std::vector<dof_id_type>>>>(
77 "elem_integers_swaps",
79 "For each row, every two entries are interpreted as a pair of 'from' and 'to' to remap the " 80 "element extra integer for that elevation. If multiple element extra integers need to be " 81 "swapped, the enties are stacked based on the order provided in " 82 "'elem_integer_names_to_swap' to form the third dimension.");
86 "The boundary ID to set on the starting boundary for a partial revolution.");
89 "end_boundary",
"The boundary ID to set on the ending boundary for partial revolving.");
92 "clockwise",
true,
"Revolve clockwise around the axis or not (i.e., counterclockwise)");
95 "nums_azimuthal_intervals",
96 "List of the numbers of azimuthal interval discretization for each azimuthal section");
98 params.
addParam<
bool>(
"preserve_volumes",
100 "Whether the volume of the revolved mesh is preserving the circular area " 101 "by modifying (expanding) the radius to account for polygonization.");
105 "subdomain_swaps boundary_swaps elem_integer_names_to_swap elem_integers_swaps",
"ID Swap");
113 _axis_point(getParam<
Point>(
"axis_point")),
114 _axis_direction(getParam<
Point>(
"axis_direction")),
115 _revolving_angles(isParamValid(
"revolving_angles")
116 ? getParam<
std::vector<
Real>>(
"revolving_angles")
117 :
std::vector<
Real>(1, 360.0)),
120 _elem_integer_names_to_swap(getParam<
std::vector<
std::string>>(
"elem_integer_names_to_swap")),
121 _elem_integers_swaps(
123 _clockwise(getParam<bool>(
"clockwise")),
124 _nums_azimuthal_intervals(getParam<
std::vector<unsigned
int>>(
"nums_azimuthal_intervals")),
125 _preserve_volumes(getParam<bool>(
"preserve_volumes")),
126 _has_start_boundary(isParamValid(
"start_boundary")),
127 _start_boundary(isParamValid(
"start_boundary") ? getParam<
boundary_id_type>(
"start_boundary")
129 _has_end_boundary(isParamValid(
"end_boundary")),
130 _end_boundary(isParamValid(
"end_boundary") ? getParam<
boundary_id_type>(
"end_boundary") : 0),
131 _radius_correction_factor(1.0)
135 "The number of azimuthal intervals should be the same as the number of revolving " 140 "If specified, 'subdomain_swaps' must be the same length as 'nums_azimuthal_intervals'.");
145 "If specified, 'boundary_swaps' must be the same length as 'nums_azimuthal_intervals'.");
150 "If specified, each element of 'elem_integers_swaps' must have the same length as " 151 "the length of 'nums_azimuthal_intervals'.");
156 "If specified, 'elem_integers_swaps' must have the same length as the length of " 157 "'elem_integer_names_to_swap'.");
167 "The sum of revolving angles should be less than or equal to 360.");
172 "starting or ending boundaries can only be assigned for partial revolving.");
208 std::unique_ptr<MeshBase>
216 if (
_input->mesh_dimension() > 2)
217 paramError(
"input",
"This mesh generator only works for 1D and 2D input meshes.");
230 " of 'elem_integer_names_to_swap' is not a valid extra element integer of the " 234 const unsigned int num_extra_elem_integers =
_input->n_elem_integers();
235 std::vector<std::string> id_names;
237 for (
const auto i :
make_range(num_extra_elem_integers))
239 id_names.push_back(
_input->get_elem_integer_name(i));
245 const auto & input_subdomain_map =
_input->get_subdomain_name_map();
246 const auto & input_sideset_map =
_input->get_boundary_info().get_sideset_name_map();
247 const auto & input_nodeset_map =
_input->get_boundary_info().get_nodeset_name_map();
249 std::unique_ptr<MeshBase> input = std::move(
_input);
253 if (!input->is_serial())
257 std::set<subdomain_id_type>
blocks;
258 input->subdomain_ids(
blocks,
true);
260 for (
const auto & [bid, tbid] : swap_map)
263 if (
blocks.count(bid) == 0)
265 "Source subdomain " + std::to_string(bid) +
" was not found in the mesh");
269 std::set<subdomain_id_type> subdomain_ids_set;
270 input->subdomain_ids(subdomain_ids_set);
273 std::max((
int)max_subdomain_id, 1) + 1;
275 std::max((
int)max_subdomain_id, 1) * 2 + 1;
276 const subdomain_id_type quad_to_prism_subdomain_id_shift = std::max((
int)max_subdomain_id, 1) + 1;
278 std::max((
int)max_subdomain_id, 1) * 2 + 1;
280 std::max((
int)max_subdomain_id, 1) * 3 + 1;
281 const subdomain_id_type edge_to_tri_subdomain_id_shift = std::max((
int)max_subdomain_id, 1) + 1;
288 mooseError(
"The input mesh is either across the axis or overlapped with the axis!");
290 Real inner_product_1d(0.0);
291 bool inner_product_1d_initialized(
false);
293 std::vector<dof_id_type> node_ids_on_axis;
294 for (
const auto & node : input->node_ptr_range())
301 mooseError(
"The input mesh is across the axis.");
303 axis_centroid_cross.
norm() *
304 axis_node_cross.
norm()))
305 mooseError(
"The input mesh is not in the same plane with the rotation axis.");
308 node_ids_on_axis.push_back(node->id());
311 if (input->mesh_dimension() == 1)
314 if (inner_product_1d_initialized)
317 mooseError(
"The 1D input mesh is not perpendicular to the rotation axis.");
321 inner_product_1d_initialized =
true;
322 inner_product_1d = temp_inner_product;
329 if (!node_ids_on_axis.empty())
332 std::sort(node_ids_on_axis.begin(), node_ids_on_axis.end());
334 std::set<subdomain_id_type> converted_quad8_subdomain_ids;
335 for (
const auto & elem : input->element_ptr_range())
337 if (elem->type() ==
QUAD8)
339 std::vector<dof_id_type> elem_vertex_node_ids;
340 for (
unsigned int i = 0; i < 4; i++)
342 elem_vertex_node_ids.push_back(elem->node_id(i));
344 std::sort(elem_vertex_node_ids.begin(), elem_vertex_node_ids.end());
345 std::vector<dof_id_type> common_node_ids;
346 std::set_intersection(node_ids_on_axis.begin(),
347 node_ids_on_axis.end(),
348 elem_vertex_node_ids.begin(),
349 elem_vertex_node_ids.end(),
350 std::back_inserter(common_node_ids));
352 if (common_node_ids.size() == 1)
355 elem->subdomain_id() += quad_to_hi_pyramid_subdomain_id_shift;
356 converted_quad8_subdomain_ids.emplace(elem->subdomain_id());
361 input->all_second_order_range(
362 input->active_subdomain_set_elements_ptr_range(converted_quad8_subdomain_ids));
365 for (
auto elem : input->active_subdomain_set_elements_ptr_range(converted_quad8_subdomain_ids))
366 elem->subdomain_id() -= quad_to_hi_pyramid_subdomain_id_shift;
373 #ifdef LIBMESH_ENABLE_UNIQUE_ID 376 unique_id_type orig_unique_ids = input->parallel_max_unique_id() + orig_elem;
382 unsigned int order = 1;
385 const BoundaryInfo & input_boundary_info = input->get_boundary_info();
387 const unsigned int total_num_azimuthal_intervals =
392 const dof_id_type elem_id_shift = total_num_azimuthal_intervals * orig_elem;
396 std::vector<ElemType> types;
397 MeshTools::elem_types(*input, types);
398 for (
const auto elem_type : types)
399 if (higher_orders.count(elem_type))
404 std::vector<Real> azi_array;
407 const Real section_start_angle =
408 azi_array.empty() ? 0.0 : (azi_array.back() +
_unit_angles.back());
419 for (
const auto & node : input->node_ptr_range())
428 std::vector<boundary_id_type> ids_to_copy;
431 Point current_distance;
436 [](
auto &
c) {
return c * (-1.0) * M_PI / 180.0; });
441 [](
auto &
c) {
return c * M_PI / 180.0; });
442 std::vector<dof_id_type> nodes_on_axis;
444 for (
const auto & node : input->node_ptr_range())
452 nodes_on_axis.push_back(node->id());
455 unsigned int current_node_layer = 0;
460 for (
unsigned int e = 0; e < num_rotations; e++)
466 const auto base_angle =
470 for (
unsigned int k = 0;
471 k < order * num_layers + (e == 0 ? 1 : 0) -
475 bool is_node_created(
false);
479 if (e == 0 &&
k == 0)
480 current_distance.
zero();
483 auto layer_index = (
k - (e == 0 ? 1 : 0)) + 1;
486 const Point vector_xy =
487 Point(-2.0 * radius_and_center.first *
488 std::sin((base_angle + angle * (
Real)layer_index) / 2.0) *
489 std::sin((base_angle + angle * (
Real)layer_index) / 2.0),
490 2.0 * radius_and_center.first *
491 std::sin((base_angle + angle * (
Real)layer_index) / 2.0) *
492 std::cos((base_angle + angle * (
Real)layer_index) / 2.0),
494 current_distance =
Point(rotation_vectors[0] * vector_xy,
495 rotation_vectors[1] * vector_xy,
496 rotation_vectors[2] * vector_xy);
499 is_node_created =
true;
501 else if (e == 0 &&
k == 0)
504 current_distance.
zero();
505 is_node_created =
true;
511 node->id() + (current_node_layer * orig_nodes),
512 node->processor_id());
513 #ifdef LIBMESH_ENABLE_UNIQUE_ID 518 (current_node_layer == 0)
520 : (orig_unique_ids + (current_node_layer - 1) * (orig_nodes + orig_elem * 2) +
527 boundary_info.
add_node(new_node, ids_to_copy);
529 for (
const auto & id_to_copy : ids_to_copy)
536 current_node_layer++;
541 for (
const auto & elem : input->element_ptr_range())
543 const ElemType etype = elem->type();
546 mooseAssert(!elem->parent(),
"RevolveGenerator only works on coarse meshes.");
548 unsigned int current_layer = 0;
552 for (
unsigned int e = 0; e < num_rotations; e++)
556 for (
unsigned int k = 0;
k < num_layers; ++
k)
558 std::unique_ptr<Elem> new_elem;
559 std::unique_ptr<Elem> new_elem_1;
560 bool is_flipped(
false);
563 bool is_flipped_additional(
false);
565 std::vector<std::pair<dof_id_type, dof_id_type>> side_pairs;
576 if (nodes_cates.first.empty())
584 total_num_azimuthal_intervals,
597 total_num_azimuthal_intervals,
612 if (nodes_cates.first.empty())
620 total_num_azimuthal_intervals,
633 total_num_azimuthal_intervals,
650 if (nodes_cates.first.empty())
658 total_num_azimuthal_intervals,
662 else if (nodes_cates.first.size() == 1)
671 total_num_azimuthal_intervals,
676 else if (nodes_cates.first.size() == 2)
685 total_num_azimuthal_intervals,
691 mooseError(
"A degenerate TRI3 elements overlapped with the rotation axis cannot be " 707 if (nodes_cates.first.empty())
715 total_num_azimuthal_intervals,
719 else if (nodes_cates.first.size() == 1)
728 total_num_azimuthal_intervals,
733 else if (nodes_cates.first.size() == 3)
742 total_num_azimuthal_intervals,
749 "You either have a degenerate TRI6 element, or the mid-point of the " 750 "on-axis edge is not colinear with the two vertices, which is not supported.");
764 if (nodes_cates.first.empty())
772 total_num_azimuthal_intervals,
776 else if (nodes_cates.first.size() == 1)
785 total_num_azimuthal_intervals,
790 else if (nodes_cates.first.size() == 3)
799 total_num_azimuthal_intervals,
805 mooseError(
"You either have a degenerate TRI6 element, or the mid-point of the " 806 "on-axis edge of the TRI6 element is not colinear with the two vertices, " 807 "which is not supported.");
820 if (nodes_cates.first.empty())
828 total_num_azimuthal_intervals,
832 else if (nodes_cates.first.size() == 1)
843 total_num_azimuthal_intervals,
847 is_flipped_additional);
849 else if (nodes_cates.first.size() == 2)
858 total_num_azimuthal_intervals,
865 mooseError(
"Degenerate QUAD4 element with 3 or more aligned nodes cannot be " 866 "azimuthally revolved");
882 if (nodes_cates.first.empty())
890 total_num_azimuthal_intervals,
894 else if (nodes_cates.first.size() == 3)
903 total_num_azimuthal_intervals,
909 mooseError(
"You either have a degenerate QUAD8 element, or the mid-point of the " 910 "on-axis edge of the QUAD8 element is not colinear with the two vertices, " 911 "which is not supported.");
927 if (nodes_cates.first.empty())
935 total_num_azimuthal_intervals,
939 else if (nodes_cates.first.size() == 1)
950 total_num_azimuthal_intervals,
954 is_flipped_additional);
956 else if (nodes_cates.first.size() == 3)
965 total_num_azimuthal_intervals,
971 mooseError(
"You either have a degenerate QUAD9 element, or the mid-point of the " 972 "on-axis edge of the QUAD9 element is not colinear with the two vertices, " 973 "which is not supported.");
977 mooseError(
"The input mesh contains unsupported element type(s).");
979 new_elem->set_id(elem->id() + (current_layer * orig_elem));
980 new_elem->processor_id() = elem->processor_id();
983 new_elem_1->set_id(elem->id() + (current_layer * orig_elem) + elem_id_shift);
984 new_elem_1->processor_id() = elem->processor_id();
987 #ifdef LIBMESH_ENABLE_UNIQUE_ID 994 : (orig_unique_ids + (current_layer - 1) * (orig_nodes + orig_elem * 2) +
995 orig_nodes + elem->id());
997 new_elem->set_unique_id(uid);
1003 (current_layer == 0)
1004 ? (elem->id() + orig_unique_ids - orig_elem)
1005 : (orig_unique_ids + (current_layer - 1) * (orig_nodes + orig_elem * 2) +
1006 orig_nodes + orig_elem + elem->id());
1008 new_elem_1->set_unique_id(uid_1);
1016 switch (new_elem->type())
1019 new_elem->subdomain_id() = elem->subdomain_id();
1022 new_elem->subdomain_id() = edge_to_tri_subdomain_id_shift + elem->subdomain_id();
1026 "impossible element type generated by revolving an EDGE2 element");
1030 switch (new_elem->type())
1033 new_elem->subdomain_id() = elem->subdomain_id();
1036 new_elem->subdomain_id() = edge_to_tri_subdomain_id_shift + elem->subdomain_id();
1040 "impossible element type generated by revolving an EDGE3 element");
1044 switch (new_elem->type())
1047 new_elem->subdomain_id() = elem->subdomain_id();
1050 new_elem->subdomain_id() = tri_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1053 new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id();
1056 mooseAssert(
false,
"impossible element type generated by revolving a TRI3 element");
1060 switch (new_elem->type())
1063 new_elem->subdomain_id() = elem->subdomain_id();
1066 new_elem->subdomain_id() = tri_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1069 new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id();
1072 mooseAssert(
false,
"impossible element type generated by revolving a TRI6 element");
1076 switch (new_elem->type())
1079 new_elem->subdomain_id() = elem->subdomain_id();
1082 new_elem->subdomain_id() = tri_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1085 new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id();
1088 mooseAssert(
false,
"impossible element type generated by revolving a TRI7 element");
1092 switch (new_elem->type())
1095 new_elem->subdomain_id() = elem->subdomain_id();
1098 new_elem->subdomain_id() = quad_to_prism_subdomain_id_shift + elem->subdomain_id();
1101 new_elem->subdomain_id() =
1102 quad_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1103 new_elem_1->subdomain_id() =
1104 quad_to_prism_subdomain_id_shift + elem->subdomain_id();
1108 "impossible element type generated by revolving a QUAD4 element");
1112 switch (new_elem->type())
1115 new_elem->subdomain_id() = elem->subdomain_id();
1118 new_elem->subdomain_id() = quad_to_prism_subdomain_id_shift + elem->subdomain_id();
1122 "impossible element type generated by revolving a QUAD8 element");
1126 switch (new_elem->type())
1129 new_elem->subdomain_id() = elem->subdomain_id();
1132 new_elem->subdomain_id() =
1133 quad_to_hi_pyramid_subdomain_id_shift + elem->subdomain_id();
1136 new_elem->subdomain_id() =
1137 quad_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1138 new_elem_1->subdomain_id() =
1139 quad_to_hi_pyramid_subdomain_id_shift + elem->subdomain_id();
1143 "impossible element type generated by revolving a QUAD9 element");
1148 "The input mesh contains unsupported element type(s), which should have " 1149 "been checked in prior steps in this code.");
1156 auto new_id_it = revolving_swap_pairs.find(elem->subdomain_id());
1158 if (new_id_it != revolving_swap_pairs.end())
1160 new_elem->subdomain_id() =
1161 new_elem->subdomain_id() - elem->subdomain_id() + new_id_it->second;
1163 new_elem_1->subdomain_id() =
1164 new_elem_1->subdomain_id() - elem->subdomain_id() + new_id_it->second;
1169 Elem * added_elem_1 = NULL;
1175 for (
unsigned int i = 0; i < num_extra_elem_integers; i++)
1186 auto & elevation_extra_swap_pairs =
1189 auto new_extra_id_it = elevation_extra_swap_pairs.find(
1192 if (new_extra_id_it != elevation_extra_swap_pairs.end())
1195 new_extra_id_it->second);
1198 new_extra_id_it->second);
1204 for (
auto s : elem->side_index_range())
1206 input_boundary_info.
boundary_ids(elem, s, ids_to_copy);
1207 std::vector<boundary_id_type> ids_to_copy_swapped;
1209 ids_to_copy_swapped = ids_to_copy;
1211 for (
const auto & id_to_copy : ids_to_copy)
1219 switch (added_elem->
type())
1223 added_elem, cast_int<unsigned short>(s == 0 ? 3 : 1), ids_to_copy_swapped);
1226 if (s != axis_node_case)
1228 added_elem, cast_int<unsigned short>(s), ids_to_copy_swapped);
1232 "impossible element type generated by revolving an EDGE2 element");
1236 switch (added_elem->
type())
1240 added_elem, cast_int<unsigned short>(s == 0 ? 3 : 1), ids_to_copy_swapped);
1243 if (s != axis_node_case)
1245 added_elem, cast_int<unsigned short>(s), ids_to_copy_swapped);
1249 "impossible element type generated by revolving an EDGE3 element");
1253 switch (added_elem->
type())
1257 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1260 if ((s + 3 - axis_node_case) % 3 == 0)
1262 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1263 else if ((s + 3 - axis_node_case) % 3 == 1)
1265 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1268 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1271 if ((s + 3 - axis_node_case) % 3 == 0)
1273 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1274 else if ((s + 3 - axis_node_case) % 3 == 2)
1276 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1280 "impossible element type generated by revolving a TRI3 element");
1284 switch (added_elem->
type())
1288 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1291 if ((s + 3 - axis_node_case) % 3 == 0)
1293 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1294 else if ((s + 3 - axis_node_case) % 3 == 1)
1296 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1299 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1302 if ((s + 3 - axis_node_case) % 3 == 0)
1304 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1305 else if ((s + 3 - axis_node_case) % 3 == 2)
1307 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1311 "impossible element type generated by revolving a TRI6 element");
1315 switch (added_elem->
type())
1319 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1322 if ((s + 3 - axis_node_case) % 3 == 0)
1324 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1325 else if ((s + 3 - axis_node_case) % 3 == 1)
1327 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1330 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1333 if ((s + 3 - axis_node_case) % 3 == 0)
1335 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1336 else if ((s + 3 - axis_node_case) % 3 == 2)
1338 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1342 "impossible element type generated by revolving a TRI7 element");
1346 switch (added_elem->
type())
1350 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1353 if ((s + 4 - axis_node_case) % 4 == 1)
1355 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1356 else if ((s + 4 - axis_node_case) % 4 == 2)
1358 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1359 else if ((s + 4 - axis_node_case) % 4 == 3)
1361 added_elem, cast_int<unsigned short>(0), ids_to_copy_swapped);
1364 if ((s + 4 - axis_node_case) % 4 == 3)
1366 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1367 else if ((s + 4 - axis_node_case) % 4 == 0)
1369 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1370 else if ((s + 4 - axis_node_case) % 4 == 1)
1372 added_elem_1, cast_int<unsigned short>(3), ids_to_copy_swapped);
1375 added_elem_1, cast_int<unsigned short>(2), ids_to_copy_swapped);
1379 "impossible element type generated by revolving a QUAD4 element");
1383 switch (added_elem->
type())
1387 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1390 if ((s + 4 - axis_node_case) % 4 == 1)
1392 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1393 else if ((s + 4 - axis_node_case) % 4 == 2)
1395 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1396 else if ((s + 4 - axis_node_case) % 4 == 3)
1398 added_elem, cast_int<unsigned short>(0), ids_to_copy_swapped);
1402 "impossible element type generated by revolving a QUAD8 element");
1406 switch (added_elem->
type())
1410 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1413 if ((s + 4 - axis_node_case) % 4 == 1)
1415 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1416 else if ((s + 4 - axis_node_case) % 4 == 2)
1418 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1419 else if ((s + 4 - axis_node_case) % 4 == 3)
1421 added_elem, cast_int<unsigned short>(0), ids_to_copy_swapped);
1424 if ((s + 4 - axis_node_case) % 4 == 3)
1426 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1427 else if ((s + 4 - axis_node_case) % 4 == 0)
1429 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1430 else if ((s + 4 - axis_node_case) % 4 == 1)
1432 added_elem_1, cast_int<unsigned short>(3), ids_to_copy_swapped);
1435 added_elem_1, cast_int<unsigned short>(2), ids_to_copy_swapped);
1439 "impossible element type generated by revolving a QUAD9 element");
1444 "The input mesh contains unsupported element type(s), which should have " 1445 "been checked in prior steps in this code.");
1452 added_elem, is_flipped ? side_pairs[0].second : side_pairs[0].first,
_start_boundary);
1453 if (side_pairs.size() > 1)
1454 boundary_info.
add_side(added_elem_1,
1455 is_flipped_additional ? side_pairs[1].second
1456 : side_pairs[1].first,
1463 added_elem, is_flipped ? side_pairs[0].first : side_pairs[0].second,
_end_boundary);
1464 if (side_pairs.size() > 1)
1465 boundary_info.
add_side(added_elem_1,
1466 is_flipped_additional ? side_pairs[1].first
1467 : side_pairs[1].second,
1475 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1478 unsigned int total_new_node_layers = total_num_azimuthal_intervals * order;
1479 unsigned int new_unique_ids = orig_unique_ids + (total_new_node_layers - 1) * orig_elem * 2 +
1480 total_new_node_layers * orig_nodes;
1485 if (!input_subdomain_map.empty())
1487 if (!input_sideset_map.empty())
1489 input_sideset_map.end());
1490 if (!input_nodeset_map.empty())
1492 input_nodeset_map.end());
1501 std::pair<Real, Point>
1503 const Point & p_axis,
1504 const Point & dir_axis)
const 1508 const Real dist = (p_ext - p_axis) * dir_axis.
unit();
1509 const Point center_pt = p_axis + dist * dir_axis.
unit();
1512 return std::make_pair(
radius, center_pt);
1517 const Point & dir_axis,
1518 const Point & p_input)
const 1525 const Point x_prime = ((p_input - p_axis) - ((p_input - p_axis) * z_prime) * z_prime).
unit();
1526 const Point y_prime = z_prime.
cross(x_prime);
1529 return {{x_prime(0), y_prime(0), z_prime(0)},
1530 {x_prime(1), y_prime(1), z_prime(1)},
1531 {x_prime(2), y_prime(2), z_prime(2)}};
1534 std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>>
1536 const std::vector<dof_id_type> & nodes_on_axis)
const 1538 std::vector<dof_id_type> nodes_on_axis_in_elem;
1539 std::vector<dof_id_type> nodes_not_on_axis_in_elem;
1540 for (
unsigned int i = 0; i < elem.
n_nodes(); i++)
1542 const auto node_id = elem.
node_id(i);
1543 if (std::find(nodes_on_axis.begin(), nodes_on_axis.end(), node_id) != nodes_on_axis.end())
1545 nodes_on_axis_in_elem.push_back(i);
1549 nodes_not_on_axis_in_elem.push_back(i);
1552 return std::make_pair(nodes_on_axis_in_elem, nodes_not_on_axis_in_elem);
1558 const Point axis_component =
1561 node =
_axis_point + axis_component + rad_component;
1567 const std::unique_ptr<MeshBase> & mesh,
1568 std::unique_ptr<Elem> & new_elem,
1569 const int current_layer,
1570 const unsigned int orig_nodes,
1571 const unsigned int total_num_azimuthal_intervals,
1572 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1573 bool & is_flipped)
const 1575 if (quad_elem_type !=
QUAD4 && quad_elem_type !=
QUAD9)
1576 mooseError(
"Unsupported element type", quad_elem_type);
1578 side_pairs.push_back(std::make_pair(0, 2));
1579 const unsigned int order = quad_elem_type ==
QUAD4 ? 1 : 2;
1581 new_elem = std::make_unique<Quad4>();
1582 if (quad_elem_type ==
QUAD9)
1584 new_elem = std::make_unique<Quad9>();
1585 new_elem->set_node(4,
1592 ((current_layer + 1) %
1608 ((current_layer + 1) %
1610 order * orig_nodes)));
1614 ((current_layer + 1) %
1616 order * orig_nodes)));
1618 if (new_elem->volume() < 0.0)
1622 if (quad_elem_type ==
QUAD9)
1630 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
1633 const std::unique_ptr<MeshBase> & mesh,
1634 std::unique_ptr<Elem> & new_elem,
1635 const int current_layer,
1636 const unsigned int orig_nodes,
1637 const unsigned int total_num_azimuthal_intervals,
1638 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1640 bool & is_flipped)
const 1642 if (tri_elem_type !=
TRI3 && tri_elem_type !=
TRI7)
1643 mooseError(
"Unsupported element type", tri_elem_type);
1645 side_pairs.push_back(std::make_pair(0, 2));
1646 const unsigned int order = tri_elem_type ==
TRI3 ? 1 : 2;
1647 axis_node_case = nodes_cates.first.front();
1649 new_elem = std::make_unique<Tri3>();
1650 if (tri_elem_type ==
TRI7)
1652 new_elem = std::make_unique<Tri7>();
1653 new_elem->set_node(3,
1655 new_elem->set_node(4,
1657 ((current_layer * 2 + 1) * orig_nodes)));
1661 ((current_layer + 1) %
1669 new_elem->set_node(1,
1671 (current_layer * order * orig_nodes)));
1675 ((current_layer + 1) %
1677 order * orig_nodes)));
1679 if (new_elem->volume() < 0.0)
1682 if (tri_elem_type ==
TRI7)
1691 const std::unique_ptr<MeshBase> & mesh,
1692 std::unique_ptr<Elem> & new_elem,
1693 const int current_layer,
1694 const unsigned int orig_nodes,
1695 const unsigned int total_num_azimuthal_intervals,
1696 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1697 bool & is_flipped)
const 1702 side_pairs.push_back(std::make_pair(0, 4));
1703 const unsigned int order = prism_elem_type ==
PRISM6 ? 1 : 2;
1705 new_elem = std::make_unique<Prism6>();
1709 new_elem = std::make_unique<Prism18>();
1710 if (prism_elem_type ==
PRISM21)
1712 new_elem = std::make_unique<Prism21>();
1718 (total_num_azimuthal_intervals + 1 -
1724 new_elem->set_node(6,
1726 new_elem->set_node(7,
1728 new_elem->set_node(8,
1739 ((current_layer + 1) %
1745 ((current_layer + 1) %
1751 ((current_layer + 1) %
1770 ((current_layer + 1) %
1772 order * orig_nodes)));
1776 ((current_layer + 1) %
1778 order * orig_nodes)));
1782 ((current_layer + 1) %
1784 order * orig_nodes)));
1786 if (new_elem->volume() < 0.0)
1791 if (prism_elem_type !=
PRISM6)
1796 if (prism_elem_type ==
PRISM21)
1807 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
1810 const std::unique_ptr<MeshBase> & mesh,
1811 std::unique_ptr<Elem> & new_elem,
1812 const int current_layer,
1813 const unsigned int orig_nodes,
1814 const unsigned int total_num_azimuthal_intervals,
1815 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1817 bool & is_flipped)
const 1823 side_pairs.push_back(std::make_pair(0, 2));
1824 const unsigned int order = pyramid_elem_type ==
PYRAMID5 ? 1 : 2;
1825 axis_node_case = nodes_cates.first.front();
1827 new_elem = std::make_unique<Pyramid5>();
1831 new_elem = std::make_unique<Pyramid13>();
1834 new_elem = std::make_unique<Pyramid18>();
1835 new_elem->set_node(13,
1837 ((current_layer * 2 + 1) * orig_nodes)));
1838 new_elem->set_node(15,
1840 ((current_layer * 2 + 1) * orig_nodes)));
1841 new_elem->set_node(17,
1843 ((current_layer * 2 + 1) * orig_nodes)));
1849 (total_num_azimuthal_intervals + 1 -
1853 new_elem->set_node(6,
1855 ((current_layer * 2 + 1) * orig_nodes)));
1856 new_elem->set_node(8,
1858 ((current_layer * 2 + 1) * orig_nodes)));
1859 new_elem->set_node(5,
1861 (current_layer * 2 * orig_nodes)));
1865 ((current_layer + 1) %
1868 new_elem->set_node(9,
1870 (current_layer * 2 * orig_nodes)));
1871 new_elem->set_node(10,
1873 (current_layer * 2 * orig_nodes)));
1877 ((current_layer + 1) %
1883 ((current_layer + 1) %
1888 new_elem->set_node(0,
1890 (current_layer * order * orig_nodes)));
1891 new_elem->set_node(1,
1893 (current_layer * order * orig_nodes)));
1897 ((current_layer + 1) %
1899 order * orig_nodes)));
1903 ((current_layer + 1) %
1905 order * orig_nodes)));
1907 if (new_elem->volume() < 0.0)
1927 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
1930 const std::unique_ptr<MeshBase> & mesh,
1931 std::unique_ptr<Elem> & new_elem,
1932 const int current_layer,
1933 const unsigned int orig_nodes,
1934 const unsigned int total_num_azimuthal_intervals,
1935 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1937 bool & is_flipped)
const 1939 if (tet_elem_type !=
TET4 && tet_elem_type !=
TET10 && tet_elem_type !=
TET14)
1942 side_pairs.push_back(std::make_pair(0, 1));
1943 const unsigned int order = tet_elem_type ==
TET4 ? 1 : 2;
1947 if (nodes_cates.first[0] > 2 || nodes_cates.first[1] > 2 || nodes_cates.first[2] < 3)
1950 axis_node_case = nodes_cates.second.front();
1952 new_elem = std::make_unique<Tet4>();
1955 const bool node_order = nodes_cates.first[1] - nodes_cates.first[0] == 1;
1956 new_elem = std::make_unique<Tet10>();
1957 if (tet_elem_type ==
TET14)
1959 new_elem = std::make_unique<Tet14>();
1963 : (nodes_cates.second.front() + 3))
1965 ((current_layer * 2 + 1) * orig_nodes)));
1966 new_elem->set_node(13,
1968 : (nodes_cates.first[0] + 3))
1970 ((current_layer * 2 + 1) * orig_nodes)));
1976 (total_num_azimuthal_intervals + 1 -
1980 new_elem->set_node(4,
1982 : (nodes_cates.first[1] + 3))
1984 new_elem->set_node(5,
1986 : (nodes_cates.second.front() + 3))
1988 (current_layer * 2 * orig_nodes)));
1989 new_elem->set_node(6,
1991 : (nodes_cates.first[0] + 3))
1993 (current_layer * 2 * orig_nodes)));
1997 : (nodes_cates.second.front() + 3))
1999 ((current_layer + 1) %
2005 : (nodes_cates.first[0] + 3))
2007 ((current_layer + 1) %
2010 new_elem->set_node(9,
2012 ((current_layer * 2 + 1) * orig_nodes)));
2016 new_elem->set_node(2,
2018 (current_layer * order * orig_nodes)));
2022 ((current_layer + 1) %
2024 order * orig_nodes)));
2026 if (new_elem->volume() < 0.0)
2033 if (tet_elem_type ==
TET14)
2045 const std::unique_ptr<MeshBase> & mesh,
2046 std::unique_ptr<Elem> & new_elem,
2047 const int current_layer,
2048 const unsigned int orig_nodes,
2049 const unsigned int total_num_azimuthal_intervals,
2050 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
2051 bool & is_flipped)
const 2053 if (hex_elem_type !=
HEX8 && hex_elem_type !=
HEX20 && hex_elem_type !=
HEX27)
2056 side_pairs.push_back(std::make_pair(0, 5));
2057 const unsigned int order = hex_elem_type ==
HEX8 ? 1 : 2;
2059 new_elem = std::make_unique<Hex8>();
2062 new_elem = std::make_unique<Hex20>();
2063 if (hex_elem_type ==
HEX27)
2065 new_elem = std::make_unique<Hex27>();
2071 (total_num_azimuthal_intervals + 1 -
2085 new_elem->set_node(8,
2087 new_elem->set_node(9,
2089 new_elem->set_node(10,
2091 new_elem->set_node(11,
2096 ((current_layer + 1) %
2102 ((current_layer + 1) %
2108 ((current_layer + 1) %
2114 ((current_layer + 1) %
2137 ((current_layer + 1) %
2139 order * orig_nodes)));
2143 ((current_layer + 1) %
2145 order * orig_nodes)));
2149 ((current_layer + 1) %
2151 order * orig_nodes)));
2155 ((current_layer + 1) %
2157 order * orig_nodes)));
2159 if (new_elem->volume() < 0.0)
2171 if (hex_elem_type ==
HEX27)
2182 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
2185 const std::unique_ptr<MeshBase> & mesh,
2186 std::unique_ptr<Elem> & new_elem,
2187 const int current_layer,
2188 const unsigned int orig_nodes,
2189 const unsigned int total_num_azimuthal_intervals,
2190 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
2192 bool & is_flipped)
const 2197 side_pairs.push_back(std::make_pair(1, 3));
2198 const unsigned int order = prism_elem_type ==
PRISM6 ? 1 : 2;
2202 if (nodes_cates.first[0] > 3 || nodes_cates.first[1] > 3 || nodes_cates.first[2] < 4)
2207 const dof_id_type min_on_axis = nodes_cates.first[0];
2208 const dof_id_type max_on_axis = nodes_cates.first[1];
2209 axis_node_case = max_on_axis - min_on_axis == 1 ? min_on_axis : max_on_axis;
2211 new_elem = std::make_unique<Prism6>();
2214 new_elem = std::make_unique<Prism15>();
2215 if (prism_elem_type ==
PRISM18)
2217 new_elem = std::make_unique<Prism18>();
2220 new_elem->set_node(16,
2222 ((current_layer * 2 + 1) * orig_nodes)));
2226 (total_num_azimuthal_intervals + 1 -
2231 new_elem->set_node(10,
2233 (current_layer * 2 * orig_nodes)));
2234 new_elem->set_node(12,
2236 (current_layer * 2 * orig_nodes)));
2237 new_elem->set_node(6,
2239 (current_layer * 2 * orig_nodes)));
2243 ((current_layer + 1) %
2249 ((current_layer + 1) %
2255 ((current_layer + 1) %
2258 new_elem->set_node(7,
2260 ((current_layer * 2 + 1) * orig_nodes)));
2261 new_elem->set_node(13,
2263 ((current_layer * 2 + 1) * orig_nodes)));
2267 new_elem->set_node(4,
2269 (current_layer * order * orig_nodes)));
2270 new_elem->set_node(1,
2272 (current_layer * order * orig_nodes)));
2276 ((current_layer + 1) %
2278 order * orig_nodes)));
2282 ((current_layer + 1) %
2284 order * orig_nodes)));
2286 if (new_elem->volume() < 0.0)
2295 if (prism_elem_type ==
PRISM18)
2306 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
2310 const std::unique_ptr<MeshBase> & mesh,
2311 std::unique_ptr<Elem> & new_elem,
2312 std::unique_ptr<Elem> & new_elem_1,
2313 const int current_layer,
2314 const unsigned int orig_nodes,
2315 const unsigned int total_num_azimuthal_intervals,
2316 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
2319 bool & is_flipped_additional)
const 2321 if (!(pyramid_elem_type ==
PYRAMID5 && prism_elem_type ==
PRISM6) &&
2324 const unsigned int order = pyramid_elem_type ==
PYRAMID5 ? 1 : 2;
2326 side_pairs.push_back(std::make_pair(0, 2));
2327 axis_node_case = nodes_cates.first.front();
2328 new_elem = std::make_unique<Pyramid5>();
2331 new_elem = std::make_unique<Pyramid14>();
2332 new_elem->set_node(9,
2334 (current_layer * 2 * orig_nodes)));
2335 new_elem->set_node(10,
2337 (current_layer * 2 * orig_nodes)));
2338 new_elem->set_node(5,
2340 new_elem->set_node(8,
2342 ((current_layer * 2 + 1) * orig_nodes)));
2343 new_elem->set_node(6,
2345 ((current_layer * 2 + 1) * orig_nodes)));
2351 ((current_layer + 1) %
2357 ((current_layer + 1) %
2363 ((current_layer + 1) %
2368 new_elem->set_node(0,
2370 (current_layer * order * orig_nodes)));
2371 new_elem->set_node(1,
2373 (current_layer * order * orig_nodes)));
2377 ((current_layer + 1) %
2379 order * orig_nodes)));
2383 ((current_layer + 1) %
2385 order * orig_nodes)));
2387 if (new_elem->volume() < 0.0)
2400 side_pairs.push_back(std::make_pair(0, 4));
2401 new_elem_1 = std::make_unique<Prism6>();
2402 if (prism_elem_type ==
PRISM18)
2404 new_elem_1 = std::make_unique<Prism18>();
2405 new_elem_1->set_node(
2407 new_elem_1->set_node(8,
2409 (current_layer * 2 * orig_nodes)));
2410 new_elem_1->set_node(7,
2412 (current_layer * 2 * orig_nodes)));
2413 new_elem_1->set_node(9,
2415 ((current_layer * 2 + 1) * orig_nodes)));
2416 new_elem_1->set_node(10,
2418 ((current_layer * 2 + 1) * orig_nodes)));
2419 new_elem_1->set_node(11,
2421 ((current_layer * 2 + 1) * orig_nodes)));
2422 new_elem_1->set_node(
2424 new_elem_1->set_node(17,
2426 ((current_layer * 2 + 1) * orig_nodes)));
2427 new_elem_1->set_node(16,
2429 ((current_layer * 2 + 1) * orig_nodes)));
2430 new_elem_1->set_node(
2433 ((current_layer + 1) %
2436 new_elem_1->set_node(
2439 ((current_layer + 1) %
2442 new_elem_1->set_node(
2445 ((current_layer + 1) %
2449 new_elem_1->set_node(0,
2451 (current_layer * order * orig_nodes)));
2452 new_elem_1->set_node(1,
2454 (current_layer * order * orig_nodes)));
2455 new_elem_1->set_node(2,
2457 (current_layer * order * orig_nodes)));
2458 new_elem_1->set_node(
2461 ((current_layer + 1) %
2463 order * orig_nodes)));
2464 new_elem_1->set_node(
2467 ((current_layer + 1) %
2469 order * orig_nodes)));
2470 new_elem_1->set_node(
2473 ((current_layer + 1) %
2475 order * orig_nodes)));
2477 if (new_elem_1->volume() < 0.0)
2482 if (prism_elem_type ==
PRISM18)
2488 is_flipped_additional =
true;
void swapNodesInElem(Elem &elem, const unsigned int nd1, const unsigned int nd2)
void createPRISMfromQUAD(const std::pair< std::vector< dof_id_type >, std::vector< dof_id_type >> &nodes_cates, const ElemType prism_elem_type, const Elem *elem, const std::unique_ptr< MeshBase > &mesh, std::unique_ptr< Elem > &new_elem, const int current_layer, const unsigned int orig_nodes, const unsigned int total_num_azimuthal_intervals, std::vector< std::pair< dof_id_type, dof_id_type >> &side_pairs, dof_id_type &axis_node_case, bool &is_flipped) const
Create a new PRISM element from an existing QUAD element by revolving it.
This RevolveGenerator object is designed to revolve a 1D mesh into 2D, or a 2D mesh into 3D based on ...
std::pair< Real, Point > getRotationCenterAndRadius(const Point &p_ext, const Point &p_axis, const Point &dir_axis) const
Get the rotation center and radius of the circular rotation based on the rotation axis and the extern...
unique_id_type & set_unique_id()
virtual void reserve_nodes(const dof_id_type nn)=0
const bool _preserve_volumes
Volume preserving function is optional.
bool _has_start_boundary
Whether a starting boundary is specified.
virtual const char * what() const
auto norm() const -> decltype(std::norm(Real()))
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
void remove_orphaned_nodes()
T & getMesh(MooseMesh &mesh)
function to cast mesh
boundary_id_type _start_boundary
Boundary ID of the starting boundary.
void nodeModification(Node &node)
Modify the position of a node to account for radius correction.
static InputParameters validParams()
boundary_id_type _end_boundary
Boundary ID of the ending boundary.
registerMooseObject("ReactorApp", RevolveGenerator)
const Point & _axis_direction
A direction vector of the axis of revolution.
std::pair< std::vector< dof_id_type >, std::vector< dof_id_type > > onAxisNodesIdentifier(const Elem &elem, const std::vector< dof_id_type > &nodes_on_axis) const
Categorize the nodes of an element into two groups: nodes on the axis and nodes off the axis...
void createTETfromTRI(const std::pair< std::vector< dof_id_type >, std::vector< dof_id_type >> &nodes_cates, const ElemType tet_elem_type, const Elem *elem, const std::unique_ptr< MeshBase > &mesh, std::unique_ptr< Elem > &new_elem, const int current_layer, const unsigned int orig_nodes, const unsigned int total_num_azimuthal_intervals, std::vector< std::pair< dof_id_type, dof_id_type >> &side_pairs, dof_id_type &axis_node_case, bool &is_flipped) const
Create a new TET element from an existing TRI element by revolving it.
void createPYRAMIDPRISMfromQUAD(const std::pair< std::vector< dof_id_type >, std::vector< dof_id_type >> &nodes_cates, const ElemType pyramid_elem_type, const ElemType prism_elem_type, const Elem *elem, const std::unique_ptr< MeshBase > &mesh, std::unique_ptr< Elem > &new_elem, std::unique_ptr< Elem > &new_elem_1, const int current_layer, const unsigned int orig_nodes, const unsigned int total_num_azimuthal_intervals, std::vector< std::pair< dof_id_type, dof_id_type >> &side_pairs, dof_id_type &axis_node_case, bool &is_flipped, bool &is_flipped_additional) const
Create a new PYRAMID element and a new PRISM element from an existing QUAD element by revolving it...
std::unique_ptr< MeshBase > & _input
Lower dimensional mesh from another generator.
const std::vector< std::string > & _elem_integer_names_to_swap
Names and indices of extra element integers to swap.
unsigned int add_elem_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
bool has_elem_integer(std::string_view name) const
const std::vector< unsigned int > & _nums_azimuthal_intervals
Numbers of azimuthal mesh intervals in each azimuthal section.
unique_id_type unique_id() const
const Parallel::Communicator & comm() const
RevolveGenerator(const InputParameters ¶meters)
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
virtual void set_next_unique_id(unique_id_type id)=0
const std::vector< std::vector< std::vector< dof_id_type > > > & _elem_integers_swaps
Extra element integers to swap out for each elevation and each element integer name.
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
const BoundaryInfo & get_boundary_info() const
virtual const std::string & name() const
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
void createPYRAMIDfromTRI(const std::pair< std::vector< dof_id_type >, std::vector< dof_id_type >> &nodes_cates, const ElemType pyramid_elem_type, const Elem *elem, const std::unique_ptr< MeshBase > &mesh, std::unique_ptr< Elem > &new_elem, const int current_layer, const unsigned int orig_nodes, const unsigned int total_num_azimuthal_intervals, std::vector< std::pair< dof_id_type, dof_id_type >> &side_pairs, dof_id_type &axis_node_case, bool &is_flipped) const
Create a new PYRAMID element from an existing TRI element by revolving it.
bool _has_end_boundary
Whether an ending boundary is specified.
std::map< boundary_id_type, std::string > & set_sideset_name_map()
TypeVector< Real > unit() const
void libmesh_ignore(const Args &...)
void add_node(const Node *node, const boundary_id_type id)
static InputParameters validParams()
bool _full_circle_revolving
Whether to revolve for a full circle or not.
virtual unsigned int n_nodes() const=0
const std::vector< std::vector< subdomain_id_type > > & _subdomain_swaps
Subdomains to swap out for each azimuthal section.
const std::vector< Real > _revolving_angles
Angles of revolution delineating each azimuthal section.
virtual Elem * add_elem(Elem *e)=0
bool absoluteFuzzyLessThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
void idSwapParametersProcessor(const std::string &class_name, const std::string &id_name, const std::vector< std::vector< T >> &id_swaps, std::vector< std::unordered_map< T, T >> &id_swap_pairs, const unsigned int row_index_shift=0)
void set_mesh_dimension(unsigned char d)
void paramError(const std::string ¶m, Args... args) const
TypeVector< typename CompareTypes< Real, T2 >::supertype > cross(const TypeVector< T2 > &v) const
const bool & _clockwise
Revolving direction.
std::vector< std::unordered_map< boundary_id_type, boundary_id_type > > _boundary_swap_pairs
Easier to work with version of _boundary_swaps.
const Point & _axis_point
A point of the axis of revolution.
std::vector< Real > _unit_angles
Unit angles of all azimuthal sections of revolution.
std::unique_ptr< MeshBase > generate() override
std::vector< std::unordered_map< subdomain_id_type, subdomain_id_type > > _subdomain_swap_pairs
Easier to work with version of _sudomain_swaps.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void max(const T &r, T &o, Request &req) const
void createQUADfromEDGE(const ElemType quad_elem_type, const Elem *elem, const std::unique_ptr< MeshBase > &mesh, std::unique_ptr< Elem > &new_elem, const int current_layer, const unsigned int orig_nodes, const unsigned int total_num_azimuthal_intervals, std::vector< std::pair< dof_id_type, dof_id_type >> &side_pairs, bool &is_flipped) const
Create a new QUAD element from an existing EDGE element by revolving it.
const Node * node_ptr(const unsigned int i) const
std::map< boundary_id_type, std::string > & set_nodeset_name_map()
const std::vector< std::vector< boundary_id_type > > & _boundary_swaps
Boundaries to swap out for each elevation.
A base class that contains common members for Reactor module mesh generators.
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
Real _radius_correction_factor
Radius correction factor.
std::vector< unsigned int > _elem_integer_indices_to_swap
void createHEXfromQUAD(const ElemType hex_elem_type, const Elem *elem, const std::unique_ptr< MeshBase > &mesh, std::unique_ptr< Elem > &new_elem, const int current_layer, const unsigned int orig_nodes, const unsigned int total_num_azimuthal_intervals, std::vector< std::pair< dof_id_type, dof_id_type >> &side_pairs, bool &is_flipped) const
Create a new HEX element from an existing QUAD element by revolving it.
void extraElemIntegerSwapParametersProcessor(const std::string &class_name, const unsigned int num_sections, const unsigned int num_integers, const std::vector< std::vector< std::vector< dof_id_type >>> &elem_integers_swaps, std::vector< std::unordered_map< dof_id_type, dof_id_type >> &elem_integers_swap_pairs)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
Point meshCentroidCalculator(const MeshBase &mesh)
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
virtual void delete_remote_elements()
Real radiusCorrectionFactor(const std::vector< Real > &azimuthal_list, const bool full_circle=true, const unsigned int order=1, const bool is_first_value_vertex=true)
Makes radial correction to preserve ring area.
std::vector< Point > rotationVectors(const Point &p_axis, const Point &dir_axis, const Point &p_input) const
Calculate the transform matrix between the rotation coordinate system and the original coordinate sys...
virtual const Node * node_ptr(const dof_id_type i) const=0
const DofMap &dof_map LIBMESH_COMMA unsigned int std::string & set_subdomain_name_map()
void createPRISMfromTRI(const ElemType prism_elem_type, const Elem *elem, const std::unique_ptr< MeshBase > &mesh, std::unique_ptr< Elem > &new_elem, const int current_layer, const unsigned int orig_nodes, const unsigned int total_num_azimuthal_intervals, std::vector< std::pair< dof_id_type, dof_id_type >> &side_pairs, bool &is_flipped) const
Create a new PRISM element from an existing TRI element by revolving it.
virtual ElemType type() const=0
dof_id_type node_id(const unsigned int i) const
virtual void reserve_elem(const dof_id_type ne)=0
static const std::string k
void ErrorVector unsigned int
auto index_range(const T &sizable)
std::vector< std::unordered_map< dof_id_type, dof_id_type > > _elem_integers_swap_pairs
Easier to work with version of _elem_integers_swaps.
void set_extra_integer(const unsigned int index, const dof_id_type value)
virtual void renumber_nodes_and_elements()=0
bool absoluteFuzzyGreaterThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
void createTRIfromEDGE(const std::pair< std::vector< dof_id_type >, std::vector< dof_id_type >> &nodes_cates, const ElemType tri_elem_type, const Elem *elem, const std::unique_ptr< MeshBase > &mesh, std::unique_ptr< Elem > &new_elem, const int current_layer, const unsigned int orig_nodes, const unsigned int total_num_azimuthal_intervals, std::vector< std::pair< dof_id_type, dof_id_type >> &side_pairs, dof_id_type &axis_node_case, bool &is_flipped) const
Create a new TRI element from an existing EDGE element by revolving it.