DOFVectorBase.hpp 6.77 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
92
93
94
95
    /// 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
    virtual ~DOFVectorBase() override
    {
      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
152
    virtual void compress() override
    {
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
217
218
219
220
221
222
223
224
225
226
227
    /// 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
    virtual void preAdapt(bool mightCoarsen) override
    {
      dataTransfer_->preAdapt(*this, mightCoarsen);
    }

    /// Implementation of \ref DOFVectorInterface::postAdapt
    virtual void postAdapt(bool refined) override
    {
      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"