Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
Gradient.hpp
Go to the documentation of this file.
1 // Copyright (c) 2020 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_FLUX_METHOD_GRADIENT
22 #define FUB_FLUX_METHOD_GRADIENT
23 
24 #include "fub/Direction.hpp"
25 #include "fub/State.hpp"
26 
27 namespace fub {
28 struct NoLimiter2 {
29  double operator()(double) const noexcept { return 1.0; }
30  Array1d operator()(Array1d) const noexcept { return Array1d::Constant(1.0); }
31 };
32 
33 struct UpwindLimiter {
34  double operator()(double) const noexcept { return 0.0; }
35  Array1d operator()(Array1d) const noexcept { return Array1d::Constant(0.0); }
36 };
37 
38 struct MinModLimiter {
39  double operator()(double R) const noexcept {
40  const double two_over_one_plus_R = 2.0 / (1.0 + R);
41  return std::min(two_over_one_plus_R, R * two_over_one_plus_R);
42  }
43  Array1d operator()(Array1d R) const noexcept {
44  const Array1d two_over_one_plus_R = 2.0 / (1.0 + R);
45  return two_over_one_plus_R.min(R * two_over_one_plus_R);
46  }
47 };
48 
50  double operator()(double R) const noexcept {
51  return 4.0 * R / ((1.0 + R) * (1.0 + R));
52  }
53  Array1d operator()(Array1d R) const noexcept {
54  return 4.0 * R / ((1.0 + R) * (1.0 + R));
55  }
56 };
57 
58 template <typename Limiter> class CentralDifferenceGradient {
59 public:
60  double ComputeGradient(double sL, double sR);
62 
63  template <typename State>
64  void ComputeGradient(State& grad, const State& sL, const State& sR);
65 
66 private:
67  Limiter limiter_;
68 };
69 
70 template <typename Equation,
71  typename GradientMethod = CentralDifferenceGradient<MinModLimiter>>
73 public:
78 
81 
82  ConservativeGradient() = default;
83 
84  explicit ConservativeGradient(const Equation& eq) : equation_{eq} {}
85 
86  explicit ConservativeGradient(const GradientMethod& method)
87  : gradient_{method} {}
88 
89  ConservativeGradient(const Equation&, const GradientMethod& method)
90  : gradient_{method} {}
91 
92  void ComputeGradient(Gradient& dudx, span<const Complete, 3> q, double dx,
93  Direction dir);
94 
96  double dx, Direction dir);
97 
98 private:
104  GradientMethod gradient_{};
105 };
106 
107 template <typename EulerEquation,
108  typename GradientMethod = CentralDifferenceGradient<MinModLimiter>>
110 public:
115 
118 
119  PrimitiveGradient() = default;
120 
121  explicit PrimitiveGradient(const EulerEquation& equation)
122  : equation_{equation} {}
123 
124  explicit PrimitiveGradient(const GradientMethod& method)
125  : gradient_{method} {}
126 
127  PrimitiveGradient(const EulerEquation& equation, const GradientMethod& method)
128  : equation_{equation}, gradient_{method} {}
129 
130  void ComputeGradient(Gradient& gradient, span<const Complete, 3> q, double dx,
131  Direction dir);
132 
134  double dx, Direction dir);
135 
136 private:
137  EulerEquation equation_{};
148  GradientMethod gradient_{};
149 };
150 
151 template <typename EulerEquation,
152  typename GradientMethod = CentralDifferenceGradient<MinModLimiter>>
154 public:
161 
164 
166 
167  explicit CharacteristicsGradient(const EulerEquation& equation)
168  : equation_{equation} {}
169 
170  explicit CharacteristicsGradient(const GradientMethod& method)
171  : gradient_{method} {}
172 
173  CharacteristicsGradient(const EulerEquation& equation,
174  const GradientMethod& method)
175  : equation_{equation}, gradient_{method} {}
176 
177  void ComputeGradient(Gradient& gradient, span<const Complete, 3> q, double dx,
178  Direction dir);
179 
181  double dx, Direction dir);
182 
183 private:
184  EulerEquation equation_{};
199  GradientMethod gradient_{};
200 };
201 
202 template <typename Limiter>
204  Array1d sR) {
205  const MaskArray mask = (sL * sR > 0.0);
206  const Array1d R = sR / sL;
207  return mask.select(0.5 * limiter_(R) * (sL + sR), 0.0);
208 }
209 
210 template <typename Limiter>
212  double sR) {
213  if (sL * sR <= 0.0) {
214  return 0.0;
215  }
216  const double R = sR / sL;
217  return 0.5 * limiter_(R) * (sL + sR);
218 }
219 
220 template <typename Limiter>
221 template <typename State>
223  const State& sL,
224  const State& sR) {
225  ForEachComponent([this](auto&& grad_u, auto&& sL,
226  auto&& sR) { grad_u = ComputeGradient(sL, sR); },
227  grad, sL, sR);
228 }
229 
230 template <typename Equation, typename GradientMethod>
232  Gradient& dudx, span<const Complete, 3> q, double dx, Direction) {
234  [dx](double& slope, double uL, double uM) { slope = (uM - uL) / dx; },
235  dudx_L_, q[0], q[1]);
237  [dx](double& slope, double uM, double uR) { slope = (uR - uM) / dx; },
238  dudx_R_, q[1], q[2]);
239  gradient_.ComputeGradient(dudx, dudx_L_, dudx_R_);
240 }
241 
242 template <typename Equation, typename GradientMethod>
246  [dx](auto&& slope, Array1d uL, Array1d uM) { slope = (uM - uL) / dx; },
247  dudx_L_array_, q[0], q[1]);
249  [dx](auto&& slope, Array1d uM, Array1d uR) { slope = (uR - uM) / dx; },
250  dudx_R_array_, q[1], q[2]);
251  gradient_.ComputeGradient(dudx, dudx_L_array_, dudx_R_array_);
252 }
253 
254 template <typename Equation, typename GradientMethod>
256  Gradient& dwdx, span<const Complete, 3> q, double dx, Direction) {
257  PrimFromComplete(equation_, wL_, q[0]);
258  PrimFromComplete(equation_, wM_, q[1]);
259  PrimFromComplete(equation_, wR_, q[2]);
261  [dx](double& slope, double wL, double wR) { slope = (wR - wL) / dx; },
262  dwdx_L_, wL_, wM_);
264  [dx](double& slope, double wL, double wR) { slope = (wR - wL) / dx; },
265  dwdx_R_, wM_, wR_);
266  gradient_.ComputeGradient(dwdx, dwdx_L_, dwdx_R_);
267 }
268 
269 template <typename Equation, typename GradientMethod>
272  PrimFromComplete(equation_, wL_array_, q[0]);
273  PrimFromComplete(equation_, wM_array_, q[1]);
274  PrimFromComplete(equation_, wR_array_, q[2]);
276  [dx](auto&& slope, Array1d wL, Array1d wR) { slope = (wR - wL) / dx; },
277  dwdx_L_array_, wL_array_, wM_array_);
279  [dx](auto&& slope, Array1d wL, Array1d wR) { slope = (wR - wL) / dx; },
280  dwdx_R_array_, wM_array_, wR_array_);
281  gradient_.ComputeGradient(dwdx, dwdx_L_array_, dwdx_R_array_);
282 }
283 
284 template <typename Equation>
286  const Primitive<Equation>& left,
287  const Primitive<Equation>& right, double rhoc,
288  double ooc2, double dx, int ix) {
289  const double dp = (right.pressure - left.pressure) / dx;
290  const double du = (right.velocity[ix] - left.velocity[ix]) / dx;
291  const double drho = (right.density - left.density) / dx;
292  amplitudes.minus = dp - rhoc * du;
293  amplitudes.plus = dp + rhoc * du;
294  amplitudes.zero[0] = drho - ooc2 * dp;
295  constexpr int Rank = Equation::Rank();
296  for (int i = 1; i < Rank; ++i) {
297  const int iy = (ix + i) % Rank;
298  amplitudes.zero[i] = (right.velocity[iy] - left.velocity[iy]) / dx;
299  }
301  Primitive<Equation>>()) {
302  for (int i = 0; i < amplitudes.species.size(); ++i) {
303  amplitudes.species[i] = (right.species[i] - left.species[i]) / dx;
304  }
305  }
306 }
307 
308 template <typename Equation>
310  const PrimitiveArray<Equation>& left,
311  const PrimitiveArray<Equation>& right, Array1d rhoc,
312  Array1d ooc2, double dx, int ix) {
313  const Array1d dp = (right.pressure - left.pressure) / dx;
314  const Array1d du = (right.velocity.row(ix) - left.velocity.row(ix)) / dx;
315  const Array1d drho = (right.density - left.density) / dx;
316  amplitudes.minus = dp - rhoc * du;
317  amplitudes.plus = dp + rhoc * du;
318  amplitudes.zero.row(0) = drho - ooc2 * dp;
319  constexpr int Rank = Equation::Rank();
320  for (int i = 1; i < Rank; ++i) {
321  const int iy = (ix + i) % Rank;
322  amplitudes.zero.row(i) =
323  (right.velocity.row(iy) - left.velocity.row(iy)) / dx;
324  }
326  Primitive<Equation>>()) {
327  for (int i = 0; i < amplitudes.species.rows(); ++i) {
328  amplitudes.species.row(i) =
329  (right.species.row(i) - left.species.row(i)) / dx;
330  }
331  }
332 }
333 
334 template <typename Equation, typename GradientMethod>
336  GradientArray& dKdx, span<const CompleteArray, 3> q, double dx, Direction dir) {
337  PrimFromComplete(equation_, wL_array_, q[0]);
338  PrimFromComplete(equation_, wM_array_, q[1]);
339  PrimFromComplete(equation_, wR_array_, q[2]);
340  const int ix = static_cast<int>(dir);
341  const Array1d rho = q[1].density;
342  const Array1d c = q[1].speed_of_sound;
343  const Array1d ooc2 = 1.0 / (c * c);
344  const Array1d rhoc = rho * c;
345  ComputeAmplitudes(dKdx_L_array_, wL_array_, wM_array_, rhoc, ooc2, dx, ix);
346  ComputeAmplitudes(dKdx_R_array_, wM_array_, wR_array_, rhoc, ooc2, dx, ix);
347  gradient_.ComputeGradient(dKdx, dKdx_L_array_, dKdx_R_array_);
348 }
349 
350 template <typename Equation, typename GradientMethod>
352  Gradient& dKdx, span<const Complete, 3> q, double dx, Direction dir) {
353  PrimFromComplete(equation_, wL_, q[0]);
354  PrimFromComplete(equation_, wM_, q[1]);
355  PrimFromComplete(equation_, wR_, q[2]);
356  const int ix = static_cast<int>(dir);
357  const double rho = q[1].density;
358  const double c = q[1].speed_of_sound;
359  const double ooc2 = 1.0 / (c * c);
360  const double rhoc = rho * c;
361  ComputeAmplitudes(dKdx_L_, wL_, wM_, rhoc, ooc2, dx, ix);
362  ComputeAmplitudes(dKdx_R_, wM_, wR_, rhoc, ooc2, dx, ix);
363  gradient_.ComputeGradient(dKdx, dKdx_L_, dKdx_R_);
364 }
365 } // namespace fub
366 
367 #endif
Definition: Gradient.hpp:58
Array1d ComputeGradient(Array1d sL, Array1d sR)
Definition: Gradient.hpp:203
Limiter limiter_
Definition: Gradient.hpp:67
double ComputeGradient(double sL, double sR)
Definition: Gradient.hpp:211
void ComputeGradient(State &grad, const State &sL, const State &sR)
Definition: Gradient.hpp:222
Definition: Gradient.hpp:153
CharacteristicsGradient(const EulerEquation &equation)
Definition: Gradient.hpp:167
::fub::Characteristics< EulerEquation > Characteristics
Definition: Gradient.hpp:157
PrimitiveArray dwdx_L_array_
Definition: Gradient.hpp:195
CharacteristicsGradient(const EulerEquation &equation, const GradientMethod &method)
Definition: Gradient.hpp:173
EulerEquation equation_
Definition: Gradient.hpp:184
Primitive dwdx_R_
Definition: Gradient.hpp:189
void ComputeGradient(Gradient &gradient, span< const Complete, 3 > q, double dx, Direction dir)
Definition: Gradient.hpp:351
Characteristics dKdx_L_
Definition: Gradient.hpp:190
Primitive dwdx_L_
Definition: Gradient.hpp:188
Primitive wR_
Definition: Gradient.hpp:187
Primitive wL_
Definition: Gradient.hpp:185
CharacteristicsArray dKdx_R_array_
Definition: Gradient.hpp:198
Characteristics dKdx_R_
Definition: Gradient.hpp:191
CharacteristicsGradient(const GradientMethod &method)
Definition: Gradient.hpp:170
CharacteristicsArray dKdx_L_array_
Definition: Gradient.hpp:197
PrimitiveArray wR_array_
Definition: Gradient.hpp:194
CharacteristicsArray GradientArray
Definition: Gradient.hpp:163
PrimitiveArray dwdx_R_array_
Definition: Gradient.hpp:196
PrimitiveArray wM_array_
Definition: Gradient.hpp:193
Characteristics Gradient
Definition: Gradient.hpp:162
GradientMethod gradient_
Definition: Gradient.hpp:199
PrimitiveArray wL_array_
Definition: Gradient.hpp:192
::fub::CharacteristicsArray< EulerEquation > CharacteristicsArray
Definition: Gradient.hpp:158
Primitive wM_
Definition: Gradient.hpp:186
Definition: Gradient.hpp:72
ConservativeGradient(const GradientMethod &method)
Definition: Gradient.hpp:86
void ComputeGradient(Gradient &dudx, span< const Complete, 3 > q, double dx, Direction dir)
Definition: Gradient.hpp:231
Conservative dudx_R_
Definition: Gradient.hpp:101
Equation equation_
Definition: Gradient.hpp:99
GradientMethod gradient_
Definition: Gradient.hpp:104
ConservativeGradient(const Equation &, const GradientMethod &method)
Definition: Gradient.hpp:89
ConservativeArray dudx_L_array_
Definition: Gradient.hpp:102
ConservativeArray dudx_R_array_
Definition: Gradient.hpp:103
::fub::Conservative< Equation > Conservative
Definition: Gradient.hpp:76
Conservative Gradient
Definition: Gradient.hpp:79
ConservativeArray GradientArray
Definition: Gradient.hpp:80
::fub::ConservativeArray< Equation > ConservativeArray
Definition: Gradient.hpp:77
ConservativeGradient(const Equation &eq)
Definition: Gradient.hpp:84
Conservative dudx_L_
Definition: Gradient.hpp:100
Definition: Gradient.hpp:109
Primitive wL_
Definition: Gradient.hpp:138
Primitive dwdx_L_
Definition: Gradient.hpp:141
Primitive wR_
Definition: Gradient.hpp:140
PrimitiveArray wL_array_
Definition: Gradient.hpp:143
PrimitiveArray GradientArray
Definition: Gradient.hpp:117
PrimitiveGradient(const EulerEquation &equation)
Definition: Gradient.hpp:121
::fub::PrimitiveArray< EulerEquation > PrimitiveArray
Definition: Gradient.hpp:114
PrimitiveGradient(const EulerEquation &equation, const GradientMethod &method)
Definition: Gradient.hpp:127
::fub::Primitive< EulerEquation > Primitive
Definition: Gradient.hpp:113
Primitive Gradient
Definition: Gradient.hpp:116
PrimitiveArray dwdx_R_array_
Definition: Gradient.hpp:147
Primitive wM_
Definition: Gradient.hpp:139
PrimitiveGradient(const GradientMethod &method)
Definition: Gradient.hpp:124
PrimitiveArray wM_array_
Definition: Gradient.hpp:144
Primitive dwdx_R_
Definition: Gradient.hpp:142
void ComputeGradient(Gradient &gradient, span< const Complete, 3 > q, double dx, Direction dir)
Definition: Gradient.hpp:255
PrimitiveArray dwdx_L_array_
Definition: Gradient.hpp:146
GradientMethod gradient_
Definition: Gradient.hpp:148
EulerEquation equation_
Definition: Gradient.hpp:137
PrimitiveArray wR_array_
Definition: Gradient.hpp:145
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
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
Array< double, 1 > Array1d
Definition: Eigen.hpp:53
void ComputeAmplitudes(Characteristics< Equation > &amplitudes, const Primitive< Equation > &left, const Primitive< Equation > &right, double rhoc, double ooc2, double dx, int ix)
Definition: Gradient.hpp:285
void PrimFromComplete(const PerfectGas< Rank > &, Primitive< PerfectGas< Rank >> &prim, const Complete< PerfectGas< Rank >> &complete)
Definition: PerfectGas.hpp:322
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
void ForEachComponent(F function, Ts &&... states)
Definition: State.hpp:624
Array< bool, 1 > MaskArray
Definition: Eigen.hpp:59
Definition: Gradient.hpp:38
double operator()(double R) const noexcept
Definition: Gradient.hpp:39
Array1d operator()(Array1d R) const noexcept
Definition: Gradient.hpp:43
Definition: Gradient.hpp:28
double operator()(double) const noexcept
Definition: Gradient.hpp:29
Array1d operator()(Array1d) const noexcept
Definition: Gradient.hpp:30
Definition: Gradient.hpp:33
Array1d operator()(Array1d) const noexcept
Definition: Gradient.hpp:35
double operator()(double) const noexcept
Definition: Gradient.hpp:34
Definition: Gradient.hpp:49
Array1d operator()(Array1d R) const noexcept
Definition: Gradient.hpp:53
double operator()(double R) const noexcept
Definition: Gradient.hpp:50
Definition: EulerEquation.hpp:343