Chi-Tech
volmesher_predefunpart_parmetis.cc
Go to the documentation of this file.
2
5
6#include "chi_runtime.h"
7#include "chi_log.h"
8#include "chi_mpi.h"
9
10
11#include "petsc.h"
12
13//###################################################################
14/** Applies KBA-style partitioning to the mesh.*/
16 PARMETIS(const UnpartitionedMesh &umesh)
17{
18 Chi::log.Log() << "Partitioning mesh with ParMETIS.";
19
20 //================================================== Determine avg num faces
21 // per cell
22 const size_t num_raw_cells = umesh.GetNumberOfCells();
23 size_t num_raw_faces = 0;
24 for (auto& cell : umesh.GetRawCells())
25 num_raw_faces += cell->faces.size();
26 size_t avg_num_face_per_cell =
27 std::ceil(static_cast<double>(num_raw_faces)/
28 static_cast<double>(num_raw_cells));
29
30 //================================================== Start building indices
31 std::vector<int64_t> cell_pids(num_raw_cells, 0);
32 if (Chi::mpi.location_id == 0)
33 {
34 if (num_raw_cells > 1)
35 {
36 //======================================== Build indices
37 std::vector<int64_t> i_indices(num_raw_cells+1,0);
38 std::vector<int64_t> j_indices;
39 j_indices.reserve(num_raw_cells * avg_num_face_per_cell);
40 {
41 int64_t i=0;
42 int64_t icount = 0;
43 for (auto cell : umesh.GetRawCells())
44 {
45 i_indices[i] = icount;
46
47 for (auto& face : cell->faces)
48 if (face.has_neighbor)
49 {
50 j_indices.push_back(static_cast<int64_t>(face.neighbor));
51 ++icount;
52 }
53 ++i;
54 }
55 i_indices[i] = icount;
56 }
57
58 Chi::log.Log0Verbose1() << "Done building indices.";
59
60 //======================================== Copy to raw arrays
61 int64_t* i_indices_raw;
62 int64_t* j_indices_raw;
63 PetscMalloc(i_indices.size()*sizeof(int64_t),&i_indices_raw);
64 PetscMalloc(j_indices.size()*sizeof(int64_t),&j_indices_raw);
65
66 for (int64_t j=0; j<static_cast<int64_t>(i_indices.size()); ++j)
67 i_indices_raw[j] = i_indices[j];
68
69 for (int64_t j=0; j<static_cast<int64_t>(j_indices.size()); ++j)
70 j_indices_raw[j] = j_indices[j];
71
72 Chi::log.Log0Verbose1() << "Done copying to raw indices.";
73
74 //========================================= Create adjacency matrix
75 Mat Adj; //Adjacency matrix
76 MatCreateMPIAdj(PETSC_COMM_SELF,
77 (int64_t)num_raw_cells,
78 (int64_t)num_raw_cells,
79 i_indices_raw, j_indices_raw, nullptr, &Adj);
80
81 Chi::log.Log0Verbose1() << "Done creating adjacency matrix.";
82
83 //========================================= Create partitioning
84 MatPartitioning part;
85 IS is,isg;
86 MatPartitioningCreate(MPI_COMM_SELF,&part);
87 MatPartitioningSetAdjacency(part,Adj);
88 MatPartitioningSetType(part,"parmetis");
89 MatPartitioningSetNParts(part, Chi::mpi.process_count);
90 MatPartitioningApply(part,&is);
91 MatPartitioningDestroy(&part);
92 MatDestroy(&Adj);
93 ISPartitioningToNumbering(is,&isg);
94 Chi::log.Log0Verbose1() << "Done building paritioned index set.";
95
96 //========================================= Get cell global indices
97 const int64_t* cell_pids_raw;
98 ISGetIndices(is,&cell_pids_raw);
99 for (size_t i=0; i<num_raw_cells; ++i)
100 cell_pids[i] = cell_pids_raw[i];
101 ISRestoreIndices(is,&cell_pids_raw);
102
103 Chi::log.Log0Verbose1() << "Done retrieving cell global indices.";
104 }//if more than 1 cell
105 }//if home location
106
107 //======================================== Broadcast partitioning to all
108 // locations
109 MPI_Bcast(cell_pids.data(), //buffer [IN/OUT]
110 static_cast<int>(num_raw_cells), //count
111 MPI_LONG_LONG_INT, //data type
112 0, //root
113 Chi::mpi.comm); //communicator
114 Chi::log.Log() << "Done partitioning mesh.";
115
116 return cell_pids;
117}
static chi::ChiLog & log
Definition: chi_runtime.h:81
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
LogStream Log0Verbose1()
Definition: chi_log.h:234
const MPI_Comm & comm
MPI communicator.
Definition: mpi_info.h:28
std::vector< LightWeightCell * > & GetRawCells()
struct _p_Mat * Mat