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'.");
160 MooseUtils::absoluteFuzzyEqual(
164 if (MooseUtils::absoluteFuzzyGreaterThan(
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 if (!input->preparation().has_cached_elem_data)
258 input->cache_elem_data();
261 std::set<subdomain_id_type>
blocks;
262 input->subdomain_ids(
blocks,
true);
264 for (
const auto & [bid, tbid] : swap_map)
267 if (
blocks.count(bid) == 0)
269 "Source subdomain " + std::to_string(bid) +
" was not found in the mesh");
272 std::set<subdomain_id_type> subdomain_ids_set;
273 input->subdomain_ids(subdomain_ids_set);
276 std::max((
int)max_subdomain_id, 1) + 1;
278 std::max((
int)max_subdomain_id, 1) * 2 + 1;
279 const subdomain_id_type quad_to_prism_subdomain_id_shift = std::max((
int)max_subdomain_id, 1) + 1;
281 std::max((
int)max_subdomain_id, 1) * 2 + 1;
283 std::max((
int)max_subdomain_id, 1) * 3 + 1;
284 const subdomain_id_type edge_to_tri_subdomain_id_shift = std::max((
int)max_subdomain_id, 1) + 1;
290 if (MooseUtils::absoluteFuzzyEqual(axis_centroid_cross.
norm(), 0.0))
291 mooseError(
"The input mesh is either across the axis or overlapped with the axis!");
293 Real inner_product_1d(0.0);
294 bool inner_product_1d_initialized(
false);
296 std::vector<dof_id_type> node_ids_on_axis;
297 for (
const auto & node : input->node_ptr_range())
301 if (!MooseUtils::absoluteFuzzyEqual(axis_node_cross.
norm(), 0.0))
303 if (MooseUtils::absoluteFuzzyLessThan(axis_node_cross * axis_centroid_cross, 0.0))
304 mooseError(
"The input mesh is across the axis.");
305 else if (MooseUtils::absoluteFuzzyLessThan(axis_node_cross * axis_centroid_cross,
306 axis_centroid_cross.
norm() *
307 axis_node_cross.
norm()))
308 mooseError(
"The input mesh is not in the same plane with the rotation axis.");
311 node_ids_on_axis.push_back(node->id());
314 if (input->mesh_dimension() == 1)
317 if (inner_product_1d_initialized)
319 if (!MooseUtils::absoluteFuzzyEqual(temp_inner_product, inner_product_1d))
320 mooseError(
"The 1D input mesh is not perpendicular to the rotation axis.");
324 inner_product_1d_initialized =
true;
325 inner_product_1d = temp_inner_product;
332 if (!node_ids_on_axis.empty())
335 std::sort(node_ids_on_axis.begin(), node_ids_on_axis.end());
337 std::set<subdomain_id_type> converted_quad8_subdomain_ids;
338 for (
const auto & elem : input->element_ptr_range())
340 if (elem->type() ==
QUAD8)
342 std::vector<dof_id_type> elem_vertex_node_ids;
343 for (
unsigned int i = 0; i < 4; i++)
345 elem_vertex_node_ids.push_back(elem->node_id(i));
347 std::sort(elem_vertex_node_ids.begin(), elem_vertex_node_ids.end());
348 std::vector<dof_id_type> common_node_ids;
349 std::set_intersection(node_ids_on_axis.begin(),
350 node_ids_on_axis.end(),
351 elem_vertex_node_ids.begin(),
352 elem_vertex_node_ids.end(),
353 std::back_inserter(common_node_ids));
355 if (common_node_ids.size() == 1)
358 elem->subdomain_id() += quad_to_hi_pyramid_subdomain_id_shift;
359 converted_quad8_subdomain_ids.emplace(elem->subdomain_id());
364 input->all_second_order_range(
365 input->active_subdomain_set_elements_ptr_range(converted_quad8_subdomain_ids));
368 for (
auto elem : input->active_subdomain_set_elements_ptr_range(converted_quad8_subdomain_ids))
369 elem->subdomain_id() -= quad_to_hi_pyramid_subdomain_id_shift;
376 #ifdef LIBMESH_ENABLE_UNIQUE_ID 379 unique_id_type orig_unique_ids = input->parallel_max_unique_id() + orig_elem;
385 unsigned int order = 1;
388 const BoundaryInfo & input_boundary_info = input->get_boundary_info();
390 const unsigned int total_num_azimuthal_intervals =
395 const dof_id_type elem_id_shift = total_num_azimuthal_intervals * orig_elem;
399 std::vector<ElemType> types;
400 MeshTools::elem_types(*input, types);
401 for (
const auto elem_type : types)
402 if (higher_orders.count(elem_type))
407 std::vector<Real> azi_array;
410 const Real section_start_angle =
411 azi_array.empty() ? 0.0 : (azi_array.back() +
_unit_angles.back());
422 for (
const auto & node : input->node_ptr_range())
431 std::vector<boundary_id_type> ids_to_copy;
434 Point current_distance;
439 [](
auto &
c) {
return c * (-1.0) * M_PI / 180.0; });
444 [](
auto &
c) {
return c * M_PI / 180.0; });
445 std::vector<dof_id_type> nodes_on_axis;
447 for (
const auto & node : input->node_ptr_range())
452 const bool isOnAxis = MooseUtils::absoluteFuzzyEqual(radius_and_center.first, 0.0);
455 nodes_on_axis.push_back(node->id());
458 unsigned int current_node_layer = 0;
463 for (
unsigned int e = 0; e < num_rotations; e++)
469 const auto base_angle =
473 for (
unsigned int k = 0;
474 k < order * num_layers + (e == 0 ? 1 : 0) -
478 bool is_node_created(
false);
482 if (e == 0 &&
k == 0)
483 current_distance.
zero();
486 auto layer_index = (
k - (e == 0 ? 1 : 0)) + 1;
489 const Point vector_xy =
490 Point(-2.0 * radius_and_center.first *
491 std::sin((base_angle + angle * (
Real)layer_index) / 2.0) *
492 std::sin((base_angle + angle * (
Real)layer_index) / 2.0),
493 2.0 * radius_and_center.first *
494 std::sin((base_angle + angle * (
Real)layer_index) / 2.0) *
495 std::cos((base_angle + angle * (
Real)layer_index) / 2.0),
497 current_distance =
Point(rotation_vectors[0] * vector_xy,
498 rotation_vectors[1] * vector_xy,
499 rotation_vectors[2] * vector_xy);
502 is_node_created =
true;
504 else if (e == 0 &&
k == 0)
507 current_distance.
zero();
508 is_node_created =
true;
514 node->id() + (current_node_layer * orig_nodes),
515 node->processor_id());
516 #ifdef LIBMESH_ENABLE_UNIQUE_ID 521 (current_node_layer == 0)
523 : (orig_unique_ids + (current_node_layer - 1) * (orig_nodes + orig_elem * 2) +
530 boundary_info.
add_node(new_node, ids_to_copy);
532 for (
const auto & id_to_copy : ids_to_copy)
539 current_node_layer++;
544 for (
const auto & elem : input->element_ptr_range())
546 const ElemType etype = elem->type();
549 mooseAssert(!elem->parent(),
"RevolveGenerator only works on coarse meshes.");
551 unsigned int current_layer = 0;
555 for (
unsigned int e = 0; e < num_rotations; e++)
559 for (
unsigned int k = 0;
k < num_layers; ++
k)
561 std::unique_ptr<Elem> new_elem;
562 std::unique_ptr<Elem> new_elem_1;
563 bool is_flipped(
false);
566 bool is_flipped_additional(
false);
568 std::vector<std::pair<dof_id_type, dof_id_type>> side_pairs;
579 if (nodes_cates.first.empty())
587 total_num_azimuthal_intervals,
600 total_num_azimuthal_intervals,
615 if (nodes_cates.first.empty())
623 total_num_azimuthal_intervals,
636 total_num_azimuthal_intervals,
653 if (nodes_cates.first.empty())
661 total_num_azimuthal_intervals,
665 else if (nodes_cates.first.size() == 1)
674 total_num_azimuthal_intervals,
679 else if (nodes_cates.first.size() == 2)
688 total_num_azimuthal_intervals,
694 mooseError(
"A degenerate TRI3 elements overlapped with the rotation axis cannot be " 710 if (nodes_cates.first.empty())
718 total_num_azimuthal_intervals,
722 else if (nodes_cates.first.size() == 1)
731 total_num_azimuthal_intervals,
736 else if (nodes_cates.first.size() == 3)
745 total_num_azimuthal_intervals,
752 "You either have a degenerate TRI6 element, or the mid-point of the " 753 "on-axis edge is not colinear with the two vertices, which is not supported.");
767 if (nodes_cates.first.empty())
775 total_num_azimuthal_intervals,
779 else if (nodes_cates.first.size() == 1)
788 total_num_azimuthal_intervals,
793 else if (nodes_cates.first.size() == 3)
802 total_num_azimuthal_intervals,
808 mooseError(
"You either have a degenerate TRI6 element, or the mid-point of the " 809 "on-axis edge of the TRI6 element is not colinear with the two vertices, " 810 "which is not supported.");
823 if (nodes_cates.first.empty())
831 total_num_azimuthal_intervals,
835 else if (nodes_cates.first.size() == 1)
846 total_num_azimuthal_intervals,
850 is_flipped_additional);
852 else if (nodes_cates.first.size() == 2)
861 total_num_azimuthal_intervals,
868 mooseError(
"Degenerate QUAD4 element with 3 or more aligned nodes cannot be " 869 "azimuthally revolved");
885 if (nodes_cates.first.empty())
893 total_num_azimuthal_intervals,
897 else if (nodes_cates.first.size() == 3)
906 total_num_azimuthal_intervals,
912 mooseError(
"You either have a degenerate QUAD8 element, or the mid-point of the " 913 "on-axis edge of the QUAD8 element is not colinear with the two vertices, " 914 "which is not supported.");
930 if (nodes_cates.first.empty())
938 total_num_azimuthal_intervals,
942 else if (nodes_cates.first.size() == 1)
953 total_num_azimuthal_intervals,
957 is_flipped_additional);
959 else if (nodes_cates.first.size() == 3)
968 total_num_azimuthal_intervals,
974 mooseError(
"You either have a degenerate QUAD9 element, or the mid-point of the " 975 "on-axis edge of the QUAD9 element is not colinear with the two vertices, " 976 "which is not supported.");
980 mooseError(
"The input mesh contains unsupported element type(s).");
982 new_elem->set_id(elem->id() + (current_layer * orig_elem));
983 new_elem->processor_id() = elem->processor_id();
986 new_elem_1->set_id(elem->id() + (current_layer * orig_elem) + elem_id_shift);
987 new_elem_1->processor_id() = elem->processor_id();
990 #ifdef LIBMESH_ENABLE_UNIQUE_ID 997 : (orig_unique_ids + (current_layer - 1) * (orig_nodes + orig_elem * 2) +
998 orig_nodes + elem->id());
1000 new_elem->set_unique_id(uid);
1006 (current_layer == 0)
1007 ? (elem->id() + orig_unique_ids - orig_elem)
1008 : (orig_unique_ids + (current_layer - 1) * (orig_nodes + orig_elem * 2) +
1009 orig_nodes + orig_elem + elem->id());
1011 new_elem_1->set_unique_id(uid_1);
1019 switch (new_elem->type())
1022 new_elem->subdomain_id() = elem->subdomain_id();
1025 new_elem->subdomain_id() = edge_to_tri_subdomain_id_shift + elem->subdomain_id();
1029 "impossible element type generated by revolving an EDGE2 element");
1033 switch (new_elem->type())
1036 new_elem->subdomain_id() = elem->subdomain_id();
1039 new_elem->subdomain_id() = edge_to_tri_subdomain_id_shift + elem->subdomain_id();
1043 "impossible element type generated by revolving an EDGE3 element");
1047 switch (new_elem->type())
1050 new_elem->subdomain_id() = elem->subdomain_id();
1053 new_elem->subdomain_id() = tri_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1056 new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id();
1059 mooseAssert(
false,
"impossible element type generated by revolving a TRI3 element");
1063 switch (new_elem->type())
1066 new_elem->subdomain_id() = elem->subdomain_id();
1069 new_elem->subdomain_id() = tri_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1072 new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id();
1075 mooseAssert(
false,
"impossible element type generated by revolving a TRI6 element");
1079 switch (new_elem->type())
1082 new_elem->subdomain_id() = elem->subdomain_id();
1085 new_elem->subdomain_id() = tri_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1088 new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id();
1091 mooseAssert(
false,
"impossible element type generated by revolving a TRI7 element");
1095 switch (new_elem->type())
1098 new_elem->subdomain_id() = elem->subdomain_id();
1101 new_elem->subdomain_id() = quad_to_prism_subdomain_id_shift + elem->subdomain_id();
1104 new_elem->subdomain_id() =
1105 quad_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1106 new_elem_1->subdomain_id() =
1107 quad_to_prism_subdomain_id_shift + elem->subdomain_id();
1111 "impossible element type generated by revolving a QUAD4 element");
1115 switch (new_elem->type())
1118 new_elem->subdomain_id() = elem->subdomain_id();
1121 new_elem->subdomain_id() = quad_to_prism_subdomain_id_shift + elem->subdomain_id();
1125 "impossible element type generated by revolving a QUAD8 element");
1129 switch (new_elem->type())
1132 new_elem->subdomain_id() = elem->subdomain_id();
1135 new_elem->subdomain_id() =
1136 quad_to_hi_pyramid_subdomain_id_shift + elem->subdomain_id();
1139 new_elem->subdomain_id() =
1140 quad_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1141 new_elem_1->subdomain_id() =
1142 quad_to_hi_pyramid_subdomain_id_shift + elem->subdomain_id();
1146 "impossible element type generated by revolving a QUAD9 element");
1151 "The input mesh contains unsupported element type(s), which should have " 1152 "been checked in prior steps in this code.");
1159 auto new_id_it = revolving_swap_pairs.find(elem->subdomain_id());
1161 if (new_id_it != revolving_swap_pairs.end())
1163 new_elem->subdomain_id() =
1164 new_elem->subdomain_id() - elem->subdomain_id() + new_id_it->second;
1166 new_elem_1->subdomain_id() =
1167 new_elem_1->subdomain_id() - elem->subdomain_id() + new_id_it->second;
1172 Elem * added_elem_1 = NULL;
1178 for (
unsigned int i = 0; i < num_extra_elem_integers; i++)
1189 auto & elevation_extra_swap_pairs =
1192 auto new_extra_id_it = elevation_extra_swap_pairs.find(
1195 if (new_extra_id_it != elevation_extra_swap_pairs.end())
1198 new_extra_id_it->second);
1201 new_extra_id_it->second);
1207 for (
auto s : elem->side_index_range())
1209 input_boundary_info.
boundary_ids(elem, s, ids_to_copy);
1210 std::vector<boundary_id_type> ids_to_copy_swapped;
1212 ids_to_copy_swapped = ids_to_copy;
1214 for (
const auto & id_to_copy : ids_to_copy)
1222 switch (added_elem->
type())
1226 added_elem, cast_int<unsigned short>(s == 0 ? 3 : 1), ids_to_copy_swapped);
1229 if (s != axis_node_case)
1231 added_elem, cast_int<unsigned short>(s), ids_to_copy_swapped);
1235 "impossible element type generated by revolving an EDGE2 element");
1239 switch (added_elem->
type())
1243 added_elem, cast_int<unsigned short>(s == 0 ? 3 : 1), ids_to_copy_swapped);
1246 if (s != axis_node_case)
1248 added_elem, cast_int<unsigned short>(s), ids_to_copy_swapped);
1252 "impossible element type generated by revolving an EDGE3 element");
1256 switch (added_elem->
type())
1260 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1263 if ((s + 3 - axis_node_case) % 3 == 0)
1265 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1266 else if ((s + 3 - axis_node_case) % 3 == 1)
1268 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1271 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1274 if ((s + 3 - axis_node_case) % 3 == 0)
1276 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1277 else if ((s + 3 - axis_node_case) % 3 == 2)
1279 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1283 "impossible element type generated by revolving a TRI3 element");
1287 switch (added_elem->
type())
1291 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1294 if ((s + 3 - axis_node_case) % 3 == 0)
1296 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1297 else if ((s + 3 - axis_node_case) % 3 == 1)
1299 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1302 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1305 if ((s + 3 - axis_node_case) % 3 == 0)
1307 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1308 else if ((s + 3 - axis_node_case) % 3 == 2)
1310 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1314 "impossible element type generated by revolving a TRI6 element");
1318 switch (added_elem->
type())
1322 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1325 if ((s + 3 - axis_node_case) % 3 == 0)
1327 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1328 else if ((s + 3 - axis_node_case) % 3 == 1)
1330 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1333 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1336 if ((s + 3 - axis_node_case) % 3 == 0)
1338 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1339 else if ((s + 3 - axis_node_case) % 3 == 2)
1341 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1345 "impossible element type generated by revolving a TRI7 element");
1349 switch (added_elem->
type())
1353 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1356 if ((s + 4 - axis_node_case) % 4 == 1)
1358 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1359 else if ((s + 4 - axis_node_case) % 4 == 2)
1361 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1362 else if ((s + 4 - axis_node_case) % 4 == 3)
1364 added_elem, cast_int<unsigned short>(0), ids_to_copy_swapped);
1367 if ((s + 4 - axis_node_case) % 4 == 3)
1369 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1370 else if ((s + 4 - axis_node_case) % 4 == 0)
1372 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1373 else if ((s + 4 - axis_node_case) % 4 == 1)
1375 added_elem_1, cast_int<unsigned short>(3), ids_to_copy_swapped);
1378 added_elem_1, cast_int<unsigned short>(2), ids_to_copy_swapped);
1382 "impossible element type generated by revolving a QUAD4 element");
1386 switch (added_elem->
type())
1390 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1393 if ((s + 4 - axis_node_case) % 4 == 1)
1395 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1396 else if ((s + 4 - axis_node_case) % 4 == 2)
1398 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1399 else if ((s + 4 - axis_node_case) % 4 == 3)
1401 added_elem, cast_int<unsigned short>(0), ids_to_copy_swapped);
1405 "impossible element type generated by revolving a QUAD8 element");
1409 switch (added_elem->
type())
1413 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1416 if ((s + 4 - axis_node_case) % 4 == 1)
1418 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1419 else if ((s + 4 - axis_node_case) % 4 == 2)
1421 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1422 else if ((s + 4 - axis_node_case) % 4 == 3)
1424 added_elem, cast_int<unsigned short>(0), ids_to_copy_swapped);
1427 if ((s + 4 - axis_node_case) % 4 == 3)
1429 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1430 else if ((s + 4 - axis_node_case) % 4 == 0)
1432 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1433 else if ((s + 4 - axis_node_case) % 4 == 1)
1435 added_elem_1, cast_int<unsigned short>(3), ids_to_copy_swapped);
1438 added_elem_1, cast_int<unsigned short>(2), ids_to_copy_swapped);
1442 "impossible element type generated by revolving a QUAD9 element");
1447 "The input mesh contains unsupported element type(s), which should have " 1448 "been checked in prior steps in this code.");
1455 added_elem, is_flipped ? side_pairs[0].second : side_pairs[0].first,
_start_boundary);
1456 if (side_pairs.size() > 1)
1457 boundary_info.
add_side(added_elem_1,
1458 is_flipped_additional ? side_pairs[1].second
1459 : side_pairs[1].first,
1466 added_elem, is_flipped ? side_pairs[0].first : side_pairs[0].second,
_end_boundary);
1467 if (side_pairs.size() > 1)
1468 boundary_info.
add_side(added_elem_1,
1469 is_flipped_additional ? side_pairs[1].first
1470 : side_pairs[1].second,
1478 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1481 unsigned int total_new_node_layers = total_num_azimuthal_intervals * order;
1482 unsigned int new_unique_ids = orig_unique_ids + (total_new_node_layers - 1) * orig_elem * 2 +
1483 total_new_node_layers * orig_nodes;
1488 if (!input_subdomain_map.empty())
1490 if (!input_sideset_map.empty())
1492 input_sideset_map.end());
1493 if (!input_nodeset_map.empty())
1495 input_nodeset_map.end());
1504 std::pair<Real, Point>
1506 const Point & p_axis,
1507 const Point & dir_axis)
const 1511 const Real dist = (p_ext - p_axis) * dir_axis.
unit();
1512 const Point center_pt = p_axis + dist * dir_axis.
unit();
1515 return std::make_pair(
radius, center_pt);
1520 const Point & dir_axis,
1521 const Point & p_input)
const 1528 const Point x_prime = ((p_input - p_axis) - ((p_input - p_axis) * z_prime) * z_prime).
unit();
1529 const Point y_prime = z_prime.
cross(x_prime);
1532 return {{x_prime(0), y_prime(0), z_prime(0)},
1533 {x_prime(1), y_prime(1), z_prime(1)},
1534 {x_prime(2), y_prime(2), z_prime(2)}};
1537 std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>>
1539 const std::vector<dof_id_type> & nodes_on_axis)
const 1541 std::vector<dof_id_type> nodes_on_axis_in_elem;
1542 std::vector<dof_id_type> nodes_not_on_axis_in_elem;
1543 for (
unsigned int i = 0; i < elem.
n_nodes(); i++)
1545 const auto node_id = elem.
node_id(i);
1546 if (std::find(nodes_on_axis.begin(), nodes_on_axis.end(), node_id) != nodes_on_axis.end())
1548 nodes_on_axis_in_elem.push_back(i);
1552 nodes_not_on_axis_in_elem.push_back(i);
1555 return std::make_pair(nodes_on_axis_in_elem, nodes_not_on_axis_in_elem);
1561 const Point axis_component =
1564 node =
_axis_point + axis_component + rad_component;
1570 const std::unique_ptr<MeshBase> & mesh,
1571 std::unique_ptr<Elem> & new_elem,
1572 const int current_layer,
1573 const unsigned int orig_nodes,
1574 const unsigned int total_num_azimuthal_intervals,
1575 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1576 bool & is_flipped)
const 1578 if (quad_elem_type !=
QUAD4 && quad_elem_type !=
QUAD9)
1579 mooseError(
"Unsupported element type", quad_elem_type);
1581 side_pairs.push_back(std::make_pair(0, 2));
1582 const unsigned int order = quad_elem_type ==
QUAD4 ? 1 : 2;
1584 new_elem = std::make_unique<Quad4>();
1585 if (quad_elem_type ==
QUAD9)
1587 new_elem = std::make_unique<Quad9>();
1588 new_elem->set_node(4,
1595 ((current_layer + 1) %
1611 ((current_layer + 1) %
1613 order * orig_nodes)));
1617 ((current_layer + 1) %
1619 order * orig_nodes)));
1621 if (new_elem->volume() < 0.0)
1625 if (quad_elem_type ==
QUAD9)
1633 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
1636 const std::unique_ptr<MeshBase> & mesh,
1637 std::unique_ptr<Elem> & new_elem,
1638 const int current_layer,
1639 const unsigned int orig_nodes,
1640 const unsigned int total_num_azimuthal_intervals,
1641 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1643 bool & is_flipped)
const 1645 if (tri_elem_type !=
TRI3 && tri_elem_type !=
TRI7)
1646 mooseError(
"Unsupported element type", tri_elem_type);
1648 side_pairs.push_back(std::make_pair(0, 2));
1649 const unsigned int order = tri_elem_type ==
TRI3 ? 1 : 2;
1650 axis_node_case = nodes_cates.first.front();
1652 new_elem = std::make_unique<Tri3>();
1653 if (tri_elem_type ==
TRI7)
1655 new_elem = std::make_unique<Tri7>();
1656 new_elem->set_node(3,
1658 new_elem->set_node(4,
1660 ((current_layer * 2 + 1) * orig_nodes)));
1664 ((current_layer + 1) %
1672 new_elem->set_node(1,
1674 (current_layer * order * orig_nodes)));
1678 ((current_layer + 1) %
1680 order * orig_nodes)));
1682 if (new_elem->volume() < 0.0)
1685 if (tri_elem_type ==
TRI7)
1694 const std::unique_ptr<MeshBase> & mesh,
1695 std::unique_ptr<Elem> & new_elem,
1696 const int current_layer,
1697 const unsigned int orig_nodes,
1698 const unsigned int total_num_azimuthal_intervals,
1699 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1700 bool & is_flipped)
const 1705 side_pairs.push_back(std::make_pair(0, 4));
1706 const unsigned int order = prism_elem_type ==
PRISM6 ? 1 : 2;
1708 new_elem = std::make_unique<Prism6>();
1712 new_elem = std::make_unique<Prism18>();
1713 if (prism_elem_type ==
PRISM21)
1715 new_elem = std::make_unique<Prism21>();
1721 (total_num_azimuthal_intervals + 1 -
1727 new_elem->set_node(6,
1729 new_elem->set_node(7,
1731 new_elem->set_node(8,
1742 ((current_layer + 1) %
1748 ((current_layer + 1) %
1754 ((current_layer + 1) %
1773 ((current_layer + 1) %
1775 order * orig_nodes)));
1779 ((current_layer + 1) %
1781 order * orig_nodes)));
1785 ((current_layer + 1) %
1787 order * orig_nodes)));
1789 if (new_elem->volume() < 0.0)
1794 if (prism_elem_type !=
PRISM6)
1799 if (prism_elem_type ==
PRISM21)
1810 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
1813 const std::unique_ptr<MeshBase> & mesh,
1814 std::unique_ptr<Elem> & new_elem,
1815 const int current_layer,
1816 const unsigned int orig_nodes,
1817 const unsigned int total_num_azimuthal_intervals,
1818 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1820 bool & is_flipped)
const 1826 side_pairs.push_back(std::make_pair(0, 2));
1827 const unsigned int order = pyramid_elem_type ==
PYRAMID5 ? 1 : 2;
1828 axis_node_case = nodes_cates.first.front();
1830 new_elem = std::make_unique<Pyramid5>();
1834 new_elem = std::make_unique<Pyramid13>();
1837 new_elem = std::make_unique<Pyramid18>();
1838 new_elem->set_node(13,
1840 ((current_layer * 2 + 1) * orig_nodes)));
1841 new_elem->set_node(15,
1843 ((current_layer * 2 + 1) * orig_nodes)));
1844 new_elem->set_node(17,
1846 ((current_layer * 2 + 1) * orig_nodes)));
1852 (total_num_azimuthal_intervals + 1 -
1856 new_elem->set_node(6,
1858 ((current_layer * 2 + 1) * orig_nodes)));
1859 new_elem->set_node(8,
1861 ((current_layer * 2 + 1) * orig_nodes)));
1862 new_elem->set_node(5,
1864 (current_layer * 2 * orig_nodes)));
1868 ((current_layer + 1) %
1871 new_elem->set_node(9,
1873 (current_layer * 2 * orig_nodes)));
1874 new_elem->set_node(10,
1876 (current_layer * 2 * orig_nodes)));
1880 ((current_layer + 1) %
1886 ((current_layer + 1) %
1891 new_elem->set_node(0,
1893 (current_layer * order * orig_nodes)));
1894 new_elem->set_node(1,
1896 (current_layer * order * orig_nodes)));
1900 ((current_layer + 1) %
1902 order * orig_nodes)));
1906 ((current_layer + 1) %
1908 order * orig_nodes)));
1910 if (new_elem->volume() < 0.0)
1930 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
1933 const std::unique_ptr<MeshBase> & mesh,
1934 std::unique_ptr<Elem> & new_elem,
1935 const int current_layer,
1936 const unsigned int orig_nodes,
1937 const unsigned int total_num_azimuthal_intervals,
1938 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
1940 bool & is_flipped)
const 1942 if (tet_elem_type !=
TET4 && tet_elem_type !=
TET10 && tet_elem_type !=
TET14)
1945 side_pairs.push_back(std::make_pair(0, 1));
1946 const unsigned int order = tet_elem_type ==
TET4 ? 1 : 2;
1950 if (nodes_cates.first[0] > 2 || nodes_cates.first[1] > 2 || nodes_cates.first[2] < 3)
1953 axis_node_case = nodes_cates.second.front();
1955 new_elem = std::make_unique<Tet4>();
1958 const bool node_order = nodes_cates.first[1] - nodes_cates.first[0] == 1;
1959 new_elem = std::make_unique<Tet10>();
1960 if (tet_elem_type ==
TET14)
1962 new_elem = std::make_unique<Tet14>();
1966 : (nodes_cates.second.front() + 3))
1968 ((current_layer * 2 + 1) * orig_nodes)));
1969 new_elem->set_node(13,
1971 : (nodes_cates.first[0] + 3))
1973 ((current_layer * 2 + 1) * orig_nodes)));
1979 (total_num_azimuthal_intervals + 1 -
1983 new_elem->set_node(4,
1985 : (nodes_cates.first[1] + 3))
1987 new_elem->set_node(5,
1989 : (nodes_cates.second.front() + 3))
1991 (current_layer * 2 * orig_nodes)));
1992 new_elem->set_node(6,
1994 : (nodes_cates.first[0] + 3))
1996 (current_layer * 2 * orig_nodes)));
2000 : (nodes_cates.second.front() + 3))
2002 ((current_layer + 1) %
2008 : (nodes_cates.first[0] + 3))
2010 ((current_layer + 1) %
2013 new_elem->set_node(9,
2015 ((current_layer * 2 + 1) * orig_nodes)));
2019 new_elem->set_node(2,
2021 (current_layer * order * orig_nodes)));
2025 ((current_layer + 1) %
2027 order * orig_nodes)));
2029 if (new_elem->volume() < 0.0)
2036 if (tet_elem_type ==
TET14)
2048 const std::unique_ptr<MeshBase> & mesh,
2049 std::unique_ptr<Elem> & new_elem,
2050 const int current_layer,
2051 const unsigned int orig_nodes,
2052 const unsigned int total_num_azimuthal_intervals,
2053 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
2054 bool & is_flipped)
const 2056 if (hex_elem_type !=
HEX8 && hex_elem_type !=
HEX20 && hex_elem_type !=
HEX27)
2059 side_pairs.push_back(std::make_pair(0, 5));
2060 const unsigned int order = hex_elem_type ==
HEX8 ? 1 : 2;
2062 new_elem = std::make_unique<Hex8>();
2065 new_elem = std::make_unique<Hex20>();
2066 if (hex_elem_type ==
HEX27)
2068 new_elem = std::make_unique<Hex27>();
2074 (total_num_azimuthal_intervals + 1 -
2088 new_elem->set_node(8,
2090 new_elem->set_node(9,
2092 new_elem->set_node(10,
2094 new_elem->set_node(11,
2099 ((current_layer + 1) %
2105 ((current_layer + 1) %
2111 ((current_layer + 1) %
2117 ((current_layer + 1) %
2140 ((current_layer + 1) %
2142 order * orig_nodes)));
2146 ((current_layer + 1) %
2148 order * orig_nodes)));
2152 ((current_layer + 1) %
2154 order * orig_nodes)));
2158 ((current_layer + 1) %
2160 order * orig_nodes)));
2162 if (new_elem->volume() < 0.0)
2174 if (hex_elem_type ==
HEX27)
2185 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
2188 const std::unique_ptr<MeshBase> & mesh,
2189 std::unique_ptr<Elem> & new_elem,
2190 const int current_layer,
2191 const unsigned int orig_nodes,
2192 const unsigned int total_num_azimuthal_intervals,
2193 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
2195 bool & is_flipped)
const 2200 side_pairs.push_back(std::make_pair(1, 3));
2201 const unsigned int order = prism_elem_type ==
PRISM6 ? 1 : 2;
2205 if (nodes_cates.first[0] > 3 || nodes_cates.first[1] > 3 || nodes_cates.first[2] < 4)
2210 const dof_id_type min_on_axis = nodes_cates.first[0];
2211 const dof_id_type max_on_axis = nodes_cates.first[1];
2212 axis_node_case = max_on_axis - min_on_axis == 1 ? min_on_axis : max_on_axis;
2214 new_elem = std::make_unique<Prism6>();
2217 new_elem = std::make_unique<Prism15>();
2218 if (prism_elem_type ==
PRISM18)
2220 new_elem = std::make_unique<Prism18>();
2223 new_elem->set_node(16,
2225 ((current_layer * 2 + 1) * orig_nodes)));
2229 (total_num_azimuthal_intervals + 1 -
2234 new_elem->set_node(10,
2236 (current_layer * 2 * orig_nodes)));
2237 new_elem->set_node(12,
2239 (current_layer * 2 * orig_nodes)));
2240 new_elem->set_node(6,
2242 (current_layer * 2 * orig_nodes)));
2246 ((current_layer + 1) %
2252 ((current_layer + 1) %
2258 ((current_layer + 1) %
2261 new_elem->set_node(7,
2263 ((current_layer * 2 + 1) * orig_nodes)));
2264 new_elem->set_node(13,
2266 ((current_layer * 2 + 1) * orig_nodes)));
2270 new_elem->set_node(4,
2272 (current_layer * order * orig_nodes)));
2273 new_elem->set_node(1,
2275 (current_layer * order * orig_nodes)));
2279 ((current_layer + 1) %
2281 order * orig_nodes)));
2285 ((current_layer + 1) %
2287 order * orig_nodes)));
2289 if (new_elem->volume() < 0.0)
2298 if (prism_elem_type ==
PRISM18)
2309 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
2313 const std::unique_ptr<MeshBase> & mesh,
2314 std::unique_ptr<Elem> & new_elem,
2315 std::unique_ptr<Elem> & new_elem_1,
2316 const int current_layer,
2317 const unsigned int orig_nodes,
2318 const unsigned int total_num_azimuthal_intervals,
2319 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
2322 bool & is_flipped_additional)
const 2324 if (!(pyramid_elem_type ==
PYRAMID5 && prism_elem_type ==
PRISM6) &&
2327 const unsigned int order = pyramid_elem_type ==
PYRAMID5 ? 1 : 2;
2329 side_pairs.push_back(std::make_pair(0, 2));
2330 axis_node_case = nodes_cates.first.front();
2331 new_elem = std::make_unique<Pyramid5>();
2334 new_elem = std::make_unique<Pyramid14>();
2335 new_elem->set_node(9,
2337 (current_layer * 2 * orig_nodes)));
2338 new_elem->set_node(10,
2340 (current_layer * 2 * orig_nodes)));
2341 new_elem->set_node(5,
2343 new_elem->set_node(8,
2345 ((current_layer * 2 + 1) * orig_nodes)));
2346 new_elem->set_node(6,
2348 ((current_layer * 2 + 1) * orig_nodes)));
2354 ((current_layer + 1) %
2360 ((current_layer + 1) %
2366 ((current_layer + 1) %
2371 new_elem->set_node(0,
2373 (current_layer * order * orig_nodes)));
2374 new_elem->set_node(1,
2376 (current_layer * order * orig_nodes)));
2380 ((current_layer + 1) %
2382 order * orig_nodes)));
2386 ((current_layer + 1) %
2388 order * orig_nodes)));
2390 if (new_elem->volume() < 0.0)
2403 side_pairs.push_back(std::make_pair(0, 4));
2404 new_elem_1 = std::make_unique<Prism6>();
2405 if (prism_elem_type ==
PRISM18)
2407 new_elem_1 = std::make_unique<Prism18>();
2408 new_elem_1->set_node(
2410 new_elem_1->set_node(8,
2412 (current_layer * 2 * orig_nodes)));
2413 new_elem_1->set_node(7,
2415 (current_layer * 2 * orig_nodes)));
2416 new_elem_1->set_node(9,
2418 ((current_layer * 2 + 1) * orig_nodes)));
2419 new_elem_1->set_node(10,
2421 ((current_layer * 2 + 1) * orig_nodes)));
2422 new_elem_1->set_node(11,
2424 ((current_layer * 2 + 1) * orig_nodes)));
2425 new_elem_1->set_node(
2427 new_elem_1->set_node(17,
2429 ((current_layer * 2 + 1) * orig_nodes)));
2430 new_elem_1->set_node(16,
2432 ((current_layer * 2 + 1) * orig_nodes)));
2433 new_elem_1->set_node(
2436 ((current_layer + 1) %
2439 new_elem_1->set_node(
2442 ((current_layer + 1) %
2445 new_elem_1->set_node(
2448 ((current_layer + 1) %
2452 new_elem_1->set_node(0,
2454 (current_layer * order * orig_nodes)));
2455 new_elem_1->set_node(1,
2457 (current_layer * order * orig_nodes)));
2458 new_elem_1->set_node(2,
2460 (current_layer * order * orig_nodes)));
2461 new_elem_1->set_node(
2464 ((current_layer + 1) %
2466 order * orig_nodes)));
2467 new_elem_1->set_node(
2470 ((current_layer + 1) %
2472 order * orig_nodes)));
2473 new_elem_1->set_node(
2476 ((current_layer + 1) %
2478 order * orig_nodes)));
2480 if (new_elem_1->volume() < 0.0)
2485 if (prism_elem_type ==
PRISM18)
2491 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...
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
void remove_orphaned_nodes()
void paramError(const std::string ¶m, Args... args) const
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 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()
const std::string & name() const
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
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)
TypeVector< typename CompareTypes< Real, T2 >::supertype > cross(const TypeVector< T2 > &v) const
std::map< subdomain_id_type, std::string > & set_subdomain_name_map()
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.
void set_unique_id(unique_id_type new_id)
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
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
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.