Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
StateArray.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_ARRAY_HPP
22 #define FUB_STATE_ARRAY_HPP
23 
24 #include "fub/State.hpp"
25 #include "fub/ext/Eigen.hpp"
26 #include <boost/mp11/algorithm.hpp>
27 
28 namespace fub {
29 namespace detail {
30 template <typename Depths, int Width> struct ArrayStateBaseImpl {
31  template <typename T>
32  using fn = typename DepthToStateValueTypeImpl<T, Width>::type;
33  using type = boost::mp11::mp_transform<fn, Depths>;
34 };
35 } // namespace detail
36 
37 template <typename Depths, int Width>
38 using ArrayStateBase = typename detail::ArrayStateBaseImpl<Depths, Width>::type;
39 
40 template <typename Depths, int Width>
41 struct ArrayState : ArrayStateBase<Depths, Width> {
44 
45  using Base::Base;
46 
47  template <typename Equation>
48  ArrayState(const Equation& eq) : Base{} {
49  auto depths = ::fub::Depths(eq, Type<ArrayState>{});
51  overloaded{
52  [&](Array1d& id, ScalarDepth) { id = Array1d::Zero(); },
53  [&](auto&& ids, auto depth) {
54  if constexpr (std::is_same_v<std::decay_t<decltype(depth)>,
55  int>) {
56  ids = ArrayXd::Zero(depth, kDefaultChunkSize);
57  } else {
58  ids = Array<double, decltype(depth)::value>::Zero();
59  }
60  },
61  },
62  *this, depths);
63  }
64 
65  ArrayState& operator+=(const Base& other) {
66  ForEachVariable([](auto&& that, auto&& other) { that += other; }, *this,
67  other);
68  return *this;
69  }
70 
71  ArrayState& operator-=(const Base& other) {
72  ForEachVariable([](auto&& that, auto&& other) { that -= other; }, *this,
73  other);
74  return *this;
75  }
76 
77  ArrayState& operator*=(double lambda) {
78  ForEachVariable([lambda](auto&& that) { that *= lambda; },
79  *this);
80  return *this;
81  }
82 };
83 
84 template <typename Depths, int Width>
85 struct StateTraits<ArrayState<Depths, Width>>
86  : StateTraits<ArrayStateBase<Depths, Width>> {};
87 
88 template <typename Eq, int Width = kDefaultChunkSize>
89 struct PrimitiveArray : ArrayState<typename Eq::PrimitiveDepths, Width> {
91 
92  using Base::Base;
93 };
94 
95 template <typename Eq, int Width>
96 struct StateTraits<PrimitiveArray<Eq, Width>>
97  : StateTraits<ArrayState<typename Eq::PrimitiveDepths, Width>> {};
98 
99 template <typename Eq, int Width = kDefaultChunkSize>
101  : ArrayState<typename Eq::CharacteristicsDepths, Width> {
103 
104  using Base::Base;
105 };
106 
107 template <typename Eq, int Width = kDefaultChunkSize>
108 struct KineticStateArray : ArrayState<typename Eq::KineticStateDepths, Width> {
110 
111  using Base::Base;
112 };
113 
114 template <typename Eq, int Width>
115 struct StateTraits<KineticStateArray<Eq, Width>>
116  : StateTraits<ArrayState<typename Eq::KineticStateDepths, Width>> {};
117 
118 template <typename Eq, int Width>
120  : StateTraits<ArrayState<typename Eq::CharacteristicsDepths, Width>> {};
121 
122 namespace detail {
123 template <typename Eq, int Width> struct ConservativeArrayBaseImpl {
124  template <typename T>
125  using fn = typename DepthToStateValueTypeImpl<T, Width>::type;
126  using type = boost::mp11::mp_transform<fn, typename Eq::ConservativeDepths>;
127 };
128 } // namespace detail
129 
130 template <typename Eq, int Width = kDefaultChunkSize>
132  typename detail::ConservativeArrayBaseImpl<Eq, Width>::type;
133 
134 template <typename Eq, int Width = kDefaultChunkSize>
136  using Equation = Eq;
137  // using Depths = typename Equation::ConservativeDepths;
139 
140  static constexpr int Size() { return Width; }
141 
142  ConservativeArray() = default;
144  auto depths = fub::Depths(eq, Type<Conservative<Equation>>{});
146  overloaded{
147  [&](Array1d& id, ScalarDepth) { id = Array1d::Zero(); },
148  [&](auto&& ids, auto depth) {
149  if constexpr (std::is_same_v<std::decay_t<decltype(depth)>,
150  int>) {
151  ids = ArrayXd::Zero(depth, kDefaultChunkSize);
152  } else {
153  ids = Array<double, decltype(depth)::value>::Zero();
154  }
155  },
156  },
157  *this, depths);
158  }
159 };
160 
161 template <typename Eq, int Width>
162 struct StateTraits<ConservativeArray<Eq, Width>>
163  : StateTraits<ConservativeArrayBase<Eq, Width>> {};
164 
165 namespace detail {
166 template <typename Eq, int Width> struct CompleteArrayBaseImpl {
167  template <typename T>
168  using fn = typename DepthToStateValueTypeImpl<T, Width>::type;
169  using type = boost::mp11::mp_transform<fn, typename Eq::CompleteDepths>;
170 };
171 } // namespace detail
172 
173 template <typename Eq, int Width>
175  typename detail::CompleteArrayBaseImpl<Eq, Width>::type;
176 
177 template <typename Eq, int Width = kDefaultChunkSize>
178 struct CompleteArray : CompleteArrayBase<Eq, Width> {
179  using Equation = Eq;
180  // using Depths = typename Equation::CompleteDepths;
182 
183  static constexpr int Size() { return Width; }
184 
185  CompleteArray() = default;
186  CompleteArray(const Equation& eq) {
187  auto depths = fub::Depths(eq, Type<Complete<Equation>>{});
189  overloaded{
190  [&](Array1d& id, ScalarDepth) { id = Array1d::Zero(); },
191  [&](auto&& ids, auto depth) {
192  if constexpr (std::is_same_v<std::decay_t<decltype(depth)>,
193  int>) {
194  ids = ArrayXd::Zero(depth, kDefaultChunkSize);
195  } else {
196  ids = Array<double, decltype(depth)::value>::Zero();
197  }
198  },
199  },
200  *this, depths);
201  }
202 };
203 
204 template <typename Eq, int Width>
205 struct StateTraits<CompleteArray<Eq, Width>>
206  : StateTraits<CompleteArrayBase<Eq, Width>> {};
207 
208 template <typename Eq, int N>
210  return x;
211 }
212 
213 template <typename Eq, int N>
215  return x;
216 }
217 
218 template <typename Eq, int N>
220  return x;
221 }
222 
223 template <typename Eq, int N>
225  return x;
226 }
227 
228 template <typename Eq, int N>
229 void Load(Conservative<Eq>& q, const ConservativeArray<Eq, N>& qs, int i) {
230  ForEachComponent([&](auto& qi, auto qsi) { qi = qsi[i]; }, q, qs);
231 }
232 
233 template <typename Eq, int N>
234 void Load(Complete<Eq>& q, const CompleteArray<Eq, N>& qs, int i) {
235  ForEachComponent([&](auto& qi, auto qsi) { qi = qsi[i]; }, q, qs);
236 }
237 
238 template <typename Eq, int N, typename Layout, std::size_t Rank>
240  nodeduce_t<const BasicView<const Conservative<Eq>, Layout,
241  static_cast<int>(Rank)>&>
242  view,
243  std::array<std::ptrdiff_t, Rank> index) {
245  [&](auto& component, auto data) {
246  component = std::apply(
247  [&](auto... i) { return Load(int_constant<N>(), data, i...); },
248  index);
249  },
250  state, view);
251 }
252 
253 template <typename Eq, int N, typename Layout, int Rank>
254 void Load(
256  const BasicView<const Conservative<Eq>, Layout, Rank>& view,
257  nodeduce_t<const std::array<std::ptrdiff_t, std::size_t(Rank)>&> index) {
259  [&](auto&& component, auto data) {
260  component = Load(int_constant<N>(), data, index);
261  },
262  state, view);
263 }
264 
265 template <typename Eq>
267  nodeduce_t<ViewPointer<const Conservative<Eq>>> pointer) {
269  overloaded{
270  [](Array1d& x, const double* p) { x = Eigen::Map<const Array1d>(p); },
271  [](auto& xs, std::pair<const double*, std::ptrdiff_t> ps) {
272  const double* p = ps.first;
273  for (int i = 0; i < xs.rows(); ++i) {
274  xs.row(i) = Eigen::Map<const Array1d>(p);
275  p += ps.second;
276  }
277  }},
278  state, pointer);
279 }
280 
281 template <typename Eq, int N, typename Layout, int Rank>
282 void Load(
283  CompleteArray<Eq, N>& state,
284  const BasicView<const Complete<Eq>, Layout, Rank>& view,
285  nodeduce_t<const std::array<std::ptrdiff_t, std::size_t(Rank)>&> index) {
287  [&](auto&& component, auto data) {
288  component = Load(int_constant<N>(), data, index);
289  },
290  state, view);
291 }
292 
293 template <typename Eq>
295  nodeduce_t<ViewPointer<const Complete<Eq>>> pointer) {
297  overloaded{
298  [](Array1d& x, const double* p) { x = Eigen::Map<const Array1d>(p); },
299  [](auto& xs, std::pair<const double*, std::ptrdiff_t> ps) {
300  const double* p = ps.first;
301  for (int i = 0; i < xs.rows(); ++i) {
302  xs.row(i) = Eigen::Map<const Array1d>(p);
303  p += ps.second;
304  }
305  }},
306  state, pointer);
307 }
308 
309 template <typename Eq, int N, typename Layout, int Rank>
310 void LoadN(
311  CompleteArray<Eq, N>& state,
312  const BasicView<const Complete<Eq>, Layout, Rank>& view, int size,
313  nodeduce_t<const std::array<std::ptrdiff_t, std::size_t(Rank)>&> pos) {
315  [&](auto&& s, auto v) { s = LoadN(int_constant<N>{}, v, size, pos); },
316  state, view);
317 }
318 
319 template <typename Eq, int N, typename Layout, int Rank>
320 void LoadN(
322  const BasicView<const Conservative<Eq>, Layout, Rank>& view, int size,
323  nodeduce_t<const std::array<std::ptrdiff_t, std::size_t(Rank)>&> pos) {
325  [&](auto& s, auto v) { s = LoadN(int_constant<N>{}, v, size, pos); },
326  state, view);
327 }
328 
329 template <typename Eq>
331  nodeduce_t<ViewPointer<const Complete<Eq>>> pointer, int n) {
334  overloaded{[n](Array1d& x, const double* p) {
335 #ifdef __clang__
336 #pragma clang loop vectorize(disable)
337 #endif
338  for (int i = 0; i < n; ++i) {
339  x(i) = p[i];
340  }
341  },
342  [n](auto& xs, std::pair<const double*, std::ptrdiff_t> ps) {
343  const double* p = ps.first;
344  for (int i = 0; i < xs.rows(); ++i) {
345 #ifdef __clang__
346 #pragma clang loop vectorize(disable)
347 #endif
348  for (int j = 0; j < n; ++j) {
349  xs(i, j) = p[j];
350  }
351  p += ps.second;
352  }
353  }},
354  state, pointer);
355 }
356 
357 template <typename Eq>
359  nodeduce_t<ViewPointer<const Conservative<Eq>>> pointer, int n) {
362  overloaded{[n](Array1d& x, const double* p) {
363 #ifdef __clang__
364 #pragma clang loop vectorize(disable)
365 #endif
366  for (int i = 0; i < n; ++i) {
367  x(i) = p[i];
368  }
369  },
370  [n](auto& xs, std::pair<const double*, std::ptrdiff_t> ps) {
371  const double* p = ps.first;
372  for (int i = 0; i < xs.rows(); ++i) {
373 #ifdef __clang__
374 #pragma clang loop vectorize(disable)
375 #endif
376  for (int j = 0; j < n; ++j) {
377  xs(i, j) = p[j];
378  }
379  p += ps.second;
380  }
381  }},
382  state, pointer);
383 }
384 
385 template <typename Eq>
387  const ConservativeArray<Eq>& state) {
388  ForEachVariable(overloaded{[](double* p, const Array1d& x) {
389  Eigen::Map<Array1d>{p} = x;
390  },
391  [](auto& ptr, const auto& x) {
392  for (int i = 0; i < x.rows(); ++i) {
393  Eigen::Map<Array1d>(ptr.first) = x.row(i);
394  ptr.first += ptr.second;
395  }
396  }},
397  pointer, state);
398 }
399 
400 template <typename Eq>
402  const CompleteArray<Eq>& state) {
403  ForEachVariable(overloaded{[](double* p, const Array1d& x) {
404  Eigen::Map<Array1d>{p} = x;
405  },
406  [](auto& ptr, const auto& x) {
407  for (int i = 0; i < x.rows(); ++i) {
408  Eigen::Map<Array1d>(ptr.first) = x.row(i);
409  ptr.first += ptr.second;
410  }
411  }},
412  pointer, state);
413 }
414 
415 template <typename Eq>
417  const ConservativeArray<Eq>& state, int n) {
418  ForEachVariable(overloaded{[n](double* p, const Array1d& x) {
419 #ifdef __clang__
420 #pragma clang loop vectorize(disable)
421 #endif
422  for (int i = 0; i < n; ++i) {
423  p[i] = x(i);
424  }
425  },
426  [n](auto& ptr, const auto& x) {
427  for (int i = 0; i < x.rows(); ++i) {
428 #ifdef __clang__
429 #pragma clang loop vectorize(disable)
430 #endif
431  for (int j = 0; j < n; ++j) {
432  ptr.first[i * ptr.second + j] = x(i, j);
433  }
434  }
435  }},
436  pointer, state);
437 }
438 
439 template <typename Eq>
441  const CompleteArray<Eq>& state, int n) {
442  ForEachVariable(overloaded{[n](double* p, const Array1d& x) {
443 #ifdef __clang__
444 #pragma clang loop vectorize(disable)
445 #endif
446  for (int i = 0; i < n; ++i) {
447  p[i] = x(i);
448  }
449  },
450  [n](auto& ptr, const auto& x) {
451  for (int i = 0; i < x.rows(); ++i) {
452 #ifdef __clang__
453 #pragma clang loop vectorize(disable)
454 #endif
455  for (int j = 0; j < n; ++j) {
456  ptr.first[i * ptr.second + j] = x(i, j);
457  }
458  }
459  }},
460  pointer, state);
461 }
462 
463 template <typename Eq, int N, typename Layout, int Rank>
464 void Store(
465  const BasicView<Conservative<Eq>, Layout, Rank>& view,
466  const ConservativeArray<Eq, N>& state,
467  nodeduce_t<const std::array<std::ptrdiff_t, std::size_t(Rank)>&> index) {
468  ForEachComponent([&](auto data, auto block) { Store(data, block, index); },
469  view, state);
470 }
471 
472 template <typename Eq, int N, typename Layout, int Rank>
473 void Store(
474  const BasicView<Complete<Eq>, Layout, Rank>& view,
475  const CompleteArray<Eq, N>& state,
476  nodeduce_t<const std::array<std::ptrdiff_t, std::size_t(Rank)>&> index) {
477  ForEachComponent([&](auto data, auto block) { Store(data, block, index); },
478  view, state);
479 }
480 
481 template <typename Eq, int N, typename Layout, int Rank>
482 void StoreN(
483  const BasicView<Complete<Eq>, Layout, Rank>& view,
484  const CompleteArray<Eq, N>& state, int size,
485  nodeduce_t<const std::array<std::ptrdiff_t, std::size_t(Rank)>&> pos) {
486  ForEachComponent([&](auto& s, auto v) { StoreN(v, size, s, pos[0]); }, state,
487  view);
488 }
489 
490 template <typename Eq, int N, typename Layout, int Rank>
491 void StoreN(
492  const BasicView<Conservative<Eq>, Layout, Rank>& view,
493  const ConservativeArray<Eq, N>& state, int size,
494  nodeduce_t<const std::array<std::ptrdiff_t, std::size_t(Rank)>&> pos) {
495  ForEachComponent([&](auto&& s, auto&& v) { StoreN(v, size, s, pos[0]); },
496  state, view);
497 }
498 
499 } // namespace fub
500 
501 #endif
#define FUB_ASSERT(x)
Definition: assert.hpp:39
std::decay_t< decltype(std::declval< T >().GetEquation())> Equation
A template typedef to detect the member function.
Definition: Meta.hpp:59
decltype(::fub::Depths(std::declval< typename T::Equation const & >(), Type< T >{})) Depths
Definition: State.hpp:189
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
typename detail::CompleteArrayBaseImpl< Eq, Width >::type CompleteArrayBase
Definition: StateArray.hpp:175
std::conditional_t< N==1||M==1, Eigen::Array< T, N, M >, Eigen::Array< T, N, M, Eigen::RowMajor > > Array
Definition: Eigen.hpp:50
Array< double, 1 > Array1d
Definition: Eigen.hpp:53
constexpr const int kDefaultChunkSize
Definition: Eigen.hpp:39
void ForEachVariable(F function, Ts &&... states)
Definition: State.hpp:89
void StoreN(nodeduce_t< ViewPointer< Conservative< Eq >>> pointer, const ConservativeArray< Eq > &state, int n)
Definition: StateArray.hpp:416
typename nodeduce< T >::type nodeduce_t
Definition: type_traits.hpp:47
constexpr struct fub::DepthsFn Depths
void Load(State &state, const BasicView< const State, Layout, Rank > &view, const std::array< std::ptrdiff_t, State::Equation::Rank()> &index)
Definition: State.hpp:640
void LoadN(CompleteArray< Eq, N > &state, const BasicView< const Complete< Eq >, Layout, Rank > &view, int size, nodeduce_t< const std::array< std::ptrdiff_t, std::size_t(Rank)> & > pos)
Definition: StateArray.hpp:310
typename detail::ArrayStateBaseImpl< Depths, Width >::type ArrayStateBase
Definition: StateArray.hpp:38
const Conservative< Eq > & AsCons(const Conservative< Eq > &x)
Definition: State.hpp:438
void Store(const BasicView< Conservative< Eq >, Layout, Eq::Rank()> &view, const Conservative< Eq > &state, const std::array< std::ptrdiff_t, Eq::Rank()> &index)
Definition: State.hpp:663
void ForEachComponent(F function, Ts &&... states)
Definition: State.hpp:624
std::integral_constant< int, I > int_constant
Definition: type_traits.hpp:183
typename detail::ConservativeArrayBaseImpl< Eq, Width >::type ConservativeArrayBase
Definition: StateArray.hpp:132
std::ptrdiff_t index
Definition: type_traits.hpp:179
Definition: StateArray.hpp:41
ArrayState & operator-=(const Base &other)
Definition: StateArray.hpp:71
ArrayState & operator+=(const Base &other)
Definition: StateArray.hpp:65
ArrayState & operator*=(double lambda)
Definition: StateArray.hpp:77
ArrayStateBase< Depths, Width > Base
Definition: StateArray.hpp:43
ArrayState(const Equation &eq)
Definition: StateArray.hpp:48
Definition: State.hpp:403
Definition: StateArray.hpp:101
Definition: StateArray.hpp:178
static constexpr int Size()
Definition: StateArray.hpp:183
CompleteArray(const Equation &eq)
Definition: StateArray.hpp:186
Eq Equation
Definition: StateArray.hpp:179
CompleteArray()=default
Definition: StateArray.hpp:135
Eq Equation
Definition: StateArray.hpp:136
ConservativeArray(const Equation &eq)
Definition: StateArray.hpp:143
static constexpr int Size()
Definition: StateArray.hpp:140
Definition: StateArray.hpp:108
Definition: StateArray.hpp:89
This type is used to tag scalar quantities.
Definition: State.hpp:109
Definition: State.hpp:162
Definition: State.hpp:750
Definition: type_traits.hpp:291