115 dof_id_type num_edges, num_local_elems, local_elem_id, nj, side;
116 std::vector<dof_id_type> side_weights;
117 std::vector<dof_id_type> elem_weights;
123 elem_weights.clear();
125 elem_weights.resize(num_local_elems);
129 for (dof_id_type k = 0; k < num_local_elems; k++)
136 "Local element id " << k <<
" is not smaller than " <<
_local_id_to_elem.size());
143 side_weights.clear();
146 side_weights.resize(num_edges);
153 "Local element id " << local_elem_id <<
" is not smaller than "
156 unsigned int n_neighbors = 0;
159 for (
auto neighbor : elem->neighbor_ptr_range())
163 if (neighbor !=
nullptr && neighbor->active())
174 if (n_neighbors != row.size())
176 "Cannot construct dual graph correctly since the number of neighbors is inconsistent");
197 const std::vector<std::vector<dof_id_type>> & graph,
198 const std::vector<dof_id_type> & elem_weights,
199 const std::vector<dof_id_type> & side_weights,
200 const dof_id_type num_parts,
201 const dof_id_type num_parts_per_compute_node,
202 const std::string & part_package,
203 std::vector<dof_id_type> & partition)
206 PetscInt num_local_elems, num_elems, *xadj =
nullptr, *adjncy =
nullptr, i, *
values =
nullptr,
207 *petsc_elem_weights =
nullptr;
208 const PetscInt * parts;
209 MatPartitioning part;
213 num_elems = num_local_elems = graph.size();
217 LibmeshPetscCallA(
comm.
get(), PetscCalloc1(num_local_elems + 1, &xadj));
221 for (
auto & row : graph)
224 xadj[num_local_elems] = xadj[num_local_elems - 1] + row.size();
227 LibmeshPetscCallA(
comm.
get(), PetscCalloc1(xadj[num_local_elems], &adjncy));
231 for (
auto & row : graph)
232 for (
auto elem : row)
238 mooseAssert(!side_weights.size(),
239 "No side weights should be provided since there are no neighbors at all");
243 if (side_weights.size())
245 mooseAssert((PetscInt)side_weights.size() == i,
246 "Side weight size " << side_weights.size()
247 <<
" does not match with adjacency matrix size " << i);
248 LibmeshPetscCallA(
comm.
get(), PetscCalloc1(side_weights.size(), &
values));
250 for (
auto weight : side_weights)
256 MatCreateMPIAdj(
comm.
get(), num_local_elems, num_elems, xadj, adjncy,
values, &dual));
258 LibmeshPetscCallA(
comm.
get(), MatPartitioningCreate(
comm.
get(), &part));
259#if !PETSC_VERSION_LESS_THAN(3, 12, 3)
260 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetUseEdgeWeights(part, PETSC_TRUE));
262 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetAdjacency(part, dual));
264 if (!num_local_elems)
266 mooseAssert(!elem_weights.size(),
267 "No element weights should be provided since there are no elements at all");
271 if (elem_weights.size())
273 mooseAssert((PetscInt)elem_weights.size() == num_local_elems,
274 "Element weight size " << elem_weights.size()
275 <<
" does not match with the number of local elements"
278 LibmeshPetscCallA(
comm.
get(), PetscCalloc1(elem_weights.size(), &petsc_elem_weights));
280 for (
auto weight : elem_weights)
281 petsc_elem_weights[i++] = weight;
283 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetVertexWeights(part, petsc_elem_weights));
286 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetNParts(part, num_parts));
287#if PETSC_VERSION_LESS_THAN(3, 9, 2)
288 mooseAssert(part_package !=
"party",
"PETSc-3.9.3 or higher is required for using party");
290#if PETSC_VERSION_LESS_THAN(3, 9, 0)
291 mooseAssert(part_package !=
"chaco",
"PETSc-3.9.0 or higher is required for using chaco");
293 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetType(part, part_package.c_str()));
294 if (part_package ==
"hierarch")
296 MatPartitioningHierarchicalSetNfineparts(part, num_parts_per_compute_node));
298 LibmeshPetscCallA(
comm.
get(), MatPartitioningSetFromOptions(part));
299 LibmeshPetscCallA(
comm.
get(), MatPartitioningApply(part, &is));
301 LibmeshPetscCallA(
comm.
get(), ISGetIndices(is, &parts));
304 for (i = 0; i < num_local_elems; i++)
307 LibmeshPetscCallA(
comm.
get(), ISRestoreIndices(is, &parts));
308 LibmeshPetscCallA(
comm.
get(), MatPartitioningDestroy(&part));
309 LibmeshPetscCallA(
comm.
get(), MatDestroy(&dual));
310 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)