76 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
81 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
87 auto side_list = boundary_info.build_active_side_list();
92 ") does not exist in the mesh.");
98 boundary_mesh->set_mesh_dimension(
mesh->mesh_dimension() - 1);
99 boundary_mesh->set_spatial_dimension(
mesh->mesh_dimension());
102 std::vector<Node *> boundary_nodes;
105 std::map<dof_id_type, dof_id_type> mesh_node_id_to_boundary_node_id;
107 dof_id_type boundary_node_id = 0;
110 std::map<dof_id_type, std::tuple<dof_id_type, unsigned short int, boundary_id_type>>
111 boundary_elem_to_mesh_elem;
112 for (
auto & side : side_list)
117 const Elem * elem =
mesh->elem_ptr(std::get<0>(side));
120 std::unique_ptr<const Elem> boundary_elem = elem->side_ptr(std::get<1>(side));
123 std::vector<dof_id_type> bnd_elem_node_ids(boundary_elem->n_nodes());
126 for (MooseIndex(boundary_elem->n_nodes()) j = 0; j < boundary_elem->n_nodes(); ++j)
128 const Node * node = boundary_elem->node_ptr(j);
131 if (mesh_node_id_to_boundary_node_id.find(node->id()) ==
132 mesh_node_id_to_boundary_node_id.end())
135 mesh_node_id_to_boundary_node_id.insert(
136 std::pair<dof_id_type, dof_id_type>(node->id(), boundary_node_id));
141 boundary_nodes.push_back(boundary_mesh->add_point(pt, boundary_node_id));
144 bnd_elem_node_ids[j] = boundary_node_id;
150 bnd_elem_node_ids[j] = mesh_node_id_to_boundary_node_id.find(node->id())->second;
158 boundary_elem_to_mesh_elem.insert(
159 std::pair<dof_id_type, std::tuple<dof_id_type, unsigned short int, boundary_id_type>>(
160 new_bnd_elem->id(), side));
165 for (MooseIndex(boundary_elem->n_nodes()) j = 0; j < boundary_elem->n_nodes(); ++j)
167 dof_id_type old_node_id = boundary_elem->node_ptr(j)->id();
168 if (mesh_node_id_to_boundary_node_id.find(old_node_id) ==
169 mesh_node_id_to_boundary_node_id.end())
170 mooseError(
"Node id", old_node_id,
" not linked to new node id.");
171 dof_id_type new_node_id = mesh_node_id_to_boundary_node_id.find(old_node_id)->second;
172 new_bnd_elem->set_node(j, boundary_nodes[new_node_id]);
178 boundary_mesh->prepare_for_use();
184 auto partitioner_enum = getParam<MooseEnum>(
"partitioner");
185 MooseMesh::setPartitioner(*boundary_mesh, partitioner_enum,
false,
_pars, *
this);
193 std::vector<BoundaryName> sideset_names =
196 std::vector<boundary_id_type> boundary_ids =
199 mooseAssert(sideset_names.size() ==
_n_patches,
200 "sideset_names must have as many entries as user-requested number of patches.");
201 mooseAssert(boundary_ids.size() ==
_n_patches,
202 "boundary_ids must have as many entries as user-requested number of patches.");
206 for (
const auto & elem : boundary_mesh->active_element_ptr_range())
208 const auto it = boundary_elem_to_mesh_elem.find(elem->id());
209 if (it == boundary_elem_to_mesh_elem.end())
210 mooseError(
"Element in the boundary mesh with id ",
212 " not found in boundary_elem_to_mesh_elem.");
214 auto side = boundary_elem_to_mesh_elem.find(elem->id())->second;
216 mooseAssert(elem->processor_id() < boundary_ids.size(),
217 "Processor id larger than number of patches.");
218 boundary_info.add_side(
219 std::get<0>(side), std::get<1>(side), boundary_ids[elem->processor_id()]);
223 for (MooseIndex(boundary_ids.size()) j = 0; j < boundary_ids.size(); ++j)
225 boundary_info.sideset_name(boundary_ids[j]) = sideset_names[j];
226 boundary_info.nodeset_name(boundary_ids[j]) = sideset_names[j];
238 auto bounding_box = MeshTools::create_bounding_box(
mesh);
239 const auto & min = bounding_box.min();
240 const auto & max = bounding_box.max();
241 const auto & delta = max - min;
244 std::vector<unsigned int> nelems(3);
248 unsigned int largest_id = 0;
249 Real largest = delta(0);
250 for (
unsigned int j = 1; j < 3; ++j)
251 if (largest < delta(j))
264 unsigned int smallest_id = 0;
265 Real smallest = delta(0);
266 for (
unsigned int j = 1; j < 3; ++j)
267 if (smallest > delta(j))
274 unsigned int id1 = 1, id2 = 2;
275 if (smallest_id == 1)
277 else if (smallest_id == 2)
281 nelems[smallest_id] = 1;
282 nelems[id1] = std::round(std::sqrt(delta(id1) / delta(id2) *
_n_patches));
283 nelems[id2] = std::round(std::sqrt(delta(id2) / delta(id1) *
_n_patches));
284 const std::size_t final_n_patches = nelems[id1] * nelems[id2];
290 _console <<
"Note: For creating radiation patches for boundary " <<
_sideset
291 <<
" using grid partitioner number of patches was changed from " <<
_n_patches
292 <<
" to " << final_n_patches << std::endl;
297 const Point delem(delta(0) / nelems[0], delta(1) / nelems[1], delta(2) / nelems[2]);
298 for (
auto & elem_ptr :
mesh.active_element_ptr_range())
300 const Point centroid = elem_ptr->vertex_average();
301 std::array<unsigned int, 3> ielem;
302 for (
const auto i : make_range(LIBMESH_DIM))
304 const auto dist = centroid(i) - min(i);
307 : std::floor(dist / delem(i));
309 elem_ptr->processor_id() = ielem[0] + nelems[0] * (ielem[1] + ielem[2] * nelems[1]);
310 mooseAssert(elem_ptr->processor_id() <
_n_patches,
"Invalid processor id");
320 std::set<processor_id_type> processor_ids;
321 for (
auto & elem_ptr :
mesh.active_element_ptr_range())
322 processor_ids.insert(elem_ptr->processor_id());
330 <<
" are empty. Adjusting number of patches from " <<
_n_patches <<
" to "
331 << processor_ids.size() << std::endl;
335 std::vector<processor_id_type> processor_ids_vec;
336 for (
auto &
p : processor_ids)
337 processor_ids_vec.push_back(
p);
338 std::sort(processor_ids_vec.begin(), processor_ids_vec.end());
341 std::map<processor_id_type, processor_id_type> processor_id_remap;
342 for (MooseIndex(processor_ids_vec.size()) j = 0; j < processor_ids_vec.size(); ++j)
343 processor_id_remap[processor_ids_vec[j]] = j;
345 for (
auto & elem_ptr :
mesh.active_element_ptr_range())
347 processor_id_type
p = elem_ptr->processor_id();
348 const auto & it = processor_id_remap.find(
p);
349 if (it == processor_id_remap.end())
350 mooseError(
"Parition id ",
p,
" not in processor_id_remap.");
351 elem_ptr->processor_id() = it->second;