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

#include <memory>
#include <utility>

#include <dune/common/shared_ptr.hh>

#include <amdis/DataTransfer.hpp>
#include <amdis/LinearAlgebra.hpp>
10
#include <amdis/Observer.hpp>
11
12
13
14
15
#include <amdis/common/Concepts.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/gridfunctions/GridFunction.hpp>
#include <amdis/typetree/TreePath.hpp>

16
17
18
19
20
21
22
23
24
namespace Dune
{
  namespace Functions
  {
    template <class PB>
    class DefaultGlobalBasis;
  }
}

25
26
namespace AMDiS
{
27
28
29
30
31
  // Forward declarations
  template <class PB>
  class ParallelGlobalBasis;


32
33
34
35
36
37
38
39
  /// \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
   **/
  template <class GB, class T = double>
  class DOFVector
      : public VectorBase<GB, VectorBackend<BackendTraits<GB,T>>>
Praetorius, Simon's avatar
Praetorius, Simon committed
40
41
42
      , private Observer<event::preAdapt>
      , private Observer<event::adapt>
      , private Observer<event::postAdapt>
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  {
    using Self = DOFVector;
    using Super = VectorBase<GB, VectorBackend<BackendTraits<GB,T>>>;

  public:
    using Backend = VectorBackend<BackendTraits<GB,T>>;

    using GlobalBasis = GB;

    /// The index/size - type
    using size_type  = typename GlobalBasis::size_type;

    /// The type of the elements of the DOFVector
    using value_type = typename Backend::value_type;

58
59
    /// Wrapper for the implementation of the transfer of data during grid adaption
    using DataTransfer = DataTransferWrapper<Self>;
60
61
62

  public:
    /// 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
65
              DataTransferOperation op = DataTransferOperation::INTERPOLATE)
      : Super(basis)
Praetorius, Simon's avatar
Praetorius, Simon committed
66
67
68
      , Observer<event::preAdapt>(basis->gridView().grid())
      , Observer<event::adapt>(*basis)
      , Observer<event::postAdapt>(basis->gridView().grid())
69
70
      , dataTransfer_(op, basis)
      , basis_(basis)
71
72
    {}

73
74
75
76
77
78
    /// Constructor creating a new basis from a Dune::Functions::DefaultGlobalBasis.
    // TODO(FM): Replace explicit type with concept check
    DOFVector(Dune::Functions::DefaultGlobalBasis<typename GB::PreBasis>&& basis,
              DataTransferOperation op = DataTransferOperation::INTERPOLATE)
      : DOFVector(std::make_shared<GB>(std::move(basis)), op)
    {}
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

    template <class GB_,
      REQUIRES(Concepts::Similar<GB_,GB>)>
    DOFVector(GB_&& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
      : DOFVector(Dune::wrap_or_move(FWD(basis)), op)
    {}


    template <class TreePath = RootTreePath>
    auto child(TreePath const& path = {})
    {
      auto&& tp = makeTreePath(path);
      return makeDOFVectorView(*this, tp);
    }

    template <class TreePath = RootTreePath>
    auto child(TreePath const& path = {}) const
    {
      auto&& tp = makeTreePath(path);
      return makeDiscreteFunction(*this, tp);
    }


    /// Interpolation of GridFunction to DOFVector, assuming that there is no
    /// reference to this DOFVector in the expression.
    /// See \ref DOFVectorView::interpolate_noalias
    template <class Expr, class Tag = tag::average>
    void interpolate_noalias(Expr&& expr, Tag strategy)
    {
      child().interpolate_noalias(FWD(expr), strategy);
    }

    /// Interpolation of GridFunction to DOFVector.
    /// See \ref DOFVectorView::interpolate
    template <class Expr, class Tag = tag::average>
    void interpolate(Expr&& expr, Tag strategy)
    {
      child().interpolate(FWD(expr), strategy);
    }

    /// Interpolation of GridFunction to DOFVector.
    /// See \ref DOFVectorView::interpolate
    template <class Expr>
    DOFVector& operator<<(Expr&& expr)
    {
      child().interpolate(FWD(expr));
      return *this;
    }


    /// Write DOFVector to file
    void backup(std::string const& filename);

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


    /// Return the associated DataTransfer object
137
    DataTransfer const& dataTransfer() const
138
139
140
141
142
    {
      return dataTransfer_;
    }

    /// Return the associated DataTransfer object
143
    DataTransfer& dataTransfer()
144
145
146
147
148
    {
      return dataTransfer_;
    }

    /// Assign the DataTransfer object
149
    void setDataTransfer(DataTransfer const& dataTransfer)
150
151
152
153
    {
      dataTransfer_ = dataTransfer;
    }

154
155
156
157
    void setDataTransfer(DataTransfer&& dataTransfer)
    {
      dataTransfer_ = std::move(dataTransfer);
    }
158

159
160
    /// Create a new DataTransfer object based on the operation type
    void setDataTransfer(DataTransferOperation op)
161
    {
162
      setDataTransfer(newDataTransfer(op, basis_));
163
164
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
165
166
  protected:

167
168
    /// Override of Observer update(event::preAdapt) method. Redirects to preAdapt method of the
    /// \ref DataTransfer object.
Praetorius, Simon's avatar
Praetorius, Simon committed
169
    void updateImpl(event::preAdapt e) override
170
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
171
      dataTransfer_.preAdapt(*this, e.value);
172
173
    }

174
175
    /// Override of Observer update(event::adapt) method. Redirects to adapt method of the
    /// \ref DataTransfer object.
Praetorius, Simon's avatar
Praetorius, Simon committed
176
    void updateImpl(event::adapt e) override
177
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
178
      assert(e.value);
179
180
      this->resize();
      dataTransfer_.adapt(*this);
181
182
    }

183
184
    /// Override of Observer update(event::postAdapt) method. Redirects to postAdapt method of the
    /// \ref DataTransfer object.
Praetorius, Simon's avatar
Praetorius, Simon committed
185
    void updateImpl(event::postAdapt) override
186
    {
187
      dataTransfer_.postAdapt(*this);
188
189
190
191
192
    }

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

    std::shared_ptr<GB> basis_;
196
197
198
199
200
  };

#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
  template <class GB>
  DOFVector(GB&& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
201
    -> DOFVector<ParallelGlobalBasis<typename Underlying_t<GB>::PreBasis>>;
202
203
204
205
206
207
208
209
210
211
212
213
#endif

  /// \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.
   **/
214
215
216
  template <class ValueType = double, class GB>
  DOFVector<ParallelGlobalBasis<typename Underlying_t<GB>::PreBasis>, ValueType>
  makeDOFVector(GB&& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
217
218
219
220
221
222
223
  {
    return {FWD(basis), op};
  }

} // end namespace AMDiS

#include <amdis/DOFVector.inc.hpp>