Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
Reconstruct.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_RECONSTRUCT
22 #define FUB_FLUX_METHOD_RECONSTRUCT
23 
24 #include "fub/Direction.hpp"
25 #include "fub/State.hpp"
27 
28 namespace fub {
29 
30 template <typename Equation> class ConservativeReconstruction {
31 public:
35 
39 
40  explicit ConservativeReconstruction(const Equation& equation)
41  : equation_{equation} {}
42 
43  void Reconstruct(Complete& reconstruction, const Complete& q0,
44  const Gradient& du_dx, Duration dt, double dx, Direction dir,
45  Side side) noexcept;
46 
47  void Reconstruct(CompleteArray& reconstruction, const CompleteArray& q0,
48  const GradientArray& du_dx, Duration dt, double dx,
49  Direction dir, Side side) noexcept;
50 
51 private:
53 
58 
63 };
64 
65 template <typename EulerEquation> class PrimitiveReconstruction {
66 public:
70 
74 
75  explicit PrimitiveReconstruction(const EulerEquation& equation)
76  : equation_{equation} {}
77 
78  void Reconstruct(Complete& reconstruction, const Complete& q0,
79  const Gradient& dw_dx, Duration dt, double dx, Direction dir,
80  Side side) noexcept;
81 
82  void Reconstruct(CompleteArray& reconstruction, const CompleteArray& q0,
83  const GradientArray& dw_dx, Duration dt, double dx,
84  Direction dir, Side side) noexcept;
85 
86 private:
87  EulerEquation equation_;
88 
91 
94 };
95 
96 template <typename EulerEquation> class CharacteristicsReconstruction {
97 public:
102 
107 
108  explicit CharacteristicsReconstruction(const EulerEquation& equation)
109  : equation_{equation} {}
110 
111  void Reconstruct(Complete& reconstruction, const Complete& q0,
112  const Gradient& dw_dx, Duration dt, double dx, Direction dir,
113  Side side) noexcept;
114 
115  void Reconstruct(CompleteArray& reconstruction, const CompleteArray& q0,
116  const GradientArray& dw_dx, Duration dt, double dx,
117  Direction dir, Side side) noexcept;
118 
119 private:
120  EulerEquation equation_;
121 
125 
129 };
130 
131 template <typename Equation>
133  Complete& reconstruction, const Complete& q0, const Gradient& dq_dx,
134  Duration dt, double dx, Direction dir, Side side) noexcept {
136  [dx](double& uL, double& uR, double u, double du_dx) {
137  const double du = 0.5 * dx * du_dx;
138  uL = u - du;
139  uR = u + du;
140  },
141  AsCons(q_left_), AsCons(q_right_), q0, dq_dx);
142  CompleteFromCons(equation_, q_left_, q_left_);
143  CompleteFromCons(equation_, q_right_, q_right_);
144  Flux(equation_, flux_left_, q_left_, dir);
145  Flux(equation_, flux_right_, q_right_, dir);
146  const double lambda_half = 0.5 * dt.count() / dx;
147  const Complete& q = side == Side::Lower ? q_left_ : q_right_;
149  [&lambda_half](double& rec, double u, double fL, double fR) {
150  const double dF = fL - fR;
151  const double dU = lambda_half * dF;
152  rec = u + dU;
153  },
154  AsCons(reconstruction), AsCons(q), flux_left_, flux_right_);
155  CompleteFromCons(equation_, reconstruction, reconstruction);
156 }
157 
158 template <typename Equation>
160  CompleteArray& reconstruction, const CompleteArray& q0,
161  const GradientArray& dq_dx, Duration dt, double dx, Direction dir,
162  Side side) noexcept {
164  [dx](auto&& uL, auto&& uR, auto&& u, auto&& du_dx) {
165  const Array1d du = 0.5 * dx * du_dx;
166  uL = u - du;
167  uR = u + du;
168  },
169  AsCons(q_left_array_), AsCons(q_right_array_), q0, dq_dx);
170  CompleteFromCons(equation_, q_left_array_, q_left_array_);
171  CompleteFromCons(equation_, q_right_array_, q_right_array_);
172  Flux(equation_, flux_left_array_, q_left_array_, dir);
173  Flux(equation_, flux_right_array_, q_right_array_, dir);
174  const double lambda_half = 0.5 * dt.count() / dx;
175  const CompleteArray& q = side == Side::Lower ? q_left_array_ : q_right_array_;
177  [&lambda_half](auto&& rec, auto&& u, auto&& fL, auto&& fR) {
178  const Array1d dF = fL - fR;
179  const Array1d dU = lambda_half * dF;
180  rec = u + dU;
181  },
182  AsCons(reconstruction), AsCons(q), flux_left_array_, flux_right_array_);
183  CompleteFromCons(equation_, reconstruction, reconstruction);
184 }
185 
186 template <typename EulerEquation>
188  Complete& reconstruction, const Complete& q0, const Primitive& dw_dx,
189  Duration dt, double dx, Direction dir, Side side) noexcept {
190  PrimFromComplete(equation_, w_, q0);
191  const int ix = static_cast<int>(dir);
192  const int sign = (side == Side::Upper) - (side == Side::Lower);
193  const double lambda = sign * dt.count() / dx;
194  const double dx_half = sign * 0.5 * dx;
195  const double u = w_.velocity[ix];
196  const double rho = q0.density;
197  const double a = q0.speed_of_sound;
198  const double a2 = a * a;
199  const double rho_a2 = rho * a2;
200  w_rec_.density =
201  w_.density +
202  dx_half * (dw_dx.density -
203  lambda * (u * dw_dx.density + rho * dw_dx.velocity[ix]));
204  w_rec_.pressure =
205  w_.pressure +
206  dx_half * (dw_dx.pressure -
207  lambda * (rho_a2 * dw_dx.velocity[ix] + u * dw_dx.pressure));
208  w_rec_.velocity[ix] =
209  w_.velocity[ix] +
210  dx_half * (dw_dx.velocity[ix] +
211  lambda * (u * dw_dx.velocity[ix] + dw_dx.pressure / rho));
212  constexpr int Rank = EulerEquation::Rank();
213  for (int i = 1; i < Rank; ++i) {
214  const int iy = (ix + i) % Rank;
215  w_rec_.velocity[iy] =
216  w_.velocity[iy] +
217  dx_half * (dw_dx.velocity[iy] - lambda * u * dw_dx.velocity[iy]);
218  }
220  for (int i = 0; i < w_rec_.species.size(); ++i) {
221  w_rec_.species[i] =
222  w_.species[i] +
223  dx_half * (dw_dx.species[i] - lambda * u * dw_dx.species[i]);
224  }
225  }
226  CompleteFromPrim(equation_, reconstruction, w_rec_);
227 }
228 
229 template <typename EulerEquation>
231  CompleteArray& reconstruction, const CompleteArray& q0,
232  const PrimitiveArray& dw_dx, Duration dt, double dx, Direction dir,
233  Side side) noexcept {
234  PrimFromComplete(equation_, w_array_, q0);
235  const int ix = static_cast<int>(dir);
236  const int sign = (side == Side::Upper) - (side == Side::Lower);
237  const Array1d lambda = Array1d::Constant(sign * dt.count() / dx);
238  const Array1d dx_half = Array1d::Constant(sign * 0.5 * dx);
239  const Array1d u = w_array_.velocity.row(ix);
240  const Array1d rho = q0.density;
241  const Array1d a = q0.speed_of_sound;
242  const Array1d a2 = a * a;
243  const Array1d rho_a2 = rho * a2;
244  w_rec_array_.density =
245  w_array_.density +
246  dx_half * (dw_dx.density -
247  lambda * (u * dw_dx.density + rho * dw_dx.velocity.row(ix)));
248  w_rec_array_.pressure =
249  w_array_.pressure +
250  dx_half * (dw_dx.pressure - lambda * (rho_a2 * dw_dx.velocity.row(ix) +
251  u * dw_dx.pressure));
252  w_rec_array_.velocity.row(ix) =
253  w_array_.velocity.row(ix) +
254  dx_half * (dw_dx.velocity.row(ix) +
255  lambda * (u * dw_dx.velocity.row(ix) + dw_dx.pressure / rho));
256  constexpr int Rank = EulerEquation::Rank();
257  for (int i = 1; i < Rank; ++i) {
258  const int iy = (ix + i) % Rank;
259  w_rec_array_.velocity.row(iy) =
260  w_array_.velocity.row(iy) + dx_half * (dw_dx.velocity.row(iy) -
261  lambda * u * dw_dx.velocity.row(iy));
262  }
264  for (int i = 0; i < w_rec_array_.species.rows(); ++i) {
265  w_rec_array_.species.row(i) =
266  w_array_.species.row(i) +
267  dx_half * (dw_dx.species.row(i) - lambda * u * dw_dx.species.row(i));
268  }
269  }
270  CompleteFromPrim(equation_, reconstruction, w_rec_array_);
271 }
272 
273 template <typename EulerEquation>
275  Complete& reconstruction, const Complete& q0, const Characteristics& dKdx,
276  Duration dt, double dx, Direction dir, Side side) noexcept {
277  PrimFromComplete(equation_, w_rec_, q0);
278  const int ix = static_cast<int>(dir);
279  const double u = w_rec_.velocity[ix];
280  const double c = q0.speed_of_sound;
281  const int sign = (side == Side::Upper) - (side == Side::Lower);
282  const double lambda = sign * dt.count() / dx;
283  const double dx_half = sign * 0.5 * dx;
284  dKdt_.minus = dx_half * dKdx.minus * (1.0 - lambda * (u - c));
285  dKdt_.plus = dx_half * dKdx.plus * (1.0 - lambda * (u + c));
286  for (int i = 0; i < dKdt_.zero.size(); ++i) {
287  dKdt_.zero[i] = dx_half * dKdx.zero[i] * (1.0 - lambda * u);
288  }
290  for (int i = 0; i < dKdt_.species.size(); ++i) {
291  dKdt_.species[i] = dx_half * dKdx.species[i] * (1.0 - lambda * u);
292  }
293  }
294  const double rho = w_rec_.density;
295  const double rhoc = rho * c;
296  const double c2 = c * c;
297  dwdt_.pressure = 0.5 * (dKdt_.minus + dKdt_.plus);
298  dwdt_.density = dwdt_.pressure / c2 + dKdt_.zero[0];
299  dwdt_.velocity.row(ix) = 0.5 * (dKdt_.plus - dKdt_.minus) / rhoc;
300  constexpr int Rank = EulerEquation::Rank();
301  for (int i = 1; i < Rank; ++i) {
302  const int iy = (ix + i) % Rank;
303  dwdt_.velocity.row(iy) = dKdt_.zero[i];
304  }
306  for (int i = 0; i < dKdt_.species.size(); ++i) {
307  dwdt_.species[i] = dKdt_.species[i];
308  }
309  }
310  w_rec_ += dwdt_;
311  CompleteFromPrim(equation_, reconstruction, w_rec_);
312 }
313 
314 template <typename EulerEquation>
316  CompleteArray& reconstruction, const CompleteArray& q0,
317  const CharacteristicsArray& dKdx, Duration dt, double dx, Direction dir,
318  Side side) noexcept {
319  PrimFromComplete(equation_, w_rec_array_, q0);
320  const int ix = static_cast<int>(dir);
321  const Array1d u = w_rec_array_.velocity.row(ix);
322  const Array1d c = q0.speed_of_sound;
323  const int sign = (side == Side::Upper) - (side == Side::Lower);
324  const Array1d lambda = Array1d::Constant(sign * dt.count() / dx);
325  const Array1d dx_half = Array1d::Constant(sign * 0.5 * dx);
326  dKdt_array_.minus =
327  dx_half * dKdx.minus * (Array1d::Constant(1.0) - lambda * (u - c));
328  dKdt_array_.plus =
329  dx_half * dKdx.plus * (Array1d::Constant(1.0) - lambda * (u + c));
330  for (int i = 0; i < dKdt_array_.zero.rows(); ++i) {
331  dKdt_array_.zero.row(i) =
332  dx_half * dKdx.zero.row(i) * (Array1d::Constant(1.0) - lambda * u);
333  }
335  for (int i = 0; i < dKdt_array_.species.rows(); ++i) {
336  dKdt_array_.species.row(i) =
337  dx_half * dKdx.species.row(i) * (Array1d::Constant(1.0) - lambda * u);
338  }
339  }
340  const Array1d rho = w_rec_array_.density;
341  const Array1d rhoc = rho * c;
342  const Array1d c2 = c * c;
343  dwdt_array_.pressure = 0.5 * (dKdt_array_.minus + dKdt_array_.plus);
344  dwdt_array_.density = dwdt_array_.pressure / c2 + dKdt_array_.zero.row(0);
345  dwdt_array_.velocity.row(ix) = 0.5 * (dKdt_array_.plus - dKdt_array_.minus) / rhoc;
346  constexpr int Rank = EulerEquation::Rank();
347  for (int i = 1; i < Rank; ++i) {
348  const int iy = (ix + i) % Rank;
349  dwdt_array_.velocity.row(iy) = dKdt_array_.zero.row(i);
350  }
352  for (int i = 0; i < dKdt_array_.species.rows(); ++i) {
353  dwdt_array_.species.row(i) = dKdt_array_.species.row(i);
354  }
355  }
356  w_rec_array_ += dwdt_array_;
357  CompleteFromPrim(equation_, reconstruction, w_rec_array_);
358 }
359 
360 } // namespace fub
361 
362 #endif
Definition: Reconstruct.hpp:96
Primitive w_rec_
Definition: Reconstruct.hpp:122
CharacteristicsReconstruction(const EulerEquation &equation)
Definition: Reconstruct.hpp:108
PrimitiveArray w_rec_array_
Definition: Reconstruct.hpp:126
EulerEquation equation_
Definition: Reconstruct.hpp:120
CharacteristicsArray GradientArray
Definition: Reconstruct.hpp:106
Primitive dwdt_
Definition: Reconstruct.hpp:123
Characteristics dKdt_
Definition: Reconstruct.hpp:124
::fub::CharacteristicsArray< EulerEquation > CharacteristicsArray
Definition: Reconstruct.hpp:103
void Reconstruct(Complete &reconstruction, const Complete &q0, const Gradient &dw_dx, Duration dt, double dx, Direction dir, Side side) noexcept
Definition: Reconstruct.hpp:274
::fub::Characteristics< EulerEquation > Characteristics
Definition: Reconstruct.hpp:98
Characteristics Gradient
Definition: Reconstruct.hpp:101
CharacteristicsArray dKdt_array_
Definition: Reconstruct.hpp:128
PrimitiveArray dwdt_array_
Definition: Reconstruct.hpp:127
Definition: Reconstruct.hpp:30
CompleteArray q_right_array_
Definition: Reconstruct.hpp:60
ConservativeReconstruction(const Equation &equation)
Definition: Reconstruct.hpp:40
Complete q_right_
Definition: Reconstruct.hpp:55
Conservative flux_left_
Definition: Reconstruct.hpp:56
void Reconstruct(Complete &reconstruction, const Complete &q0, const Gradient &du_dx, Duration dt, double dx, Direction dir, Side side) noexcept
Definition: Reconstruct.hpp:132
ConservativeArray GradientArray
Definition: Reconstruct.hpp:38
ConservativeArray flux_right_array_
Definition: Reconstruct.hpp:62
ConservativeArray flux_left_array_
Definition: Reconstruct.hpp:61
Conservative Gradient
Definition: Reconstruct.hpp:34
CompleteArray q_left_array_
Definition: Reconstruct.hpp:59
::fub::ConservativeArray< Equation > ConservativeArray
Definition: Reconstruct.hpp:36
Conservative flux_right_
Definition: Reconstruct.hpp:57
Equation equation_
Definition: Reconstruct.hpp:52
::fub::Conservative< Equation > Conservative
Definition: Reconstruct.hpp:32
Complete q_left_
Definition: Reconstruct.hpp:54
Definition: Reconstruct.hpp:65
EulerEquation equation_
Definition: Reconstruct.hpp:87
Primitive w_rec_
Definition: Reconstruct.hpp:89
void Reconstruct(Complete &reconstruction, const Complete &q0, const Gradient &dw_dx, Duration dt, double dx, Direction dir, Side side) noexcept
Definition: Reconstruct.hpp:187
Primitive w_
Definition: Reconstruct.hpp:90
::fub::PrimitiveArray< EulerEquation > PrimitiveArray
Definition: Reconstruct.hpp:71
PrimitiveArray w_rec_array_
Definition: Reconstruct.hpp:92
Primitive Gradient
Definition: Reconstruct.hpp:69
PrimitiveArray w_array_
Definition: Reconstruct.hpp:93
::fub::Primitive< EulerEquation > Primitive
Definition: Reconstruct.hpp:67
PrimitiveReconstruction(const EulerEquation &equation)
Definition: Reconstruct.hpp:75
PrimitiveArray GradientArray
Definition: Reconstruct.hpp:73
void CompleteFromCons(Equation &&equation, Complete< std::decay_t< Equation >> &complete, const Conservative< std::decay_t< Equation >> &cons)
Definition: CompleteFromCons.hpp:42
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
void Flux(Eq &&equation, Conservative< Equation > &flux, const Complete< Equation > &state, Direction dir, [[maybe_unused]] double x=0.0)
Definition: Equation.hpp:108
std::chrono::duration< double > Duration
Definition: Duration.hpp:31
Side
This is a type safe type to denote a side.
Definition: Direction.hpp:34
Array< double, 1 > Array1d
Definition: Eigen.hpp:53
void PrimFromComplete(const PerfectGas< Rank > &, Primitive< PerfectGas< Rank >> &prim, const Complete< PerfectGas< Rank >> &complete)
Definition: PerfectGas.hpp:322
void CompleteFromPrim(const PerfectGas< Rank > &equation, Complete< PerfectGas< Rank >> &complete, const Primitive< PerfectGas< Rank >> &prim)
Definition: PerfectGas.hpp:314
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
const Conservative< Eq > & AsCons(const Conservative< Eq > &x)
Definition: State.hpp:438
void ForEachComponent(F function, Ts &&... states)
Definition: State.hpp:624
Definition: EulerEquation.hpp:343