16 #include "libmesh/distributed_mesh.h"
17 #include "libmesh/elem.h"
31 params.
addRequiredParam<MeshGeneratorName>(
"input",
"The mesh we want to modify");
33 params.
addParam<SubdomainName>(
"new_block_name",
34 "The lower dimensional block name to create (optional)");
36 "sidesets",
"The sidesets from which to create the new block");
45 _input(getMesh(
"input")),
46 _sideset_names(getParam<
std::vector<BoundaryName>>(
"sidesets"))
60 std::unique_ptr<MeshBase>
63 std::unique_ptr<MeshBase> mesh = std::move(
_input);
68 new_block_id = getParam<SubdomainID>(
"new_block_id");
71 std::set<SubdomainID> preexisting_subdomain_ids;
72 mesh->subdomain_ids(preexisting_subdomain_ids);
73 if (preexisting_subdomain_ids.empty())
77 const auto highest_subdomain_id =
78 *std::max_element(preexisting_subdomain_ids.begin(), preexisting_subdomain_ids.end());
79 mooseAssert(highest_subdomain_id < std::numeric_limits<SubdomainID>::max(),
80 "A SubdomainID with max possible value was found");
81 new_block_id = highest_subdomain_id + 1;
85 bool distributed =
false;
86 if (
typeid(mesh).
name() ==
typeid(std::unique_ptr<DistributedMesh>).
name())
89 auto side_list = mesh->get_boundary_info().build_side_list();
90 std::sort(side_list.begin(),
92 [](std::tuple<dof_id_type, unsigned short int, boundary_id_type> a,
93 std::tuple<dof_id_type, unsigned short int, boundary_id_type> b) {
94 auto a_elem_id = std::get<0>(a);
95 auto b_elem_id = std::get<0>(b);
96 if (a_elem_id == b_elem_id)
98 auto a_side_id = std::get<1>(a);
99 auto b_side_id = std::get<1>(b);
100 if (a_side_id == b_side_id)
101 return std::get<2>(a) < std::get<2>(b);
103 return a_side_id < b_side_id;
106 return a_elem_id < b_elem_id;
110 std::set<boundary_id_type> sidesets(sideset_ids.begin(), sideset_ids.end());
112 std::vector<ElemSideDouble> element_sides_on_boundary;
113 for (
const auto & triple : side_list)
114 if (sidesets.count(std::get<2>(triple)))
115 element_sides_on_boundary.push_back(
116 ElemSideDouble(mesh->elem_ptr(std::get<0>(triple)), std::get<1>(triple)));
118 dof_id_type max_elem_id = mesh->max_elem_id();
119 mesh->comm().max(max_elem_id);
120 auto max_elems_to_add = element_sides_on_boundary.size();
121 mesh->comm().max(max_elems_to_add);
123 for (MooseIndex(element_sides_on_boundary) i = 0; i < element_sides_on_boundary.size(); ++i)
125 Elem * elem = element_sides_on_boundary[i].elem;
126 if (distributed && elem->processor_id() != processor_id())
129 unsigned int side = element_sides_on_boundary[i].side;
132 std::unique_ptr<Elem> side_elem(elem->build_side_ptr(side,
false));
135 side_elem->processor_id() = elem->processor_id();
138 side_elem->subdomain_id() = new_block_id;
142 side_elem->set_interior_parent(elem);
146 side_elem->set_id(max_elem_id + processor_id() * max_elems_to_add + i);
149 mesh->add_elem(side_elem.release());
154 mesh->subdomain_name(new_block_id) = getParam<SubdomainName>(
"new_block_name");