MultiTypeMatrix.hpp 3.91 KB
Newer Older
1
2
3
#pragma once

#include <tuple>
4
5
6
#include <type_traits>

#include <dune/common/ftraits.hh>
7

8
9
#include <amdis/common/Concepts.hpp>
#include <amdis/common/Loops.hpp>
10
#include <amdis/common/Math.hpp>
11
12
#include <amdis/common/Mpl.hpp>
#include <amdis/common/MultiTypeVector.hpp>
13
14
15
#include <amdis/common/StaticSize.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/typetree/MultiIndex.hpp>
16
17
18
19
20
21
22
23
24
25
26
27
28

namespace AMDiS
{
  // forward declaration
  template <class... Rows>
  class MultiTypeMatrix;
}

namespace Dune
{
  template <class... Rows>
  struct FieldTraits<AMDiS::MultiTypeMatrix<Rows...>>
  {
29
30
    using field_type = std::common_type_t<typename Dune::FieldTraits<Rows>::field_type...>;
    using real_type = std::common_type_t<typename Dune::FieldTraits<Rows>::real_type...>;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  };
}


namespace AMDiS
{
  // Rows should be of type MultiTypeVector
  template <class... Rows>
  class MultiTypeMatrix
      : public std::tuple<Rows...>
  {
    using Self = MultiTypeMatrix;
    using Super = std::tuple<Rows...>;

45
    static_assert(IsEqual<int, Rows::dimension...>::value,
46
47
48
49
50
51
52
      "All columns must have the same length.");

  public:
    using field_type = typename Dune::FieldTraits<Self>::field_type;
    using real_type = typename Dune::FieldTraits<Self>::real_type;
    using size_type = std::size_t;

53
54
    static constexpr int rows = std::tuple_size<Super>::value;
    static constexpr int cols = Math::max(Rows::dimension...);
55
56
57
58

    template <class... Rows_,
      REQUIRES( Concepts::Similar<Types<Rows...>, Types<Rows_...>> )>
    MultiTypeMatrix(Rows_&&... rows)
59
      : Super(FWD(rows)...)
60
61
62
63
64
65
    {}

    /// Default construction of tuple of FieldVectors
    MultiTypeMatrix() = default;

    /// Construct tuple by initializing all tuple elements with a constant value
66
    explicit MultiTypeMatrix(real_type value)
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
117
118
119
    {
      *this = value;
    }

    /// Assignment of real number to all tuple elements
    MultiTypeMatrix& operator=(real_type value)
    {
      forEach(*this, [value](auto& fv) { fv = value; });
      return *this;
    }

    // Compound assignment operator +=
    MultiTypeMatrix& operator+=(MultiTypeMatrix const& that)
    {
      forEach(range_<0,rows>, [&that,this](auto const _i) { (*this)[_i] += that[_i]; });
      return *this;
    }

    // Compound assignment operator -=
    MultiTypeMatrix& operator-=(MultiTypeMatrix const& that)
    {
      forEach(range_<0,rows>, [&that,this](auto const _i) { (*this)[_i] -= that[_i]; });
      return *this;
    }

    // Scaling of all tuple elements by a constant value
    MultiTypeMatrix& operator*=(real_type value)
    {
      forEach(*this, [value](auto& fv) { fv *= value; });
      return *this;
    }

    // Scaling of all tuple elements by the inverse of a constant value
    MultiTypeMatrix& operator/=(real_type value)
    {
      forEach(*this, [value](auto& fv) { fv /= value; });
      return *this;
    }

    /// Const access to the tuple elements
    template <std::size_t I, std::size_t J>
    decltype(auto) operator()(const index_t<I>&, const index_t<J>&) const
    {
      return std::get<J>(std::get<I>(*this));
    }

    /// Mutable access to the tuple elements
    template <std::size_t I, std::size_t J>
    decltype(auto) operator()(const index_t<I>&, const index_t<J>&)
    {
      return std::get<J>(std::get<I>(*this));
    }

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

    /// Const access to the rows
    template <std::size_t I>
    decltype(auto) operator[](const index_t<I>&) const
    {
      return std::get<I>(*this);
    }

    /// Mutable access to the rows
    template <std::size_t I>
    decltype(auto) operator[](const index_t<I>&)
    {
      return std::get<I>(*this);
    }

135
136
137
138
139
140
141
142
143
144
145
    /// Return number of elements of the tuple
    static constexpr std::size_t num_rows()
    {
      return rows;
    }

    /// Return number of elements of the tuple
    static constexpr std::size_t num_cols()
    {
      return cols;
    }
146
147
148
149
150

    static constexpr std::size_t size()
    {
      return rows;
    }
151
152
153
  };

} // end namespace AMDiS