VectorBase.hpp 3.58 KB
Newer Older
1
2
#pragma once

Praetorius, Simon's avatar
Praetorius, Simon committed
3
#include <iterator>
4
5

#include <dune/common/rangeutilities.hh>
Praetorius, Simon's avatar
Praetorius, Simon committed
6
#include <dune/functions/functionspacebases/flatmultiindex.hh>
7
8

#include <amdis/common/FakeContainer.hpp>
Praetorius, Simon's avatar
Praetorius, Simon committed
9
#include <amdis/utility/MappedRangeView.hpp>
10
11
12

namespace AMDiS
{
Praetorius, Simon's avatar
Praetorius, Simon committed
13
14
  /// \brief CRTP base class for flat vector backends
  template <class Derived>
15
16
17
  class VectorBase
  {
  private:
Praetorius, Simon's avatar
Praetorius, Simon committed
18
    Derived const& asDerived() const
19
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
20
      return static_cast<Derived const&>(*this);
21
22
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
23
    Derived& asDerived()
24
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
25
      return static_cast<Derived&>(*this);
26
27
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
28
29
30
31
  protected:
    /// Protected constructor prevents from direct construction of this class.
    /// Only use it as base class in the sense of CRTP.
    VectorBase() = default;
32

Praetorius, Simon's avatar
Praetorius, Simon committed
33
34
35
  public:
    void finish() { /* do nothing */ }
    void synchronize() { /* do nothing */ }
36

Praetorius, Simon's avatar
Praetorius, Simon committed
37
38
39
    /// Insert or add \p value at position \p idx, using the passed \p assign functor.
    template <class MultiIndex, class ValueType, class Assign>
    void insert(MultiIndex const& idx, ValueType const& value, Assign assign)
40
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
41
      assign(value, asDerived().at(idx));
42
43
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
44
45
46
    /// Gather values from the vector into the output range \p buffer decribed as an output iterator
    template <class IndexRange, class OutputIterator>
    void gather(IndexRange const& localInd, OutputIterator buffer) const
47
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
48
49
      for (auto const& idx : localInd)
        *buffer++ = asDerived().at(idx);
50
51
52
    }


Praetorius, Simon's avatar
Praetorius, Simon committed
53
54
55
    /// Scatter the values from the local \p vec into the container using the passed \p assign functor.
    template <class IndexRange, class LocalVec, class Assign>
    void scatter(IndexRange const& localInd, LocalVec const& vec, FakeContainer<bool,true>, Assign assign)
56
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
57
58
59
      auto vec_it = std::begin(vec);
      for (auto const& idx : localInd)
        assign(*vec_it++, asDerived().at(idx));
60
61
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
62
63
64
65
    /// Scatter some values from the local \p vec into the container using the passed \p assign functor.
    /// The values to scatter are selected using the \p mask range that needs to be forward iterable.
    template <class IndexRange, class LocalVec, class MaskRange, class Assign>
    void scatter(IndexRange const& localInd, LocalVec const& vec, MaskRange const& mask, Assign assign)
66
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
67
68
69
70
71
72
73
      auto vec_it = std::begin(vec);
      auto mask_it = std::begin(mask);
      auto ind_it = std::begin(localInd);
      for (; vec_it != std::end(vec); ++vec_it, ++mask_it, ++ind_it) {
        if (*mask_it)
          assign(*vec_it, asDerived().at(*ind_it));
      }
74
75
76
    }


Praetorius, Simon's avatar
Praetorius, Simon committed
77
78
79
    /// Apply the functor \p f to all entries of the list of multi-indices \p localInd.
    template <class IndexRange, class Func>
    void forEach(IndexRange const& localInd, Func&& f) const
80
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
81
82
      for (auto const& idx : localInd)
        f(idx, asDerived().at(idx));
83
84
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
85
86
87
    /// Apply the functor \p f to all entries of the list of multi-indices \p localInd.
    template <class IndexRange, class Func>
    void forEach(IndexRange const& localInd, Func&& f)
88
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
89
90
      for (auto const& idx : localInd)
        f(idx, asDerived().at(idx));
91
92
93
    }


Praetorius, Simon's avatar
Praetorius, Simon committed
94
    /// Apply the functor \p f to all entries of the container
95
    template <class Func>
Praetorius, Simon's avatar
Praetorius, Simon committed
96
    void forEach(Func&& f) 
97
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
98
99
      forEach(mappedRangeView(Dune::range(asDerived().size()),
        [](auto i) { return Dune::Functions::FlatMultiIndex<decltype(i)>{i}; }), FWD(f));
100
101
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
102
    /// Apply the functor \p f to all entries of the container
103
    template <class Func>
Praetorius, Simon's avatar
Praetorius, Simon committed
104
    void forEach(Func&& f) const 
105
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
106
107
      forEach(mappedRangeView(Dune::range(asDerived().size()),
        [](auto i) { return Dune::Functions::FlatMultiIndex<decltype(i)>{i}; }), FWD(f));
108
109
110
111
    }
  };

} // end namespace AMDiS