| 255 | //----------------------------------------------------------------------------- |
| 256 | template <typename T> |
| 257 | std::vector<int> refine(MPI_Comm comm, const graph::AdjacencyList<T>& adj_graph) |
| 258 | { |
| 259 | common::Timer timer("Compute graph partition (ParMETIS Refine)"); |
| 260 | |
| 261 | // Get some MPI data |
| 262 | const int process_number = dolfinx::MPI::rank(comm); |
| 263 | |
| 264 | // Options for ParMETIS |
| 265 | idx_t options[4]; |
| 266 | options[0] = 1; |
| 267 | options[1] = 0; |
| 268 | options[2] = 15; |
| 269 | // options[3] = PARMETIS_PSR_UNCOUPLED; |
| 270 | |
| 271 | // For repartition, PARMETIS_PSR_COUPLED seems to suppress all |
| 272 | // migration if already balanced. Try PARMETIS_PSR_UNCOUPLED for |
| 273 | // better edge cut. |
| 274 | |
| 275 | // Partitioning array to be computed by ParMETIS. Prefill with |
| 276 | // process_number. |
| 277 | const std::int32_t num_local_cells = adj_graph.num_nodes(); |
| 278 | std::vector<idx_t> part(num_local_cells, process_number); |
| 279 | assert(!part.empty()); |
| 280 | |
| 281 | // Number of partitions (one for each process) |
| 282 | idx_t nparts = dolfinx::MPI::size(comm); |
| 283 | // Remaining ParMETIS parameters |
| 284 | idx_t ncon = 1; |
| 285 | idx_t* elmwgt = nullptr; |
| 286 | idx_t wgtflag = 0; |
| 287 | idx_t edgecut = 0; |
| 288 | idx_t numflag = 0; |
| 289 | std::vector<real_t> tpwgts(ncon * nparts, 1.0 / static_cast<real_t>(nparts)); |
| 290 | std::vector<real_t> ubvec(ncon, 1.05); |
| 291 | |
| 292 | // Call ParMETIS to partition graph |
| 293 | common::Timer timer1("ParMETIS: call ParMETIS_V3_RefineKway"); |
| 294 | [[maybe_unused]] int err = ParMETIS_V3_RefineKway( |
| 295 | adj_graph.node_distribution().data(), adj_graph.nodes().data(), |
| 296 | adj_graph.edges().data(), elmwgt, nullptr, &wgtflag, &numflag, &ncon, |
| 297 | &nparts, tpwgts.data(), ubvec.data(), options, &edgecut, part.data(), |
| 298 | &comm); |
| 299 | assert(err == METIS_OK); |
| 300 | timer1.stop(); |
| 301 | |
| 302 | // Copy cell partition data |
| 303 | return std::vector<int>(part.begin(), part.end()); |
| 304 | //----------------------------------------------------------------------------- |
| 305 | } |
| 306 | #endif |
| 307 | |
| 308 | //----------------------------------------------------------------------------- |