114 dof_id_type num_edges, num_local_elems, local_elem_id, nj, side;
115 std::vector<dof_id_type> side_weights;
116 std::vector<dof_id_type> elem_weights;
123 std::sort(row.begin(), row.end());
125 elem_weights.clear();
127 elem_weights.resize(num_local_elems);
131 for (dof_id_type k = 0; k < num_local_elems; k++)
138 "Local element id " << k <<
" is not smaller than " <<
_local_id_to_elem.size());
145 side_weights.clear();
148 side_weights.resize(num_edges);
152 std::map<dof_id_type, dof_id_type> global_index_to_weight;
156 "Local element id " << local_elem_id <<
" is not smaller than "
158 global_index_to_weight.clear();
160 unsigned int n_neighbors = 0;
163 for (
auto neighbor : elem->neighbor_ptr_range())
167 if (neighbor !=
nullptr && neighbor->active())
177 if (n_neighbors != row.size())
179 "Cannot construct dual graph correctly since the number of neighbors is inconsistent");
182 mooseAssert(global_index_to_weight.size() == row.size(),
"These must match");
183 for (
const auto [_, weight] : global_index_to_weight)
184 side_weights[nj++] = weight;
206 const std::vector<std::vector<dof_id_type>> & graph,
207 const std::vector<dof_id_type> & elem_weights,
208 const std::vector<dof_id_type> & side_weights,
209 const dof_id_type num_parts,
210 const dof_id_type num_parts_per_compute_node,
211 const std::string & part_package,
212 std::vector<dof_id_type> & partition)
215 PetscInt num_local_elems, num_elems, *xadj =
nullptr, *adjncy =
nullptr, i, *
values =
nullptr,
216 *petsc_elem_weights =
nullptr;
217 const PetscInt * parts;
218 MatPartitioning part;
222 num_elems = num_local_elems = graph.size();
226 LibmeshPetscCallA(
comm.
get(), PetscCalloc1(num_local_elems + 1, &xadj));
230 for (
auto & row : graph)
233 xadj[num_local_elems] = xadj[num_local_elems - 1] + row.size();
236 LibmeshPetscCallA(
comm.
get(), PetscCalloc1(xadj[num_local_elems], &adjncy));
240 for (
auto & row : graph)
241 for (
const auto elem : row)
247 mooseAssert(!side_weights.size(),
248 "No side weights should be provided since there are no neighbors at all");
252 if (side_weights.size())
254 mooseAssert((PetscInt)side_weights.size() == i,
255 "Side weight size " << side_weights.size()
256 <<
" does not match with adjacency matrix size " << i);
257 LibmeshPetscCallA(
comm.
get(), PetscCalloc1(side_weights.size(), &
values));
259 for (
auto weight : side_weights)
265 MatCreateMPIAdj(
comm.
get(), num_local_elems, num_elems, xadj, adjncy,
values, &dual));
267 LibmeshPetscCallA(
comm.
get(), MatPartitioningCreate(
comm.
get(), &part));
271 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetUseEdgeWeights(part, PETSC_TRUE));
272 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetAdjacency(part, dual));
274 if (!num_local_elems)
275 mooseAssert(!elem_weights.size(),
276 "No element weights should be provided since there are no elements at all");
279 if (elem_weights.size())
281 mooseAssert((PetscInt)elem_weights.size() == num_local_elems,
282 "Element weight size " << elem_weights.size()
283 <<
" does not match with the number of local elements"
286 LibmeshPetscCallA(
comm.
get(), PetscCalloc1(elem_weights.size(), &petsc_elem_weights));
288 for (
auto weight : elem_weights)
289 petsc_elem_weights[i++] = weight;
291 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetVertexWeights(part, petsc_elem_weights));
294 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetNParts(part, num_parts));
295 mooseAssert(part_package !=
"party",
"PETSc-3.9.3 or higher is required for using party");
296 mooseAssert(part_package !=
"chaco",
"PETSc-3.9.0 or higher is required for using chaco");
297 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetType(part, part_package.c_str()));
298 if (part_package ==
"hierarch")
300 MatPartitioningHierarchicalSetNfineparts(part, num_parts_per_compute_node));
302 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetFromOptions(part));
303 LibmeshPetscCallA(
comm.
get(), MatPartitioningApply(part, &is));
305 LibmeshPetscCallA(
comm.
get(), ISGetIndices(is, &parts));
308 for (i = 0; i < num_local_elems; i++)
311 LibmeshPetscCallA(
comm.
get(), ISRestoreIndices(is, &parts));
312 LibmeshPetscCallA(
comm.
get(), MatPartitioningDestroy(&part));
313 LibmeshPetscCallA(
comm.
get(), MatDestroy(&dual));
314 LibmeshPetscCallA(
comm.
get(), ISDestroy(&is));
static void partitionGraph(const Parallel::Communicator &comm, const std::vector< std::vector< dof_id_type > > &graph, const std::vector< dof_id_type > &elem_weights, const std::vector< dof_id_type > &side_weights, const dof_id_type num_parts, const dof_id_type num_parts_per_compute_node, const std::string &part_package, std::vector< dof_id_type > &partition)