DOFVector.hpp 3.66 KB
Newer Older
1
2
3
4
#pragma once

#include <dune/istl/bvector.hh>

5
6
#include <amdis/Output.hpp>
#include <amdis/common/ClonablePtr.hpp>
7
8
#include <amdis/linear_algebra/DOFVectorBase.hpp>
#include <amdis/utility/MultiIndex.hpp>
9
10
11

namespace AMDiS
{
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  template <class T, class = void>
  struct BlockVectorType
  {
    using type = Dune::FieldVector<T,1>;
  };

  template <class T>
  struct BlockVectorType<T, typename T::field_type>
  {
    using type = T;
  };

	template <class BasisType, class ValueType = double>
	class DOFVector
      : public DOFVectorBase<BasisType>
	{
	  using Self = DOFVector;
    using Super = DOFVectorBase<BasisType>;
30

31
32
33
	public:
    /// The type of the finite element space / basis
	  using Basis = BasisType;
34

35
36
    /// The type of the elements of the DOFVector
	  using value_type = typename BlockVectorType<ValueType>::type;
37

38
39
    /// The vector type of the underlying base vector
	  using BaseVector = Dune::BlockVector<value_type>;
40

41
42
    /// The index/size - type
	  using size_type  = typename Basis::size_type;
43

44
45
46
47
48
49
50
    /// Constructor. Constructs new BaseVector.
    DOFVector(BasisType const& basis)
      : Super(basis)
      , vector_(ClonablePtr<BaseVector>::make())
    {
      compress();
    }
51

52
53
54
55
56
    /// Constructor. Takes pointer of data-vector.
    DOFVector(BasisType const& basis, Dune::BlockVector<ValueType>& vector)
      : Super(basis)
      , vector_(vector)
    {}
57

58
59
60
61
62
    /// Return the data-vector \ref vector
    BaseVector const& vector() const
    {
      return *vector_;
    }
63

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


71
72
73
74
75
76
77
78
79
80
81
82
83
84
    /// Resize the \ref vector to the size of the \ref basis.
    virtual void compress() override
    {
      if (vector_->size() != this->size()) {
        resize(this->size());
        *vector_ = value_type(0);
      }
    }

    template <class SizeInfo>
    void resize(SizeInfo s)
    {
      vector_->resize(size_type(s));
    }
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
    /// Access the entry \p i of the \ref vector with read-access.
    template <class Index>
    value_type const& operator[](Index idx) const
    {
      size_type i = flatMultiIndex(idx);
      test_exit_dbg(i < vector_->size(),
        "Index ", i, " out of range [0,", vector_->size(), ")" );
      return (*vector_)[i];
    }

    /// Access the entry \p i of the \ref vector with write-access.
    template <class Index>
    value_type& operator[](Index idx)
    {
      size_type i = flatMultiIndex(idx);
      test_exit_dbg(i < vector_->size(),
        "Index ", i, " out of range [0,", vector_->size(), ")" );
      return (*vector_)[i];
    }

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

116
117
118
119
120
    /// Calls the copy assignment operator of the BaseVector \ref vector
    void copy(Self const& that)
    {
      *vector_ = that.vector();
    }
121

122
123
124
	private:
    ClonablePtr<BaseVector> vector_;
	};
125

Praetorius, Simon's avatar
Praetorius, Simon committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
  // Deduction rule
  template <class Basis, class T>
  DOFVector(Basis const& basis, Dune::BlockVector<T>& coefficients)
    -> DOFVector<Basis, typename T::field_type>;
#endif


  /// Constructor a dofvector from given basis and name
  template <class ValueType = double, class Basis>
  DOFVector<Basis, ValueType>
  makeDOFVector(Basis const& basis)
  {
    return {basis};
  }

  /// Constructor a dofvector from given basis, name, and coefficient vector
  template <class Basis, class T>
  DOFVector<Basis, typename T::field_type>
  makeDOFVector(Basis const& basis, Dune::BlockVector<T>& coefficients)
  {
    return {basis, coefficients};
  }

150
} // end namespace AMDiS