ryujin 2.1.1 revision ee5cbcbf2346c1299c942d0e1f13b46449973c18
Loading...
Searching...
No Matches
wave_speed_estimator.template.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2020 - 2026 by the ryujin authors
4//
5
6#pragma once
7
9
10#include <newton.h>
11#include <simd.h>
12
13// #define DEBUG_WAVE_SPEED_ESTIMATOR
14
15namespace ryujin
16{
17 namespace EulerAEOS
18 {
19 /*
20 * The WaveSpeedEstimatorView is a guaranteed maximal wavespeed (GMS)
21 * estimate for the extended Riemann problem outlined in
22 * @cite ClaytonGuermondPopov-2022. For extenstions on handling negative
23 * pressures, we follow @cite clayton2023robust (see §4.6).
24 *
25 * In contrast to the algorithm outlined in above reference the
26 * algorithm takes a couple of shortcuts to significantly decrease the
27 * computational footprint. These simplifications still guarantee that
28 * we have an upper bound on the maximal wavespeed - but the number
29 * bound might be larger. In particular:
30 *
31 * - We do not check and treat the case phi(p_min) > 0. This
32 * corresponds to two expansion waves, see §5.2 in the reference. In
33 * this case we have
34 *
35 * 0 < p_star < p_min <= p_max.
36 *
37 * And due to the fact that p_star < p_min the wavespeeds reduce to
38 * a left wavespeed v_L - a_L and right wavespeed v_R + a_R. This
39 * implies that it is sufficient to set p_2 to ANY value provided
40 * that p_2 <= p_min hold true in order to compute the correct
41 * wavespeed.
42 *
43 * If p_2 > p_min then a more pessimistic bound is computed.
44 *
45 * - FIXME: Simplification in p_star_RS
46 */
47
48
49 template <int dim, typename Number>
51 const primitive_type &riemann_data_i,
52 const primitive_type &riemann_data_j) const
53 {
54 const auto pinf = view_.eos_interpolation_pinfty();
55
56 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
57 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
58
59#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
60 std::cout << "rho_left: " << rho_i << std::endl;
61 std::cout << "u_left: " << u_i << std::endl;
62 std::cout << "p_left: " << p_i << std::endl;
63 std::cout << "gamma_left: " << gamma_i << std::endl;
64 std::cout << "a_left: " << a_i << std::endl;
65 std::cout << "rho_right: " << rho_j << std::endl;
66 std::cout << "u_right: " << u_j << std::endl;
67 std::cout << "p_right: " << p_j << std::endl;
68 std::cout << "gamma_right: " << gamma_j << std::endl;
69 std::cout << "a_right: " << a_j << std::endl;
70#endif
71
72 const Number p_max = std::max(p_i, p_j) + pinf;
73 const Number phi_p_max = phi_of_p_max(riemann_data_i, riemann_data_j);
74
75 if (!view_.compute_strict_bounds()) {
76#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
77 const Number p_star_RS = p_star_RS_full(riemann_data_i, riemann_data_j);
78 const Number p_star_SS = p_star_SS_full(riemann_data_i, riemann_data_j);
79 const Number p_debug =
80 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
81 phi_p_max, Number(0.), p_star_SS, std::min(p_max, p_star_RS));
82 std::cout << " p^*_debug = " << p_debug << "\n";
83 std::cout << " phi(p_*_d) = "
84 << phi(riemann_data_i, riemann_data_j, p_debug) << "\n";
85 std::cout << "-> lambda_deb = "
86 << compute_lambda(riemann_data_i, riemann_data_j, p_debug)
87 << std::endl;
88#endif
89
90 const Number p_star_tilde =
91 p_star_interpolated(riemann_data_i, riemann_data_j);
92 const Number p_star_backup =
93 p_star_failsafe(riemann_data_i, riemann_data_j);
94
95 const Number p_2 =
96 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
97 phi_p_max,
98 Number(0.),
99 std::min(p_star_tilde, p_star_backup),
100 std::min(p_max, p_star_tilde));
101
102#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
103 std::cout << " p^*_tilde = " << p_2 << "\n";
104 std::cout << " phi(p_*_t) = "
105 << phi(riemann_data_i, riemann_data_j, p_2) << "\n";
106 std::cout << "-> lambda_max = "
107 << compute_lambda(riemann_data_i, riemann_data_j, p_2) << "\n"
108 << std::endl;
109#endif
110
111 return compute_lambda(riemann_data_i, riemann_data_j, p_2);
112 }
113
114 const Number p_star_RS = p_star_RS_full(riemann_data_i, riemann_data_j);
115 const Number p_star_SS = p_star_SS_full(riemann_data_i, riemann_data_j);
116
117 const Number p_2 =
118 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
119 phi_p_max, Number(0.), p_star_SS, std::min(p_max, p_star_RS));
120
121#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
122 std::cout << " p^*_tilde = " << p_2 << "\n";
123 std::cout << " phi(p_*_t) = "
124 << phi(riemann_data_i, riemann_data_j, p_2) << "\n";
125 std::cout << "-> lambda_max = "
126 << compute_lambda(riemann_data_i, riemann_data_j, p_2)
127 << std::endl;
128#endif
129
130 return compute_lambda(riemann_data_i, riemann_data_j, p_2);
131 }
132
133
134 template <int dim, typename Number>
135 DEAL_II_ALWAYS_INLINE inline Number
137 const PrecomputedVectorView &pv,
138 const state_type &U_i,
139 const state_type &U_j,
140 const unsigned int i,
141 const unsigned int *js,
142 const dealii::Tensor<1, dim, Number> &n_ij) const
143 {
144 const auto &[p_i, unused_i, s_i, eta_i] =
145 pv.template read_tensor<Number, precomputed_type>(i);
146
147 const auto &[p_j, unused_j, s_j, eta_j] =
148 pv.template read_tensor<Number, precomputed_type>(js);
149
150 const auto riemann_data_i = riemann_data_from_state(U_i, p_i, n_ij);
151 const auto riemann_data_j = riemann_data_from_state(U_j, p_j, n_ij);
152
153 return compute(riemann_data_i, riemann_data_j);
154 }
155
156
157 template <int dim, typename Number>
158 DEAL_II_ALWAYS_INLINE inline Number
159 WaveSpeedEstimatorView<dim, Number>::c(const Number &gamma) const
160 {
161 /*
162 * We implement the continuous and monotonic function c(gamma) as
163 * defined in (A.3) on page A469 of @cite ClaytonGuermondPopov-2022.
164 * But with a simplified quick cut-off for the case gamma > 3:
165 *
166 * c(gamma)^2 = 1 for gamma <= 5 / 3
167 * c(gamma)^2 = (3 * gamma + 11) / (6 * gamma + 6) in between
168 * c(gamma)^2 = max(1/2, 5 / 6 - slope (gamma - 3)) for gamma > 3
169 *
170 * Due to the fact that the function is monotonic we can simply clip
171 * the values without checking the conditions:
172 */
173
174 constexpr ScalarNumber slope =
175 ScalarNumber(-0.34976871477801828189920753948709);
176
177 const Number first_radicand = (ScalarNumber(3.) * gamma + Number(11.)) /
178 (ScalarNumber(6.) * gamma + Number(6.));
179
180 const Number second_radicand =
181 Number(5. / 6.) + slope * (gamma - Number(3.));
182
183 Number radicand = std::min(first_radicand, second_radicand);
184 radicand = std::min(Number(1.), radicand);
185 radicand = std::max(Number(1. / 2.), radicand);
186
187 return std::sqrt(radicand);
188 }
189
190
191 template <int dim, typename Number>
192 DEAL_II_ALWAYS_INLINE inline Number
194 const Number &gamma,
195 const Number &a) const
196 {
197 const auto covolume_b = view_.eos_covolume_constant();
198
199 const Number numerator =
200 ScalarNumber(2.) * a * (Number(1.) - covolume_b * rho);
201
202 const Number denominator = gamma - Number(1.);
203
204 return safe_division(numerator, denominator);
205 }
206
207
208 template <int dim, typename Number>
209 DEAL_II_ALWAYS_INLINE inline Number
211 const primitive_type &riemann_data_i,
212 const primitive_type &riemann_data_j) const
213 {
214 const auto pinf = view_.eos_interpolation_pinfty();
215
216 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
217 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
218 const auto alpha_i = alpha(rho_i, gamma_i, a_i);
219 const auto alpha_j = alpha(rho_j, gamma_j, a_j);
220
221 /*
222 * First get p_min, p_max.
223 *
224 * Then, we get gamma_min/max, and alpha_min/max. Note that the
225 * *_min/max values are associated with p_min/max and are not
226 * necessarily the minimum/maximum of *_i vs *_j.
227 */
228
229 const Number p_min = std::min(p_i, p_j);
230 const Number p_max = std::max(p_i, p_j);
231
232 const Number gamma_min =
233 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
234 p_i, p_j, gamma_i, gamma_j);
235
236 const Number alpha_min =
237 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
238 p_i, p_j, alpha_i, alpha_j);
239
240 const Number alpha_hat_min = c(gamma_min) * alpha_min;
241
242 const Number alpha_max = dealii::compare_and_apply_mask<
243 dealii::SIMDComparison::greater_than_or_equal>(
244 p_i, p_j, alpha_i, alpha_j);
245
246 const Number gamma_m = std::min(gamma_i, gamma_j);
247 const Number gamma_M = std::max(gamma_i, gamma_j);
248
249 const Number numerator =
250 dealii::compare_and_apply_mask<dealii::SIMDComparison::equal>(
251 p_max + pinf,
252 Number(0.),
253 Number(0.),
254 positive_part(alpha_hat_min + alpha_max - (u_j - u_i)));
255
256 /*
257 * The admissible set is p_min >= pinf. But numerically let's avoid
258 * division by zero and ensure positivity:
259 */
260 const Number p_ratio = safe_division(p_min + pinf, p_max + pinf);
261
262 /*
263 * Here, we use a trick: The r-factor only shows up in the formula
264 * for the case \gamma_min = \gamma_m, otherwise the r-factor
265 * vanishes. We can accomplish this by using the following modified
266 * exponent (where we substitute gamma_m by gamma_min):
267 */
268 const Number r_exponent =
269 (gamma_M - gamma_min) / (ScalarNumber(2.) * gamma_min * gamma_M);
270
271 /*
272 * Compute (5.7) first formula for \tilde p_1^\ast and (5.8)
273 * second formula for \tilde p_2^\ast at the same time:
274 */
275
276 const Number first_exponent =
277 (gamma_M - Number(1.)) / (ScalarNumber(2.) * gamma_M);
278
279 const Number first_exponent_inverse =
280 safe_division(Number(1.), first_exponent);
281
282 const Number first_denom =
283 alpha_hat_min * ryujin::pow(p_ratio, r_exponent - first_exponent) +
284 alpha_max;
285
286 const Number p_1_tilde =
287 (p_max + pinf) * ryujin::pow(safe_division(numerator, first_denom),
288 first_exponent_inverse) -
289 pinf;
290
291#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
292 std::cout << "RS p_1_tilde = " << p_1_tilde << "\n";
293#endif
294
295 /*
296 * Compute (5.7) second formula for \tilde p_2^\ast and (5.8) first
297 * formula for \tilde p_1^\ast at the same time:
298 */
299
300 const Number second_exponent =
301 (gamma_m - Number(1.)) / (ScalarNumber(2.) * gamma_m);
302
303 const Number second_exponent_inverse =
304 safe_division(Number(1.), second_exponent);
305
306 Number second_denom =
307 alpha_hat_min * ryujin::pow(p_ratio, -second_exponent) +
308 alpha_max * ryujin::pow(p_ratio, r_exponent);
309
310 const Number p_2_tilde =
311 (p_max + pinf) * ryujin::pow(safe_division(numerator, second_denom),
312 second_exponent_inverse) -
313 pinf;
314
315#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
316 std::cout << "RS p_2_tilde = " << p_2_tilde << "\n";
317#endif
318
319 return std::min(p_1_tilde, p_2_tilde);
320 }
321
322
323 template <int dim, typename Number>
324 DEAL_II_ALWAYS_INLINE inline Number
326 const primitive_type &riemann_data_i,
327 const primitive_type &riemann_data_j) const
328 {
329 const auto pinf = view_.eos_interpolation_pinfty();
330
331 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
332 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
333
334 const Number gamma_m = std::min(gamma_i, gamma_j);
335
336 const Number alpha_hat_i = c(gamma_i) * alpha(rho_i, gamma_i, a_i);
337 const Number alpha_hat_j = c(gamma_j) * alpha(rho_j, gamma_j, a_j);
338
339 /*
340 * Compute (5.10) formula for \tilde p_1^\ast:
341 *
342 * Cost: 2x pow, 4x division, 0x sqrt
343 */
344
345 const Number exponent =
346 (gamma_m - Number(1.)) / (ScalarNumber(2.) * gamma_m);
347 const Number exponent_inverse = Number(1.) / exponent;
348
349 const Number numerator =
350 dealii::compare_and_apply_mask<dealii::SIMDComparison::equal>(
351 p_j + pinf,
352 Number(0.),
353 Number(0.),
354 positive_part(alpha_hat_i + alpha_hat_j - (u_j - u_i)));
355
356 const Number denominator =
357 alpha_hat_i *
358 ryujin::pow(safe_division(p_i + pinf, p_j + pinf), -exponent) +
359 alpha_hat_j;
360
361 const Number p_1_tilde =
362 (p_j + pinf) * ryujin::pow(safe_division(numerator, denominator),
363 exponent_inverse) -
364 pinf;
365
366#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
367 std::cout << "SS p_1_tilde = " << p_1_tilde << "\n";
368#endif
369
370 const auto p_2_tilde = p_star_failsafe(riemann_data_i, riemann_data_j);
371
372 return std::min(p_1_tilde, p_2_tilde);
373 }
374
375
376 template <int dim, typename Number>
377 DEAL_II_ALWAYS_INLINE inline Number
379 const primitive_type &riemann_data_i,
380 const primitive_type &riemann_data_j) const
381 {
382 const auto covolume_b = view_.eos_covolume_constant();
383 const auto pinf = view_.eos_interpolation_pinfty();
384
385 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
386 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
387
388 /*
389 * Compute (5.11) formula for \tilde p_2^\ast:
390 *
391 * Cost: 0x pow, 3x division, 3x sqrt
392 */
393
394 const Number p_max = std::max(p_i, p_j) + pinf;
395
396 const Number radicand_i = safe_division(
397 ScalarNumber(2.) * (Number(1.) - covolume_b * rho_i) * p_max,
398 rho_i * ((gamma_i + Number(1.)) * p_max +
399 (gamma_i - Number(1.)) * (p_i + pinf)));
400
401 const Number x_i = std::sqrt(radicand_i);
402
403 const Number radicand_j = safe_division(
404 ScalarNumber(2.) * (Number(1.) - covolume_b * rho_j) * p_max,
405 rho_j * ((gamma_j + Number(1.)) * p_max +
406 (gamma_j - Number(1.)) * (p_j + pinf)));
407
408 const Number x_j = std::sqrt(radicand_j);
409
410 const Number a = x_i + x_j;
411 const Number b =
412 dealii::compare_and_apply_mask<dealii::SIMDComparison::equal>(
413 a, Number(0.), Number(0.), u_j - u_i);
414
415 const Number c = -(p_i + pinf) * x_i - (p_j + pinf) * x_j;
416
417 const Number base = safe_division(
418 std::abs(-b +
419 std::sqrt(positive_part(b * b - ScalarNumber(4.) * a * c))),
420 std::abs(ScalarNumber(2.) * a));
421
422 const Number p_2_tilde = base * base - pinf;
423
424#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
425 std::cout << "SS p_2_tilde = " << p_2_tilde << "\n";
426#endif
427 return p_2_tilde;
428 }
429
430
431 template <int dim, typename Number>
432 DEAL_II_ALWAYS_INLINE inline Number
434 const primitive_type &riemann_data_i,
435 const primitive_type &riemann_data_j) const
436 {
437 const auto pinf = view_.eos_interpolation_pinfty();
438
439 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
440 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
441 const auto alpha_i = alpha(rho_i, gamma_i, a_i);
442 const auto alpha_j = alpha(rho_j, gamma_j, a_j);
443
444 /*
445 * First get p_min, p_max.
446 *
447 * Then, we get gamma_min/max, and alpha_min/max. Note that the
448 * *_min/max values are associated with p_min/max and are not
449 * necessarily the minimum/maximum of *_i vs *_j.
450 */
451
452 const Number p_min = std::min(p_i, p_j) + pinf;
453 const Number p_max = std::max(p_i, p_j) + pinf;
454
455 const Number gamma_min =
456 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
457 p_i, p_j, gamma_i, gamma_j);
458
459 const Number alpha_min =
460 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
461 p_i, p_j, alpha_i, alpha_j);
462
463 const Number alpha_hat_min = c(gamma_min) * alpha_min;
464
465 const Number gamma_max = dealii::compare_and_apply_mask<
466 dealii::SIMDComparison::greater_than_or_equal>(
467 p_i, p_j, gamma_i, gamma_j);
468
469 const Number alpha_max = dealii::compare_and_apply_mask<
470 dealii::SIMDComparison::greater_than_or_equal>(
471 p_i, p_j, alpha_i, alpha_j);
472
473 const Number alpha_hat_max = c(gamma_max) * alpha_max;
474
475 const Number gamma_m = std::min(gamma_i, gamma_j);
476 const Number gamma_M = std::max(gamma_i, gamma_j);
477
478 const Number p_ratio = safe_division(p_min, p_max);
479
480 /*
481 * Here, we use a trick: The r-factor only shows up in the formula
482 * for the case \gamma_min = \gamma_m, otherwise the r-factor
483 * vanishes. We can accomplish this by using the following modified
484 * exponent (where we substitute gamma_m by gamma_min):
485 */
486 const Number r_exponent =
487 (gamma_M - gamma_min) / (ScalarNumber(2.) * gamma_min * gamma_M);
488
489 /*
490 * Compute a simultaneous upper bound on
491 * (5.7) second formula for \tilde p_2^\ast
492 * (5.8) first formula for \tilde p_1^\ast
493 * (5.11) formula for \tilde p_2^\ast
494 */
495
496 const Number exponent =
497 (gamma_m - Number(1.)) / (ScalarNumber(2.) * gamma_m);
498 const Number exponent_inverse = Number(1.) / exponent;
499
500 const Number numerator =
501 positive_part(alpha_hat_min + /*SIC!*/ alpha_max - (u_j - u_i));
502
503 Number denominator = alpha_hat_min * ryujin::pow(p_ratio, -exponent) +
504 alpha_hat_max * ryujin::pow(p_ratio, r_exponent);
505
506 const auto temp = safe_division(numerator, denominator);
507
508 const Number p_tilde = p_max * ryujin::pow(temp, exponent_inverse) - pinf;
509
510#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
511 std::cout << "IN p_*_tilde = " << p_tilde << "\n";
512#endif
513
514 return p_tilde;
515 }
516
517
518 template <int dim, typename Number>
519 DEAL_II_ALWAYS_INLINE inline Number
520 WaveSpeedEstimatorView<dim, Number>::f(const primitive_type &riemann_data,
521 const Number p_star) const
522 {
523 constexpr ScalarNumber min = std::numeric_limits<ScalarNumber>::min();
524
525 const auto covolume_b = view_.eos_covolume_constant();
526 const auto pinf = view_.eos_interpolation_pinfty();
527
528 const auto &[rho, u, p, gamma, a] = riemann_data;
529
530 const Number one_minus_b_rho = Number(1.) - covolume_b * rho;
531 const Number gamma_minus_one = gamma - Number(1.);
532
533 const Number Az =
534 ScalarNumber(2.) * one_minus_b_rho / (rho * (gamma + Number(1.)));
535
536 const Number Bz = gamma_minus_one / (gamma + Number(1.)) * (p + pinf);
537
538 const Number radicand = safe_division(Az, p_star + pinf + Bz);
539
540 /* true_value is shock case */
541 const Number true_value = (p_star - p) * std::sqrt(radicand);
542
543 const auto exponent = ScalarNumber(0.5) * gamma_minus_one / gamma;
544
545 const Number ratio = safe_division(p_star + pinf, p + pinf);
546 const Number factor = ryujin::pow(ratio, exponent) - Number(1.);
547
548 /* false_value is rarefaction case */
549 const auto false_value = ScalarNumber(2.) * a * one_minus_b_rho * factor /
550 std::max(gamma_minus_one, Number(min));
551
552 return dealii::compare_and_apply_mask<
553 dealii::SIMDComparison::greater_than_or_equal>(
554 p_star, p, true_value, false_value);
555 }
556
557
558 template <int dim, typename Number>
559 DEAL_II_ALWAYS_INLINE inline Number
561 const primitive_type &riemann_data_i,
562 const primitive_type &riemann_data_j,
563 const Number p_in) const
564 {
565 const Number &u_i = riemann_data_i[1];
566 const Number &u_j = riemann_data_j[1];
567
568 return f(riemann_data_i, p_in) + f(riemann_data_j, p_in) + u_j - u_i;
569 }
570
571
572 template <int dim, typename Number>
573 DEAL_II_ALWAYS_INLINE inline Number
575 const primitive_type &riemann_data_i,
576 const primitive_type &riemann_data_j) const
577 {
578 const auto covolume_b = view_.eos_covolume_constant();
579 const auto pinf = view_.eos_interpolation_pinfty();
580
581 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
582 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
583
584 const Number p_max = std::max(p_i, p_j) + pinf;
585
586 const Number radicand_inverse_i =
587 safe_division(ScalarNumber(0.5) * rho_i,
588 Number(1.) - covolume_b * rho_i) *
589 ((gamma_i + Number(1.)) * p_max +
590 (gamma_i - Number(1.)) * (p_i + pinf));
591
592 const Number value_i =
593 safe_division(p_max - p_i, std::sqrt(radicand_inverse_i));
594
595 const Number radicand_inverse_j =
596 safe_division(ScalarNumber(0.5) * rho_j,
597 Number(1.) - covolume_b * rho_j) *
598 ((gamma_j + Number(1.)) * p_max +
599 (gamma_j - Number(1.)) * (p_j + pinf));
600
601 const Number value_j =
602 safe_division(p_max - p_j, std::sqrt(radicand_inverse_j));
603
604 return value_i + value_j + u_j - u_i;
605 }
606
607
608 template <int dim, typename Number>
609 DEAL_II_ALWAYS_INLINE inline Number
611 const primitive_type &riemann_data, const Number p_star) const
612 {
613 const auto pinf = view_.eos_interpolation_pinfty();
614
615 const auto &[rho, u, p, gamma, a] = riemann_data;
616
617 const auto factor =
618 ScalarNumber(0.5) * (gamma + ScalarNumber(1.)) / gamma;
619
620 const Number tmp = safe_division(positive_part(p_star - p), p + pinf);
621
622 return u - a * std::sqrt(Number(1.) + factor * tmp);
623 }
624
625
626 template <int dim, typename Number>
627 DEAL_II_ALWAYS_INLINE inline Number
629 const primitive_type &riemann_data, const Number p_star) const
630 {
631 const auto pinf = view_.eos_interpolation_pinfty();
632
633 const auto &[rho, u, p, gamma, a] = riemann_data;
634
635 const auto factor =
636 ScalarNumber(0.5) * (gamma + ScalarNumber(1.)) / gamma;
637
638 const Number tmp = safe_division(positive_part(p_star - p), p + pinf);
639
640 return u + a * std::sqrt(Number(1.) + factor * tmp);
641 }
642
643
644 template <int dim, typename Number>
645 DEAL_II_ALWAYS_INLINE inline Number
647 const primitive_type &riemann_data_i,
648 const primitive_type &riemann_data_j,
649 const Number p_star) const
650 {
651 const Number nu_11 = lambda1_minus(riemann_data_i, p_star);
652 const Number nu_32 = lambda3_plus(riemann_data_j, p_star);
653
654 return std::max(positive_part(nu_32), negative_part(nu_11));
655 }
656
657
658 template <int dim, typename Number>
659 DEAL_II_ALWAYS_INLINE inline auto
661 const state_type &U,
662 const Number &p,
663 const dealii::Tensor<1, dim, Number> &n_ij) const -> primitive_type
664 {
665 const auto rho = view_.density(U);
666 const auto rho_inverse = ScalarNumber(1.0) / rho;
667
668 const auto m = view_.momentum(U);
669 const auto proj_m = n_ij * m;
670
671 const auto gamma = view_.surrogate_gamma(U, p);
672
673 const auto covolume_b = view_.eos_covolume_constant();
674 const auto pinf = view_.eos_interpolation_pinfty();
675 const auto x = Number(1.) - covolume_b * rho;
676 const auto a = std::sqrt(gamma * (p + pinf) / (rho * x));
677
678#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
680 Number(p + pinf),
681 [](auto val) { return val >= ScalarNumber(0.); },
682 dealii::ExcMessage("Internal error: p + pinf < 0."));
683
685 x,
686 [](auto val) { return val > ScalarNumber(0.); },
687 dealii::ExcMessage("Internal error: 1. - b * rho <= 0."));
688
690 gamma,
691 [](auto val) { return val >= ScalarNumber(1.); },
692 dealii::ExcMessage("Internal error: gamma < 1."));
693#endif
694
695 return {{rho, proj_m * rho_inverse, p, gamma, a}};
696 }
697
698 } // namespace EulerAEOS
699} // namespace ryujin
primitive_type riemann_data_from_state(const state_type &U, const Number &p, const dealii::Tensor< 1, dim, Number > &n_ij) const
Number alpha(const Number &rho, const Number &gamma, const Number &a) const
typename View::PrecomputedVectorView PrecomputedVectorView
Number phi_of_p_max(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
Number p_star_SS_full(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
typename std::array< Number, riemann_data_size > primitive_type
Number p_star_interpolated(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
Number compute_lambda(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number p_star) const
Number p_star_failsafe(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
Number lambda3_plus(const primitive_type &primitive_state, const Number p_star) const
Number p_star_RS_full(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
Number lambda1_minus(const primitive_type &riemann_data, const Number p_star) const
Number compute(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
#define AssertThrowSIMD(variable, condition, exception)
Definition simd.h:34
DEAL_II_HOST_DEVICE T pow(const T x, const T b)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number positive_part(const Number number)
Definition simd.h:149
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number negative_part(const Number number)
Definition simd.h:161
DEAL_II_ALWAYS_INLINE Number safe_division(const Number &numerator, const Number &denominator)