AMDiS 2.10
The Adaptive Multi-Dimensional Simulation Toolbox
IndexDistribution.hpp
1#pragma once
2
3#include <array>
4#include <algorithm>
5#include <iterator>
6#include <numeric>
7#include <vector>
8
9#include <petsc.h>
10
11#include <dune/common/typeutilities.hh>
12#include <dune/common/parallel/communication.hh>
13
14#if HAVE_MPI
15#include <dune/common/parallel/indexset.hh>
16#include <dune/common/parallel/localindex.hh>
17#include <dune/common/parallel/plocalindex.hh>
18#include <dune/common/parallel/remoteindices.hh>
19#include <dune/common/parallel/remoteindices.hh>
20
21#include <amdis/common/parallel/Communicator.hpp>
22#include <amdis/linearalgebra/ParallelIndexSet.hpp>
23#endif
24
25#include <amdis/functions/GlobalIdSet.hpp>
26#include <amdis/linearalgebra/AttributeSet.hpp>
27
28namespace AMDiS
29{
31 template <class LI>
33 {
35
36 public:
37 using size_type = LI;
38 using DofIndex = size_type;
39 using LocalIndex = size_type;
40 using GlobalIndex = PetscInt;
41
42 public:
43 template <class Basis,
44 Dune::disableCopyMove<Self, Basis> = 0>
45 PetscSequentialIndexDistribution(Basis const& basis)
46 {
47 update(basis);
48 }
49
50 MPI_Comm comm() const
51 {
52 return PETSC_COMM_SELF;
53 }
54
56 size_type localSize() const
57 {
58 return localSize_;
59 }
60
62 std::array<size_type,1> localSizes() const
63 {
64 return {localSize_};
65 }
66
68 size_type globalSize() const
69 {
70 return globalSize_;
71 }
72
74 std::array<GlobalIndex,1> globalStarts() const
75 {
76 return {0u};
77 }
78
80 std::vector<GlobalIndex> const& globalIndices() const
81 {
82 return indices_;
83 }
84
86 GlobalIndex ghostSize() const
87 {
88 return 0;
89 }
90
92 std::array<GlobalIndex,0> ghostIndices() const
93 {
94 return {};
95 }
96
98 LocalIndex globalToGhost(GlobalIndex const& n) const
99 {
100 assert(false && "There are no ghost indices in sequential dofmappings");
101 return 0;
102 }
103
105 LocalIndex dofToGhost(DofIndex const& n) const
106 {
107 assert(false && "There are no ghost indices in sequential dofmappings");
108 return 0;
109 }
110
112 GlobalIndex global(LocalIndex const& n) const
113 {
114 return n;
115 }
116
118 LocalIndex globalToLocal(GlobalIndex const& n) const
119 {
120 return n;
121 }
122
124 LocalIndex dofToLocal(DofIndex const& n) const
125 {
126 return n;
127 }
128
129
131 bool owner(DofIndex const& n) const
132 {
133 assert(n < localSize());
134 return true;
135 }
136
138 bool globalOwner(GlobalIndex const& n) const
139 {
140 return globalOwner(0, n);
141 }
142
144 bool globalOwner(int p, GlobalIndex const& n) const
145 {
146 assert(p == 0);
147 assert(n < globalSize());
148 return true;
149 }
150
152 template <class Basis>
153 void update(Basis const& basis)
154 {
155 localSize_ = basis.dimension();
156 globalSize_ = basis.dimension();
157 indices_.resize(globalSize_);
158 std::iota(indices_.begin(), indices_.end(), size_type(0));
159 }
160
161 void debug() const {}
162
163 private:
164 size_type localSize_ = 0;
165 size_type globalSize_ = 0;
166 std::vector<GlobalIndex> indices_;
167 };
168
170 template <class GlobalId, class LI, class Comm>
172 {
174 };
175
176#if HAVE_MPI
178 template <class GlobalId, class LI>
179 class PetscParallelIndexDistribution
180 {
181 friend class MatrixNnzStructure;
182
183 using Self = PetscParallelIndexDistribution;
184 using PLocalIndex = Dune::ParallelLocalIndex<DefaultAttributeSet::Type>;
185 using IndexSet = Dune::ParallelIndexSet<GlobalId, PLocalIndex, 512>;
186 using Attribute = typename AttributeSet<IndexSet>::type;
187 using RemoteIndices = Dune::RemoteIndices<IndexSet>;
188
189 public:
190 using size_type = LI;
191 using DofIndex = size_type;
192 using LocalIndex = size_type;
193 using GlobalIndex = PetscInt;
194
195 public:
196 template <class Basis,
197 Dune::disableCopyMove<Self, Basis> = 0>
198 PetscParallelIndexDistribution(Basis const& basis)
199 : world_(basis.gridView().comm())
200 {
201 update(basis);
202 }
203
204 MPI_Comm comm() const
205 {
206 return world_;
207 }
208
210 size_type localSize() const
211 {
212 return localSize_;
213 }
214
216 std::vector<size_type> const& localSizes() const
217 {
218 return sizes_;
219 }
220
222 size_type globalSize() const
223 {
224 return globalSize_;
225 }
226
228 std::vector<GlobalIndex> const& globalStarts() const
229 {
230 return starts_;
231 }
232
234 std::vector<GlobalIndex> const& globalIndices() const
235 {
236 return globalIndices_;
237 }
238
240 size_type ghostSize() const
241 {
242 return ghostSize_;
243 }
244
246 std::vector<GlobalIndex> const& ghostIndices() const
247 {
248 return ghostIndices_;
249 }
250
252 LocalIndex globalToGhost(GlobalIndex const& n) const
253 {
254 auto it = std::find(ghostIndices_.begin(), ghostIndices_.end(), n);
255 assert(it != ghostIndices_.end());
256 return std::distance(ghostIndices_.begin(), it);
257 }
258
260 LocalIndex dofToGhost(DofIndex const& n) const
261 {
262 assert(!owner(n));
263 assert(n < ghostLocalIndices_.size());
264 assert(ghostLocalIndices_[n] < ghostSize_);
265
266 return ghostLocalIndices_[n];
267 }
268
270 GlobalIndex global(DofIndex const& n) const
271 {
272 assert(n < globalIndices_.size());
273 return globalIndices_[n];
274 }
275
276
278 LocalIndex globalToLocal(GlobalIndex const& n) const
279 {
280 return n - starts_[world_.rank()];
281 }
282
284 LocalIndex dofToLocal(DofIndex const& n) const
285 {
286 assert(n < globalIndices_.size());
287 return globalToLocal(globalIndices_[n]);
288 }
289
291 bool owner(DofIndex const& n) const
292 {
293 assert(n < owner_.size());
294 return owner_[n];
295 }
296
298 bool globalOwner(GlobalIndex const& n) const
299 {
300 return globalOwner(world_.rank(), n);
301 }
302
304 bool globalOwner(int p, GlobalIndex const& n) const
305 {
306 assert(p < world_.size());
307 return n >= starts_[p] && n < starts_[p+1];
308 }
309
310 RemoteIndices const& remoteIndices() const
311 {
312 return *remoteIndices_;
313 }
314
316 template <class Basis>
317 void update(Basis const& basis);
318
319 void debug() const;
320
321 private:
322 void reset()
323 {
324 sizes_.clear();
325 starts_.clear();
326 localSize_ = 0;
327 globalSize_ = 0;
328 ghostSize_ = 0;
329
330 globalIndices_.clear();
331 ghostIndices_.clear();
332 ghostLocalIndices_.clear();
333 owner_.clear();
334 indexSet_ = std::make_unique<IndexSet>();
335 remoteIndices_ = std::make_unique<RemoteIndices>();
336 }
337
338 private:
339 Mpi::Communicator world_;
340
341 std::vector<size_type> sizes_;
342 std::vector<GlobalIndex> starts_;
343 size_type localSize_;
344 size_type globalSize_;
345 size_type ghostSize_;
346
347 std::vector<GlobalIndex> globalIndices_; // indexed by LocalIndex
348 std::vector<GlobalIndex> ghostIndices_;
349 std::vector<LocalIndex> ghostLocalIndices_;
350 std::vector<bool> owner_;
351
352 std::unique_ptr<IndexSet> indexSet_ = nullptr;
353 std::unique_ptr<RemoteIndices> remoteIndices_ = nullptr;
354
355 const Mpi::Tag tag_{7513};
356 };
357
358 template <class GlobalId, class LI>
359 struct PetscIndexDistributionType<GlobalId, LI, Dune::Communication<MPI_Comm>>
360 {
361 using type = PetscParallelIndexDistribution<GlobalId, LI>;
362 };
363#endif
364
365 template <class B>
366 using PetscIndexDistribution_t
367 = typename PetscIndexDistributionType<GlobalIdType_t<B>, typename B::size_type, typename B::GridView::CollectiveCommunication>::type;
368
369} // end namespace AMDiS
370
371#include <amdis/linearalgebra/petsc/IndexDistribution.inc.hpp>
Sparsity pattern used to create PETSc matrices.
Definition: MatrixNnzStructure.hpp:18
Fallback for PetscParallelIndexDistribution in case there is only one mpi core.
Definition: IndexDistribution.hpp:33
size_type globalSize() const
The total number of global DOFs.
Definition: IndexDistribution.hpp:68
void update(Basis const &basis)
Update the local to global mapping. Must be called before mapping local to global.
Definition: IndexDistribution.hpp:153
bool owner(DofIndex const &n) const
DOF index n is owned by this processor.
Definition: IndexDistribution.hpp:131
size_type localSize() const
How many DOFs are owned by my processor?
Definition: IndexDistribution.hpp:56
LocalIndex dofToLocal(DofIndex const &n) const
Map DOF index to consecutive local owner index.
Definition: IndexDistribution.hpp:124
bool globalOwner(GlobalIndex const &n) const
Global index n is owned by this processor.
Definition: IndexDistribution.hpp:138
std::array< size_type, 1 > localSizes() const
Return the sequence of number of local indices for all processors.
Definition: IndexDistribution.hpp:62
LocalIndex globalToLocal(GlobalIndex const &n) const
Map global index to consecutive local owner index.
Definition: IndexDistribution.hpp:118
GlobalIndex ghostSize() const
Return number of ghost indices.
Definition: IndexDistribution.hpp:86
bool globalOwner(int p, GlobalIndex const &n) const
Global index n is owned by processor p.
Definition: IndexDistribution.hpp:144
GlobalIndex global(LocalIndex const &n) const
Global index of local index n.
Definition: IndexDistribution.hpp:112
LocalIndex globalToGhost(GlobalIndex const &n) const
Map global index to local ghost index.
Definition: IndexDistribution.hpp:98
std::vector< GlobalIndex > const & globalIndices() const
Return the vector of global indices.
Definition: IndexDistribution.hpp:80
LocalIndex dofToGhost(DofIndex const &n) const
Map DOF index to local ghost index.
Definition: IndexDistribution.hpp:105
std::array< GlobalIndex, 0 > ghostIndices() const
Return the vector of ghost indices.
Definition: IndexDistribution.hpp:92
std::array< GlobalIndex, 1 > globalStarts() const
Return the sequence of starting points of the global indices for all processors.
Definition: IndexDistribution.hpp:74
By default the PetscParallelIndexDistribution is just a sequential distribution.
Definition: IndexDistribution.hpp:172