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"