ParallelGlobalBasis.hpp 6.36 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma once


#include <algorithm>
#include <list>
#include <memory>
#include <type_traits>
#include <utility>

#include <dune/common/concept.hh>
#include <dune/common/reservedvector.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/typeutilities.hh>
#include <dune/common/version.hh>

#include <dune/functions/common/type_traits.hh>
#include <dune/functions/functionspacebases/concepts.hh>
18
#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
19
20
21
22
23
24
25
26
27
28
#include <dune/functions/functionspacebases/defaultlocalview.hh>
#include <dune/functions/functionspacebases/flatmultiindex.hh>

#include <dune/grid/common/adaptcallback.hh>

#include <dune/typetree/treepath.hh>

#include <amdis/AdaptiveGrid.hpp>
#include <amdis/Observer.hpp>
#include <amdis/Output.hpp>
29
30
31
32
#include <amdis/common/Concepts.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/linearalgebra/Traits.hpp>
#include <amdis/typetree/MultiIndex.hpp>
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#if DUNE_VERSION_LT(DUNE_FUNCTIONS,2,7)
#include <dune/functions/functionspacebases/defaultlocalindexset.hh>
#endif

namespace AMDiS
{
  /**
   * \brief Parallel global basis defined on a (sequential) pre-basis
   *
   * This class is an expansion to Dune::Functions::DefaultGlobalBasis<PB>. It adds a communicator
   * to use the basis in parallel as well as automatic update functionality.
   *
   * \tparam PB  Pre-basis providing the implementation details
   */
  template <class PB>
  class ParallelGlobalBasis
50
51
      : public Dune::Functions::DefaultGlobalBasis<PB>
      , public Notifier<event::adapt>
Praetorius, Simon's avatar
Praetorius, Simon committed
52
      , private Observer<event::adapt>
53
54
  {
    using Self = ParallelGlobalBasis<PB>;
55
    using Super = Dune::Functions::DefaultGlobalBasis<PB>;
56
57
58
59
60
61
62

  public:
    /// Pre-basis providing the implementation details
    using PreBasis = PB;

    /// The grid view that the FE space is defined on
    using GridView = typename PreBasis::GridView;
Praetorius, Simon's avatar
Praetorius, Simon committed
63
    using Grid = typename GridView::Grid;
64
65
66
67
68

    /// Type of the local view on the restriction of the basis to a single element
    using LocalView = Dune::Functions::DefaultLocalView<Self>;

    /// Type of the communicator
69
70
71
    using Comm = std::conditional_t<Traits::IsFlatIndex<typename Super::MultiIndex>::value,
      typename BackendTraits<Self>::Comm,
      SequentialCommunication>;
72

Praetorius, Simon's avatar
Praetorius, Simon committed
73
    struct DummyImpl {};
74
75
    using ADH = Dune::AdaptDataHandle<Grid, DummyImpl>;

Praetorius, Simon's avatar
Praetorius, Simon committed
76
77
78
79

  public:

    /// Construct this global basis with given name and grid, and constructing a preBasis.
80
    /**
81
     * \param name     Name associated with this basis for initfile parameter attachment.
Praetorius, Simon's avatar
Praetorius, Simon committed
82
83
     * \param grid     The Grid providing the GridView for this basis
     * \param args...  Argument list for PreBasis
84
85
86
     *
     * This will forward all arguments to the constructor of PreBasis
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
87
88
89
    template <class... Args,
      Dune::Functions::enableIfConstructible<PreBasis, Args...> = 0>
    ParallelGlobalBasis(std::string const& name, Grid const& grid, Args&&... args)
90
91
      : Super(FWD(args)...)
      , Observer<event::adapt>(grid)
Praetorius, Simon's avatar
Praetorius, Simon committed
92
      , comm_(CommunicationCreator<Comm>::create(static_cast<Super const&>(*this), name + "->solver"))
93
    {}
94

Praetorius, Simon's avatar
Praetorius, Simon committed
95
96
97
98
99
    /// Construct this global basis with empty name
    template <class... Args,
      Dune::Functions::enableIfConstructible<PreBasis, Args...> = 0>
    ParallelGlobalBasis(Grid const& grid, Args&&... args)
      : ParallelGlobalBasis(std::string(""), grid, FWD(args)...)
100
101
    {}

102
    /// Converting constructor from dune-functions style basis.
Praetorius, Simon's avatar
Praetorius, Simon committed
103
    /**
104
     *  This will create a new ParallelGlobalBasis. The pre-basis is copied from the constructor
105
106
     *  argument and a new communication object is built.
     */
107
108
    template <class GB_,
      Dune::disableCopyMove<Self, GB_> = 0,
109
      REQUIRES(Concepts::GlobalBasis<GB_,GridView>)>
110
    ParallelGlobalBasis(GB_&& from)
Praetorius, Simon's avatar
Praetorius, Simon committed
111
112
113
      : ParallelGlobalBasis(std::string(""), from.gridView().grid(), from.preBasis())
    {}

Praetorius, Simon's avatar
Praetorius, Simon committed
114
115
116
117
118
    /// Copy constructor
    ParallelGlobalBasis(ParallelGlobalBasis const&) = delete;

    /// Move constructor
    ParallelGlobalBasis(ParallelGlobalBasis&&) = default;
Praetorius, Simon's avatar
Praetorius, Simon committed
119
120

  public:
121

Praetorius, Simon's avatar
Praetorius, Simon committed
122
    /// \brief Update the stored grid view
123
124
125
126
127
128
    /**
     * This will update the indexing information of the global basis as well as the communicator.
     * It is called automatically if the grid has changed.
     */
    void update(GridView const& gv)
    {
129
130
131
      Super::preBasis().update(gv);
      Super::preBasis().initializeIndices();
      comm_.update(*this);
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    }

    /// Return local view for basis
    LocalView localView() const
    {
      return LocalView(*this);
    }

    /// Return *this because we are not embedded in a larger basis
    ParallelGlobalBasis const& rootBasis() const
    {
      return *this;
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
146
147
148
149
150
    /// \brief Return the communicator.
    /**
     * This provides the means to communicate data associated to the basis with
     * other processes.
     **/
151
152
    Comm const& communicator() const  { return comm_; }
    Comm&       communicator()        { return comm_; }
153

Praetorius, Simon's avatar
Praetorius, Simon committed
154
    ADH globalRefineCallback() const
155
156
157
158
159
160
    {
      // TODO(FM): Implement
      error_exit("Not implemented: ParallelGlobalBasis::globalRefineCallback()");
      return ADH{};
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
161
162
163
164
165
  protected:
    /// Updates the underlying basis when event::adapt is triggered by the observed grid
    void updateImpl(event::adapt e) override
    {
      if (e.value) {
166
167
        update(Super::gridView());
        Notifier<event::adapt>::notify(e);
Praetorius, Simon's avatar
Praetorius, Simon committed
168
169
170
      }
    }

171
  protected:
172
    Comm comm_;
173
174
  };

Praetorius, Simon's avatar
Praetorius, Simon committed
175
176
177

  template <class MultiIndex, class GV, class PBF>
  auto makeGlobalBasis(std::string const& name, GV const& gridView, PBF&& preBasisFactory)
178
179
  {
    auto preBasis = preBasisFactory.template makePreBasis<MultiIndex>(gridView);
Praetorius, Simon's avatar
Praetorius, Simon committed
180
    return ParallelGlobalBasis<TYPEOF(preBasis)>(name, gridView.grid(), std::move(preBasis));
181
182
  }

Praetorius, Simon's avatar
Praetorius, Simon committed
183
184
  template <class GV, class PBF>
  auto makeGlobalBasis(std::string const& name, GV const& gridView, PBF&& preBasisFactory)
185
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
186
    using RawPreBasisFactory = remove_cvref_t<PBF>;
187
188
189
190
191
    using MultiIndex = std::conditional_t<
      (RawPreBasisFactory::requiredMultiIndexSize == 1),
      Dune::Functions::FlatMultiIndex<std::size_t>,
      Dune::ReservedVector<std::size_t, RawPreBasisFactory::requiredMultiIndexSize>>;

Praetorius, Simon's avatar
Praetorius, Simon committed
192
    return makeGlobalBasis<MultiIndex, GV, PBF>(name, gridView, FWD(preBasisFactory));
193
194
  }

Praetorius, Simon's avatar
Praetorius, Simon committed
195
196
  template <class GV, class PBF>
  auto makeGlobalBasis(GV const& gridView, PBF&& preBasisFactory)
197
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
198
    return makeGlobalBasis(std::string(""), gridView, FWD(preBasisFactory));
199
200
201
  }

} // end namespace AMDiS