Communication.hpp 2.88 KB
Newer Older
1
2
3
4
5
6
7
8
9
#pragma once

#include <petsc.h>

#include <dune/common/parallel/indexset.hh>
#include <dune/common/parallel/localindex.hh>
#include <dune/common/parallel/plocalindex.hh>
#include <dune/common/parallel/remoteindices.hh>
#include <dune/common/std/optional.hh>
10
#include <dune/common/typeutilities.hh>
11

12
#include <amdis/functions/GlobalIdSet.hpp>
13
14
15
16
17
18
#include <amdis/linearalgebra/Communication.hpp>
#include <amdis/linearalgebra/DOFMapping.hpp>
#include <amdis/linearalgebra/ParallelIndexSet.hpp>

namespace AMDiS
{
Praetorius, Simon's avatar
Praetorius, Simon committed
19
  template <class GlobalId, class SizeType>
20
21
  class DistributedCommunication
  {
22
    using Self = DistributedCommunication;
23
24
  public:
#if HAVE_MPI
25
26
    using LocalIndex = Dune::ParallelLocalIndex<DefaultAttributeSet::Type>;
    using IndexSet = Dune::ParallelIndexSet<GlobalId, LocalIndex, 512>;
27
28
29
30
    using RemoteIndices = Dune::RemoteIndices<IndexSet>;
#else
    struct IndexSet
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
31
32
      constexpr SizeType size() const { return size_; }
      SizeType size_ = 0;
33
34
35
36
37
38
39
    };

    struct RemoteIndices {};
#endif
    using DofMap = DofMapping<IndexSet, PetscInt>;

  public:
40
41
    template <class Basis,
      Dune::disableCopyMove<Self, Basis> = 0>
42
    DistributedCommunication(Basis const& basis)
43
      : remoteIndices_(std::make_unique<RemoteIndices>())
44
45
46
47
    {
      update(basis);
    }

48
49
50
    DistributedCommunication(Self const& other) = delete;
    DistributedCommunication(Self&& other) = default;

51
52
53
54
55
    /// Return the ParallelIndexSet
    IndexSet const& indexSet() const { return *indexSet_; }
    IndexSet&       indexSet()       { return *indexSet_; }

    /// Return the RemoteIndices
56
57
    RemoteIndices const& remoteIndices() const { return *remoteIndices_; }
    RemoteIndices&       remoteIndices()       { return *remoteIndices_; }
58
59
60
61
62
63

    /// Return the DofMapping
    DofMap const& dofMap() const { return dofMap_; }
    DofMap&       dofMap()       { return dofMap_; }

    /// Update the indexSet, remoteIndices and dofmapping
64
    template <class Basis>
65
66
    void update(Basis const& basis)
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
67
      indexSet_ = std::make_unique<IndexSet>();
68
69
70

#if HAVE_MPI
      buildParallelIndexSet(basis, *indexSet_);
71
72
      remoteIndices_->setIndexSets(*indexSet_, *indexSet_, Environment::comm());
      remoteIndices_->template rebuild<true>();
73
74
75
76
77
78
79
80
#else
      (*indexSet_).size_ = basis.dimension();
#endif

      dofMap_.update(*this);
    }

  protected:
Praetorius, Simon's avatar
Praetorius, Simon committed
81
    std::unique_ptr<IndexSet> indexSet_ = nullptr;
82
    std::unique_ptr<RemoteIndices> remoteIndices_;
83
84
85
    DofMap dofMap_;
  };

86
87
88
  template <class B>
  using DistributedCommunication_t
    = DistributedCommunication<GlobalIdType_t<B>, typename B::size_type>;
89

90
91
92

  template <class G, class L>
  struct CommunicationCreator<DistributedCommunication<G,L>>
93
  {
94
    using Communication = DistributedCommunication<G,L>;
95

96
97
    template <class Basis>
    static Communication create(Basis const& basis, std::string const& prefix = "")
98
    {
99
      return {basis};
100
101
102
103
    }
  };

} // end namespace AMDiS