32 const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
33 const dof_id_type elem_id,
34 std::vector<dof_id_type> & converted_elems_ids)
37 BoundaryInfo & boundary_info =
mesh.get_boundary_info();
39 std::vector<std::vector<boundary_id_type>> elem_side_list;
40 elem_side_list.resize(6);
43 const unsigned int n_elem_extra_ids =
mesh.n_elem_integers();
44 std::vector<dof_id_type> exist_extra_ids(n_elem_extra_ids);
46 for (
unsigned int j = 0; j < n_elem_extra_ids; j++)
47 exist_extra_ids[j] =
mesh.elem_ptr(elem_id)->get_extra_integer(j);
49 std::vector<std::vector<unsigned int>> opt_option;
50 std::vector<const Node *> elem_node_list = {
mesh.elem_ptr(elem_id)->node_ptr(0),
51 mesh.elem_ptr(elem_id)->node_ptr(1),
52 mesh.elem_ptr(elem_id)->node_ptr(2),
53 mesh.elem_ptr(elem_id)->node_ptr(3),
54 mesh.elem_ptr(elem_id)->node_ptr(4),
55 mesh.elem_ptr(elem_id)->node_ptr(5),
56 mesh.elem_ptr(elem_id)->node_ptr(6),
57 mesh.elem_ptr(elem_id)->node_ptr(7)};
58 std::vector<std::vector<unsigned int>> rotated_tet_face_indices;
60 std::vector<std::vector<const Node *>> optimized_node_list;
63 std::vector<Elem *> elems_Tet4;
64 for (
const auto i : index_range(optimized_node_list))
66 auto new_elem = std::make_unique<Tet4>();
67 new_elem->set_node(0,
const_cast<Node *
>(optimized_node_list[i][0]));
68 new_elem->set_node(1,
const_cast<Node *
>(optimized_node_list[i][1]));
69 new_elem->set_node(2,
const_cast<Node *
>(optimized_node_list[i][2]));
70 new_elem->set_node(3,
const_cast<Node *
>(optimized_node_list[i][3]));
71 new_elem->subdomain_id() =
mesh.elem_ptr(elem_id)->subdomain_id();
72 elems_Tet4.push_back(
mesh.add_elem(std::move(new_elem)));
73 converted_elems_ids.push_back(elems_Tet4.back()->id());
75 for (
unsigned int j = 0; j < 4; j++)
80 if (rotated_tet_face_indices[i][j] < 6)
82 for (
const auto & side_info : elem_side_list[rotated_tet_face_indices[i][j]])
83 boundary_info.add_side(elems_Tet4.back(), j, side_info);
89 for (
unsigned int i = 0; i < 6; i++)
90 for (
unsigned int j = 0; j < n_elem_extra_ids; j++)
92 elems_Tet4[i]->set_extra_integer(j, exist_extra_ids[j]);
98 const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
99 const dof_id_type elem_id,
100 std::vector<dof_id_type> & converted_elems_ids)
103 BoundaryInfo & boundary_info =
mesh.get_boundary_info();
105 std::vector<std::vector<boundary_id_type>> elem_side_list;
108 const unsigned int n_elem_extra_ids =
mesh.n_elem_integers();
109 std::vector<dof_id_type> exist_extra_ids(n_elem_extra_ids);
112 for (
unsigned int j = 0; j < n_elem_extra_ids; j++)
113 exist_extra_ids[j] =
mesh.elem_ptr(elem_id)->get_extra_integer(j);
115 std::vector<const Node *> elem_node_list = {
mesh.elem_ptr(elem_id)->node_ptr(0),
116 mesh.elem_ptr(elem_id)->node_ptr(1),
117 mesh.elem_ptr(elem_id)->node_ptr(2),
118 mesh.elem_ptr(elem_id)->node_ptr(3),
119 mesh.elem_ptr(elem_id)->node_ptr(4),
120 mesh.elem_ptr(elem_id)->node_ptr(5)};
121 std::vector<std::vector<unsigned int>> rotated_tet_face_indices;
122 std::vector<std::vector<const Node *>> optimized_node_list;
125 std::vector<Elem *> elems_Tet4;
126 for (
const auto i : index_range(optimized_node_list))
128 auto new_elem = std::make_unique<Tet4>();
129 new_elem->set_node(0,
const_cast<Node *
>(optimized_node_list[i][0]));
130 new_elem->set_node(1,
const_cast<Node *
>(optimized_node_list[i][1]));
131 new_elem->set_node(2,
const_cast<Node *
>(optimized_node_list[i][2]));
132 new_elem->set_node(3,
const_cast<Node *
>(optimized_node_list[i][3]));
133 new_elem->subdomain_id() =
mesh.elem_ptr(elem_id)->subdomain_id();
134 elems_Tet4.push_back(
mesh.add_elem(std::move(new_elem)));
135 converted_elems_ids.push_back(elems_Tet4.back()->id());
137 for (
unsigned int j = 0; j < 4; j++)
142 if (rotated_tet_face_indices[i][j] < 5)
144 for (
const auto & side_info : elem_side_list[rotated_tet_face_indices[i][j]])
145 boundary_info.add_side(elems_Tet4.back(), j, side_info);
151 for (
unsigned int i = 0; i < 3; i++)
152 for (
unsigned int j = 0; j < n_elem_extra_ids; j++)
154 elems_Tet4[i]->set_extra_integer(j, exist_extra_ids[j]);
160 const std::vector<libMesh::BoundaryInfo::BCTuple> & bdry_side_list,
161 const dof_id_type elem_id,
162 std::vector<dof_id_type> & converted_elems_ids)
165 BoundaryInfo & boundary_info =
mesh.get_boundary_info();
167 std::vector<std::vector<boundary_id_type>> elem_side_list;
170 const unsigned int n_elem_extra_ids =
mesh.n_elem_integers();
171 std::vector<dof_id_type> exist_extra_ids(n_elem_extra_ids);
173 for (
unsigned int j = 0; j < n_elem_extra_ids; j++)
174 exist_extra_ids[j] =
mesh.elem_ptr(elem_id)->get_extra_integer(j);
176 std::vector<const Node *> elem_node_list = {
mesh.elem_ptr(elem_id)->node_ptr(0),
177 mesh.elem_ptr(elem_id)->node_ptr(1),
178 mesh.elem_ptr(elem_id)->node_ptr(2),
179 mesh.elem_ptr(elem_id)->node_ptr(3),
180 mesh.elem_ptr(elem_id)->node_ptr(4)};
181 std::vector<std::vector<unsigned int>> rotated_tet_face_indices;
182 std::vector<std::vector<const Node *>> optimized_node_list;
185 std::vector<Elem *> elems_Tet4;
186 for (
const auto i : index_range(optimized_node_list))
188 auto new_elem = std::make_unique<Tet4>();
189 new_elem->set_node(0,
const_cast<Node *
>(optimized_node_list[i][0]));
190 new_elem->set_node(1,
const_cast<Node *
>(optimized_node_list[i][1]));
191 new_elem->set_node(2,
const_cast<Node *
>(optimized_node_list[i][2]));
192 new_elem->set_node(3,
const_cast<Node *
>(optimized_node_list[i][3]));
193 new_elem->subdomain_id() =
mesh.elem_ptr(elem_id)->subdomain_id();
194 elems_Tet4.push_back(
mesh.add_elem(std::move(new_elem)));
195 converted_elems_ids.push_back(elems_Tet4.back()->id());
197 for (
unsigned int j = 0; j < 4; j++)
202 if (rotated_tet_face_indices[i][j] < 5)
204 for (
const auto & side_info : elem_side_list[rotated_tet_face_indices[i][j]])
205 boundary_info.add_side(elems_Tet4.back(), j, side_info);
211 for (
unsigned int i = 0; i < 2; i++)
212 for (
unsigned int j = 0; j < n_elem_extra_ids; j++)
214 elems_Tet4[i]->set_extra_integer(j, exist_extra_ids[j]);
291 std::vector<std::vector<unsigned int>> & rotated_tet_face_indices,
292 std::vector<std::vector<const Node *>> & tet_nodes_list)
295 std::vector<dof_id_type> node_ids(8);
296 for (
unsigned int i = 0; i < 8; i++)
297 node_ids[i] = hex_nodes[i]->
id();
299 const unsigned int min_node_id_index = std::distance(
300 std::begin(node_ids), std::min_element(std::begin(node_ids), std::end(node_ids)));
306 const auto neighbor_node_ids = {node_ids[neighbor_node_indices[0]],
307 node_ids[neighbor_node_indices[1]],
308 node_ids[neighbor_node_indices[2]]};
309 const unsigned int sec_min_pos =
310 std::distance(std::begin(neighbor_node_ids),
311 std::min_element(std::begin(neighbor_node_ids), std::end(neighbor_node_ids)));
317 std::vector<unsigned int> face_rotation;
318 std::vector<unsigned int> rotated_indices;
319 nodeRotationHEX8(min_node_id_index, sec_min_pos, face_rotation, rotated_indices);
320 std::vector<const Node *> rotated_hex_nodes;
321 for (
unsigned int i = 0; i < 8; i++)
322 rotated_hex_nodes.push_back(hex_nodes[rotated_indices[i]]);
329 std::vector<std::vector<unsigned int>> tet_face_indices;
330 const auto tet_nodes_set =
tetNodesForHex(diagonal_directions, tet_face_indices);
331 for (
const auto & tet_face_index : tet_face_indices)
333 rotated_tet_face_indices.push_back(std::vector<unsigned int>());
334 for (
const auto & face_index : tet_face_index)
337 rotated_tet_face_indices.back().push_back(face_rotation[face_index]);
339 rotated_tet_face_indices.back().push_back(6);
343 for (
const auto & tet_nodes : tet_nodes_set)
345 tet_nodes_list.push_back(std::vector<const Node *>());
346 for (
const auto & tet_node : tet_nodes)
347 tet_nodes_list.back().push_back(rotated_hex_nodes[tet_node]);
384 std::vector<std::vector<unsigned int>> & tet_face_indices)
386 const std::vector<std::vector<bool>> possible_inputs = {{
true,
true,
true,
true,
true,
false},
387 {
true,
true,
true,
true,
false,
false},
388 {
true,
true,
true,
false,
true,
false},
389 {
true,
false,
true,
true,
true,
false},
390 {
true,
false,
true,
true,
false,
false},
391 {
true,
false,
true,
false,
true,
false},
392 {
true,
false,
true,
false,
false,
false}};
394 const unsigned int input_index = std::distance(
395 std::begin(possible_inputs),
396 std::find(std::begin(possible_inputs), std::end(possible_inputs), diagonal_directions));
402 {0, 6, 2, 6}, {1, 6, 2, 6}, {1, 6, 5, 6}, {0, 6, 3, 4}, {6, 6, 3, 6}, {6, 4, 5, 6}};
403 return {{0, 1, 2, 6}, {0, 5, 1, 6}, {0, 4, 5, 6}, {0, 2, 3, 7}, {0, 6, 2, 7}, {0, 4, 6, 7}};
406 {0, 1, 2, 6}, {6, 6, 2, 6}, {6, 6, 5, 1}, {0, 6, 3, 4}, {6, 6, 3, 6}, {6, 4, 5, 6}};
407 return {{0, 1, 2, 5}, {0, 2, 6, 5}, {0, 6, 4, 5}, {0, 2, 3, 7}, {0, 6, 2, 7}, {0, 4, 6, 7}};
410 {0, 6, 2, 6}, {1, 6, 2, 6}, {1, 6, 5, 6}, {4, 6, 5, 6}, {4, 6, 3, 6}, {0, 6, 3, 6}};
411 return {{0, 1, 2, 6}, {0, 5, 1, 6}, {0, 4, 5, 6}, {0, 7, 4, 6}, {0, 3, 7, 6}, {0, 2, 3, 6}};
414 {4, 6, 5, 1}, {6, 6, 5, 6}, {6, 1, 2, 6}, {4, 0, 3, 6}, {6, 6, 3, 6}, {6, 6, 2, 0}};
415 return {{0, 7, 4, 5}, {0, 6, 7, 5}, {0, 1, 6, 5}, {0, 3, 7, 2}, {0, 7, 6, 2}, {0, 6, 1, 2}};
417 tet_face_indices = {{0, 1, 2, 6}, {0, 6, 3, 4}, {5, 4, 6, 1}, {5, 6, 3, 2}, {6, 6, 6, 6}};
418 return {{0, 1, 2, 5}, {0, 2, 3, 7}, {4, 7, 5, 0}, {5, 7, 6, 2}, {0, 2, 7, 5}};
421 {4, 6, 5, 1}, {6, 6, 5, 6}, {6, 1, 2, 6}, {2, 6, 6, 0}, {3, 6, 6, 0}, {3, 6, 6, 4}};
422 return {{0, 7, 4, 5}, {0, 6, 7, 5}, {0, 1, 6, 5}, {1, 6, 2, 0}, {2, 6, 3, 0}, {3, 6, 7, 0}};
425 {1, 4, 5, 6}, {6, 6, 5, 6}, {6, 6, 3, 4}, {1, 6, 2, 0}, {6, 6, 2, 6}, {6, 0, 3, 6}};
426 return {{0, 4, 5, 7}, {0, 5, 6, 7}, {0, 6, 3, 7}, {0, 5, 1, 2}, {0, 6, 5, 2}, {0, 3, 6, 2}};
434 const unsigned int sec_min_pos,
435 std::vector<unsigned int> & face_rotation,
436 std::vector<unsigned int> & node_rotation)
442 const std::vector<std::vector<std::vector<unsigned int>>> preset_indices = {
443 {{0, 1, 2, 3, 4, 5, 6, 7}, {0, 3, 7, 4, 1, 2, 6, 5}, {0, 4, 5, 1, 3, 7, 6, 2}},
444 {{1, 0, 4, 5, 2, 3, 7, 6}, {1, 2, 3, 0, 5, 6, 7, 4}, {1, 5, 6, 2, 0, 4, 7, 3}},
445 {{2, 3, 0, 1, 6, 7, 4, 5}, {2, 1, 5, 6, 3, 0, 4, 7}, {2, 6, 7, 3, 1, 5, 4, 0}},
446 {{3, 2, 6, 7, 0, 1, 5, 4}, {3, 0, 1, 2, 7, 4, 5, 6}, {3, 7, 4, 0, 2, 6, 5, 1}},
447 {{4, 5, 1, 0, 7, 6, 2, 3}, {4, 7, 6, 5, 0, 3, 2, 1}, {4, 0, 3, 7, 5, 1, 2, 6}},
448 {{5, 4, 7, 6, 1, 0, 3, 2}, {5, 6, 2, 1, 4, 7, 3, 0}, {5, 1, 0, 4, 6, 2, 3, 7}},
449 {{6, 7, 3, 2, 5, 4, 0, 1}, {6, 5, 4, 7, 2, 1, 0, 3}, {6, 2, 1, 5, 7, 3, 0, 4}},
450 {{7, 6, 5, 4, 3, 2, 1, 0}, {7, 4, 0, 3, 6, 5, 1, 2}, {7, 3, 2, 6, 4, 0, 1, 5}}};
452 const std::vector<std::vector<std::vector<unsigned int>>> preset_face_indices = {
453 {{0, 1, 2, 3, 4, 5}, {4, 0, 3, 5, 1, 2}, {1, 4, 5, 2, 0, 3}},
454 {{1, 0, 4, 5, 2, 3}, {0, 2, 3, 4, 1, 5}, {2, 1, 5, 3, 0, 4}},
455 {{0, 3, 4, 1, 2, 5}, {2, 0, 1, 5, 3, 4}, {3, 2, 5, 4, 0, 1}},
456 {{3, 0, 2, 5, 4, 1}, {0, 4, 1, 2, 3, 5}, {4, 3, 5, 1, 0, 2}},
457 {{1, 5, 2, 0, 4, 3}, {5, 4, 3, 2, 1, 0}, {4, 1, 0, 3, 5, 2}},
458 {{5, 1, 4, 3, 2, 0}, {2, 5, 3, 0, 1, 4}, {1, 2, 0, 4, 5, 3}},
459 {{3, 5, 4, 0, 2, 1}, {5, 2, 1, 4, 3, 0}, {2, 3, 0, 1, 5, 4}},
460 {{5, 3, 2, 1, 4, 0}, {4, 5, 1, 0, 3, 2}, {3, 4, 0, 2, 5, 1}}};
462 if (min_id_index > 7 || sec_min_pos > 2)
463 mooseError(
"The input node index is out of range.");
467 face_rotation = preset_face_indices[min_id_index][sec_min_pos];
468 node_rotation = preset_indices[min_id_index][sec_min_pos];
596 std::vector<std::vector<unsigned int>> & rotated_tet_face_indices,
597 std::vector<std::vector<const Node *>> & tet_nodes_list)
600 std::vector<dof_id_type> node_ids(4);
601 for (
unsigned int i = 0; i < 4; i++)
602 node_ids[i] = pyramid_nodes[i]->
id();
604 const unsigned int min_node_id_index = std::distance(
605 std::begin(node_ids), std::min_element(std::begin(node_ids), std::end(node_ids)));
610 std::vector<unsigned int> face_rotation;
611 std::vector<unsigned int> rotated_indices;
613 std::vector<const Node *> rotated_pyramid_nodes;
614 for (
unsigned int i = 0; i < 5; i++)
615 rotated_pyramid_nodes.push_back(pyramid_nodes[rotated_indices[i]]);
618 const std::vector<std::vector<unsigned int>> tet_nodes_set = {{0, 1, 2, 4}, {0, 2, 3, 4}};
619 const std::vector<std::vector<unsigned int>> tet_face_indices = {{4, 0, 1, 5}, {4, 5, 2, 3}};
623 for (
const auto & tet_face_index : tet_face_indices)
625 rotated_tet_face_indices.push_back(std::vector<unsigned int>());
626 for (
const auto & face_index : tet_face_index)
629 rotated_tet_face_indices.back().push_back(face_rotation[face_index]);
631 rotated_tet_face_indices.back().push_back(5);
635 for (
const auto & tet_nodes : tet_nodes_set)
637 tet_nodes_list.push_back(std::vector<const Node *>());
638 for (
const auto & tet_node : tet_nodes)
639 tet_nodes_list.back().push_back(rotated_pyramid_nodes[tet_node]);
1007 const dof_id_type & elem_id,
1008 const std::vector<std::vector<boundary_id_type>> & elem_side_info,
1012 unsigned int lid_index = 0;
1013 for (
const auto & i : make_range(1, 4))
1015 if (
mesh.elem_ptr(elem_id)->side_ptr(4)->node_ptr(i)->id() <
1016 mesh.elem_ptr(elem_id)->side_ptr(4)->node_ptr(lid_index)->id())
1019 auto new_elem_0 = std::make_unique<Tet4>();
1020 new_elem_0->set_node(
1023 new_elem_0->set_node(
1026 new_elem_0->set_node(
1029 new_elem_0->set_node(3,
mesh.elem_ptr(elem_id)->node_ptr(4));
1030 new_elem_0->subdomain_id() =
mesh.elem_ptr(elem_id)->subdomain_id() + subdomain_id_shift_base;
1031 auto new_elem_ptr_0 =
mesh.add_elem(std::move(new_elem_0));
1034 auto new_elem_1 = std::make_unique<Tet4>();
1035 new_elem_1->set_node(
1038 new_elem_1->set_node(
1041 new_elem_1->set_node(
1044 new_elem_1->set_node(3,
mesh.elem_ptr(elem_id)->node_ptr(4));
1045 new_elem_1->subdomain_id() =
mesh.elem_ptr(elem_id)->subdomain_id() + subdomain_id_shift_base;
1046 auto new_elem_ptr_1 =
mesh.add_elem(std::move(new_elem_1));
1049 for (
const auto & bid : elem_side_info[0])
1050 mesh.get_boundary_info().add_side(new_elem_ptr_0, 2 - lid_index % 2, bid);
1051 for (
const auto & bid : elem_side_info[1])
1053 mesh.get_boundary_info().add_side(new_elem_ptr_1, 2, bid);
1055 mesh.get_boundary_info().add_side(new_elem_ptr_0, 1, bid);
1056 for (
const auto & bid : elem_side_info[2])
1057 mesh.get_boundary_info().add_side(new_elem_ptr_1, 2 + lid_index % 2, bid);
1058 for (
const auto & bid : elem_side_info[3])
1060 mesh.get_boundary_info().add_side(new_elem_ptr_0, 1, bid);
1062 mesh.get_boundary_info().add_side(new_elem_ptr_1, 3, bid);
1063 for (
const auto & bid : elem_side_info[4])
1065 mesh.get_boundary_info().add_side(new_elem_ptr_0, 0, bid);
1066 mesh.get_boundary_info().add_side(new_elem_ptr_1, 0, bid);
1080 const std::vector<BoundaryName> & boundary_names,
1081 const unsigned int conversion_element_layer_number,
1082 const bool external_boundaries_checking)
1084 mooseAssert(
mesh.is_serial(),
1085 "This method only supports serial meshes. If you are calling this method with a "
1086 "distributed mesh, please serialize it first.");
1091 if (sid_shift_base * 3 > std::numeric_limits<subdomain_id_type>::max())
1098 std::vector<boundary_id_type> boundary_ids;
1099 for (
const auto &
sideset : boundary_names)
1107 auto & sideset_map =
mesh.get_boundary_info().get_sideset_map();
1108 auto side_list =
mesh.get_boundary_info().build_side_list();
1110 std::vector<std::pair<dof_id_type, std::vector<unsigned int>>> elems_list;
1111 std::vector<std::set<dof_id_type>> layered_elems_list;
1112 layered_elems_list.push_back(std::set<dof_id_type>());
1114 if (!
mesh.is_prepared())
1115 mesh.find_neighbors();
1116 for (
const auto & side_info : side_list)
1118 if (std::get<2>(side_info) == uniform_tmp_bid)
1126 if (
mesh.elem_ptr(std::get<0>(side_info))->default_side_order() != 1)
1128 "The provided boundary set contains non-linear side elements, which is not supported.");
1129 const auto side_type =
1130 mesh.elem_ptr(std::get<0>(side_info))->side_ptr(std::get<1>(side_info))->type();
1131 layered_elems_list.back().emplace(std::get<0>(side_info));
1135 const auto neighbor_ptr =
1136 mesh.elem_ptr(std::get<0>(side_info))->neighbor_ptr(std::get<1>(side_info));
1139 if (external_boundaries_checking)
1141 "The provided boundary contains non-external sides, which is required when "
1142 "external_boundaries_checking is enabled.");
1144 layered_elems_list.back().emplace(neighbor_ptr->id());
1147 if (conversion_element_layer_number == 1)
1149 if (side_type == TRI3)
1151 else if (side_type == QUAD4)
1153 auto pit = std::find_if(elems_list.begin(),
1155 [elem_id = std::get<0>(side_info)](
const auto & p)
1156 { return p.first == elem_id; });
1157 if (elems_list.size() && pit != elems_list.end())
1159 pit->second.push_back(std::get<1>(side_info));
1162 elems_list.push_back(std::make_pair(
1163 std::get<0>(side_info), std::vector<unsigned int>({std::get<1>(side_info)})));
1166 auto sit = std::find_if(elems_list.begin(),
1168 [elem_id = neighbor_ptr->id()](
const auto & p)
1169 { return p.first == elem_id; });
1170 if (elems_list.size() && sit != elems_list.end())
1172 sit->second.push_back(
1173 neighbor_ptr->which_neighbor_am_i(
mesh.elem_ptr(std::get<0>(side_info))));
1177 elems_list.push_back(std::make_pair(
1179 std::vector<unsigned int>(
1180 {neighbor_ptr->which_neighbor_am_i(mesh.elem_ptr(std::get<0>(side_info)))})));
1184 else if (side_type == C0POLYGON)
1185 throw MooseException(
"The provided boundary set contains C0POLYGON side elements, which "
1186 "is not supported.");
1189 "Impossible scenario: a linear non-polygon side element that is neither TRI3 "
1195 if (conversion_element_layer_number > 1)
1197 std::set<dof_id_type> total_elems_set(layered_elems_list.back());
1199 while (layered_elems_list.back().size() &&
1200 layered_elems_list.size() < conversion_element_layer_number)
1202 layered_elems_list.push_back(std::set<dof_id_type>());
1203 for (
const auto & elem_id : *(layered_elems_list.end() - 2))
1205 for (
const auto & i_side : make_range(
mesh.elem_ptr(elem_id)->n_sides()))
1207 if (
mesh.elem_ptr(elem_id)->neighbor_ptr(i_side) !=
nullptr)
1209 const auto & neighbor_id =
mesh.elem_ptr(elem_id)->neighbor_ptr(i_side)->id();
1210 if (total_elems_set.find(neighbor_id) == total_elems_set.end())
1212 layered_elems_list.back().emplace(neighbor_id);
1213 total_elems_set.emplace(neighbor_id);
1222 if (layered_elems_list.back().empty())
1223 layered_elems_list.pop_back();
1225 if (conversion_element_layer_number > layered_elems_list.size())
1226 throw MooseException(
"There is fewer layers of elements in the input mesh than the requested "
1227 "number of layers to convert.");
1229 std::vector<std::pair<dof_id_type, bool>> original_elems;
1232 const unsigned int n_layer_conversion = layered_elems_list.size() - 1;
1233 for (
unsigned int i = 0; i < n_layer_conversion; ++i)
1234 for (
const auto & elem_id : layered_elems_list[i])
1238 if (
mesh.elem_ptr(elem_id)->type() != TET4)
1240 original_elems.push_back(std::make_pair(elem_id,
false));
1241 mesh.elem_ptr(elem_id)->subdomain_id() += sid_shift_base;
1245 const subdomain_id_type block_id_to_remove = sid_shift_base * 3;
1247 std::vector<dof_id_type> converted_elems_ids_to_track;
1249 mesh, original_elems, converted_elems_ids_to_track, block_id_to_remove,
false);
1254 if (n_layer_conversion)
1256 for (
const auto & elem_id : layered_elems_list[n_layer_conversion])
1258 for (
const auto & i_side : make_range(
mesh.elem_ptr(elem_id)->n_sides()))
1260 if (
mesh.elem_ptr(elem_id)->neighbor_ptr(i_side) !=
nullptr &&
1261 layered_elems_list[n_layer_conversion - 1].count(
1262 mesh.elem_ptr(elem_id)->neighbor_ptr(i_side)->id()))
1264 if (elems_list.size() && elems_list.back().first == elem_id)
1265 elems_list.back().second.push_back(i_side);
1267 elems_list.push_back(std::make_pair(elem_id, std::vector<unsigned int>({i_side})));
1274 for (
const auto & elem_info : elems_list)
1277 std::vector<std::vector<boundary_id_type>> elem_side_info(
1278 mesh.elem_ptr(elem_info.first)->n_sides());
1279 auto side_range = sideset_map.equal_range(
mesh.elem_ptr(elem_info.first));
1280 for (
auto i = side_range.first; i != side_range.second; ++i)
1281 elem_side_info[i->second.first].push_back(i->second.second);
1284 mesh, elem_info.first, elem_info.second, elem_side_info, sid_shift_base);
1288 for (
const auto & elem_info : elems_list)
1289 mesh.elem_ptr(elem_info.first)->subdomain_id() = block_id_to_remove;
1290 for (
auto elem_it =
mesh.active_subdomain_elements_begin(block_id_to_remove);
1291 elem_it !=
mesh.active_subdomain_elements_end(block_id_to_remove);
1293 mesh.delete_elem(*elem_it);
1295 mesh.get_boundary_info().remove_id(uniform_tmp_bid);
1298 mesh.unset_is_prepared();