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

3
4
5
6
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

7
8
9
#include <string>
#include <memory>

10
11
#include <dune/common/reservedvector.hh>
#include <dune/functions/functionspacebases/flatmultiindex.hh>
12
13
#include <dune/functions/functionspacebases/interpolate.hh>

14
#include <dune/amdis/Output.hpp>
15
16
#include <dune/amdis/common/ClonablePtr.hpp>
#include <dune/amdis/common/ScalarTypes.hpp>
17
#include <dune/amdis/linear_algebra/mtl/MTLDenseVector.hpp>
18
19
20

namespace AMDiS
{
21
  /// The basic container that stores a base vector and a corresponding feSpace
22
23
24
25
  template <class FeSpaceType, class ValueType = double>
  class DOFVector
  {
    using Self = DOFVector;
26

27
  public:
28
    /// The type of the \ref feSpace
29
    using FeSpace    = FeSpaceType;
30

31
    /// The type of the base vector
32
    using BaseVector = MTLDenseVector<ValueType>;
33

34
    /// The index/size - type
35
    using size_type  = typename FeSpace::size_type;
36

37
    /// The type of the elements of the DOFVector
38
    using value_type = ValueType;
39

40
    /// The underlying field-type (typically the same as \ref value_type)
41
    using field_type = typename BaseVector::value_type;
42

43
44
45
46
47
48
49
50
    /// Constructor. Constructs new BaseVector.
    DOFVector(FeSpace const& feSpace, std::string name)
      : feSpace(feSpace)
      , name(name)
      , vector(ClonablePtr<BaseVector>::make())
    {
      compress();
    }
51

52
    /// Constructor. Takes reference to existing BaseVector
53
    DOFVector(FeSpace const& feSpace, std::string name,
54
55
56
57
58
              BaseVector& vector_ref)
      : feSpace(feSpace)
      , name(name)
      , vector(vector_ref)
    {}
59

60
61
62
63
64
    /// Return the basis \ref feSpace of the vector
    FeSpace const& getFeSpace() const
    {
        return feSpace;
    }
65

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

72
73
74
75
76
    /// Return the data-vector \ref vector
    BaseVector& getVector()
    {
      return *vector;
    }
77

78
79
80
81
82
    /// Return the size of the \ref feSpace
    size_type getSize() const
    {
      return feSpace.size();
    }
83

84
85
86
87
88
    /// Return the \ref name of this vector
    std::string getName() const
    {
      return name;
    }
89

90
91
92
    /// Resize the \ref vector to the size of the \ref feSpace.
    void compress()
    {
93
94
      if (num_rows(*vector) != getSize())
        vector->change_dim(getSize());
95
    }
96
97


98
99
100
    /// Access the entry \p i of the \ref vector with read-access.
    value_type const& operator[](size_type i) const
    {
101
102
      test_exit_dbg( i < num_rows(*vector) ,
        "Index ", i, " out of range [0,", num_rows(*vector), ")" );
103
104
      return (*vector)[i];
    }
105

106
107
108
    /// Access the entry \p i of the \ref vector with write-access.
    value_type& operator[](size_type i)
    {
109
110
      test_exit_dbg( i < num_rows(*vector) ,
        "Index ", i, " out of range [0,", num_rows(*vector), ")" );
111
112
      return (*vector)[i];
    }
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

    using FlatIndex = Dune::Functions::FlatMultiIndex<size_type>;
    using BlockIndex = Dune::ReservedVector<size_type,1>;

    value_type& operator[](FlatIndex idx)
    {
      size_type i = idx[0];
      test_exit_dbg( i < num_rows(*vector) ,
        "Index ", i, " out of range [0,", num_rows(*vector), ")" );
      return (*vector)[i];
    }

    value_type& operator[](BlockIndex idx)
    {
      size_type i = idx[0];
      test_exit_dbg( i < num_rows(*vector) ,
        "Index ", i, " out of range [0,", num_rows(*vector), ")" );
      return (*vector)[i];
    }

134
    /// \brief interpolate a function \p f to the basis \ref feSpace and store the
135
136
137
138
    /// coefficients in \ref vector.
    template <class F>
    void interpol(F const& f)
    {
139
140
      // NOTE: This needs a change in mtl dense_vector implementation, i.e. we
      // have to add an alias for the function change_dim with the name resize.
141
      Dune::Functions::interpolate(feSpace, wrapper(*vector), f);
142
    }
143

144
145
    /// Scale each DOFVector by the factor \p s.
    template <class Scalar>
146
    std::enable_if_t< Concepts::Arithmetic<Scalar>, Self&>
147
148
149
150
151
    operator*=(Scalar s)
    {
      (*vector) *= s;
      return *this;
    }
152

153
154
    /// Sets each DOFVector to the scalar \p s.
    template <class Scalar>
155
    std::enable_if_t< Concepts::Arithmetic<Scalar>, Self&>
156
157
158
159
160
    operator=(Scalar s)
    {
      (*vector) = s;
      return *this;
    }
161

162
163
164
165
166
    /// Calls the copy assignment operator of the BaseVector \ref vector
    void copy(Self const& that)
    {
      *vector = that.getVector();
    }
167

168
  private:
169
    /// The finite element space / basis associated with the data vector
170
    FeSpace const& feSpace;
171

172
    /// The name of the DOFVector (used in file-writing)
173
    std::string	name;
174

175
    /// The data-vector (can hold a new BaseVector or a pointer to external data
176
    ClonablePtr<BaseVector> vector;
177

178
179
180
    // friend class declarations
    template <class, class> friend class SystemVector;
  };
181
182


183
184
185
  /// Constructor a dofvector from given feSpace and name
  template <class FeSpaceType, class ValueType = double>
  DOFVector<FeSpaceType, ValueType>
186
  makeDOFVector(FeSpaceType const& feSpace, std::string name)
187
188
189
  {
    return {feSpace, name};
  }
190
191

} // end namespace AMDiS