GlobalBasis.hpp 5.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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>
16
#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
17
18
19
20
21
22
23
#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>
24
25
#include <amdis/common/Concepts.hpp>
#include <amdis/common/TypeTraits.hpp>
26
#include <amdis/functions/FlatPreBasis.hpp>
27
#include <amdis/functions/LocalView.hpp>
28
29
#include <amdis/linearalgebra/Traits.hpp>
#include <amdis/typetree/MultiIndex.hpp>
30
31
32
33
34
35
36

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

namespace AMDiS
{
37
38
  template <class PreBasisFactory, class PBF = remove_cvref_t<PreBasisFactory>>
  using MultiIndex_t = std::conditional_t<(PBF::requiredMultiIndexSize == 1),
Müller, Felix's avatar
Müller, Felix committed
39
    Dune::Functions::FlatMultiIndex<std::size_t>,
40
    Dune::ReservedVector<std::size_t, PBF::requiredMultiIndexSize>>;
Müller, Felix's avatar
Müller, Felix committed
41
42


43
  /**
44
   * \brief Global basis defined on a pre-basis
45
   *
46
47
48
   * 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.
49
50
51
52
   *
   * \tparam PB  Pre-basis providing the implementation details
   */
  template <class PB>
53
  class GlobalBasis
54
55
      : public Dune::Functions::DefaultGlobalBasis<PB>
      , public Notifier<event::adapt>
Praetorius, Simon's avatar
Praetorius, Simon committed
56
      , private Observer<event::adapt>
57
  {
58
    using Self = GlobalBasis<PB>;
59
    using Super = Dune::Functions::DefaultGlobalBasis<PB>;
60
61
62
63
64
65
66

  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
67
    using Grid = typename GridView::Grid;
68
69

    /// Type of the local view on the restriction of the basis to a single element
70
    using LocalView = AMDiS::LocalView<Self>;
71
72

    /// Type of the communicator
73
74
75
    using Comm = std::conditional_t<Traits::IsFlatIndex<typename Super::MultiIndex>::value,
      typename BackendTraits<Self>::Comm,
      SequentialCommunication>;
76

Praetorius, Simon's avatar
Praetorius, Simon committed
77
    struct DummyImpl {};
78
79
    using ADH = Dune::AdaptDataHandle<Grid, DummyImpl>;

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

Müller, Felix's avatar
Müller, Felix committed
97
98
    /// Construct this global basis with a preBasisFactory
    template <class PBF>
99
100
101
    GlobalBasis(std::string const& name, GridView const& gridView,
                PBF const& preBasisFactory)
      : GlobalBasis(name, gridView.grid(),
102
          flatPreBasis(preBasisFactory.template makePreBasis<MultiIndex_t<PBF>>(gridView)))
103
104
    {}

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

Praetorius, Simon's avatar
Praetorius, Simon committed
112
    /// Copy constructor
113
    GlobalBasis(GlobalBasis const&) = delete;
Praetorius, Simon's avatar
Praetorius, Simon committed
114
115

    /// Move constructor
116
    GlobalBasis(GlobalBasis&&) = default;
Praetorius, Simon's avatar
Praetorius, Simon committed
117
118
119

  public:
    /// \brief Update the stored grid view
120
    /**
121
122
     * This will update the indexing information of the global basis as well as
     * the communicator. It is called automatically if the grid has changed.
123
124
125
     */
    void update(GridView const& gv)
    {
126
127
128
      Super::preBasis().update(gv);
      Super::preBasis().initializeIndices();
      comm_.update(*this);
129
130
131
132
133
134
135
136
137
    }

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

    /// Return *this because we are not embedded in a larger basis
138
    GlobalBasis const& rootBasis() const
139
140
141
142
    {
      return *this;
    }

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

Praetorius, Simon's avatar
Praetorius, Simon committed
151
    ADH globalRefineCallback() const
152
153
    {
      // TODO(FM): Implement
154
      error_exit("Not implemented: GlobalBasis::globalRefineCallback()");
155
156
157
      return ADH{};
    }

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

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

170
  protected:
171
    Comm comm_;
172
173
  };

Praetorius, Simon's avatar
Praetorius, Simon committed
174

Müller, Felix's avatar
Müller, Felix committed
175
  // Deduction guides
Praetorius, Simon's avatar
Praetorius, Simon committed
176
  template <class GV, class PBF>
177
178
  GlobalBasis(std::string const& name, GV const& gridView, PBF const& preBasisFactory)
    -> GlobalBasis<decltype(flatPreBasis(
179
          preBasisFactory.template makePreBasis<MultiIndex_t<PBF>>(gridView)))>;
180

Praetorius, Simon's avatar
Praetorius, Simon committed
181
  template <class GV, class PBF>
182
183
  GlobalBasis(GV const& gridView, PBF const& preBasisFactory)
    -> GlobalBasis<decltype(flatPreBasis(
184
          preBasisFactory.template makePreBasis<MultiIndex_t<PBF>>(gridView)))>;
185
186

} // end namespace AMDiS