DOFVector.hpp 8.15 KB
Newer Older
1
2
3
4
5
#pragma once

#include <memory>
#include <utility>

6
#include <dune/common/concept.hh>
7
8
#include <dune/common/shared_ptr.hh>

9
10
#include <dune/functions/functionspacebases/concepts.hh>

11
12
#include <amdis/DataTransfer.hpp>
#include <amdis/LinearAlgebra.hpp>
13
#include <amdis/Observer.hpp>
14
15
#include <amdis/common/Concepts.hpp>
#include <amdis/common/TypeTraits.hpp>
16
#include <amdis/functions/ParallelGlobalBasis.hpp>
17
#include <amdis/gridfunctions/DiscreteFunction.hpp>
18
19
20
21
#include <amdis/typetree/TreePath.hpp>

namespace AMDiS
{
22
23
24
25
26
  // Forward declarations
  template <class PB>
  class ParallelGlobalBasis;


27
28
29
30
  /// \brief The basic container that stores a base vector and a corresponding basis
  /**
   * \tparam GB  Basis of the vector
   * \tparam T   Type of the coefficients
Praetorius, Simon's avatar
Praetorius, Simon committed
31
   * \tparam TraitsType  Collection of parameter for the linear-algebra backend
32
   **/
Praetorius, Simon's avatar
Praetorius, Simon committed
33
  template <class GB, class T = double, class TraitsType = BackendTraits<GB>>
34
  class DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
35
      : public VectorFacade<T, TraitsType::template VectorImpl>
Praetorius, Simon's avatar
Praetorius, Simon committed
36
37
38
      , private Observer<event::preAdapt>
      , private Observer<event::adapt>
      , private Observer<event::postAdapt>
39
40
41
42
  {
    using Self = DOFVector;

  public:
43
    /// A global basis associated to the coefficients
44
45
    using GlobalBasis = GB;

46
47
48
    /// The internal coefficient vector storage
    using Coefficients = VectorFacade<T, TraitsType::template VectorImpl>;

49
50
51
52
    /// The index/size - type
    using size_type  = typename GlobalBasis::size_type;

    /// The type of the elements of the DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
53
    using value_type = T;
54

55
56
    /// Wrapper for the implementation of the transfer of data during grid adaption
    using DataTransfer = DataTransferWrapper<Self>;
57

Praetorius, Simon's avatar
Praetorius, Simon committed
58
59
60
    /// Collection of parameter for the linear-algebra backend
    using Traits = TraitsType;

61
  public:
62
    /// (1) Constructor. Stores the shared_ptr of the basis and creates a new DataTransfer.
Praetorius, Simon's avatar
Praetorius, Simon committed
63
    DOFVector(std::shared_ptr<GB> const& basis,
64
              DataTransferOperation op = DataTransferOperation::INTERPOLATE)
Praetorius, Simon's avatar
Praetorius, Simon committed
65
      : Coefficients(*basis)
Praetorius, Simon's avatar
Praetorius, Simon committed
66
      , Observer<event::preAdapt>(basis->gridView().grid())
67
      , Observer<event::adapt>(*basis)
Praetorius, Simon's avatar
Praetorius, Simon committed
68
      , Observer<event::postAdapt>(basis->gridView().grid())
69
70
      , dataTransfer_(op, basis)
      , basis_(basis)
71
72
    {}

73
74
    /// (2) Constructor. Forwards to (1) by wrapping reference into non-destroying
    /// shared_ptr, see \ref Dune::wrap_or_move.
75
76
77
78
79
80
    template <class GB_,
      REQUIRES(Concepts::Similar<GB_,GB>)>
    DOFVector(GB_&& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
      : DOFVector(Dune::wrap_or_move(FWD(basis)), op)
    {}

81
82
83
84
85
    /// (3) Constructor. Forwards to (1) by creating a new basis from a dune-functions pre-basis factory.
    template <class GV, class PBF,
      REQUIRES(Concepts::PreBasisFactory<PBF, GV, MultiIndex_t<PBF>>)>
    DOFVector(GV const& gridView, PBF const& preBasisFactory, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
      : DOFVector(std::make_shared<GB>(gridView, preBasisFactory), op)
86
87
    {}

88
    /// Return the global basis
Praetorius, Simon's avatar
Praetorius, Simon committed
89
    std::shared_ptr<GlobalBasis const> const& basis() const { return basis_; }
90

91
92
93
    /// Transform the DOFVector into a DiscreteFunction
    template <class... Indices>
    auto discreteFunction(Indices... ii)
94
    {
95
      return DiscreteFunction{coefficients(), *basis_, makeTreePath(ii...)};
96
97
    }

98
99
100
    /// Transform the DOFVector into a DiscreteFunction
    template <class... Indices>
    auto discreteFunction(Indices... ii) const
101
    {
102
      return DiscreteFunction{coefficients(), *basis_, makeTreePath(ii...)};
103
104
105
106
107
    }


    /// Interpolation of GridFunction to DOFVector, assuming that there is no
    /// reference to this DOFVector in the expression.
108
    /// See \ref DiscreteFunction::interpolate_noalias
109
    template <class Expr, class Tag = tag::average>
Praetorius, Simon's avatar
Praetorius, Simon committed
110
    void interpolate_noalias(Expr&& expr, Tag strategy = {})
111
    {
112
      discreteFunction().interpolate_noalias(FWD(expr), strategy);
113
114
115
    }

    /// Interpolation of GridFunction to DOFVector.
116
    /// See \ref DiscreteFunction::interpolate
117
    template <class Expr, class Tag = tag::average>
Praetorius, Simon's avatar
Praetorius, Simon committed
118
    void interpolate(Expr&& expr, Tag strategy = {})
119
    {
120
      discreteFunction().interpolate(FWD(expr), strategy);
121
122
123
    }

    /// Interpolation of GridFunction to DOFVector.
124
    /// See \ref DiscreteFunction::interpolate
125
126
127
    template <class Expr>
    DOFVector& operator<<(Expr&& expr)
    {
128
      discreteFunction().interpolate(FWD(expr));
129
130
131
132
      return *this;
    }


133
    Coefficients const& coefficients() const
Praetorius, Simon's avatar
Praetorius, Simon committed
134
135
136
137
    {
      return static_cast<Coefficients const&>(*this);
    }

138
    Coefficients& coefficients()
Praetorius, Simon's avatar
Praetorius, Simon committed
139
140
141
142
    {
      return static_cast<Coefficients&>(*this);
    }

143
144
145
146
147
148
    /// Write DOFVector to file
    void backup(std::string const& filename);

    /// Read backup data from file
    void restore(std::string const& filename);

149
150
151
152
153
154
155
156
157
158
159
160
161
    void resize()
    {
      Coefficients::resize(sizeInfo(*basis_));
    }

    using Coefficients::resize;

    void resizeZero()
    {
      Coefficients::resizeZero(sizeInfo(*basis_));
    }

    using Coefficients::resizeZero;
162
163

    /// Return the associated DataTransfer object
164
    DataTransfer const& dataTransfer() const
165
166
167
168
169
    {
      return dataTransfer_;
    }

    /// Return the associated DataTransfer object
170
    DataTransfer& dataTransfer()
171
172
173
174
175
    {
      return dataTransfer_;
    }

    /// Assign the DataTransfer object
176
    void setDataTransfer(DataTransfer const& dataTransfer)
177
178
179
180
    {
      dataTransfer_ = dataTransfer;
    }

181
182
183
184
    void setDataTransfer(DataTransfer&& dataTransfer)
    {
      dataTransfer_ = std::move(dataTransfer);
    }
185

186
187
    /// Create a new DataTransfer object based on the operation type
    void setDataTransfer(DataTransferOperation op)
188
    {
189
      setDataTransfer(DataTransfer(op, basis_));
190
191
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
192
193
  protected:

194
195
    /// Override of Observer update(event::preAdapt) method. Redirects to preAdapt method of the
    /// \ref DataTransfer object.
Praetorius, Simon's avatar
Praetorius, Simon committed
196
    void updateImpl(event::preAdapt e) override
197
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
198
      dataTransfer_.preAdapt(*this, e.value);
199
200
    }

201
202
    /// Override of Observer update(event::adapt) method. Redirects to adapt method of the
    /// \ref DataTransfer object.
Praetorius, Simon's avatar
Praetorius, Simon committed
203
    void updateImpl(event::adapt e) override
204
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
205
      assert(e.value);
206
      resize();
207
      dataTransfer_.adapt(*this);
208
209
    }

210
211
    /// Override of Observer update(event::postAdapt) method. Redirects to postAdapt method of the
    /// \ref DataTransfer object.
Praetorius, Simon's avatar
Praetorius, Simon committed
212
    void updateImpl(event::postAdapt) override
213
    {
214
      dataTransfer_.postAdapt(*this);
215
216
217
218
219
    }

  private:
    /// Data interpolation when the grid changes, set by default
    /// to \ref DataTransferOperation::INTERPOLATE.
220
221
    DataTransfer dataTransfer_;

Praetorius, Simon's avatar
Praetorius, Simon committed
222
    std::shared_ptr<GlobalBasis const> basis_;
223
224
  };

225
226

  // deduction guides
227
228
  template <class GB>
  DOFVector(GB&& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
229
    -> DOFVector<Underlying_t<GB>>;
230

231
232
233
234
  template <class GV, class PBF>
  DOFVector(GV const& gridView, PBF const& pbf, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
    -> DOFVector<decltype(ParallelGlobalBasis{gridView,pbf})>;

235
236
237
238
239
240
241
242
243
244
245

  /// \brief Create a DOFVector from a basis.
  /**
   * This generator function accepts the basis as reference, temporary, or
   * shared_ptr. Internally the reference is wrapped into a non-destroying
   * shared_ptr and the temporary is moved into a new shared_ptr.
   *
   * The DataTransferOperation controls what is done during grid changes with the
   * DOFVector. The default is interpolation of the data to the new grid. See
   * \ref DataTransferOperation for more options.
   **/
246
  template <class ValueType = double, class GB>
247
  DOFVector<Underlying_t<GB>, ValueType>
248
  makeDOFVector(GB&& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
249
250
251
252
  {
    return {FWD(basis), op};
  }

Praetorius, Simon's avatar
Praetorius, Simon committed
253
  /// A Generator for a mutable \ref DiscreteFunction
254
255
  template <class GB, class T, class... Indices>
  auto discreteFunction(DOFVector<GB,T>& dofVec, Indices... ii)
Praetorius, Simon's avatar
Praetorius, Simon committed
256
  {
257
    return dofVec.discreteFunction(ii...);
Praetorius, Simon's avatar
Praetorius, Simon committed
258
259
260
  }

  /// A Generator for a mutable \ref DiscreteFunction
261
262
  template <class GB, class T, class... Indices>
  auto discreteFunction(DOFVector<GB,T> const& dofVec, Indices... ii)
Praetorius, Simon's avatar
Praetorius, Simon committed
263
  {
264
    return dofVec.discreteFunction(ii...);
Praetorius, Simon's avatar
Praetorius, Simon committed
265
266
  }

267
268
269
} // end namespace AMDiS

#include <amdis/DOFVector.inc.hpp>