DOFVector.hpp 5.08 KB
Newer Older
1
2
#pragma once

3
#include <algorithm>
4
#include <memory>
5
#include <string>
6

7
8
#include <dune/common/reservedvector.hh>
#include <dune/functions/functionspacebases/flatmultiindex.hh>
9
10
#include <dune/functions/functionspacebases/interpolate.hh>

11
12
13
14
15
#include <amdis/Output.hpp>
#include <amdis/common/ClonablePtr.hpp>
#include <amdis/common/ScalarTypes.hpp>
#include <amdis/linear_algebra/mtl/MTLDenseVector.hpp>
#include <amdis/utility/MultiIndex.hpp>
16
17
18

namespace AMDiS
{
19
20
  /// The basic container that stores a base vector and a corresponding basis
  template <class GlobalBasis, class RangeType = double>
21
22
23
  class DOFVector
  {
    using Self = DOFVector;
24

25
  public:
26
27
    /// The type of the \ref basis
    using Basis = GlobalBasis;
28

29
    /// The type of the base vector
30
    using BaseVector = MTLDenseVector<RangeType>;
31

32
    /// The index/size - type
33
    using size_type  = typename GlobalBasis::size_type;
34

35
    /// The type of the elements of the DOFVector
36
    using range_type = RangeType;
37

38
    /// Constructor. Constructs new BaseVector.
39
40
41
42
    DOFVector(GlobalBasis const& basis, std::string name)
      : basis_(&basis)
      , name_(name)
      , vector_(ClonablePtr<BaseVector>::make())
43
44
45
    {
      compress();
    }
46

47
    /// Constructor. Takes reference to existing BaseVector
48
    DOFVector(GlobalBasis const& basis, std::string name,
49
              BaseVector& vector_ref)
50
51
52
      : basis_(&basis)
      , name_(name)
      , vector_(vector_ref)
53
    {}
54

55
56
    /// Return the basis \ref basis of the vector
    Basis const& basis() const
57
    {
58
        return *basis_;
59
    }
60

61
    /// Return the data-vector \ref vector
62
    BaseVector const& vector() const
63
    {
64
      return *vector_;
65
    }
66

67
    /// Return the data-vector \ref vector
68
    BaseVector& vector()
69
    {
70
      return *vector_;
71
    }
72

73
74
    /// Return the size of the \ref basis
    size_type size() const
75
    {
76
      return basis_->dimension();
77
    }
78

79
    /// Return the \ref name of this vector
80
    std::string name() const
81
    {
82
      return name_;
83
    }
84

85
    /// Resize the \ref vector to the size of the \ref basis.
86
87
    void compress()
    {
88
89
90
      if (num_rows(*vector_) != size()) {
        resize(size());
        *vector_ = range_type(0);
91
      }
92
    }
93

94
95
    template <class SizeInfo>
    void resize(SizeInfo s)
96
    {
97
      vector_->change_dim(size_type(s));
98
    }
99

100

101
102
    /// Access the entry \p i of the \ref vector with read-access.
    template <class Index>
103
    range_type const& operator[](Index idx) const
104
    {
105
      auto const i = flatMultiIndex(idx);
106
107
108
      test_exit_dbg( i < num_rows(*vector_) ,
        "Index ", i, " out of range [0,", num_rows(*vector_), ")" );
      return (*vector_)[i];
109
110
    }

111
112
    /// Access the entry \p i of the \ref vector with write-access.
    template <class Index>
113
    range_type& operator[](Index idx)
114
    {
115
      auto const i = flatMultiIndex(idx);
116
117
118
      test_exit_dbg( i < num_rows(*vector_) ,
        "Index ", i, " out of range [0,", num_rows(*vector_), ")" );
      return (*vector_)[i];
119
120
    }

121
    /// \brief interpolate a function \p f to the basis \ref basis and store the
122
123
    /// coefficients in \ref vector.
    template <class F>
124
    void interpol(F&& f)
125
    {
126
      Dune::Functions::interpolate(*basis_, *this, std::forward<F>(f));
127
    }
128

129
130
    /// Scale each DOFVector by the factor \p s.
    template <class Scalar>
131
    std::enable_if_t< Concepts::Arithmetic<Scalar>, Self&>
132
133
    operator*=(Scalar s)
    {
134
      (*vector_) *= s;
135
136
      return *this;
    }
137

138
139
    /// Sets each DOFVector to the scalar \p s.
    template <class Scalar>
140
    std::enable_if_t< Concepts::Arithmetic<Scalar>, Self&>
141
142
    operator=(Scalar s)
    {
143
      (*vector_) = s;
144
145
      return *this;
    }
146

147
148
149
    /// Calls the copy assignment operator of the BaseVector \ref vector
    void copy(Self const& that)
    {
150
      *vector_ = *that.vector_;
151
    }
152

153
  private:
154
    /// The finite element space / basis associated with the data vector
155
    Basis const* basis_;
156

157
    /// The name of the DOFVector (used in file-writing)
158
    std::string	name_;
159

160
    /// The data-vector (can hold a new BaseVector or a pointer to external data
161
    ClonablePtr<BaseVector> vector_;
162

163
164
165
    // friend class declarations
    template <class, class> friend class SystemVector;
  };
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
  // Deduction rules
  template <class GlobalBasis>
  DOFVector(GlobalBasis const& basis, std::string name)
    -> DOFVector<GlobalBasis, double>;

  template <class GlobalBasis, class RangeType>
  DOFVector(GlobalBasis const& basis, std::string name, MTLDenseVector<RangeType>& coefficients)
    -> DOFVector<GlobalBasis, RangeType>;
#endif

  /// Constructor a dofvector from given basis and name
  template <class GlobalBasis, class RangeType = double>
  DOFVector<GlobalBasis, RangeType>
  makeDOFVector(GlobalBasis const& basis, std::string name)
182
  {
183
    return {basis, name};
184
  }
185

186
187
188
189
190
191
192
193
  /// Constructor a dofvector from given basis, name, and coefficient vector
  template <class GlobalBasis, class RangeType>
  DOFVector<GlobalBasis, RangeType>
  makeDOFVector(GlobalBasis const& basis, std::string name, MTLDenseVector<RangeType>& coefficients)
  {
    return {basis, name, coefficients};
  }

194
} // end namespace AMDiS