DOFVectorBase.hpp 6.74 KB
Newer Older
1
2
#pragma once

3
#include <cmath>
4
#include <utility>
5

6
#include <dune/common/typetraits.hh>
7
#include <dune/functions/functionspacebases/sizeinfo.hh>
8

9
#include <amdis/DataTransfer.hpp>
10
#include <amdis/GridTransferManager.hpp>
11
#include <amdis/OperatorList.hpp>
12
#include <amdis/common/Math.hpp>
13
14
15
#include <amdis/linearalgebra/DOFVectorInterface.hpp>
#include <amdis/typetree/MultiIndex.hpp>
#include <amdis/typetree/TreePath.hpp>
16
17
18

namespace AMDiS
{
19
20
21
22
23
24
25
26
27
  /// \brief The basic container that stores a base vector and a corresponding basis
  /**
   * Basis implementation of DOFVector, i.e. a vector storing all the
   * assembled Operators indexed with DOF indices. The vector data is associated
   * to a global basis.
   *
   * \tparam B  Basis of the vector
   * \tparam Backend  A linear algebra backend implementing the storage and operations.
   **/
28
  template <class BasisType, class Backend>
29
30
31
32
33
34
  class DOFVectorBase
      : public DOFVectorInterface
  {
    using Self = DOFVectorBase;

  public:
35
    /// The type of the functionspace basis associated to this vector
36
    using Basis = BasisType;
37
38
39
40
    using LocalView = typename Basis::LocalView;

    using Element = typename LocalView::Element;
    using Geometry = typename Element::Geometry;
41
42
43
44

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

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

48
    /// The type of the data vector used in the backend
49
    using BaseVector = typename Backend::BaseVector;
50
    using ElementVector = Dune::DynamicVector<double>;
51

52
53
54
55
56
57
    /// Defines an interface to transfer the data during grid adaption
    using DataTransfer = DataTransferInterface<Self>;

    /// A creator for a concrete data transfer object, depending on \ref DataTransferOperation
    using DataTransferFactory = AMDiS::DataTransferFactory<Self>;

58
  public:
59
    /// Constructor. Constructs new BaseVector.
60
    DOFVectorBase(BasisType const& basis, DataTransferOperation op = NO_OPERATION)
61
      : basis_(&basis)
62
      , dataTransfer_(DataTransferFactory::create(op, basis))
63
64
    {
      compress();
65
      GridTransferManager::attach(*this);
66
      operators_.init(basis);
67
    }
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    /// Copy constructor
    DOFVectorBase(Self const& that)
      : basis_(that.basis_)
      , backend_(that.backend_)
      , elementVector_(that.elementVector_)
      , operators_(that.operators_)
      , dataTransfer_(that.dataTransfer_)
    {
      GridTransferManager::attach(*this);
    }

    /// Move constructor
    DOFVectorBase(Self&& that)
      : basis_(std::move(that.basis_))
      , backend_(std::move(that.backend_))
      , elementVector_(std::move(that.elementVector_))
      , operators_(std::move(that.operators_))
      , dataTransfer_(std::move(that.dataTransfer_))
    {
      GridTransferManager::attach(*this);
    }

    /// Destructor
92
    ~DOFVectorBase() override
93
94
95
    {
      GridTransferManager::detach(*this);
    }
96
97
98
99

    /// Copy assignment operator
    Self& operator=(Self const& that)
    {
100
      GridTransferManager::detach(*this);
101
      basis_ = that.basis_;
102
103
      backend_.resize(that.size());
      backend_ = that.backend_;
104
105
      dataTransfer_ = that.dataTransfer_;
      GridTransferManager::attach(*this);
106
107
108
109
110
111
112
      return *this;
    }

    /// Move assignment
    Self& operator=(Self&& that) = default;

    /// Sets each DOFVector to the scalar \p value.
113
114
115
    template <class Number,
      std::enable_if_t<Dune::IsNumber<Number>::value, int> = 0>
    Self& operator=(Number value)
116
    {
117
      backend_.set(value);
118
119
120
      return *this;
    }

121
    /// Return the basis \ref basis_ associated to the vector
122
123
    Basis const& basis() const
    {
124
125
126
127
128
129
130
131
132
133
134
135
136
      return *basis_;
    }

    /// Return the data-vector
    BaseVector const& vector() const
    {
      return backend_.vector();
    }

    /// Return the data-vector
    BaseVector& vector()
    {
      return backend_.vector();
137
138
139
140
141
142
143
144
    }

    /// Return the size of the \ref basis
    size_type size() const
    {
      return basis_->dimension();
    }

145
146
147
148
149
    void resize(Dune::Functions::SizeInfo<Basis> const& s)
    {
      backend_.resize(size_type(s));
    }

150
    /// Resize the \ref vector to the size of the \ref basis and set to zero
151
    void compress() override
152
    {
153
      if (size_type(backend_.size()) != size()) {
154
        backend_.resize(size());
155
        backend_.set(0);
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
      }
    }

    /// Access the entry \p idx of the \ref vector with read-access.
    template <class Index>
    auto const& operator[](Index idx) const
    {
      size_type i = flatMultiIndex(idx);
      return backend_[i];
    }

    /// Access the entry \p idx of the \ref vector with write-access.
    template <class Index>
    auto& operator[](Index idx)
    {
      size_type i = flatMultiIndex(idx);
      return backend_[i];
    }

175
    void init(bool asmVector);
176

177
    void finish(bool asmVector);
178

179
    /// Insert a block of values into the matrix (add to existing values)
180
    void insert(LocalView const& localView, ElementVector const& elementVector);
181

182
183
184
    /// Associate a local operator with this DOFVector
    template <class ContextTag, class Operator, class TreePath = RootTreePath>
    void addOperator(ContextTag contextTag, Operator const& preOp, TreePath path = {});
185

186
187
    /// Assemble the vector operators on the bound element.
    void assemble(LocalView const& localView);
188

189
190
    /// Assemble all vector operators
    void assemble();
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
    /// Return the associated DataTransfer object
    DataTransfer const& dataTransfer() const
    {
      return *dataTransfer_;
    }

    /// Return the associated DataTransfer object
    DataTransfer& dataTransfer()
    {
      return *dataTransfer_;
    }

    /// Create a new DataTransfer object based on the operation type
    void setDataTransfer(DataTransferOperation op)
    {
      dataTransfer_ = DataTransferFactory::create(op, this->basis());
    }

    /// Assign the DataTransfer object
    void setDataTransfer(std::shared_ptr<DataTransfer> const& dataTransfer)
    {
      dataTransfer_ = dataTransfer;
    }

    /// Implementation of \ref DOFVectorInterface::preAdapt
217
    void preAdapt(bool mightCoarsen) override
218
219
220
221
222
    {
      dataTransfer_->preAdapt(*this, mightCoarsen);
    }

    /// Implementation of \ref DOFVectorInterface::postAdapt
223
    void postAdapt(bool refined) override
224
225
226
227
    {
      dataTransfer_->postAdapt(*this, refined);
    }

228
229
230
  private:
    /// The finite element space / basis associated with the data vector
    Basis const* basis_;
231

232
    /// Data backend
233
    Backend backend_;
234
235
236
237
238
239

    /// Dense vector to store coefficients during \ref assemble()
    ElementVector elementVector_;

    /// List of operators associated to nodes
    VectorOperators<Basis> operators_;
240
241
242

    /// Data interpolation when the grid changes
    std::shared_ptr<DataTransfer> dataTransfer_;
243
244
245
  };

} // end namespace AMDiS
246
247

#include "DOFVectorBase.inc.hpp"