DOFVector.hpp 6.52 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
#include <amdis/common/Concepts.hpp>
#include <amdis/common/TypeTraits.hpp>
13
#include <amdis/gridfunctions/DiscreteFunction.hpp>
14
15
#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

    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);
91
      return makeDiscreteFunction(*this, tp);
92
93
94
95
96
97
98
99
100
101
102
103
    }

    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.
104
    /// See \ref DiscreteFunction::interpolate_noalias
105
106
107
108
109
110
111
    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.
112
    /// See \ref DiscreteFunction::interpolate
113
114
115
116
117
118
119
    template <class Expr, class Tag = tag::average>
    void interpolate(Expr&& expr, Tag strategy)
    {
      child().interpolate(FWD(expr), strategy);
    }

    /// Interpolation of GridFunction to DOFVector.
120
    /// See \ref DiscreteFunction::interpolate
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    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>