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

3
#include <cmath>
4

5
#include <dune/functions/functionspacebases/sizeinfo.hh>
6

7
#include <amdis/common/Math.hpp>
8
9
10
11
12
13
14
#include <amdis/common/ScalarTypes.hpp>
#include <amdis/linear_algebra/DOFVectorInterface.hpp>
#include <amdis/utility/MultiIndex.hpp>

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

  public:
    /// The type of the \ref basis
    using Basis = BasisType;

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

28
29
30
31
32
33
    /// The type of the elements of the DOFVector
    using value_type = typename Backend::value_type;

    using BaseVector = typename Backend::BaseVector;

  public:
34
35
36
    /// Constructor. Constructs new BaseVector.
    DOFVectorBase(BasisType const& basis)
      : basis_(&basis)
37
38
39
    {
      compress();
    }
40

41
    /// Return the basis \ref basis_ associated to the vector
42
43
    Basis const& basis() const
    {
44
45
46
47
48
49
50
51
52
53
54
55
56
      return *basis_;
    }

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

    /// Return the data-vector
    BaseVector& vector()
    {
      return backend_.vector();
57
58
59
60
61
62
63
64
    }

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

65
66
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    void resize(Dune::Functions::SizeInfo<Basis> const& s)
    {
      backend_.resize(size_type(s));
    }

    /// Resize the \ref vector to the size of the \ref basis.
    virtual void compress() override
    {
      if (backend_.size() != size()) {
        backend_.resize(size());
        vector() = 0;
      }
    }

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

    /// Insert a block of values into the matrix (add to existing values)
    template <class ElementVector>
    void insert(typename Basis::LocalView const& localView,
                ElementVector const& elementVector)
    {
      for (size_type i = 0; i < localView.size(); ++i) {
        if (std::abs(elementVector[i]) > threshold<double>) {
          size_type const idx = flatMultiIndex(localView.index(i));
          backend_[idx] += elementVector[i];
        }
      }
    }

    /// Sets each DOFVector to the scalar \p value.
    template <class Scalar,
      std::enable_if_t<Concepts::Arithmetic<Scalar>, int> = 0>
    Self& operator=(Scalar value)
    {
      vector() = value;
      return *this;
    }

117
118
119
  private:
    /// The finite element space / basis associated with the data vector
    Basis const* basis_;
120
121

    Backend backend_;
122
123
124
  };

} // end namespace AMDiS