Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
Equation.hpp
Go to the documentation of this file.
1 // Copyright (c) 2018 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_EQUATION_HPP
22 #define FUB_EQUATION_HPP
23 
24 #include "fub/Direction.hpp"
25 #include "fub/State.hpp"
26 #include "fub/StateArray.hpp"
27 #include "fub/core/type_traits.hpp"
28 
29 #include "fub/ext/Eigen.hpp"
30 
31 #include <fmt/format.h>
32 
33 namespace fub {
34 
35 template <typename Eq, typename... Args>
36 using FluxT = decltype(std::declval<Eq>().Flux(std::declval<Args>()...));
37 
38 template <typename Eq>
39 using ScalarFluxT =
40  decltype(std::declval<const Eq&>().Flux(std::declval<Conservative<Eq>&>(),
41  std::declval<const Complete<Eq>&>(),
42  Direction::X));
43 
44 template <typename Eq, typename N = int_constant<kDefaultChunkSize>>
45 using VectorizedFluxT = decltype(std::declval<const Eq&>().Flux(
46  std::declval<ConservativeArray<Eq, N::value>&>(),
47  std::declval<const CompleteArray<Eq, N::value>&>(), Direction::X));
48 
49 template <typename Eq>
50 using ScalarReconstructT = decltype(std::declval<const Eq&>().Reconstruct(
51  std::declval<Complete<Eq>&>(), std::declval<const Conservative<Eq>&>()));
52 
53 template <typename Eq, typename N = int_constant<kDefaultChunkSize>>
54 using VectorizedReconstructT = decltype(std::declval<const Eq&>().Reconstruct(
55  std::declval<CompleteArray<Eq, N::value>&>(),
56  std::declval<const ConservativeArray<Eq, N::value>&>()));
57 
58 template <typename Equation>
59 struct HasScalarFlux : is_detected<ScalarFluxT, Equation> {};
60 
61 template <typename Equation, int N = kDefaultChunkSize>
63  : is_detected<VectorizedFluxT, Equation, int_constant<N>> {};
64 
65 template <typename Equation>
66 struct HasScalarReconstruction : is_detected<ScalarReconstructT, Equation> {};
67 
68 template <typename Equation, int N = kDefaultChunkSize>
70  : is_detected<VectorizedReconstructT, Equation, int_constant<N>> {};
71 
72 template <typename Equation>
73 struct HasReconstruction : disjunction<HasScalarReconstruction<Equation>,
74  HasVectorizedReconstruction<Equation>> {
75 };
76 
77 template <typename Extent>
79  std::ptrdiff_t n = 1) {
80  const std::array<std::ptrdiff_t, Extent::rank()> extents =
81  AsArray(layout.extents());
83 }
84 
85 template <typename State, typename Layout, int Rank>
87  const IndexBox<Rank>& box) {
88  auto subview = [](const auto& pdv, const IndexBox<Rank>& box) {
89  using PatchDataView = std::decay_t<decltype(pdv)>;
90  if constexpr (PatchDataView::Rank() == Rank) {
91  return pdv.Subview(box);
92  } else if constexpr (PatchDataView::Rank() == Rank + 1) {
93  const std::ptrdiff_t lower = pdv.Box().lower[Rank];
94  const std::ptrdiff_t upper = pdv.Box().upper[Rank];
95  const IndexBox<Rank + 1> embedded_box =
96  Embed<Rank + 1>(box, {lower, upper});
97  return pdv.Subview(embedded_box);
98  }
99  };
100  View<State> strided{};
102  [&](auto& dest, const auto& src) { dest = subview(src, box); }, strided,
103  state);
104  return strided;
105 }
106 
107 template <typename Eq, typename Equation = std::decay_t<Eq>>
108 void Flux(Eq&& equation, Conservative<Equation>& flux,
109  const Complete<Equation>& state, Direction dir,
110  [[maybe_unused]] double x = 0.0) {
111  if constexpr (is_detected<FluxT, Eq, Conservative<Equation>&,
113  double>::value) {
114  equation.Flux(flux, state, dir, x);
115  } else if constexpr (is_detected_exact<Conservative<Equation>, FluxT, Eq,
117  double>::value) {
118  flux = equation.Flux(state, dir, x);
119  } else if constexpr (is_detected_exact<Conservative<Equation>, FluxT, Eq,
120  const Complete<Equation>&,
121  Direction>::value) {
122  flux = equation.Flux(state, dir);
123  } else {
124  static_assert(is_detected<FluxT, Eq, Conservative<Equation>&,
125  const Complete<Equation>&, Direction>::value);
126  equation.Flux(flux, state, dir);
127  }
128 }
129 
130 template <typename Eq, typename Equation = std::decay_t<Eq>>
131 void Flux(Eq&& equation, ConservativeArray<Equation>& flux,
132  const CompleteArray<Equation>& state, Direction dir,
133  [[maybe_unused]] double x = 0.0) {
134  if constexpr (is_detected<FluxT, Eq, ConservativeArray<Equation>&,
136  double>::value) {
137  equation.Flux(flux, state, dir, x);
138  } else if constexpr (is_detected_exact<ConservativeArray<Equation>, FluxT, Eq,
140  Direction, double>::value) {
141  flux = equation.Flux(state, dir, x);
142  } else if constexpr (is_detected_exact<ConservativeArray<Equation>, FluxT, Eq,
144  Direction>::value) {
145  flux = equation.Flux(state, dir);
146  } else if constexpr (is_detected<FluxT, Eq, ConservativeArray<Equation>&,
148  Direction>::value) {
149  equation.Flux(flux, state, dir);
150  }
151 }
152 
153 template <typename Eq, typename Equation = std::decay_t<Eq>>
154 void Flux(Eq&& equation, ConservativeArray<Equation>& flux,
155  const CompleteArray<Equation>& state, MaskArray mask, Direction dir,
156  [[maybe_unused]] double x = 0.0) {
157  if constexpr (is_detected<FluxT, Eq, ConservativeArray<Equation>&,
159  double>::value) {
160  equation.Flux(flux, state, mask, dir, x);
161  } else if constexpr (is_detected_exact<ConservativeArray<Equation>, FluxT, Eq,
163  Direction, double>::value) {
164  flux = equation.Flux(state, mask, dir, x);
165  } else if constexpr (is_detected_exact<ConservativeArray<Equation>, FluxT, Eq,
167  Direction>::value) {
168  flux = equation.Flux(state, mask, dir);
169  } else if constexpr (is_detected<FluxT, Eq, ConservativeArray<Equation>&,
171  Direction>::value) {
172  equation.Flux(flux, state, mask, dir);
173  } else {
174  Flux(equation, flux, state, dir, x);
175  }
176 }
177 
178 template <typename State, typename ReturnType, typename Equation>
179 ReturnType VarNames(const Equation& equation) {
180  using Traits = StateTraits<State>;
181  constexpr auto names = Traits::names;
182  const auto depths = fub::Depths(equation, Type<State>{});
183  const std::size_t n_names =
184  std::tuple_size<remove_cvref_t<decltype(names)>>::value;
185  ReturnType varnames;
186  varnames.reserve(n_names);
187  boost::mp11::tuple_for_each(Zip(names, StateToTuple(depths)), [&](auto xs) {
188  const int ncomp = std::get<1>(xs);
189  if (ncomp == 1) {
190  varnames.push_back(std::get<0>(xs));
191  } else {
192  for (int i = 0; i < ncomp; ++i) {
193  varnames.push_back(fmt::format("{}_{}", std::get<0>(xs), i));
194  }
195  }
196  });
197  return varnames;
198 }
199 
200 } // namespace fub
201 
202 #endif
An extents object defines a multidimensional index space which is the Cartesian product of integers e...
Definition: mdspan.hpp:208
This mapping does row first indexing (as in Fortran).
Definition: mdspan.hpp:302
constexpr const Extents & extents() const noexcept
Definition: mdspan.hpp:325
std::decay_t< decltype(std::declval< T >().GetEquation())> Equation
A template typedef to detect the member function.
Definition: Meta.hpp:59
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
auto Shrink(const layout_left::mapping< Extent > &layout, Direction dir, std::ptrdiff_t n=1)
Definition: Equation.hpp:78
void Flux(Eq &&equation, Conservative< Equation > &flux, const Complete< Equation > &state, Direction dir, [[maybe_unused]] double x=0.0)
Definition: Equation.hpp:108
typename remove_cvref< T >::type remove_cvref_t
Definition: type_traits.hpp:226
ReturnType VarNames(const Equation &equation)
Definition: Equation.hpp:179
View< State > Subview(const BasicView< State, Layout, Rank > &state, const IndexBox< Rank > &box)
Definition: Equation.hpp:86
void ForEachVariable(F function, Ts &&... states)
Definition: State.hpp:89
decltype(std::declval< Eq >().Flux(std::declval< Args >()...)) FluxT
Definition: Equation.hpp:36
constexpr std::array< std::ptrdiff_t, Extents::rank()> AsArray(Extents e) noexcept
Definition: PatchDataView.hpp:154
constexpr struct fub::DepthsFn Depths
decltype(std::declval< const Eq & >().Reconstruct(std::declval< Complete< Eq > & >(), std::declval< const Conservative< Eq > & >())) ScalarReconstructT
Definition: Equation.hpp:51
decltype(std::declval< const Eq & >().Reconstruct(std::declval< CompleteArray< Eq, N::value > & >(), std::declval< const ConservativeArray< Eq, N::value > & >())) VectorizedReconstructT
Definition: Equation.hpp:56
decltype(std::declval< const Eq & >().Flux(std::declval< Conservative< Eq > & >(), std::declval< const Complete< Eq > & >(), Direction::X)) ScalarFluxT
Definition: Equation.hpp:42
decltype(std::declval< const Eq & >().Flux(std::declval< ConservativeArray< Eq, N::value > & >(), std::declval< const CompleteArray< Eq, N::value > & >(), Direction::X)) VectorizedFluxT
Definition: Equation.hpp:47
std::ptrdiff_t Extent(const PatchDataView< T, R, L > &pdv)
Definition: StateRow.hpp:127
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
constexpr auto Zip(Ts &&... ts)
Definition: State.hpp:65
std::array< std::ptrdiff_t, N > Shift(const std::array< std::ptrdiff_t, N > &idx, Direction dir, std::ptrdiff_t shift)
Definition: PatchDataView.hpp:37
Array< bool, 1 > MaskArray
Definition: Eigen.hpp:59
auto StateToTuple(const State &x)
Definition: State.hpp:322
Definition: State.hpp:403
Definition: StateArray.hpp:178
This type has a constructor which takes an equation and might allocate any dynamically sized member v...
Definition: State.hpp:335
Definition: StateArray.hpp:135
This type has a constructor which takes an equation and might allocate any dynamically sized member v...
Definition: State.hpp:251
Definition: Equation.hpp:74
Definition: Equation.hpp:59
Definition: Equation.hpp:66
Definition: Equation.hpp:63
Definition: Equation.hpp:70
Definition: PatchDataView.hpp:56
Definition: PatchDataView.hpp:201
static constexpr int Rank() noexcept
Definition: PatchDataView.hpp:223
PatchDataView< T, R, layout_stride > Subview(const IndexBox< R > &box) const
Definition: PatchDataView.hpp:245
Definition: State.hpp:35
Definition: State.hpp:162
Definition: type_traits.hpp:129
This is std::true_type if Op<Args...> is a valid SFINAE expression and the return type is exactly Exp...
Definition: type_traits.hpp:108
This is std::true_type if Op<Args...> is a valid SFINAE expression.
Definition: type_traits.hpp:92
This file adds basic type traits utilities which are not yet implemented in all standard libraries.