Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
EulerEquation.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_EQUATIONS_EULER_EQUATION_HPP
22 #define FUB_EQUATIONS_EULER_EQUATION_HPP
23 
24 #include "fub/core/type_traits.hpp"
25 
26 namespace fub::euler {
27 template <int Dim>
28 double KineticEnergy(double density,
29  const Eigen::Array<double, Dim, 1>& momentum) noexcept {
30  return 0.5 * momentum.matrix().squaredNorm() / density;
31 }
32 
33 template <int Dim, int N, int O, int MR, int MC>
35  const Array1d& density,
36  const Eigen::Array<double, Dim, N, O, MR, MC>& momentum) noexcept {
37  Array1d squaredMomentum = momentum.matrix().colwise().squaredNorm();
38  return 0.5 * squaredMomentum / density;
39 }
40 
41 template <int Dim, int N, int O, int MR, int MC>
42 Array1d KineticEnergy(const Array1d& density,
43  const Eigen::Array<double, Dim, N, O, MR, MC>& momentum,
44  MaskArray mask) noexcept {
45  mask = mask && (density > 0.0);
46  Array1d squaredMomentum = momentum.matrix().colwise().squaredNorm();
47  Array1d safe_density = density;
48  safe_density = mask.select(density, 1.0);
49  FUB_ASSERT((safe_density > 0.0).all());
50  return 0.5 * squaredMomentum / safe_density;
51 }
52 
53 inline constexpr struct GammaFn {
54  template <typename Equation, typename State,
55  typename = std::enable_if_t<
57  constexpr auto operator()(Equation&& eq, State&& state) const
60  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
61  std::forward<State>(state));
62  }
64 
65 inline constexpr struct DensityFn {
66  template <typename Equation, typename State,
67  typename = std::enable_if_t<
69  constexpr auto operator()(Equation&& eq, State&& state) const
72  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
73  std::forward<State>(state));
74  }
76 
77 inline constexpr struct MomentumFn {
78  template <typename Equation, typename State, typename... Indices,
79  typename = std::enable_if_t<is_tag_invocable<
80  MomentumFn, Equation, State, Indices...>::value>>
81  constexpr auto
82  operator()(Equation&& eq, State&& state, Indices... d) const noexcept(
84  -> tag_invoke_result_t<MomentumFn, Equation, State, Indices...> {
85  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
86  std::forward<State>(state), d...);
87  }
89 
90 inline constexpr struct VelocityFn {
91  template <typename Equation, typename State, typename... Indices,
92  typename = std::enable_if_t<is_tag_invocable<
93  VelocityFn, Equation, State, Indices...>::value>>
94  constexpr auto
95  operator()(Equation&& eq, State&& state, Indices... d) const noexcept(
97  -> tag_invoke_result_t<VelocityFn, Equation, State, Indices...> {
98  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
99  std::forward<State>(state), d...);
100  }
102 
103 inline constexpr struct SetVelocityFn {
104  template <typename Equation, typename State, typename... Indices,
105  typename = std::enable_if_t<is_tag_invocable<
106  SetVelocityFn, Equation, State, Indices...>::value>>
107  constexpr auto
108  operator()(Equation&& eq, State&& state, Indices... d) const noexcept(
110  -> tag_invoke_result_t<SetVelocityFn, Equation, State, Indices...> {
111  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
112  std::forward<State>(state), d...);
113  }
115 
116 inline constexpr struct SpeedOfSoundFn {
117  template <typename Equation, typename State,
118  typename = std::enable_if_t<
120  constexpr auto operator()(Equation&& eq, State&& state) const
123  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
124  std::forward<State>(state));
125  }
127 
128 inline constexpr struct EnergyFn {
129  template <typename Equation, typename State,
130  typename = std::enable_if_t<
132  constexpr auto operator()(Equation&& eq, State&& state) const
135  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
136  std::forward<State>(state));
137  }
139 
140 inline constexpr struct PressureFn {
141  template <typename Equation, typename State,
142  typename = std::enable_if_t<
144  constexpr auto operator()(Equation&& eq, State&& state) const
147  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
148  std::forward<State>(state));
149  }
151 
152 inline constexpr struct MachnumberFn {
153  template <typename Equation, typename State,
154  typename = std::enable_if_t<
156  constexpr auto operator()(Equation&& eq, State&& state) const
159  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
160  std::forward<State>(state));
161  }
163 
164 inline constexpr struct TemperatureFn {
165  template <typename Equation, typename State,
166  typename = std::enable_if_t<
168  constexpr auto operator()(Equation&& eq, State&& state) const
171  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
172  std::forward<State>(state));
173  }
175 
176 inline constexpr struct InternalEnergyFn {
177  template <typename Equation, typename State,
178  typename = std::enable_if_t<
180  constexpr auto operator()(Equation&& eq, State&& state) const noexcept(
183  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
184  std::forward<State>(state));
185  }
187 
188 inline constexpr struct TotalEnthalpyFn {
189  template <typename Equation, typename State,
190  typename = std::enable_if_t<
192  constexpr auto operator()(Equation&& eq, State&& state) const noexcept(
195  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
196  std::forward<State>(state));
197  }
199 
200 inline constexpr struct MoleFractionsFn {
201  template <typename Equation, typename Dest, typename State,
202  typename = std::enable_if_t<is_tag_invocable<
203  MoleFractionsFn, Equation, Dest, State>::value>>
204  constexpr auto operator()(Equation&& eq, Dest&& dest, State&& state) const
205  noexcept(
208  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
209  std::forward<Dest>(dest),
210  std::forward<State>(state));
211  }
213 
214 inline constexpr struct KineticStateFromCompleteFn {
215  template <typename Equation, typename Dest, typename State,
216  typename = std::enable_if_t<is_tag_invocable<
217  KineticStateFromCompleteFn, Equation, Dest, State>::value>>
218  constexpr auto operator()(Equation&& eq, Dest&& dest, State&& state) const
220  Dest, State>::value)
222  State> {
223  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
224  std::forward<Dest>(dest),
225  std::forward<State>(state));
226  }
228 
229 inline constexpr struct CompleteFromKineticStateFn {
230  template <
231  typename Equation, typename Dest, typename State, typename Velocity,
232  typename = std::enable_if_t<is_tag_invocable<
233  CompleteFromKineticStateFn, Equation, Dest, State, Velocity>::value>>
234  constexpr auto operator()(Equation&& eq, Dest&& dest, State&& state,
235  Velocity&& velocity) const
237  Dest, State, Velocity>::value)
239  State, Velocity> {
240  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
241  std::forward<Dest>(dest), std::forward<State>(state),
242  std::forward<Velocity>(velocity));
243  }
244 
245  template <
246  typename Equation, typename Dest, typename State,
247  typename = std::enable_if_t<is_tag_invocable<
248  CompleteFromKineticStateFn, Equation, Dest, State>::value>>
249  constexpr auto operator()(Equation&& eq, Dest&& dest, State&& state) const
251  Dest, State>::value)
253  State> {
254  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
255  std::forward<Dest>(dest), std::forward<State>(state));
256  }
258 
259 inline constexpr struct SetIsentropicPressureFn {
260  template <typename... Args, typename = std::enable_if_t<is_tag_invocable<
261  SetIsentropicPressureFn, Args...>::value>>
262  constexpr auto operator()(Args&&... args) const noexcept(
265  return fub::meta::tag_invoke(*this, std::forward<Args>(args)...);
266  }
268 
270  template <typename Equation,
271  typename = std::enable_if_t<
275  double, double>::value ||
279  double>::value>>
280  constexpr void operator()(Equation&& eq,
281  Complete<std::decay_t<Equation>>& dest,
282  const Complete<std::decay_t<Equation>>& src,
283  double pressure_dest, double efficiency) const
284  noexcept(
286  Equation, Complete<std::decay_t<Equation>>&,
287  const Complete<std::decay_t<Equation>>&,
288  double, double>::value) {
290  Equation, Complete<std::decay_t<Equation>>&,
291  const Complete<std::decay_t<Equation>>&,
292  double, double>::value) {
293  fub::meta::tag_invoke(*this, std::forward<Equation>(eq), dest, src,
294  pressure_dest, efficiency);
295  } else {
296  const auto old_velocity = Velocity(eq, src);
297  const double rhoE_kin = KineticEnergy(src.density, src.momentum);
298  constexpr int N = std::decay_t<Equation>::Rank();
299  dest = src;
300  dest.momentum = Array<double, N, 1>::Zero();
301  dest.energy = src.energy - rhoE_kin;
302  const double h_before = (dest.energy + dest.pressure) / dest.density;
303  SetIsentropicPressure(eq, dest, dest, pressure_dest);
304  const double h_after = (dest.energy + dest.pressure) / dest.density;
305  const double h_diff = h_before - h_after;
306  const double e_kin_new =
307  2.0 * efficiency * std::abs(h_diff) + old_velocity.matrix().squaredNorm();
308  FUB_ASSERT(e_kin_new >= 0);
309  const int sign = (h_diff >= 0) - (h_diff < 0);
310  dest.momentum[0] = dest.density * (sign * std::sqrt(e_kin_new));
311  dest.energy = dest.energy + KineticEnergy(dest.density, dest.momentum);
312  }
313  }
315 
316 inline constexpr struct SpecificGasConstantFn {
317  template <typename Equation, typename State,
318  typename = std::enable_if_t<is_tag_invocable<
319  SpecificGasConstantFn, Equation, State>::value>>
320  constexpr auto operator()(Equation&& eq, State&& state) const noexcept(
323  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
324  std::forward<State>(state));
325  }
327 
328 inline constexpr struct SpeciesFn {
329  template <typename Equation, typename State, typename... Indices,
330  typename = std::enable_if_t<is_tag_invocable<
331  SpeciesFn, Equation, State, Indices...>::value>>
332  constexpr auto
333  operator()(Equation&& eq, State&& state, Indices... d) const noexcept(
335  -> tag_invoke_result_t<SpeciesFn, Equation, State, Indices...> {
336  return fub::meta::tag_invoke(*this, std::forward<Equation>(eq),
337  std::forward<State>(state), d...);
338  }
340 
341 template <typename Equation, typename State>
343  const Equation&, const State&> {};
344 
345 } // namespace fub::euler
346 
347 #endif
#define FUB_ASSERT(x)
Definition: assert.hpp:39
Definition: EulerEquation.hpp:26
constexpr struct fub::euler::InternalEnergyFn InternalEnergy
constexpr struct fub::euler::KineticStateFromCompleteFn KineticStateFromComplete
constexpr struct fub::euler::SpeedOfSoundFn SpeedOfSound
constexpr struct fub::euler::EnergyFn Energy
double KineticEnergy(double density, const Eigen::Array< double, Dim, 1 > &momentum) noexcept
Definition: EulerEquation.hpp:28
constexpr struct fub::euler::GammaFn Gamma
constexpr struct fub::euler::SpeciesFn Species
constexpr struct fub::euler::SpecificGasConstantFn SpecificGasConstant
constexpr struct fub::euler::TotalEnthalpyFn TotalEnthalpy
constexpr struct fub::euler::SetIsentropicPressureFn SetIsentropicPressure
constexpr struct fub::euler::PressureFn Pressure
constexpr struct fub::euler::MoleFractionsFn MoleFractions
constexpr struct fub::euler::MomentumFn Momentum
constexpr struct fub::euler::CompleteFromKineticStateFn CompleteFromKineticState
constexpr struct fub::euler::DensityFn Density
constexpr struct fub::euler::IsentropicExpansionWithoutDissipationFn IsentropicExpansionWithoutDissipation
constexpr struct fub::euler::VelocityFn Velocity
constexpr struct fub::euler::MachnumberFn Machnumber
constexpr struct fub::euler::TemperatureFn Temperature
constexpr struct fub::euler::SetVelocityFn SetVelocity
constexpr tag_invoke_fn::tag_invoke_fn tag_invoke
Definition: type_traits.hpp:317
std::decay_t< decltype(std::declval< T >().GetEquation())> Equation
A template typedef to detect the member function.
Definition: Meta.hpp:59
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
invoke_result_t< decltype(fub::meta::tag_invoke), _Tag, _Args... > tag_invoke_result_t
Definition: type_traits.hpp:347
Array< bool, 1 > MaskArray
Definition: Eigen.hpp:59
static constexpr all_type all
Definition: mdspan.hpp:741
This type has a constructor which takes an equation and might allocate any dynamically sized member v...
Definition: State.hpp:335
Definition: EulerEquation.hpp:229
constexpr auto operator()(Equation &&eq, Dest &&dest, State &&state, Velocity &&velocity) const noexcept(is_nothrow_tag_invocable< CompleteFromKineticStateFn, Equation, Dest, State, Velocity >::value) -> tag_invoke_result_t< CompleteFromKineticStateFn, Equation, Dest, State, Velocity >
Definition: EulerEquation.hpp:234
constexpr auto operator()(Equation &&eq, Dest &&dest, State &&state) const noexcept(is_nothrow_tag_invocable< CompleteFromKineticStateFn, Equation, Dest, State >::value) -> tag_invoke_result_t< CompleteFromKineticStateFn, Equation, Dest, State >
Definition: EulerEquation.hpp:249
Definition: EulerEquation.hpp:65
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< DensityFn, Equation, State >::value) -> tag_invoke_result_t< DensityFn, Equation, State >
Definition: EulerEquation.hpp:69
Definition: EulerEquation.hpp:128
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< EnergyFn, Equation, State >::value) -> tag_invoke_result_t< EnergyFn, Equation, State >
Definition: EulerEquation.hpp:132
Definition: EulerEquation.hpp:53
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< GammaFn, Equation, State >::value) -> tag_invoke_result_t< GammaFn, Equation, State >
Definition: EulerEquation.hpp:57
Definition: EulerEquation.hpp:176
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< InternalEnergyFn, Equation, State >::value) -> tag_invoke_result_t< InternalEnergyFn, Equation, State >
Definition: EulerEquation.hpp:180
constexpr void operator()(Equation &&eq, Complete< std::decay_t< Equation >> &dest, const Complete< std::decay_t< Equation >> &src, double pressure_dest, double efficiency) const noexcept(is_nothrow_tag_invocable< IsentropicExpansionWithoutDissipationFn, Equation, Complete< std::decay_t< Equation >> &, const Complete< std::decay_t< Equation >> &, double, double >::value)
Definition: EulerEquation.hpp:280
Definition: EulerEquation.hpp:214
constexpr auto operator()(Equation &&eq, Dest &&dest, State &&state) const noexcept(is_nothrow_tag_invocable< KineticStateFromCompleteFn, Equation, Dest, State >::value) -> tag_invoke_result_t< KineticStateFromCompleteFn, Equation, Dest, State >
Definition: EulerEquation.hpp:218
Definition: EulerEquation.hpp:152
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< MachnumberFn, Equation, State >::value) -> tag_invoke_result_t< MachnumberFn, Equation, State >
Definition: EulerEquation.hpp:156
Definition: EulerEquation.hpp:200
constexpr auto operator()(Equation &&eq, Dest &&dest, State &&state) const noexcept(is_nothrow_tag_invocable< MoleFractionsFn, Equation, State >::value) -> tag_invoke_result_t< MoleFractionsFn, Equation, State >
Definition: EulerEquation.hpp:204
Definition: EulerEquation.hpp:77
constexpr auto operator()(Equation &&eq, State &&state, Indices... d) const noexcept(is_nothrow_tag_invocable< MomentumFn, Equation, State, Indices... >::value) -> tag_invoke_result_t< MomentumFn, Equation, State, Indices... >
Definition: EulerEquation.hpp:82
Definition: EulerEquation.hpp:140
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< PressureFn, Equation, State >::value) -> tag_invoke_result_t< PressureFn, Equation, State >
Definition: EulerEquation.hpp:144
Definition: EulerEquation.hpp:259
constexpr auto operator()(Args &&... args) const noexcept(is_nothrow_tag_invocable< SetIsentropicPressureFn, Args... >::value) -> tag_invoke_result_t< SetIsentropicPressureFn, Args... >
Definition: EulerEquation.hpp:262
Definition: EulerEquation.hpp:103
constexpr auto operator()(Equation &&eq, State &&state, Indices... d) const noexcept(is_nothrow_tag_invocable< SetVelocityFn, Equation, State, Indices... >::value) -> tag_invoke_result_t< SetVelocityFn, Equation, State, Indices... >
Definition: EulerEquation.hpp:108
Definition: EulerEquation.hpp:328
constexpr auto operator()(Equation &&eq, State &&state, Indices... d) const noexcept(is_nothrow_tag_invocable< SpeciesFn, Equation, State, Indices... >::value) -> tag_invoke_result_t< SpeciesFn, Equation, State, Indices... >
Definition: EulerEquation.hpp:333
Definition: EulerEquation.hpp:316
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< SpecificGasConstantFn, Equation, State >::value) -> tag_invoke_result_t< SpecificGasConstantFn, Equation, State >
Definition: EulerEquation.hpp:320
Definition: EulerEquation.hpp:116
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< SpeedOfSoundFn, Equation, State >::value) -> tag_invoke_result_t< SpeedOfSoundFn, Equation, State >
Definition: EulerEquation.hpp:120
Definition: EulerEquation.hpp:164
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< TemperatureFn, Equation, State >::value) -> tag_invoke_result_t< TemperatureFn, Equation, State >
Definition: EulerEquation.hpp:168
Definition: EulerEquation.hpp:188
constexpr auto operator()(Equation &&eq, State &&state) const noexcept(is_nothrow_tag_invocable< TotalEnthalpyFn, Equation, State >::value) -> tag_invoke_result_t< TotalEnthalpyFn, Equation, State >
Definition: EulerEquation.hpp:192
Definition: EulerEquation.hpp:90
constexpr auto operator()(Equation &&eq, State &&state, Indices... d) const noexcept(is_nothrow_tag_invocable< VelocityFn, Equation, State, Indices... >::value) -> tag_invoke_result_t< VelocityFn, Equation, State, Indices... >
Definition: EulerEquation.hpp:95
Definition: EulerEquation.hpp:343
This is std::true_type if a given object f of type T is callable by fub::invoke(f,...
Definition: type_traits.hpp:215
Definition: type_traits.hpp:339
Definition: type_traits.hpp:323
This file adds basic type traits utilities which are not yet implemented in all standard libraries.