91 const auto dim =
mesh.spatial_dimension();
101 if (getParam<MooseEnum>(
"nodes_grid_computation") ==
"manual")
104 paramError(
"nx_nodes",
"Required for manual nodes grid specification");
108 paramError(
"nz_nodes",
"Required for 3D meshes");
113 paramError(
"number_nodes",
"Required for automatic nodes grid computation");
117 MPI_Dims_create(getParam<unsigned int>(
"number_nodes"),
dim, dims);
124 if (getParam<MooseEnum>(
"processors_grid_computation") ==
"manual")
127 paramError(
"nx_procs",
"Required for manual processors grid specification");
131 paramError(
"nz_procs",
"Required for 3D meshes");
136 paramError(
"number_procs_per_node",
"Required for automatic processors grid computation");
140 MPI_Dims_create(getParam<unsigned int>(
"number_procs_per_node"),
dim, dims);
149 if (
mesh.spatial_dimension() >= 2)
151 if (
mesh.spatial_dimension() == 3)
153 if (
isParamValid(
"number_nodes") && total_nodes != getParam<unsigned int>(
"number_nodes") &&
156 "Computed number of nodes (" + std::to_string(total_nodes) +
") does not match");
159 if (
mesh.spatial_dimension() >= 2)
161 if (
mesh.spatial_dimension() == 3)
164 procs_per_node != getParam<unsigned int>(
"number_procs_per_node") &&
processor_id() == 0)
166 "Computed number of processors per node (" + std::to_string(procs_per_node) +
169 if (procs_per_node * total_nodes !=
mesh.n_partitions() &&
processor_id() == 0)
171 procs_per_node * total_nodes,
172 " partitions, which does not add up to the total number of processors: ",
173 mesh.n_partitions());
177 const auto & nodes_min = nodes_bounding_box.min();
178 const auto & nodes_max = nodes_bounding_box.max();
181 auto nodes_mesh = std::make_unique<ReplicatedMesh>(this->
_communicator);
182 nodes_mesh->partitioner() = std::make_unique<libMesh::LinearPartitioner>();
184 if (
mesh.spatial_dimension() == 2)
185 MeshTools::Generation::build_cube(*nodes_mesh,
197 MeshTools::Generation::build_cube(*nodes_mesh,
210 std::vector<std::unique_ptr<ReplicatedMesh>> procs_meshes(nodes_mesh->n_elem());
212 for (
const auto & elem_ptr : nodes_mesh->active_element_ptr_range())
215 Point min(std::numeric_limits<Real>::max(),
216 std::numeric_limits<Real>::max(),
217 std::numeric_limits<Real>::max());
218 Point max(-std::numeric_limits<Real>::max(),
219 -std::numeric_limits<Real>::max(),
220 -std::numeric_limits<Real>::max());
223 for (
const auto & node : elem_ptr->node_ref_range())
225 min(0) = std::min(min(0), node(0));
226 min(1) = std::min(min(1), node(1));
227 min(2) = std::min(min(2), node(2));
229 max(0) = std::max(max(0), node(0));
230 max(1) = std::max(max(1), node(1));
231 max(2) = std::max(max(2), node(2));
234 auto procs_mesh = std::make_unique<ReplicatedMesh>(this->
_communicator);
235 procs_mesh->partitioner() = std::make_unique<libMesh::LinearPartitioner>();
237 if (
mesh.spatial_dimension() == 2)
238 MeshTools::Generation::build_cube(*procs_mesh,
250 MeshTools::Generation::build_cube(*procs_mesh,
262 procs_meshes[elem_ptr->id()] = std::move(procs_mesh);
265 auto nodes_point_locator_ptr = nodes_mesh->sub_point_locator();
267 std::vector<std::unique_ptr<libMesh::PointLocatorBase>> procs_point_locators(procs_meshes.size());
269 for (
unsigned int i = 0; i < procs_meshes.size(); i++)
270 procs_point_locators[i] = procs_meshes[i]->sub_point_locator();
273 for (
auto & elem_ptr :
mesh.active_element_ptr_range())
275 auto elem_centroid = elem_ptr->vertex_average();
278 auto nodes_elem_ptr = (*nodes_point_locator_ptr)(elem_centroid);
280 auto nodes_elem_id = nodes_elem_ptr->id();
286 auto procs_elem_ptr = (*procs_point_locators[nodes_elem_id])(elem_centroid);
289 elem_ptr->processor_id() = procs_elem_ptr->id() + (nodes_elem_id * procs_per_node);
292 mooseError(
"HierarchicalGridPartitioner unable to locate element within the grid!");