AMDiS  0.1
The Adaptive Multi-Dimensional Simulation Toolbox
ParallelIndexSet.hpp
1 #pragma once
2 
3 #include <cassert>
4 #include <vector>
5 
6 #include <dune/common/timer.hh>
7 
8 #include <amdis/Output.hpp>
9 #include <amdis/linearalgebra/AttributeSet.hpp>
10 
11 #if HAVE_MPI
12 #include <dune/grid/common/gridenums.hh>
13 #include <dune/grid/common/partitionset.hh>
14 
15 #include <amdis/Environment.hpp>
16 #include <amdis/functions/GlobalIdSet.hpp>
17 #include <amdis/utility/UniqueBorderPartition.hpp>
18 #endif
19 
20 namespace AMDiS
21 {
23  template <class Basis, class PIS>
24  inline void buildParallelIndexSet(Basis const& basis, PIS& parallelIndexSet)
25  {
26  Dune::Timer t;
27  using Attribute = typename AttributeSet<PIS>::type;
28  using GI = typename PIS::GlobalIndex;
29  using LI = typename PIS::LocalIndex;
30 
31 #if HAVE_MPI
32  if (Environment::mpiSize() > 1) // parallel indexset
33  {
34  auto const& gv = basis.gridView();
35  auto lv = basis.localView();
36 
37  // make disjoint partition of border entities
38  using GridView = typename Basis::GridView;
39  using Grid = typename GridView::Grid;
40  using DataHandle = UniqueBorderPartition<Grid>;
41  DataHandle borderEntities(gv.comm().rank(), gv.grid());
42  for (int i = 0; i < borderEntities.numIterations(); ++i) {
43  gv.communicate(borderEntities,
44  Dune::InterfaceType::InteriorBorder_All_Interface,
45  Dune::CommunicationDirection::ForwardCommunication);
46  }
47 
48  std::vector<bool> visited(basis.dimension(), false);
49  GlobalBasisIdSet<Basis> dofIdSet(basis);
50  parallelIndexSet.beginResize();
51  for (auto const& e : elements(gv))
52  {
53  lv.bind(e);
54  dofIdSet.bind(e);
55  for (std::size_t i = 0; i < dofIdSet.size(); ++i)
56  {
57  auto localIndex = lv.index(i);
58  if (!visited[localIndex]) {
59  auto globalId = dofIdSet.id(i);
60  using PType = Dune::PartitionType;
61  PType pt = dofIdSet.partitionType(i);
62  switch (pt)
63  {
64  case PType::InteriorEntity:
65  parallelIndexSet.add(globalId, LI(localIndex, Attribute::owner, true));
66  break;
67  case PType::BorderEntity:
68  if (borderEntities.contains(dofIdSet.entityId(i)))
69  parallelIndexSet.add(globalId, LI(localIndex, Attribute::owner, true));
70  else
71  parallelIndexSet.add(globalId, LI(localIndex, Attribute::overlap, true));
72  break;
73  case PType::OverlapEntity:
74  parallelIndexSet.add(globalId, LI(localIndex, Attribute::overlap, true));
75  break;
76  case PType::FrontEntity:
77  case PType::GhostEntity:
78  parallelIndexSet.add(globalId, LI(localIndex, Attribute::copy, true));
79  break;
80  default:
81  error_exit("Unknown partition type.");
82  }
83 
84  visited[localIndex] = true;
85  }
86  }
87  dofIdSet.unbind();
88  lv.unbind();
89  }
90  parallelIndexSet.endResize();
91  }
92  else // sequential indexset
93 #endif // HAVE_MPI
94  {
95  parallelIndexSet.beginResize();
96  for (std::size_t localIndex = 0; localIndex < basis.dimension(); ++localIndex)
97  {
98  GI globalId{std::size_t(localIndex)};
99  parallelIndexSet.add(globalId, LI(localIndex, Attribute::owner, true));
100  }
101  parallelIndexSet.endResize();
102  }
103  // test that all indices are inserted into the indexset
104  assert(parallelIndexSet.size() == basis.dimension());
105 
106  info(2, "build ParallelIndexSet needed {} seconds", t.elapsed());
107  }
108 
109 } // end namespace AMDiS
void error_exit(std::string const &str, Args &&... args)
print a message and exit
Definition: Output.hpp:142
Provide global ids for all DOFs in a global basis.
Definition: GlobalIdSet.hpp:106
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
static int mpiSize()
Return the MPI_Size of the group created by Dune::MPIHelper.
Definition: Environment.hpp:74
void buildParallelIndexSet(Basis const &basis, PIS &parallelIndexSet)
Fills a parallelIndexSet with indices from a basis.
Definition: ParallelIndexSet.hpp:24
void info(int noInfoLevel, std::string const &str, Args &&... args)
prints a message, if Environment::infoLevel() >= noInfoLevel
Definition: Output.hpp:105
Determine for each border entity which processor owns it.
Definition: UniqueBorderPartition.hpp:28