ParallelGlobalBasis.hpp 5.99 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

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

namespace AMDiS
{
Müller, Felix's avatar
Müller, Felix committed
40
41
42
43
44
45
46
  template <class PreBasisFactory>
  using MultiIndex = std::conditional_t<
    (remove_cvref_t<PreBasisFactory>::requiredMultiIndexSize == 1),
    Dune::Functions::FlatMultiIndex<std::size_t>,
    Dune::ReservedVector<std::size_t, remove_cvref_t<PreBasisFactory>::requiredMultiIndexSize>>;


47
48
49
50
51
52
53
54
55
56
  /**
   * \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
57
58
      : public Dune::Functions::DefaultGlobalBasis<PB>
      , public Notifier<event::adapt>
Praetorius, Simon's avatar
Praetorius, Simon committed
59
      , private Observer<event::adapt>
60
61
  {
    using Self = ParallelGlobalBasis<PB>;
62
    using Super = Dune::Functions::DefaultGlobalBasis<PB>;
63
64
65
66
67
68
69

  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
70
    using Grid = typename GridView::Grid;
71
72
73
74
75

    /// 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
76
77
78
    using Comm = std::conditional_t<Traits::IsFlatIndex<typename Super::MultiIndex>::value,
      typename BackendTraits<Self>::Comm,
      SequentialCommunication>;
79

Praetorius, Simon's avatar
Praetorius, Simon committed
80
    struct DummyImpl {};
81
82
    using ADH = Dune::AdaptDataHandle<Grid, DummyImpl>;

Praetorius, Simon's avatar
Praetorius, Simon committed
83
84
85
86

  public:

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

Müller, Felix's avatar
Müller, Felix committed
102
103
104
105
106
    /// Construct this global basis with a preBasisFactory
    template <class PBF>
    ParallelGlobalBasis(std::string const& name, GridView const& gridView, PBF&& preBasisFactory)
      : ParallelGlobalBasis(name, gridView.grid(),
          preBasisFactory.template makePreBasis<MultiIndex<PBF>>(gridView))
107
108
    {}

Müller, Felix's avatar
Müller, Felix committed
109
110
111
112
113
    /// Construct this global basis with empty name
    template <class Arg, class... Args,
      REQUIRES(!std::is_same_v<std::string, remove_cvref_t<Arg>>)>
    ParallelGlobalBasis(Arg&& arg, Args&&... args)
      : ParallelGlobalBasis(std::string(""), FWD(arg), FWD(args)...)
Praetorius, Simon's avatar
Praetorius, Simon committed
114
115
    {}

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

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

  public:
123

Praetorius, Simon's avatar
Praetorius, Simon committed
124
    /// \brief Update the stored grid view
125
126
127
128
129
130
    /**
     * 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)
    {
131
132
133
      Super::preBasis().update(gv);
      Super::preBasis().initializeIndices();
      comm_.update(*this);
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    }

    /// 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
148
149
150
151
152
    /// \brief Return the communicator.
    /**
     * This provides the means to communicate data associated to the basis with
     * other processes.
     **/
153
154
    Comm const& communicator() const  { return comm_; }
    Comm&       communicator()        { return comm_; }
155

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

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

Praetorius, Simon's avatar
Praetorius, Simon committed
173
174
    using Observer<event::adapt>::update;

175
  protected:
176
    Comm comm_;
177
178
  };

Praetorius, Simon's avatar
Praetorius, Simon committed
179

Müller, Felix's avatar
Müller, Felix committed
180
  // Deduction guides
Praetorius, Simon's avatar
Praetorius, Simon committed
181
  template <class GV, class PBF>
Müller, Felix's avatar
Müller, Felix committed
182
183
184
  ParallelGlobalBasis(std::string const& name, GV const& gridView, PBF&& preBasisFactory)
    -> ParallelGlobalBasis<decltype(
         preBasisFactory.template makePreBasis<MultiIndex<PBF>>(gridView))>;
185

Praetorius, Simon's avatar
Praetorius, Simon committed
186
  template <class GV, class PBF>
Müller, Felix's avatar
Müller, Felix committed
187
188
189
  ParallelGlobalBasis(GV const& gridView, PBF&& preBasisFactory)
    -> ParallelGlobalBasis<decltype(
         preBasisFactory.template makePreBasis<MultiIndex<PBF>>(gridView))>;
190
191

} // end namespace AMDiS