Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
StateRow.hpp
Go to the documentation of this file.
1 // Copyright (c) 2019 Maikel Nadolski
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #ifndef FUB_STATE_ROW_HPP
22 #define FUB_STATE_ROW_HPP
23 
24 #include "fub/State.hpp"
25 #include "fub/core/tuple.hpp"
26 
27 namespace fub {
28 
29 template <typename T, typename Depth> struct DepthToRowType {
31 };
32 
33 template <typename T> struct DepthToRowType<T, ScalarDepth> {
34  using type = span<T>;
35 };
36 
37 template <typename State> struct RowBaseImpl {
38  template <typename Depth>
40  using type = boost::mp11::mp_transform<fn, meta::Depths<State>>;
41 };
42 
43 template <typename State> struct RowBaseImpl<const State> {
44  template <typename Depth>
46  using type = boost::mp11::mp_transform<fn, meta::Depths<State>>;
47 };
48 
49 template <typename State> using RowBase = typename RowBaseImpl<State>::type;
50 
51 template <typename State> struct Row : RowBase<State> {
52  static constexpr int Rank = 1;
54  using ElementType =
55  std::conditional_t<std::is_const_v<State>, const double, double>;
56 
57  Row() = default;
58 
59  Row(const ViewPointer<State>& pointer, std::ptrdiff_t extent) {
61  overloaded{[extent](span<ElementType>& s, auto p) {
62  s = span<ElementType>(p, extent);
63  },
65  const auto& p) {
67  dynamic_extents<2>{extent, 2}, {1, p.second}};
69  mapping);
70  }},
71  *this, pointer);
72  }
73 };
74 
75 template <typename State>
76 struct StateTraits<Row<State>> : StateTraits<RowBase<State>> {};
77 
78 template <typename State> ViewPointer<State> Begin(const Row<State>& row) {
79  ViewPointer<State> pointer;
81  overloaded{
82  [&](double*& p, span<double> s) { p = s.begin(); },
83  [&](const double*& p, span<const double> s) { p = s.begin(); },
84  [&](auto& p, const mdspan<double, 2, layout_stride>& mds) {
85  p = std::pair{mds.get_span().begin(), mds.stride(1)};
86  },
87  [&](auto& p, const mdspan<const double, 2, layout_stride>& mds) {
88  p = std::pair{mds.get_span().begin(), mds.stride(1)};
89  }},
90  pointer, row);
91  return pointer;
92 }
93 
94 template <typename State> ViewPointer<State> End(const Row<State>& row) {
95  ViewPointer<State> pointer;
97  overloaded{
98  [&](double*& p, span<double> s) { p = s.end(); },
99  [&](const double*& p, span<const double> s) { p = s.end(); },
100  [&](auto& p, const mdspan<double, 2, layout_stride>& mds) {
101  p = std::pair{mds.get_span().end(), mds.stride(1)};
102  },
103  [&](auto& p, const mdspan<const double, 2, layout_stride>& mds) {
104  p = std::pair{mds.get_span().end(), mds.stride(1)};
105  }},
106  pointer, row);
107  return pointer;
108 }
109 
110 template <Direction Dir> struct ToStride {
111  template <typename T, int R, typename L>
112  std::ptrdiff_t operator()(const PatchDataView<T, R, L>& pdv) const {
113  if constexpr (R == 1) {
114  return pdv.Extent(0);
115  } else {
116  return pdv.Stride(static_cast<int>(Dir));
117  }
118  }
119 
120  template <typename T, typename L, int R>
121  std::ptrdiff_t operator()(const BasicView<T, L, R>& view) const {
122  return get<0>(view).Stride(static_cast<int>(Dir));
123  }
124 };
125 
126 template <Direction Dir, typename T, int R, typename L>
127 std::ptrdiff_t Extent(const PatchDataView<T, R, L>& pdv) {
128  return pdv.Extent(static_cast<std::size_t>(Dir));
129 }
130 
131 template <Direction Dir, typename T, typename L, int R>
132 std::ptrdiff_t Extent(const BasicView<T, L, R>& view) {
133  return Extent<Dir>(get<0>(view));
134 }
135 
136 struct ToRow {
137  std::ptrdiff_t extent;
138 
139  template <typename T> span<T> operator()(T* pointer) {
140  return {pointer, extent};
141  }
142 
143  template <typename T> Row<T> operator()(const ViewPointer<T>& pointer) {
144  return {pointer, extent};
145  }
146 };
147 
148 template <typename T> void Advance(T*& pointer, std::ptrdiff_t n) {
149  pointer += n;
150 }
151 
152 template <typename T, int R, typename L>
154  return pdv.Span().begin();
155 }
156 
157 template <typename T, int R, typename L>
158 T* End(const PatchDataView<T, R, L>& pdv) {
159  return pdv.Span().end();
160 }
161 
162 template <int N, typename T> constexpr T* GetOrForward(T* pointer) noexcept {
163  return pointer;
164 }
165 
166 template <int N, typename T>
167 constexpr decltype(auto) GetOrForward(const ViewPointer<T>& pointer) noexcept {
168  return get<N>(pointer);
169 }
170 
171 template <typename Tuple, typename Function>
172 void ForEachRow(const Tuple& views, Function f) {
173  std::tuple firsts = Transform(views, [](const auto& v) { return Begin(v); });
174  const std::ptrdiff_t row_extent = Extent<Direction::X>(std::get<0>(views));
175  if constexpr (std::tuple_element_t<0, Tuple>::rank() == 1) {
176  std::tuple rows = Transform(firsts, ToRow{row_extent});
177  std::apply(f, rows);
178  } else if constexpr (std::tuple_element_t<0, Tuple>::rank() == 2) {
179  std::tuple lasts = Transform(views, [](const auto& v) { return End(v); });
180  std::tuple strides = Transform(views, ToStride<Direction::Y>());
181  const auto& first = std::get<0>(firsts);
182  const auto& last = std::get<0>(lasts);
183  std::ptrdiff_t n = GetOrForward<0>(last) - GetOrForward<0>(first);
184  while (n >= std::get<0>(strides)) {
185  std::tuple rows = Transform(firsts, ToRow{row_extent});
186  std::apply(f, rows);
187  std::tuple firsts_and_strides = Zip(firsts, strides);
188  std::apply(
189  [](auto&... ps) { (Advance(std::get<0>(ps), std::get<1>(ps)), ...); },
190  firsts_and_strides);
191  firsts = std::apply(
192  [](auto&&... fs) { return std::tuple{std::get<0>(fs)...}; },
193  firsts_and_strides);
194  n = GetOrForward<0>(last) - GetOrForward<0>(first);
195  }
196  } else {
197  const std::ptrdiff_t ny = Extent<Direction::Y>(std::get<0>(views));
198  const std::ptrdiff_t nz = Extent<Direction::Z>(std::get<0>(views));
199  std::tuple strides_y = Transform(views, ToStride<Direction::Y>());
200  std::tuple strides_z = Transform(views, ToStride<Direction::Z>());
201  for (std::ptrdiff_t j = 0; j < nz; ++j) {
202  std::tuple pointers = firsts;
203  for (std::ptrdiff_t i = 0; i < ny; ++i) {
204  std::tuple rows = Transform(pointers, ToRow{row_extent});
205  std::apply(f, rows);
206  pointers = std::apply(
207  [](auto... ps) {
208  (Advance(std::get<0>(ps), std::get<1>(ps)), ...);
209  return std::tuple{std::get<0>(ps)...};
210  },
211  Zip(pointers, strides_y));
212  }
213  firsts = std::apply(
214  [](auto... ps) {
215  (Advance(std::get<0>(ps), std::get<1>(ps)), ...);
216  return std::tuple{std::get<0>(ps)...};
217  },
218  Zip(firsts, strides_z));
219  }
220  }
221 }
222 
223 } // namespace fub
224 
225 #endif
Definition: mdspan.hpp:573
Definition: mdspan.hpp:473
A span is a view over a contiguous sequence of objects, the storage of which is owned by some other o...
Definition: span.hpp:81
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
constexpr auto Transform(Tuple &&tuple, Function f)
Definition: tuple.hpp:53
void ForEachVariable(F function, Ts &&... states)
Definition: State.hpp:89
typename dynamic_extents_< make_index_sequence< Rank > >::type dynamic_extents
Definition: mdspan.hpp:725
void ForEachRow(const Tuple &views, Function f)
Definition: StateRow.hpp:172
ViewPointer< State > Begin(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:769
std::ptrdiff_t Extent(const PatchDataView< T, R, L > &pdv)
Definition: StateRow.hpp:127
void Advance(ViewPointer< State > &pointer, std::ptrdiff_t n) noexcept
Definition: State.hpp:825
constexpr auto Zip(Ts &&... ts)
Definition: State.hpp:65
ViewPointer< State > End(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:782
constexpr T * GetOrForward(T *pointer) noexcept
Definition: StateRow.hpp:162
typename RowBaseImpl< State >::type RowBase
Definition: StateRow.hpp:49
Definition: State.hpp:403
Definition: StateRow.hpp:29
Definition: PatchDataView.hpp:201
std::ptrdiff_t Stride(std::size_t n) const
Definition: PatchDataView.hpp:228
std::ptrdiff_t Extent(std::size_t n) const
Definition: PatchDataView.hpp:230
span< T > Span() const noexcept
Definition: PatchDataView.hpp:226
boost::mp11::mp_transform< fn, meta::Depths< State > > type
Definition: StateRow.hpp:46
typename DepthToRowType< const double, Depth >::type fn
Definition: StateRow.hpp:45
Definition: StateRow.hpp:37
boost::mp11::mp_transform< fn, meta::Depths< State > > type
Definition: StateRow.hpp:40
typename DepthToRowType< double, Depth >::type fn
Definition: StateRow.hpp:39
Definition: StateRow.hpp:51
std::conditional_t< std::is_const_v< State >, const double, double > ElementType
Definition: StateRow.hpp:55
Row()=default
Row(const ViewPointer< State > &pointer, std::ptrdiff_t extent)
Definition: StateRow.hpp:59
static constexpr int Rank
Definition: StateRow.hpp:52
This type is used to tag scalar quantities.
Definition: State.hpp:109
Definition: StateRow.hpp:136
span< T > operator()(T *pointer)
Definition: StateRow.hpp:139
std::ptrdiff_t extent
Definition: StateRow.hpp:137
Row< T > operator()(const ViewPointer< T > &pointer)
Definition: StateRow.hpp:143
Definition: StateRow.hpp:110
std::ptrdiff_t operator()(const PatchDataView< T, R, L > &pdv) const
Definition: StateRow.hpp:112
std::ptrdiff_t operator()(const BasicView< T, L, R > &view) const
Definition: StateRow.hpp:121
Definition: State.hpp:750
Definition: type_traits.hpp:291