PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
meshPartitioning.cpp
Go to the documentation of this file.
1
2/*
3 * -------------------------------------------
4 * Copyright (c) 2021 - 2026 Prashant K. Jha
5 * -------------------------------------------
6 * PeriDEM https://github.com/prashjha/PeriDEM
7 *
8 * Distributed under the Boost Software License, Version 1.0. (See accompanying
9 * file LICENSE)
10 */
11
12#include "meshPartitioning.h"
13#include "util/io.h"
14#include <stdexcept>
15#include "mesh.h"
16#include "util/vecMethods.h" // declares std::chrono and defines timeDiff()
17
18#include <metis.h>
19#include <format>
20
21void mesh::metisGraphPartition(std::string partitionMethod,
22 const std::vector<std::vector<size_t>> &nodeNeighs,
23 std::vector<size_t> &nodePartition,
24 size_t nPartitions) {
25 // record time
26 auto t1 = steady_clock::now();
27 idx_t nvtxs = nodeNeighs.size();
28 idx_t ncon = 1; // # of balancing constraints (at least 1)
29 idx_t objval;
30 int metis_return;
31 idx_t nWeights = 1;
32 std::vector<idx_t> part(nvtxs, 0);
33 std::vector<idx_t> vwgt(nvtxs * nWeights, 0);
34 auto nParts = idx_t(nPartitions);
35
36 // create adjacency data based on nodeNeighs
37 // METIS needs xadj of length nvtxs+1 (CSR row pointers).
38 std::vector<idx_t> xadj(static_cast<size_t>(nvtxs) + 1, 0);
39 std::vector<idx_t> adjncy;
40 for (size_t i=0; i<static_cast<size_t>(nvtxs); i++) {
41 adjncy.insert(adjncy.end(), nodeNeighs[i].begin(), nodeNeighs[i].end());
42 xadj[i+1] = xadj[i] + idx_t(nodeNeighs[i].size());
43 }
44 std::cout << std::format("adjcny size = {}, xadj[end] = {}\n",
45 adjncy.size(), xadj[nvtxs]);
46
47 std::cout << "\nmetisGraphPartition():\n";
48 if (partitionMethod == "metis_recursive") {
49 std::cout << " METIS_PartGraphRecursive partitions a graph into K parts\n";
50 std::cout << " using multilevel recursive bisection.\n";
51
52 metis_return = METIS_PartGraphRecursive(&nvtxs, &ncon, xadj.data(),
53 adjncy.data(), NULL, NULL,
54 NULL, &nParts, NULL, NULL, NULL, &objval,
55 part.data());
56 } else if (partitionMethod == "metis_kway") {
57 std::cout << " METIS_PartGraphKway partitions a graph into K parts\n";
58 std::cout << " using multilevel K-way partition.\n";
59
60 metis_return = METIS_PartGraphKway(&nvtxs, &ncon, xadj.data(),
61 adjncy.data(), NULL, NULL,
62 NULL, &nParts, NULL, NULL, NULL, &objval,
63 part.data());
64 } else {
65 throw std::runtime_error(
67 << "Argument partitionMethod = "
68 << partitionMethod << " is invalid.\n"
69 << "Valid values are {'metis_recursive', 'metis_kway'}.\n");
70 }
71
72 // record time
73 auto t2 = steady_clock::now();
74
75 std::cout << std::format("\n Return code = {}\n"
76 " Edge cuts for partition = {}\n"
77 " Partition calculation time (ms) = {}\n",
78 metis_return, (int) objval,
79 util::methods::timeDiff(t1, t2, "microseconds"));
80
81 // cast the part vector into nodePartition vector
82 nodePartition.resize(0);
83 nodePartition.insert(nodePartition.end(), part.begin(), part.end());
84}
85
86void mesh::metisGraphPartition(std::string partitionMethod,
87 mesh::Mesh *mesh_p,
88 const std::vector<std::vector<size_t>> &nodeNeighs,
89 size_t nPartitions) {
90 mesh_p->d_nPart = nPartitions;
91 mesh_p->d_partitionMethod = partitionMethod;
92 mesh::metisGraphPartition(partitionMethod, nodeNeighs,
93 mesh_p->d_nodePartition, nPartitions);
94}
A class for mesh data.
Definition mesh.h:53
std::vector< size_t > d_nodePartition
Node partition information. For each node i, d_nodePartition[i] specifies the partition number,...
Definition mesh.h:491
size_t d_nPart
Number of partitions.
Definition mesh.h:477
std::string d_partitionMethod
Partitioning method. It could be either empty string or "metis_recursive" or "metis_kway".
Definition mesh.h:482
Collects a message with stream syntax for use in an exception.
Definition io.h:52
void metisGraphPartition(std::string partitionMethod, const std::vector< std::vector< size_t > > &nodeNeighs, std::vector< size_t > &nodePartition, size_t nPartitions)
Partitions the nodes based on node neighborlist supplied. Function first creates a graph with nodes a...
float timeDiff(std::chrono::steady_clock::time_point begin, std::chrono::steady_clock::time_point end, std::string unit="microseconds")
Returns difference between two times.
Definition vecMethods.h:309