3.3.0
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
parallelhelpers.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
25#ifndef DUMUX_LINEAR_PARALLELHELPERS_HH
26#define DUMUX_LINEAR_PARALLELHELPERS_HH
27
28#if HAVE_MPI
29
30#include <dune/geometry/dimension.hh>
31#include <dune/grid/common/datahandleif.hh>
32#include <dune/grid/common/partitionset.hh>
33#include <dune/istl/owneroverlapcopy.hh>
34#include <dune/istl/paamg/pinfo.hh>
36
37namespace Dumux {
38
44// operator that resets result to zero at constrained DOFS
45template<class LinearSolverTraits>
47{
48 using GridView = typename LinearSolverTraits::GridView;
49 using DofMapper = typename LinearSolverTraits::DofMapper;
50 enum { dofCodim = LinearSolverTraits::dofCodim };
51
52 // TODO: this is some large number (replace by limits?)
53 static constexpr std::size_t ghostMarker_ = 1<<24;
54
55 class BaseGatherScatter
56 {
57 public:
58 BaseGatherScatter(const DofMapper& mapper)
59 : mapper_(mapper) {}
60
61 template<class EntityType>
62 int index(const EntityType& e) const
63 { return mapper_.index(e); }
64
65 bool contains(int dim, int codim) const
66 { return dofCodim == codim; }
67
69 bool fixedSize(int dim, int codim) const
70 { return true; }
71
72 template<class EntityType>
73 std::size_t size(EntityType& e) const
74 { return 1; }
75
76 template<class EntityType>
77 bool isNeitherInteriorNorBorderEntity(EntityType& e) const
78 { return e.partitionType() != Dune::InteriorEntity && e.partitionType() != Dune::BorderEntity; }
79
80 private:
81 const DofMapper& mapper_;
82 };
83
90 class GhostGatherScatter
91 : public BaseGatherScatter,
92 public Dune::CommDataHandleIF<GhostGatherScatter,std::size_t>
93 {
94 public:
95 using DataType = std::size_t;
96 using BaseGatherScatter::contains;
97 using BaseGatherScatter::fixedSize;
98 using BaseGatherScatter::size;
99
100 GhostGatherScatter(std::vector<std::size_t>& ranks, const DofMapper& mapper)
101 : BaseGatherScatter(mapper), ranks_(ranks)
102 {}
103
104 template<class MessageBuffer, class EntityType>
105 void gather(MessageBuffer& buff, const EntityType& e) const
106 {
107 auto& data = ranks_[this->index(e)];
108 if (this->isNeitherInteriorNorBorderEntity(e))
109 data = ghostMarker_;
110 buff.write(data);
111 }
112
113 template<class MessageBuffer, class EntityType>
114 void scatter(MessageBuffer& buff, const EntityType& e, std::size_t n)
115 {
116 std::size_t x;
117 buff.read(x);
118 auto& data = ranks_[this->index(e)];
119 if (this->isNeitherInteriorNorBorderEntity(e))
120 data = ghostMarker_;
121 }
122 private:
123 std::vector<std::size_t>& ranks_;
124 };
125
132 class InteriorBorderGatherScatter
133 : public BaseGatherScatter,
134 public Dune::CommDataHandleIF<InteriorBorderGatherScatter,std::size_t>
135 {
136 public:
137 using DataType = std::size_t;
138 using BaseGatherScatter::contains;
139 using BaseGatherScatter::fixedSize;
140 using BaseGatherScatter::size;
141
142 InteriorBorderGatherScatter(std::vector<std::size_t>& ranks, const DofMapper& mapper)
143 : BaseGatherScatter(mapper), ranks_(ranks)
144 {}
145
146 template<class MessageBuffer, class EntityType>
147 void gather(MessageBuffer& buff, const EntityType& e) const
148 {
149 auto& data = ranks_[this->index(e)];
150 if (this->isNeitherInteriorNorBorderEntity(e))
151 data = ghostMarker_;
152 buff.write(data);
153 }
154
155 template<class MessageBuffer, class EntityType>
156 void scatter(MessageBuffer& buff, const EntityType& e, std::size_t n)
157 {
158 std::size_t x;
159 buff.read(x);
160 auto& data = ranks_[this->index(e)];
161 using std::min;
162 data = this->isNeitherInteriorNorBorderEntity(e) ? x : min(data,x);
163 }
164 private:
165 std::vector<std::size_t>& ranks_;
166 };
167
172 struct NeighbourGatherScatter
173 : public BaseGatherScatter,
174 public Dune::CommDataHandleIF<NeighbourGatherScatter,int>
175 {
176 using DataType = int;
177 using BaseGatherScatter::contains;
178 using BaseGatherScatter::fixedSize;
179 using BaseGatherScatter::size;
180
181 NeighbourGatherScatter(const DofMapper& mapper, int rank, std::set<int>& neighbours)
182 : BaseGatherScatter(mapper), rank_(rank), neighbours_(neighbours)
183 {}
184
185 template<class MessageBuffer, class EntityType>
186 void gather(MessageBuffer& buff, const EntityType& e) const
187 {
188 buff.write(rank_);
189 }
190
191 template<class MessageBuffer, class EntityType>
192 void scatter(MessageBuffer& buff, const EntityType& e, std::size_t n)
193 {
194 int x;
195 buff.read(x);
196 neighbours_.insert(x);
197 }
198 private:
199 int rank_;
200 std::set<int>& neighbours_;
201 };
202
203
208 struct SharedGatherScatter
209 : public BaseGatherScatter,
210 public Dune::CommDataHandleIF<SharedGatherScatter,int>
211 {
212 using DataType = int;
213 using BaseGatherScatter::contains;
214 using BaseGatherScatter::fixedSize;
215 using BaseGatherScatter::size;
216
217 SharedGatherScatter(std::vector<int>& shared, const DofMapper& mapper)
218 : BaseGatherScatter(mapper), shared_(shared)
219 {}
220
221 template<class MessageBuffer, class EntityType>
222 void gather(MessageBuffer& buff, EntityType& e) const
223 {
224 int data = true;
225 buff.write(data);
226 }
227
228 template<class MessageBuffer, class EntityType>
229 void scatter(MessageBuffer& buff, const EntityType &e, std::size_t n)
230 {
231 int x;
232 buff.read(x);
233 auto& data = shared_[this->index(e)];
234 data = data || x;
235 }
236 private:
237 std::vector<int>& shared_;
238 };
239
244 template<typename GlobalIndex>
245 struct GlobalIndexGatherScatter
246 : public BaseGatherScatter,
247 public Dune::CommDataHandleIF<GlobalIndexGatherScatter<GlobalIndex>, GlobalIndex>
248 {
249 using DataType = GlobalIndex;
250 using BaseGatherScatter::contains;
251 using BaseGatherScatter::fixedSize;
252 using BaseGatherScatter::size;
253
254 GlobalIndexGatherScatter(std::vector<GlobalIndex>& globalIndices, const DofMapper& mapper)
255 : BaseGatherScatter(mapper), globalIndices_(globalIndices)
256 {}
257
258 template<class MessageBuffer, class EntityType>
259 void gather(MessageBuffer& buff, const EntityType& e) const
260 {
261 buff.write(globalIndices_[this->index(e)]);
262 }
263
264 template<class MessageBuffer, class EntityType>
265 void scatter(MessageBuffer& buff, const EntityType& e, std::size_t n)
266 {
267 DataType x;
268 buff.read(x);
269 using std::min;
270 auto& data = globalIndices_[this->index(e)];
271 data = min(data, x);
272 }
273 private:
274 std::vector<GlobalIndex>& globalIndices_;
275 };
276
277public:
278
279 ParallelISTLHelper(const GridView& gridView, const DofMapper& mapper)
280 : gridView_(gridView), mapper_(mapper)
281 {
282 initGhostsAndOwners_();
283 }
284
285 bool isGhost(std::size_t i) const
286 { return isGhost_[i] == ghostMarker_; }
287
294 template<class Comm>
295 void createParallelIndexSet(Comm& comm) const
296 {
297 if (gridView_.comm().size() <= 1)
298 {
299 comm.remoteIndices().template rebuild<false>();
300 return;
301 }
302
303 // First find out which dofs we share with other processors
304 std::vector<int> isShared(mapper_.size(), false);
305
306 SharedGatherScatter sgs(isShared, mapper_);
307 gridView_.communicate(sgs, Dune::All_All_Interface, Dune::ForwardCommunication);
308
309 // Count shared dofs that we own
310 using GlobalIndex = typename Comm::ParallelIndexSet::GlobalIndex;
311 GlobalIndex count = 0;
312 for (std::size_t i = 0; i < isShared.size(); ++i)
313 if (isShared[i] && isOwned_[i] == 1)
314 ++count;
315
316 std::vector<GlobalIndex> counts(gridView_.comm().size());
317 gridView_.comm().allgather(&count, 1, counts.data());
318
319 // Compute start index start_p = \sum_{i=0}^{i<p} counts_i
320 const int rank = gridView_.comm().rank();
321 auto start = std::accumulate(counts.begin(), counts.begin() + rank, GlobalIndex(0));
322
323 std::vector<GlobalIndex> globalIndices(mapper_.size(), std::numeric_limits<GlobalIndex>::max());
324
325 for (std::size_t i = 0; i < globalIndices.size(); ++i)
326 {
327 if (isOwned_[i] == 1 && isShared[i])
328 {
329 globalIndices[i] = start; // GlobalIndex does not implement postfix ++
330 ++start;
331 }
332 }
333
334 // publish global indices for the shared DOFS to other processors.
335 GlobalIndexGatherScatter<GlobalIndex> gigs(globalIndices, mapper_);
336 gridView_.communicate(gigs, Dune::All_All_Interface, Dune::ForwardCommunication);
337
338 resizeIndexSet_(comm, globalIndices);
339
340 // Compute neighbours using communication
341 std::set<int> neighbours;
342 NeighbourGatherScatter ngs(mapper_, gridView_.comm().rank(), neighbours);
343 gridView_.communicate(ngs, Dune::All_All_Interface, Dune::ForwardCommunication);
344 comm.remoteIndices().setNeighbours(neighbours);
345
346 comm.remoteIndices().template rebuild<false>();
347 }
348
350 const DofMapper& dofMapper() const
351 { return mapper_; }
352
354 const GridView& gridView() const
355 { return gridView_; }
356
357private:
358 void initGhostsAndOwners_()
359 {
360 const auto rank = gridView_.comm().rank();
361 isOwned_.assign(mapper_.size(), rank);
362 // find out about ghosts
363 GhostGatherScatter ggs(isOwned_, mapper_);
364
365 if (gridView_.comm().size() > 1)
366 gridView_.communicate(ggs, Dune::InteriorBorder_All_Interface, Dune::ForwardCommunication);
367
368 isGhost_ = isOwned_;
369
370 // partition interior/border
371 InteriorBorderGatherScatter dh(isOwned_, mapper_);
372
373 if (gridView_.comm().size() > 1)
374 gridView_.communicate(dh, Dune::InteriorBorder_InteriorBorder_Interface, Dune::ForwardCommunication);
375
376 // convert vector into mask vector
377 for (auto& v : isOwned_)
378 v = (v == rank) ? 1 : 0;
379 }
380
381 template<class Comm, class GlobalIndices>
382 void resizeIndexSet_(Comm& comm, const GlobalIndices& globalIndices) const
383 {
384 comm.indexSet().beginResize();
385
386 for (std::size_t localIndex = 0; localIndex < globalIndices.size(); ++localIndex)
387 {
388 const auto globalIndex = globalIndices[localIndex];
389 if (globalIndex != std::numeric_limits<typename GlobalIndices::value_type>::max())
390 {
391 const bool isOwned = isOwned_[localIndex] > 0;
392 const auto attr = getAttribute_(comm, isOwned, isGhost(localIndex));
393 using LocalIndex = typename Comm::ParallelIndexSet::LocalIndex;
394 comm.indexSet().add(globalIndex, LocalIndex{localIndex, attr});
395 }
396 }
397
398 comm.indexSet().endResize();
399 }
400
401 template<class Comm>
402 Dune::OwnerOverlapCopyAttributeSet::AttributeSet
403 getAttribute_(const Comm& comm, const bool isOwned, const bool isGhost) const
404 {
405 if (isOwned)
406 return Dune::OwnerOverlapCopyAttributeSet::owner;
407 else if (isGhost && (comm.category() == static_cast<int>(Dune::SolverCategory::nonoverlapping)) )
408 return Dune::OwnerOverlapCopyAttributeSet::overlap;
409 else
410 return Dune::OwnerOverlapCopyAttributeSet::copy;
411 }
412
413 const GridView gridView_;
414 const DofMapper& mapper_;
415 std::vector<std::size_t> isOwned_;
416 std::vector<std::size_t> isGhost_;
417
418}; // class ParallelISTLHelper
419
420template<class GridView, class DofMapper, int dofCodim>
422{
423public:
424 ParallelVectorHelper(const GridView& gridView, const DofMapper& mapper)
425 : gridView_(gridView), mapper_(mapper)
426 {}
427
428 // \brief Make a vector of the box model consistent.
429 template<class Block, class Alloc>
430 void makeNonOverlappingConsistent(Dune::BlockVector<Block, Alloc>& v) const
431 {
433 if (gridView_.comm().size() > 1)
434 gridView_.communicate(gs, Dune::InteriorBorder_InteriorBorder_Interface,
435 Dune::ForwardCommunication);
436 }
437
438private:
439 const GridView gridView_;
440 const DofMapper& mapper_;
441};
442
447template<class Matrix, class GridView, class DofMapper, int dofCodim>
449{
450 static constexpr int dim = GridView::dimension;
451 using Grid = typename GridView::Traits::Grid;
452 using BlockType = typename Matrix::block_type;
453 using IDS = typename Grid::Traits::GlobalIdSet;
454 using IdType = typename IDS::IdType;
455
477 template<class IsGhostFunc>
478 struct MatrixPatternExchange
479 : public Dune::CommDataHandleIF<MatrixPatternExchange<IsGhostFunc>, IdType>
480 {
482 using DataType = IdType;
483
484 MatrixPatternExchange(const DofMapper& mapper,
485 const std::map<IdType,int>& globalToLocal,
486 const std::map<int,IdType>& localToGlobal,
487 Matrix& A,
488 std::vector<std::set<int>>& sparsity,
489 const IsGhostFunc& isGhost)
490 : mapper_(mapper), idToIndex_(globalToLocal), indexToID_(localToGlobal)
491 , sparsity_(sparsity), A_(A), isGhost_(isGhost)
492 {
493 sparsity_.resize(A.N());
494 }
495
499 bool contains (int dim, int codim) const
500 { return (codim == dofCodim); }
501
503 bool fixedSize(int dim, int codim) const
504 { return false; }
505
509 template<class EntityType>
510 std::size_t size(EntityType& e) const
511 {
512 const auto rowIdx = mapper_.index(e);
513 std::size_t n = 0;
514 for (auto colIt = A_[rowIdx].begin(); colIt != A_[rowIdx].end(); ++colIt)
515 if (indexToID_.count(colIt.index()))
516 n++;
517
518 return n;
519 }
520
524 template<class MessageBuffer, class EntityType>
525 void gather(MessageBuffer& buff, const EntityType& e) const
526 {
527 const auto rowIdx = mapper_.index(e);
528 for (auto colIt = A_[rowIdx].begin(); colIt != A_[rowIdx].end(); ++colIt)
529 {
530 auto it = indexToID_.find(colIt.index());
531 if (it != indexToID_.end())
532 buff.write(it->second);
533 }
534 }
535
539 template<class MessageBuffer, class EntityType>
540 void scatter(MessageBuffer& buff, const EntityType& e, std::size_t n)
541 {
542 const auto rowIdx = mapper_.index(e);
543 for (std::size_t k = 0; k < n; k++)
544 {
545 IdType id;
546 buff.read(id);
547 // only add entries corresponding to border entities
548 const auto it = idToIndex_.find(id);
549 if (it != idToIndex_.end())
550 {
551 const auto colIdx = it->second;
552 if (!sparsity_[rowIdx].count(colIdx) && !isGhost_(colIdx))
553 sparsity_[rowIdx].insert(colIdx);
554 }
555 }
556 }
557
558 private:
559 const DofMapper& mapper_;
560 const std::map<IdType,int>& idToIndex_;
561 const std::map<int,IdType>& indexToID_;
562 std::vector<std::set<int>>& sparsity_;
563 Matrix& A_;
564 const IsGhostFunc& isGhost_;
565
566 }; // class MatrixPatternExchange
567
569 struct MatrixEntry
570 {
571 IdType first;
572 BlockType second;
573 MatrixEntry (const IdType& f, const BlockType& s) : first(f), second(s) {}
574 MatrixEntry () {}
575 };
576
578 struct MatrixEntryExchange
579 : public Dune::CommDataHandleIF<MatrixEntryExchange, MatrixEntry>
580 {
582 using DataType = MatrixEntry;
583
584 MatrixEntryExchange(const DofMapper& mapper,
585 const std::map<IdType,int>& globalToLocal,
586 const std::map<int,IdType>& localToGlobal,
587 Matrix& A)
588 : mapper_(mapper), idToIndex_(globalToLocal), indexToID_(localToGlobal), A_(A)
589 {}
590
594 bool contains(int dim, int codim) const
595 { return (codim == dofCodim); }
596
598 bool fixedSize(int dim, int codim) const
599 { return false; }
600
604 template<class EntityType>
605 std::size_t size(EntityType& e) const
606 {
607 const auto rowIdx = mapper_.index(e);
608 std::size_t n = 0;
609 for (auto colIt = A_[rowIdx].begin(); colIt != A_[rowIdx].end(); ++colIt)
610 if (indexToID_.count(colIt.index()))
611 n++;
612
613 return n;
614 }
615
619 template<class MessageBuffer, class EntityType>
620 void gather(MessageBuffer& buff, const EntityType& e) const
621 {
622 const auto rowIdx = mapper_.index(e);
623 for (auto colIt = A_[rowIdx].begin(); colIt != A_[rowIdx].end(); ++colIt)
624 {
625 auto it = indexToID_.find(colIt.index());
626 if (it != indexToID_.end())
627 buff.write(MatrixEntry(it->second,*colIt));
628 }
629 }
630
634 template<class MessageBuffer, class EntityType>
635 void scatter(MessageBuffer& buff, const EntityType& e, std::size_t n)
636 {
637 const auto rowIdx = mapper_.index(e);
638 for (std::size_t k = 0; k < n; k++)
639 {
640 MatrixEntry m;
641 buff.read(m);
642 // only add entries corresponding to border entities
643 auto it = idToIndex_.find(m.first);
644 if (it != idToIndex_.end())
645 if (A_[rowIdx].find(it->second) != A_[rowIdx].end())
646 A_[rowIdx][it->second] += m.second;
647 }
648 }
649
650 private:
651 const DofMapper& mapper_;
652 const std::map<IdType,int>& idToIndex_;
653 const std::map<int,IdType>& indexToID_;
654 Matrix& A_;
655
656 }; // class MatrixEntryExchange
657
658public:
659
660 ParallelMatrixHelper(const GridView& gridView, const DofMapper& mapper)
661 : gridView_(gridView), mapper_(mapper)
662 {
663 idToIndex_.clear();
664 indexToID_.clear();
665
666 for (const auto& entity : entities(gridView_, Dune::Codim<dofCodim>()))
667 {
668 if (entity.partitionType() == Dune::BorderEntity)
669 {
670 const int localIdx = mapper_.index(entity);
671 IdType dofIdxGlobal = gridView_.grid().globalIdSet().id(entity);
672
673 idToIndex_.emplace(dofIdxGlobal, localIdx);
674 indexToID_.emplace(localIdx, dofIdxGlobal);
675 }
676 }
677 }
678
684 template<class IsGhostFunc>
685 void extendMatrix(Matrix& A, const IsGhostFunc& isGhost)
686 {
687 if (gridView_.comm().size() <= 1)
688 return;
689
690 Matrix tmp(A);
691 std::size_t nnz = 0;
692 // get entries from other processes
693 std::vector<std::set<int>> sparsity;
694 MatrixPatternExchange<IsGhostFunc> datahandle(mapper_, idToIndex_, indexToID_, A, sparsity, isGhost);
695 gridView_.communicate(datahandle, Dune::InteriorBorder_InteriorBorder_Interface,
696 Dune::ForwardCommunication);
697 // add own entries, count number of nonzeros
698 for (auto rowIt = A.begin(); rowIt != A.end(); ++rowIt)
699 {
700 for (auto colIt = A[rowIt.index()].begin(); colIt != A[rowIt.index()].end(); ++colIt)
701 if (!sparsity[rowIt.index()].count(colIt.index()))
702 sparsity[rowIt.index()].insert(colIt.index());
703
704 nnz += sparsity[rowIt.index()].size();
705 }
706
707 A.setSize(tmp.N(), tmp.N(), nnz);
708 A.setBuildMode(Matrix::row_wise);
709 auto citer = A.createbegin();
710 for (auto i = sparsity.begin(), end = sparsity.end(); i!=end; ++i, ++citer)
711 {
712 for (auto si = i->begin(), send = i->end(); si!=send; ++si)
713 citer.insert(*si);
714 }
715
716 // set matrix old values
717 A = 0;
718 for (auto rowIt = tmp.begin(); rowIt != tmp.end(); ++rowIt)
719 for (auto colIt = tmp[rowIt.index()].begin(); colIt != tmp[rowIt.index()].end(); ++colIt)
720 A[rowIt.index()][colIt.index()] = tmp[rowIt.index()][colIt.index()];
721 }
722
727 void sumEntries(Matrix& A)
728 {
729 if (gridView_.comm().size() <= 1)
730 return;
731
732 MatrixEntryExchange datahandle(mapper_, idToIndex_, indexToID_, A);
733 gridView_.communicate(datahandle, Dune::InteriorBorder_InteriorBorder_Interface,
734 Dune::ForwardCommunication);
735 }
736
737private:
738 const GridView gridView_;
739 const DofMapper& mapper_;
740 std::map<IdType, int> idToIndex_;
741 std::map<int, IdType> indexToID_;
742
743};
744
748template<class LinearSolverTraits, class ParallelTraits,
749 class Matrix, class Vector, class ParallelHelper>
750void prepareLinearAlgebraParallel(Matrix& A, Vector& b, ParallelHelper& pHelper)
751{
752 if constexpr (ParallelTraits::isNonOverlapping)
753 {
754 // extend the matrix pattern such that it is usable for a parallel solver
755 // and make right-hand side consistent
756 using GridView = typename LinearSolverTraits::GridView;
757 using DofMapper = typename LinearSolverTraits::DofMapper;
758 static constexpr int dofCodim = LinearSolverTraits::dofCodim;
759 ParallelMatrixHelper<Matrix, GridView, DofMapper, dofCodim> matrixHelper(pHelper.gridView(), pHelper.dofMapper());
760 matrixHelper.extendMatrix(A, [&pHelper](auto idx){ return pHelper.isGhost(idx); });
761 matrixHelper.sumEntries(A);
762
763 ParallelVectorHelper<GridView, DofMapper, dofCodim> vectorHelper(pHelper.gridView(), pHelper.dofMapper());
764 vectorHelper.makeNonOverlappingConsistent(b);
765 }
766}
767
771template<class LinearSolverTraits, class ParallelTraits,
772 class Matrix, class Vector, class ParallelHelper>
773void prepareLinearAlgebraParallel(Matrix& A, Vector& b,
774 std::shared_ptr<typename ParallelTraits::Comm>& comm,
775 std::shared_ptr<typename ParallelTraits::LinearOperator>& fop,
776 std::shared_ptr<typename ParallelTraits::ScalarProduct>& sp,
777 ParallelHelper& pHelper)
778{
779 prepareLinearAlgebraParallel<LinearSolverTraits, ParallelTraits>(A, b, pHelper);
780 const auto category = ParallelTraits::isNonOverlapping ?
781 Dune::SolverCategory::nonoverlapping : Dune::SolverCategory::overlapping;
782
783 comm = std::make_shared<typename ParallelTraits::Comm>(pHelper.gridView().comm(), category);
784 pHelper.createParallelIndexSet(*comm);
785 fop = std::make_shared<typename ParallelTraits::LinearOperator>(A, *comm);
786 sp = std::make_shared<typename ParallelTraits::ScalarProduct>(*comm);
787}
788
789} // end namespace Dumux
790
791#endif // HAVE_MPI
792#endif
Contains a class to exchange entries of a vector.
int start(int argc, char **argv, void(*usage)(const char *, const std::string &))
Provides a main function with error handling.
Definition: start.hh:127
Definition: adapt.hh:29
void prepareLinearAlgebraParallel(Matrix &A, Vector &b, ParallelHelper &pHelper)
Prepare linear algebra variables for parallel solvers.
Definition: parallelhelpers.hh:750
LinearSolverTraitsImpl< GridGeometry, GridGeometry::discMethod > LinearSolverTraits
The type traits required for using the IstlFactoryBackend.
Definition: linearsolvertraits.hh:72
A parallel helper class providing a nonoverlapping decomposition of all degrees of freedom.
Definition: parallelhelpers.hh:47
bool isGhost(std::size_t i) const
Definition: parallelhelpers.hh:285
void createParallelIndexSet(Comm &comm) const
Creates a parallel index set.
Definition: parallelhelpers.hh:295
const DofMapper & dofMapper() const
Return the dofMapper.
Definition: parallelhelpers.hh:350
const GridView & gridView() const
Return the gridView.
Definition: parallelhelpers.hh:354
ParallelISTLHelper(const GridView &gridView, const DofMapper &mapper)
Definition: parallelhelpers.hh:279
Definition: parallelhelpers.hh:422
ParallelVectorHelper(const GridView &gridView, const DofMapper &mapper)
Definition: parallelhelpers.hh:424
void makeNonOverlappingConsistent(Dune::BlockVector< Block, Alloc > &v) const
Definition: parallelhelpers.hh:430
Helper class for adding up matrix entries on border.
Definition: parallelhelpers.hh:449
ParallelMatrixHelper(const GridView &gridView, const DofMapper &mapper)
Definition: parallelhelpers.hh:660
void extendMatrix(Matrix &A, const IsGhostFunc &isGhost)
communicates values for the sparsity pattern of the new matrix.
Definition: parallelhelpers.hh:685
void sumEntries(Matrix &A)
Sums up the entries corresponding to border vertices.
Definition: parallelhelpers.hh:727
A data handle class to exchange entries of a vector.
Definition: vectorcommdatahandle.hh:78