15 #include "libmesh/mesh_tools.h" 16 #include "libmesh/linear_partitioner.h" 17 #include "libmesh/elem.h" 18 #include "libmesh/mesh_base.h" 29 MooseEnum partPackage(
"parmetis ptscotch chaco party hierarch",
"parmetis",
false);
33 "The external package is used for partitioning the mesh via PETSc");
36 "num_cores_per_compute_node",
38 "Number of cores per compute node for hierarchical partitioning");
40 params.
addParam<
bool>(
"apply_element_weight",
42 "Indicate if we are going to apply element weights to partitioners");
45 "apply_side_weight",
false,
"Indicate if we are going to apply side weights to partitioners");
48 "Partition mesh using external packages via PETSc MatPartitioning interface");
56 _apply_element_weight(params.
get<bool>(
"apply_element_weight")),
57 _apply_side_weight(params.
get<bool>(
"apply_side_weight")),
65 std::unique_ptr<Partitioner>
68 return std::make_unique<PetscExternalPartitioner>(
_pars);
75 auto old_partitioner = std::move(
mesh.partitioner());
77 mesh.partitioner() = std::make_unique<LinearPartitioner>();
81 mesh.partitioner() = std::move(old_partitioner);
93 if (
mesh.is_replicated() && n_parts > 1)
96 Partitioner::partition(
mesh, n_parts);
104 dof_id_type num_edges, num_local_elems, local_elem_id, nj, side;
105 std::vector<dof_id_type> side_weights;
106 std::vector<dof_id_type> elem_weights;
112 elem_weights.clear();
114 elem_weights.resize(num_local_elems);
125 "Local element id " << k <<
" is not smaller than " <<
_local_id_to_elem.size());
132 side_weights.clear();
135 side_weights.resize(num_edges);
142 "Local element id " << local_elem_id <<
" is not smaller than " 145 unsigned int n_neighbors = 0;
148 for (
auto neighbor : elem->neighbor_ptr_range())
152 if (neighbor !=
nullptr && neighbor->active())
163 if (n_neighbors != row.size())
165 "Cannot construct dual graph correctly since the number of neighbors is inconsistent");
186 const std::vector<std::vector<dof_id_type>> & graph,
187 const std::vector<dof_id_type> & elem_weights,
188 const std::vector<dof_id_type> & side_weights,
191 const std::string & part_package,
192 std::vector<dof_id_type> & partition)
196 PetscInt num_local_elems, num_elems, *xadj =
nullptr, *adjncy =
nullptr, i, *values =
nullptr,
197 *petsc_elem_weights =
nullptr;
198 const PetscInt * parts;
199 MatPartitioning part;
203 num_elems = num_local_elems = graph.size();
207 ierr = PetscCalloc1(num_local_elems + 1, &xadj);
212 for (
auto & row : graph)
215 xadj[num_local_elems] = xadj[num_local_elems - 1] + row.size();
218 ierr = PetscCalloc1(xadj[num_local_elems], &adjncy);
223 for (
auto & row : graph)
224 for (
auto elem : row)
230 mooseAssert(!side_weights.size(),
231 "No side weights should be provided since there are no neighbors at all");
235 if (side_weights.size())
237 mooseAssert((PetscInt)side_weights.size() == i,
238 "Side weight size " << side_weights.size()
239 <<
" does not match with adjacency matrix size " << i);
240 ierr = PetscCalloc1(side_weights.size(), &values);
243 for (
auto weight : side_weights)
247 ierr = MatCreateMPIAdj(
comm.
get(), num_local_elems, num_elems, xadj, adjncy, values, &dual);
252 #if !PETSC_VERSION_LESS_THAN(3, 12, 3) 253 ierr = MatPartitioningSetUseEdgeWeights(part, PETSC_TRUE);
256 ierr = MatPartitioningSetAdjacency(part, dual);
259 if (!num_local_elems)
261 mooseAssert(!elem_weights.size(),
262 "No element weights should be provided since there are no elements at all");
266 if (elem_weights.size())
268 mooseAssert((PetscInt)elem_weights.size() == num_local_elems,
269 "Element weight size " << elem_weights.size()
270 <<
" does not match with the number of local elements" 273 ierr = PetscCalloc1(elem_weights.size(), &petsc_elem_weights);
276 for (
auto weight : elem_weights)
277 petsc_elem_weights[i++] =
weight;
279 ierr = MatPartitioningSetVertexWeights(part, petsc_elem_weights);
283 ierr = MatPartitioningSetNParts(part, num_parts);
285 #if PETSC_VERSION_LESS_THAN(3, 9, 2) 286 mooseAssert(part_package !=
"party",
"PETSc-3.9.3 or higher is required for using party");
288 #if PETSC_VERSION_LESS_THAN(3, 9, 0) 289 mooseAssert(part_package !=
"chaco",
"PETSc-3.9.0 or higher is required for using chaco");
291 ierr = MatPartitioningSetType(part, part_package.c_str());
293 if (part_package ==
"hierarch")
295 ierr = MatPartitioningHierarchicalSetNfineparts(part, num_parts_per_compute_node);
298 ierr = MatPartitioningSetFromOptions(part);
300 ierr = MatPartitioningApply(part, &
is);
303 ierr = ISGetIndices(
is, &parts);
307 for (i = 0; i < num_local_elems; i++)
310 ierr = ISRestoreIndices(
is, &parts);
312 ierr = MatPartitioningDestroy(&part);
314 ierr = MatDestroy(&dual);
static InputParameters validParams()
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
static InputParameters validParams()
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)
const Parallel::Communicator & comm() const
void assign_partitioning(MeshBase &mesh, const std::vector< dof_id_type > &parts)
virtual void build_graph(const MeshBase &mesh)
std::vector< Elem *> _local_id_to_elem
virtual void partition(MeshBase &mesh, const unsigned int n) override
processor_id_type _num_parts_per_compute_node
uint8_t processor_id_type
processor_id_type n_processors() const
virtual dof_id_type computeElementWeight(Elem &elm)
virtual dof_id_type computeSideWeight(Elem &elem, unsigned int side)
registerMooseObject("MooseApp", PetscExternalPartitioner)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
PetscErrorCode PetscInt const PetscInt IS * is
void preLinearPartition(MeshBase &mesh)
bool _apply_element_weight
Base class for MOOSE partitioner.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
const InputParameters & _pars
Parameters of this object, references the InputParameters stored in the InputParametersWarehouse.
PetscExternalPartitioner(const InputParameters ¶ms)
virtual void initialize(MeshBase &)
Called immediately before partitioning.
Partitions a mesh using external petsc partitioners such as parmetis, ptscotch, chaco, party, etc.
std::string _part_package
std::vector< std::vector< dof_id_type > > _dual_graph
virtual void _do_partition(MeshBase &mesh, const unsigned int n) override
virtual std::unique_ptr< Partitioner > clone() const override