DOFVectorBase.hpp 6.46 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
19

namespace AMDiS
{
  /// The basic container that stores a base vector and a corresponding basis
20
  template <class BasisType, class Backend>
21
22
23
24
25
26
  class DOFVectorBase
      : public DOFVectorInterface
  {
    using Self = DOFVectorBase;

  public:
27
    /// The type of the functionspace basis associated to this vector
28
    using Basis = BasisType;
29
30
31
32
    using LocalView = typename Basis::LocalView;

    using Element = typename LocalView::Element;
    using Geometry = typename Element::Geometry;
33
34
35
36

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

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

40
    /// The type of the data vector used in the backend
41
    using BaseVector = typename Backend::BaseVector;
42
    using ElementVector = Dune::DynamicVector<double>;
43

44
45
46
47
48
49
    /// 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>;

50
  public:
51
    /// Constructor. Constructs new BaseVector.
52
    DOFVectorBase(BasisType const& basis, DataTransferOperation op = NO_OPERATION)
53
      : basis_(&basis)
54
      , dataTransfer_(DataTransferFactory::create(op, basis))
55
56
    {
      compress();
57
      GridTransferManager::attach(*this);
58
      operators_.init(basis);
59
    }
60

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    /// 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);
    }
88
89
90
91

    /// Copy assignment operator
    Self& operator=(Self const& that)
    {
92
      GridTransferManager::detach(*this);
93
      basis_ = that.basis_;
94
95
      backend_.resize(that.size());
      backend_ = that.backend_;
96
97
      dataTransfer_ = that.dataTransfer_;
      GridTransferManager::attach(*this);
98
99
100
101
102
103
104
      return *this;
    }

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

    /// Sets each DOFVector to the scalar \p value.
105
106
107
    template <class Number,
      std::enable_if_t<Dune::IsNumber<Number>::value, int> = 0>
    Self& operator=(Number value)
108
    {
109
      backend_.set(value);
110
111
112
      return *this;
    }

113
    /// Return the basis \ref basis_ associated to the vector
114
115
    Basis const& basis() const
    {
116
117
118
119
120
121
122
123
124
125
126
127
128
      return *basis_;
    }

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

    /// Return the data-vector
    BaseVector& vector()
    {
      return backend_.vector();
129
130
131
132
133
134
135
136
    }

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

137
138
139
140
141
    void resize(Dune::Functions::SizeInfo<Basis> const& s)
    {
      backend_.resize(size_type(s));
    }

142
    /// Resize the \ref vector to the size of the \ref basis and set to zero
143
144
    virtual void compress() override
    {
145
      if (size_type(backend_.size()) != size()) {
146
        backend_.resize(size());
147
        backend_.set(0);
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
      }
    }

    /// 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];
    }

167
    void init(bool asmVector);
168

169
    void finish(bool asmVector);
170

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

174
175
176
    /// Associate a local operator with this DOFVector
    template <class ContextTag, class Operator, class TreePath = RootTreePath>
    void addOperator(ContextTag contextTag, Operator const& preOp, TreePath path = {});
177

178
179
    /// Assemble the vector operators on the bound element.
    void assemble(LocalView const& localView);
180

181
182
    /// Assemble all vector operators
    void assemble();
183

184
185
186
187
188
189
190
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
    /// 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);
    }

220
221
222
  private:
    /// The finite element space / basis associated with the data vector
    Basis const* basis_;
223

224
    /// Data backend
225
    Backend backend_;
226
227
228
229
230
231

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

    /// List of operators associated to nodes
    VectorOperators<Basis> operators_;
232
233
234

    /// Data interpolation when the grid changes
    std::shared_ptr<DataTransfer> dataTransfer_;
235
236
237
  };

} // end namespace AMDiS
238
239

#include "DOFVectorBase.inc.hpp"