214 if (
_input->mesh_dimension() > 2)
215 paramError(
"input",
"This mesh generator only works for 1D and 2D input meshes.");
217 mesh->set_mesh_dimension(
_input->mesh_dimension() + 1);
228 " of 'elem_integer_names_to_swap' is not a valid extra element integer of the "
232 const unsigned int num_extra_elem_integers =
_input->n_elem_integers();
233 std::vector<std::string> id_names;
235 for (
const auto i : make_range(num_extra_elem_integers))
237 id_names.push_back(
_input->get_elem_integer_name(i));
238 if (!
mesh->has_elem_integer(id_names[i]))
239 mesh->add_elem_integer(id_names[i]);
243 const auto & input_subdomain_map =
_input->get_subdomain_name_map();
244 const auto & input_sideset_map =
_input->get_boundary_info().get_sideset_name_map();
245 const auto & input_nodeset_map =
_input->get_boundary_info().get_nodeset_name_map();
247 std::unique_ptr<MeshBase> input = std::move(
_input);
251 if (!input->is_serial())
252 mesh->delete_remote_elements();
255 if (!input->preparation().has_cached_elem_data)
256 input->cache_elem_data();
259 std::set<subdomain_id_type>
blocks;
260 input->subdomain_ids(
blocks,
true);
262 for (
const auto & [bid, tbid] : swap_map)
264 libmesh_ignore(tbid);
265 if (
blocks.count(bid) == 0)
267 "Source subdomain " + std::to_string(bid) +
" was not found in the mesh");
270 std::set<subdomain_id_type> subdomain_ids_set;
271 input->subdomain_ids(subdomain_ids_set);
272 const subdomain_id_type max_subdomain_id = *subdomain_ids_set.rbegin();
273 const subdomain_id_type tri_to_pyramid_subdomain_id_shift =
274 std::max((
int)max_subdomain_id, 1) + 1;
275 const subdomain_id_type tri_to_tet_subdomain_id_shift =
276 std::max((
int)max_subdomain_id, 1) * 2 + 1;
277 const subdomain_id_type quad_to_prism_subdomain_id_shift = std::max((
int)max_subdomain_id, 1) + 1;
278 const subdomain_id_type quad_to_pyramid_subdomain_id_shift =
279 std::max((
int)max_subdomain_id, 1) * 2 + 1;
280 const subdomain_id_type quad_to_hi_pyramid_subdomain_id_shift =
281 std::max((
int)max_subdomain_id, 1) * 3 + 1;
282 const subdomain_id_type edge_to_tri_subdomain_id_shift = std::max((
int)max_subdomain_id, 1) + 1;
288 if (MooseUtils::absoluteFuzzyEqual(axis_centroid_cross.norm(), 0.0))
289 mooseError(
"The input mesh is either across the axis or overlapped with the axis!");
291 Real inner_product_1d(0.0);
292 bool inner_product_1d_initialized(
false);
294 std::vector<dof_id_type> node_ids_on_axis;
295 for (
const auto & node : input->node_ptr_range())
299 if (!MooseUtils::absoluteFuzzyEqual(axis_node_cross.norm(), 0.0))
301 if (MooseUtils::absoluteFuzzyLessThan(axis_node_cross * axis_centroid_cross, 0.0))
302 mooseError(
"The input mesh is across the axis.");
303 else if (MooseUtils::absoluteFuzzyLessThan(axis_node_cross * axis_centroid_cross,
304 axis_centroid_cross.norm() *
305 axis_node_cross.norm()))
306 mooseError(
"The input mesh is not in the same plane with the rotation axis.");
309 node_ids_on_axis.push_back(node->id());
312 if (input->mesh_dimension() == 1)
315 if (inner_product_1d_initialized)
317 if (!MooseUtils::absoluteFuzzyEqual(temp_inner_product, inner_product_1d))
318 mooseError(
"The 1D input mesh is not perpendicular to the rotation axis.");
322 inner_product_1d_initialized =
true;
323 inner_product_1d = temp_inner_product;
330 if (!node_ids_on_axis.empty())
333 std::sort(node_ids_on_axis.begin(), node_ids_on_axis.end());
335 std::set<subdomain_id_type> converted_quad8_subdomain_ids;
336 for (
const auto & elem : input->element_ptr_range())
338 if (elem->type() ==
QUAD8)
340 std::vector<dof_id_type> elem_vertex_node_ids;
341 for (
unsigned int i = 0; i < 4; i++)
343 elem_vertex_node_ids.push_back(elem->node_id(i));
345 std::sort(elem_vertex_node_ids.begin(), elem_vertex_node_ids.end());
346 std::vector<dof_id_type> common_node_ids;
347 std::set_intersection(node_ids_on_axis.begin(),
348 node_ids_on_axis.end(),
349 elem_vertex_node_ids.begin(),
350 elem_vertex_node_ids.end(),
351 std::back_inserter(common_node_ids));
353 if (common_node_ids.size() == 1)
356 elem->subdomain_id() += quad_to_hi_pyramid_subdomain_id_shift;
357 converted_quad8_subdomain_ids.emplace(elem->subdomain_id());
362 input->all_second_order_range(
363 input->active_subdomain_set_elements_ptr_range(converted_quad8_subdomain_ids));
366 for (
auto elem : input->active_subdomain_set_elements_ptr_range(converted_quad8_subdomain_ids))
367 elem->subdomain_id() -= quad_to_hi_pyramid_subdomain_id_shift;
371 dof_id_type orig_elem = input->n_elem();
372 dof_id_type orig_nodes = input->n_nodes();
374#ifdef LIBMESH_ENABLE_UNIQUE_ID
377 unique_id_type orig_unique_ids = input->parallel_max_unique_id() + orig_elem;
383 unsigned int order = 1;
385 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
386 const BoundaryInfo & input_boundary_info = input->get_boundary_info();
388 const unsigned int total_num_azimuthal_intervals =
392 mesh->reserve_elem(total_num_azimuthal_intervals * orig_elem * 2);
393 const dof_id_type elem_id_shift = total_num_azimuthal_intervals * orig_elem;
397 std::vector<ElemType> types;
398 MeshTools::elem_types(*input, types);
399 for (
const auto elem_type : types)
400 if (higher_orders.count(elem_type))
402 mesh->comm().max(order);
405 std::vector<Real> azi_array;
408 const Real section_start_angle =
409 azi_array.empty() ? 0.0 : (azi_array.back() +
_unit_angles.back());
412 azi_array.push_back(section_start_angle +
_unit_angles.back() * (Real)j);
420 for (
const auto & node : input->node_ptr_range())
429 std::vector<boundary_id_type> ids_to_copy;
432 Point current_distance;
437 [](
auto &
c) { return c * (-1.0) * M_PI / 180.0; });
442 [](
auto &
c) { return c * M_PI / 180.0; });
443 std::vector<dof_id_type> nodes_on_axis;
445 for (
const auto & node : input->node_ptr_range())
450 const bool isOnAxis = MooseUtils::absoluteFuzzyEqual(radius_and_center.first, 0.0);
453 nodes_on_axis.push_back(node->id());
456 unsigned int current_node_layer = 0;
461 for (
unsigned int e = 0; e < num_rotations; e++)
467 const auto base_angle =
471 for (
unsigned int k = 0;
472 k < order * num_layers + (e == 0 ? 1 : 0) -
476 bool is_node_created(
false);
480 if (e == 0 && k == 0)
481 current_distance.zero();
484 auto layer_index = (k - (e == 0 ? 1 : 0)) + 1;
487 const Point vector_xy =
488 Point(-2.0 * radius_and_center.first *
489 std::sin((base_angle + angle * (Real)layer_index) / 2.0) *
490 std::sin((base_angle + angle * (Real)layer_index) / 2.0),
491 2.0 * radius_and_center.first *
492 std::sin((base_angle + angle * (Real)layer_index) / 2.0) *
493 std::cos((base_angle + angle * (Real)layer_index) / 2.0),
495 current_distance = Point(rotation_vectors[0] * vector_xy,
496 rotation_vectors[1] * vector_xy,
497 rotation_vectors[2] * vector_xy);
500 is_node_created =
true;
502 else if (e == 0 && k == 0)
505 current_distance.zero();
506 is_node_created =
true;
511 Node * new_node =
mesh->add_point(*node + current_distance,
512 node->id() + (current_node_layer * orig_nodes),
513 node->processor_id());
514#ifdef LIBMESH_ENABLE_UNIQUE_ID
518 const unique_id_type uid =
519 (current_node_layer == 0)
521 : (orig_unique_ids + (current_node_layer - 1) * (orig_nodes + orig_elem * 2) +
523 new_node->set_unique_id(uid);
526 input_boundary_info.boundary_ids(node, ids_to_copy);
528 boundary_info.add_node(new_node, ids_to_copy);
530 for (
const auto & id_to_copy : ids_to_copy)
531 boundary_info.add_node(new_node,
537 current_node_layer++;
542 for (
const auto & elem : input->element_ptr_range())
544 const ElemType etype = elem->type();
547 mooseAssert(!elem->parent(),
"RevolveGenerator only works on coarse meshes.");
549 unsigned int current_layer = 0;
553 for (
unsigned int e = 0; e < num_rotations; e++)
557 for (
unsigned int k = 0; k < num_layers; ++k)
559 std::unique_ptr<Elem> new_elem;
560 std::unique_ptr<Elem> new_elem_1;
561 bool is_flipped(
false);
564 bool is_flipped_additional(
false);
565 dof_id_type axis_node_case(-1);
566 std::vector<std::pair<dof_id_type, dof_id_type>> side_pairs;
577 if (nodes_cates.first.empty())
585 total_num_azimuthal_intervals,
598 total_num_azimuthal_intervals,
613 if (nodes_cates.first.empty())
621 total_num_azimuthal_intervals,
634 total_num_azimuthal_intervals,
651 if (nodes_cates.first.empty())
659 total_num_azimuthal_intervals,
663 else if (nodes_cates.first.size() == 1)
672 total_num_azimuthal_intervals,
677 else if (nodes_cates.first.size() == 2)
686 total_num_azimuthal_intervals,
692 mooseError(
"A degenerate TRI3 elements overlapped with the rotation axis cannot be "
708 if (nodes_cates.first.empty())
716 total_num_azimuthal_intervals,
720 else if (nodes_cates.first.size() == 1)
729 total_num_azimuthal_intervals,
734 else if (nodes_cates.first.size() == 3)
743 total_num_azimuthal_intervals,
750 "You either have a degenerate TRI6 element, or the mid-point of the "
751 "on-axis edge is not colinear with the two vertices, which is not supported.");
765 if (nodes_cates.first.empty())
773 total_num_azimuthal_intervals,
777 else if (nodes_cates.first.size() == 1)
786 total_num_azimuthal_intervals,
791 else if (nodes_cates.first.size() == 3)
800 total_num_azimuthal_intervals,
806 mooseError(
"You either have a degenerate TRI6 element, or the mid-point of the "
807 "on-axis edge of the TRI6 element is not colinear with the two vertices, "
808 "which is not supported.");
821 if (nodes_cates.first.empty())
829 total_num_azimuthal_intervals,
833 else if (nodes_cates.first.size() == 1)
844 total_num_azimuthal_intervals,
848 is_flipped_additional);
850 else if (nodes_cates.first.size() == 2)
859 total_num_azimuthal_intervals,
866 mooseError(
"Degenerate QUAD4 element with 3 or more aligned nodes cannot be "
867 "azimuthally revolved");
883 if (nodes_cates.first.empty())
891 total_num_azimuthal_intervals,
895 else if (nodes_cates.first.size() == 3)
904 total_num_azimuthal_intervals,
910 mooseError(
"You either have a degenerate QUAD8 element, or the mid-point of the "
911 "on-axis edge of the QUAD8 element is not colinear with the two vertices, "
912 "which is not supported.");
928 if (nodes_cates.first.empty())
936 total_num_azimuthal_intervals,
940 else if (nodes_cates.first.size() == 1)
951 total_num_azimuthal_intervals,
955 is_flipped_additional);
957 else if (nodes_cates.first.size() == 3)
966 total_num_azimuthal_intervals,
972 mooseError(
"You either have a degenerate QUAD9 element, or the mid-point of the "
973 "on-axis edge of the QUAD9 element is not colinear with the two vertices, "
974 "which is not supported.");
978 mooseError(
"The input mesh contains unsupported element type(s).");
980 new_elem->set_id(elem->id() + (current_layer * orig_elem));
981 new_elem->processor_id() = elem->processor_id();
984 new_elem_1->set_id(elem->id() + (current_layer * orig_elem) + elem_id_shift);
985 new_elem_1->processor_id() = elem->processor_id();
988#ifdef LIBMESH_ENABLE_UNIQUE_ID
992 const unique_id_type uid =
995 : (orig_unique_ids + (current_layer - 1) * (orig_nodes + orig_elem * 2) +
996 orig_nodes + elem->id());
998 new_elem->set_unique_id(uid);
1003 const unique_id_type uid_1 =
1004 (current_layer == 0)
1005 ? (elem->id() + orig_unique_ids - orig_elem)
1006 : (orig_unique_ids + (current_layer - 1) * (orig_nodes + orig_elem * 2) +
1007 orig_nodes + orig_elem + elem->id());
1009 new_elem_1->set_unique_id(uid_1);
1017 switch (new_elem->type())
1020 new_elem->subdomain_id() = elem->subdomain_id();
1023 new_elem->subdomain_id() = edge_to_tri_subdomain_id_shift + elem->subdomain_id();
1027 "impossible element type generated by revolving an EDGE2 element");
1031 switch (new_elem->type())
1034 new_elem->subdomain_id() = elem->subdomain_id();
1037 new_elem->subdomain_id() = edge_to_tri_subdomain_id_shift + elem->subdomain_id();
1041 "impossible element type generated by revolving an EDGE3 element");
1045 switch (new_elem->type())
1048 new_elem->subdomain_id() = elem->subdomain_id();
1051 new_elem->subdomain_id() = tri_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1054 new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id();
1057 mooseAssert(
false,
"impossible element type generated by revolving a TRI3 element");
1061 switch (new_elem->type())
1064 new_elem->subdomain_id() = elem->subdomain_id();
1067 new_elem->subdomain_id() = tri_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1070 new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id();
1073 mooseAssert(
false,
"impossible element type generated by revolving a TRI6 element");
1077 switch (new_elem->type())
1080 new_elem->subdomain_id() = elem->subdomain_id();
1083 new_elem->subdomain_id() = tri_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1086 new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id();
1089 mooseAssert(
false,
"impossible element type generated by revolving a TRI7 element");
1093 switch (new_elem->type())
1096 new_elem->subdomain_id() = elem->subdomain_id();
1099 new_elem->subdomain_id() = quad_to_prism_subdomain_id_shift + elem->subdomain_id();
1102 new_elem->subdomain_id() =
1103 quad_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1104 new_elem_1->subdomain_id() =
1105 quad_to_prism_subdomain_id_shift + elem->subdomain_id();
1109 "impossible element type generated by revolving a QUAD4 element");
1113 switch (new_elem->type())
1116 new_elem->subdomain_id() = elem->subdomain_id();
1119 new_elem->subdomain_id() = quad_to_prism_subdomain_id_shift + elem->subdomain_id();
1123 "impossible element type generated by revolving a QUAD8 element");
1127 switch (new_elem->type())
1130 new_elem->subdomain_id() = elem->subdomain_id();
1133 new_elem->subdomain_id() =
1134 quad_to_hi_pyramid_subdomain_id_shift + elem->subdomain_id();
1137 new_elem->subdomain_id() =
1138 quad_to_pyramid_subdomain_id_shift + elem->subdomain_id();
1139 new_elem_1->subdomain_id() =
1140 quad_to_hi_pyramid_subdomain_id_shift + elem->subdomain_id();
1144 "impossible element type generated by revolving a QUAD9 element");
1149 "The input mesh contains unsupported element type(s), which should have "
1150 "been checked in prior steps in this code.");
1157 auto new_id_it = revolving_swap_pairs.find(elem->subdomain_id());
1159 if (new_id_it != revolving_swap_pairs.end())
1161 new_elem->subdomain_id() =
1162 new_elem->subdomain_id() - elem->subdomain_id() + new_id_it->second;
1164 new_elem_1->subdomain_id() =
1165 new_elem_1->subdomain_id() - elem->subdomain_id() + new_id_it->second;
1169 Elem * added_elem =
mesh->add_elem(std::move(new_elem));
1170 Elem * added_elem_1 = NULL;
1173 added_elem_1 =
mesh->add_elem(std::move(new_elem_1));
1176 for (
unsigned int i = 0; i < num_extra_elem_integers; i++)
1178 added_elem->set_extra_integer(i, elem->get_extra_integer(i));
1180 added_elem_1->set_extra_integer(i, elem->get_extra_integer(i));
1187 auto & elevation_extra_swap_pairs =
1190 auto new_extra_id_it = elevation_extra_swap_pairs.find(
1193 if (new_extra_id_it != elevation_extra_swap_pairs.end())
1196 new_extra_id_it->second);
1199 new_extra_id_it->second);
1205 for (
auto s : elem->side_index_range())
1207 input_boundary_info.boundary_ids(elem, s, ids_to_copy);
1208 std::vector<boundary_id_type> ids_to_copy_swapped;
1210 ids_to_copy_swapped = ids_to_copy;
1212 for (
const auto & id_to_copy : ids_to_copy)
1220 switch (added_elem->type())
1223 boundary_info.add_side(
1224 added_elem, cast_int<unsigned short>(s == 0 ? 3 : 1), ids_to_copy_swapped);
1227 if (s != axis_node_case)
1228 boundary_info.add_side(
1229 added_elem, cast_int<unsigned short>(s), ids_to_copy_swapped);
1233 "impossible element type generated by revolving an EDGE2 element");
1237 switch (added_elem->type())
1240 boundary_info.add_side(
1241 added_elem, cast_int<unsigned short>(s == 0 ? 3 : 1), ids_to_copy_swapped);
1244 if (s != axis_node_case)
1245 boundary_info.add_side(
1246 added_elem, cast_int<unsigned short>(s), ids_to_copy_swapped);
1250 "impossible element type generated by revolving an EDGE3 element");
1254 switch (added_elem->type())
1257 boundary_info.add_side(
1258 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1261 if ((s + 3 - axis_node_case) % 3 == 0)
1262 boundary_info.add_side(
1263 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1264 else if ((s + 3 - axis_node_case) % 3 == 1)
1265 boundary_info.add_side(
1266 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1268 boundary_info.add_side(
1269 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1272 if ((s + 3 - axis_node_case) % 3 == 0)
1273 boundary_info.add_side(
1274 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1275 else if ((s + 3 - axis_node_case) % 3 == 2)
1276 boundary_info.add_side(
1277 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1281 "impossible element type generated by revolving a TRI3 element");
1285 switch (added_elem->type())
1288 boundary_info.add_side(
1289 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1292 if ((s + 3 - axis_node_case) % 3 == 0)
1293 boundary_info.add_side(
1294 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1295 else if ((s + 3 - axis_node_case) % 3 == 1)
1296 boundary_info.add_side(
1297 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1299 boundary_info.add_side(
1300 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1303 if ((s + 3 - axis_node_case) % 3 == 0)
1304 boundary_info.add_side(
1305 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1306 else if ((s + 3 - axis_node_case) % 3 == 2)
1307 boundary_info.add_side(
1308 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1312 "impossible element type generated by revolving a TRI6 element");
1316 switch (added_elem->type())
1319 boundary_info.add_side(
1320 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1323 if ((s + 3 - axis_node_case) % 3 == 0)
1324 boundary_info.add_side(
1325 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1326 else if ((s + 3 - axis_node_case) % 3 == 1)
1327 boundary_info.add_side(
1328 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1330 boundary_info.add_side(
1331 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1334 if ((s + 3 - axis_node_case) % 3 == 0)
1335 boundary_info.add_side(
1336 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1337 else if ((s + 3 - axis_node_case) % 3 == 2)
1338 boundary_info.add_side(
1339 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1343 "impossible element type generated by revolving a TRI7 element");
1347 switch (added_elem->type())
1350 boundary_info.add_side(
1351 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1354 if ((s + 4 - axis_node_case) % 4 == 1)
1355 boundary_info.add_side(
1356 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1357 else if ((s + 4 - axis_node_case) % 4 == 2)
1358 boundary_info.add_side(
1359 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1360 else if ((s + 4 - axis_node_case) % 4 == 3)
1361 boundary_info.add_side(
1362 added_elem, cast_int<unsigned short>(0), ids_to_copy_swapped);
1365 if ((s + 4 - axis_node_case) % 4 == 3)
1366 boundary_info.add_side(
1367 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1368 else if ((s + 4 - axis_node_case) % 4 == 0)
1369 boundary_info.add_side(
1370 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1371 else if ((s + 4 - axis_node_case) % 4 == 1)
1372 boundary_info.add_side(
1373 added_elem_1, cast_int<unsigned short>(3), ids_to_copy_swapped);
1375 boundary_info.add_side(
1376 added_elem_1, cast_int<unsigned short>(2), ids_to_copy_swapped);
1380 "impossible element type generated by revolving a QUAD4 element");
1384 switch (added_elem->type())
1387 boundary_info.add_side(
1388 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1391 if ((s + 4 - axis_node_case) % 4 == 1)
1392 boundary_info.add_side(
1393 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1394 else if ((s + 4 - axis_node_case) % 4 == 2)
1395 boundary_info.add_side(
1396 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1397 else if ((s + 4 - axis_node_case) % 4 == 3)
1398 boundary_info.add_side(
1399 added_elem, cast_int<unsigned short>(0), ids_to_copy_swapped);
1403 "impossible element type generated by revolving a QUAD8 element");
1407 switch (added_elem->type())
1410 boundary_info.add_side(
1411 added_elem, cast_int<unsigned short>(s + 1), ids_to_copy_swapped);
1414 if ((s + 4 - axis_node_case) % 4 == 1)
1415 boundary_info.add_side(
1416 added_elem, cast_int<unsigned short>(4), ids_to_copy_swapped);
1417 else if ((s + 4 - axis_node_case) % 4 == 2)
1418 boundary_info.add_side(
1419 added_elem, cast_int<unsigned short>(2), ids_to_copy_swapped);
1420 else if ((s + 4 - axis_node_case) % 4 == 3)
1421 boundary_info.add_side(
1422 added_elem, cast_int<unsigned short>(0), ids_to_copy_swapped);
1425 if ((s + 4 - axis_node_case) % 4 == 3)
1426 boundary_info.add_side(
1427 added_elem, cast_int<unsigned short>(1), ids_to_copy_swapped);
1428 else if ((s + 4 - axis_node_case) % 4 == 0)
1429 boundary_info.add_side(
1430 added_elem, cast_int<unsigned short>(3), ids_to_copy_swapped);
1431 else if ((s + 4 - axis_node_case) % 4 == 1)
1432 boundary_info.add_side(
1433 added_elem_1, cast_int<unsigned short>(3), ids_to_copy_swapped);
1435 boundary_info.add_side(
1436 added_elem_1, cast_int<unsigned short>(2), ids_to_copy_swapped);
1440 "impossible element type generated by revolving a QUAD9 element");
1445 "The input mesh contains unsupported element type(s), which should have "
1446 "been checked in prior steps in this code.");
1452 boundary_info.add_side(
1453 added_elem, is_flipped ? side_pairs[0].second : side_pairs[0].first,
_start_boundary);
1454 if (side_pairs.size() > 1)
1455 boundary_info.add_side(added_elem_1,
1456 is_flipped_additional ? side_pairs[1].second
1457 : side_pairs[1].first,
1463 boundary_info.add_side(
1464 added_elem, is_flipped ? side_pairs[0].first : side_pairs[0].second,
_end_boundary);
1465 if (side_pairs.size() > 1)
1466 boundary_info.add_side(added_elem_1,
1467 is_flipped_additional ? side_pairs[1].first
1468 : side_pairs[1].second,
1476#ifdef LIBMESH_ENABLE_UNIQUE_ID
1479 unsigned int total_new_node_layers = total_num_azimuthal_intervals * order;
1480 unsigned int new_unique_ids = orig_unique_ids + (total_new_node_layers - 1) * orig_elem * 2 +
1481 total_new_node_layers * orig_nodes;
1482 mesh->set_next_unique_id(new_unique_ids);
1486 if (!input_subdomain_map.empty())
1487 mesh->set_subdomain_name_map().insert(input_subdomain_map.begin(), input_subdomain_map.end());
1488 if (!input_sideset_map.empty())
1489 mesh->get_boundary_info().set_sideset_name_map().insert(input_sideset_map.begin(),
1490 input_sideset_map.end());
1491 if (!input_nodeset_map.empty())
1492 mesh->get_boundary_info().set_nodeset_name_map().insert(input_nodeset_map.begin(),
1493 input_nodeset_map.end());
1495 mesh->remove_orphaned_nodes();
1496 mesh->renumber_nodes_and_elements();
1497 mesh->unset_is_prepared();
2307 const std::pair<std::vector<dof_id_type>, std::vector<dof_id_type>> & nodes_cates,
2308 const ElemType pyramid_elem_type,
2309 const ElemType prism_elem_type,
2311 const std::unique_ptr<MeshBase> & mesh,
2312 std::unique_ptr<Elem> & new_elem,
2313 std::unique_ptr<Elem> & new_elem_1,
2314 const int current_layer,
2315 const unsigned int orig_nodes,
2316 const unsigned int total_num_azimuthal_intervals,
2317 std::vector<std::pair<dof_id_type, dof_id_type>> & side_pairs,
2318 dof_id_type & axis_node_case,
2320 bool & is_flipped_additional)
const
2322 if (!(pyramid_elem_type == PYRAMID5 && prism_elem_type == PRISM6) &&
2323 !(pyramid_elem_type == PYRAMID14 && prism_elem_type == PRISM18))
2325 const unsigned int order = pyramid_elem_type == PYRAMID5 ? 1 : 2;
2327 side_pairs.push_back(std::make_pair(0, 2));
2328 axis_node_case = nodes_cates.first.front();
2329 new_elem = std::make_unique<Pyramid5>();
2330 if (pyramid_elem_type == PYRAMID14)
2332 new_elem = std::make_unique<Pyramid14>();
2333 new_elem->set_node(9,
2334 mesh->node_ptr(elem->node_ptr(axis_node_case + 4)->id() +
2335 (current_layer * 2 * orig_nodes)));
2336 new_elem->set_node(10,
2337 mesh->node_ptr(elem->node_ptr((axis_node_case + 3) % 4 + 4)->id() +
2338 (current_layer * 2 * orig_nodes)));
2339 new_elem->set_node(5,
2340 mesh->node_ptr(elem->node_ptr(8)->id() + (current_layer * 2 * orig_nodes)));
2341 new_elem->set_node(8,
2342 mesh->node_ptr(elem->node_ptr((axis_node_case + 1) % 4)->id() +
2343 ((current_layer * 2 + 1) * orig_nodes)));
2344 new_elem->set_node(6,
2345 mesh->node_ptr(elem->node_ptr((axis_node_case + 3) % 4)->id() +
2346 ((current_layer * 2 + 1) * orig_nodes)));
2348 13,
mesh->node_ptr(elem->node_ptr(8)->id() + ((current_layer * 2 + 1) * orig_nodes)));
2351 mesh->node_ptr(elem->node_ptr(8)->id() +
2352 ((current_layer + 1) %
2357 mesh->node_ptr(elem->node_ptr((axis_node_case + 3) % 4 + 4)->id() +
2358 ((current_layer + 1) %
2363 mesh->node_ptr(elem->node_ptr(axis_node_case + 4)->id() +
2364 ((current_layer + 1) %
2368 new_elem->set_node(4,
mesh->node_ptr(elem->node_ptr(axis_node_case)->id()));
2369 new_elem->set_node(0,
2370 mesh->node_ptr(elem->node_ptr((axis_node_case + 1) % 4)->id() +
2371 (current_layer * order * orig_nodes)));
2372 new_elem->set_node(1,
2373 mesh->node_ptr(elem->node_ptr((axis_node_case + 3) % 4)->id() +
2374 (current_layer * order * orig_nodes)));
2377 mesh->node_ptr(elem->node_ptr((axis_node_case + 3) % 4)->id() +
2378 ((current_layer + 1) %
2380 order * orig_nodes)));
2383 mesh->node_ptr(elem->node_ptr((axis_node_case + 1) % 4)->id() +
2384 ((current_layer + 1) %
2386 order * orig_nodes)));
2388 if (new_elem->volume() < 0.0)
2392 if (pyramid_elem_type == PYRAMID14)
2401 side_pairs.push_back(std::make_pair(0, 4));
2402 new_elem_1 = std::make_unique<Prism6>();
2403 if (prism_elem_type == PRISM18)
2405 new_elem_1 = std::make_unique<Prism18>();
2406 new_elem_1->set_node(
2407 6,
mesh->node_ptr(elem->node_ptr(8)->id() + (current_layer * 2 * orig_nodes)));
2408 new_elem_1->set_node(8,
2409 mesh->node_ptr(elem->node_ptr((axis_node_case + 1) % 4 + 4)->id() +
2410 (current_layer * 2 * orig_nodes)));
2411 new_elem_1->set_node(7,
2412 mesh->node_ptr(elem->node_ptr((axis_node_case + 2) % 4 + 4)->id() +
2413 (current_layer * 2 * orig_nodes)));
2414 new_elem_1->set_node(9,
2415 mesh->node_ptr(elem->node_ptr((axis_node_case + 1) % 4)->id() +
2416 ((current_layer * 2 + 1) * orig_nodes)));
2417 new_elem_1->set_node(10,
2418 mesh->node_ptr(elem->node_ptr((axis_node_case + 3) % 4)->id() +
2419 ((current_layer * 2 + 1) * orig_nodes)));
2420 new_elem_1->set_node(11,
2421 mesh->node_ptr(elem->node_ptr((axis_node_case + 2) % 4)->id() +
2422 ((current_layer * 2 + 1) * orig_nodes)));
2423 new_elem_1->set_node(
2424 15,
mesh->node_ptr(elem->node_ptr(8)->id() + ((current_layer * 2 + 1) * orig_nodes)));
2425 new_elem_1->set_node(17,
2426 mesh->node_ptr(elem->node_ptr((axis_node_case + 1) % 4 + 4)->id() +
2427 ((current_layer * 2 + 1) * orig_nodes)));
2428 new_elem_1->set_node(16,
2429 mesh->node_ptr(elem->node_ptr((axis_node_case + 2) % 4 + 4)->id() +
2430 ((current_layer * 2 + 1) * orig_nodes)));
2431 new_elem_1->set_node(
2433 mesh->node_ptr(elem->node_ptr(8)->id() +
2434 ((current_layer + 1) %
2437 new_elem_1->set_node(
2439 mesh->node_ptr(elem->node_ptr((axis_node_case + 2) % 4 + 4)->id() +
2440 ((current_layer + 1) %
2443 new_elem_1->set_node(
2445 mesh->node_ptr(elem->node_ptr((axis_node_case + 1) % 4 + 4)->id() +
2446 ((current_layer + 1) %
2450 new_elem_1->set_node(0,
2451 mesh->node_ptr(elem->node_ptr((axis_node_case + 1) % 4)->id() +
2452 (current_layer * order * orig_nodes)));
2453 new_elem_1->set_node(1,
2454 mesh->node_ptr(elem->node_ptr((axis_node_case + 3) % 4)->id() +
2455 (current_layer * order * orig_nodes)));
2456 new_elem_1->set_node(2,
2457 mesh->node_ptr(elem->node_ptr((axis_node_case + 2) % 4)->id() +
2458 (current_layer * order * orig_nodes)));
2459 new_elem_1->set_node(
2461 mesh->node_ptr(elem->node_ptr((axis_node_case + 1) % 4)->id() +
2462 ((current_layer + 1) %
2464 order * orig_nodes)));
2465 new_elem_1->set_node(
2467 mesh->node_ptr(elem->node_ptr((axis_node_case + 3) % 4)->id() +
2468 ((current_layer + 1) %
2470 order * orig_nodes)));
2471 new_elem_1->set_node(
2473 mesh->node_ptr(elem->node_ptr((axis_node_case + 2) % 4)->id() +
2474 ((current_layer + 1) %
2476 order * orig_nodes)));
2478 if (new_elem_1->volume() < 0.0)
2483 if (prism_elem_type == PRISM18)
2489 is_flipped_additional =
true;