-
Notifications
You must be signed in to change notification settings - Fork 27
/
parallel.hpp
166 lines (138 loc) · 6.32 KB
/
parallel.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* This file is part of aither.
Copyright (C) 2015-18 Michael Nucci (michael.nucci@gmail.com)
Aither is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Aither is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef PARALLELHEADERDEF // only if the macro PARALLELHEADERDEF is not defined
// execute these lines of code
#define PARALLELHEADERDEF // define the macro
/* This header contains the function declarations for many of the parallel
* functions in the code */
#include <iostream>
#include <vector> // vector
#include <string> // string
#include "mpi.h" // parallelism
#include "vector3d.hpp"
#include "blkMultiArray3d.hpp"
using std::vector;
using std::string;
using std::ios;
using std::cout;
using std::endl;
using std::cerr;
using std::ostream;
// forward class declarations
class boundaryConditions;
class procBlock;
class plot3dBlock;
class connection;
class resid;
class genArray;
class decomposition {
// rank of each procBlock
// (vector size equals number of procBlocks after decomp)
vector<int> rank_;
// parent block of each procBlock
// (vector size equals number of procBlocks after decomp)
vector<int> parBlock_;
// local position of each procBlock
// (vector size equals number of procBlocks after decomp)
vector<int> localPos_;
// lower block of split (vector size equals number of splits)
vector<int> splitHistBlkLow_;
// upper block of split (vector size equals number of splits)
vector<int> splitHistBlkUp_;
// index of split (vector size equals number of splits)
vector<int> splitHistIndex_;
// direction of split (vector size equals number of splits)
vector<string> splitHistDir_;
int numProcs_; // number of processors
public:
// Constructor
decomposition(const int&, const int&);
decomposition() : decomposition(1, 1) {}
// move constructor and assignment operator
decomposition(decomposition&&) noexcept = default;
decomposition& operator=(decomposition&&) noexcept = default;
// copy constructor and assignment operator
decomposition(const decomposition&) = default;
decomposition& operator=(const decomposition&) = default;
// Member functions
int Rank(const int &a) const {return rank_[a];}
int ParentBlock(const int &a) const {return parBlock_[a];}
int LocalPosition(const int &a) const {return localPos_[a];}
int NumProcs() const {return numProcs_;}
double IdealLoad(const vector<plot3dBlock>&) const;
double MaxLoad(const vector<plot3dBlock>&) const;
double MinLoad(const vector<plot3dBlock>&) const;
double ProcLoad(const vector<plot3dBlock>&, const int&) const;
double LoadRatio(const vector<plot3dBlock>&, const int&) const;
int MostOverloadedProc(const vector<plot3dBlock>&, double&) const;
int MostUnderloadedProc(const vector<plot3dBlock>&, double&) const;
int NumBlocksOnProc(const int&) const;
vector<int> NumBlocksOnAllProc() const;
int NumBlocks() const {return rank_.size();}
void SendToProc(const int&, const int&, const int&);
void Split(const int&, const int&, const string&);
int SendWholeOrSplit(const vector<plot3dBlock>&, const int&,
const int&, int&, string&) const;
int Size() const {return static_cast<int> (rank_.size());}
int NumSplits() const {return static_cast<int> (splitHistDir_.size());}
int SplitHistBlkLower(const int &a) const {return splitHistBlkLow_[a];}
int SplitHistBlkUpper(const int &a) const {return splitHistBlkUp_[a];}
int SplitHistIndex(const int &a) const {return splitHistIndex_[a];}
string SplitHistDir(const int &a) const {return splitHistDir_[a];}
template <typename T>
void DecompArray(vector<blkMultiArray3d<T>> &) const;
void PrintDiagnostics(const vector<plot3dBlock>&) const;
// Destructor
~decomposition() noexcept {}
};
// function definitions
ostream & operator<< (ostream &os, const decomposition&);
decomposition ManualDecomposition(vector<plot3dBlock>&,
vector<boundaryConditions>&, const int&);
decomposition CubicDecomposition(vector<plot3dBlock>&,
vector<boundaryConditions>&, const int&);
void SendNumProcBlocks(const vector<int>&, int&);
void SendConnections(vector<connection>&, const MPI_Datatype&);
void SetDataTypesMPI(MPI_Datatype &, MPI_Datatype &, MPI_Datatype &,
MPI_Datatype &, MPI_Datatype &, MPI_Datatype &,
MPI_Datatype &);
void FreeDataTypesMPI(MPI_Datatype &, MPI_Datatype &, MPI_Datatype &,
MPI_Datatype &, MPI_Datatype &, MPI_Datatype &,
MPI_Datatype &);
vector<procBlock> SendProcBlocks(const vector<procBlock> &, const int &,
const int &, const MPI_Datatype &,
const MPI_Datatype &,
const input &);
void GetProcBlocks(vector<procBlock> &, const vector<procBlock> &, const int &,
const MPI_Datatype &, const MPI_Datatype &,
const MPI_Datatype &, const input &);
void MaxLinf(resid*, resid*, int*, MPI_Datatype*);
void BroadcastString(string& str);
void BroadcastViscFaces(const MPI_Datatype&, vector<vector3d<double>> &);
template <typename T>
void decomposition::DecompArray(vector<blkMultiArray3d<T>> &arr) const {
// resize vector for split blocks
arr.resize(this->NumBlocks());
// split array by decomposition
for (auto ii = 0; ii < this->NumSplits(); ++ii) {
auto ind = this->SplitHistIndex(ii);
auto lower = this->SplitHistBlkLower(ii);
auto upper = this->SplitHistBlkUpper(ii);
auto dir = this->SplitHistDir(ii);
auto lowerArray = arr[lower].Slice(dir, {arr[lower].Start(dir), ind + 1});
auto upperArray = arr[lower].Slice(dir, {ind, arr[lower].End(dir)});
arr[lower] = lowerArray;
arr[upper] = upperArray;
}
}
#endif