19 template <
int dim,
typename Number>
20 DEAL_II_ALWAYS_INLINE
inline Number
22 const Number p_star)
const
24 const auto view = hyperbolic_system.view<dim, Number>();
25 const auto &gamma = view.gamma();
27 const auto &[rho, u, p, a] = riemann_data;
29 const Number Az =
ScalarNumber(2.) / (rho * (gamma + Number(1.)));
32 const Number radicand = Az / (p_star + Bz);
33 const Number true_value = (p_star - p) * std::sqrt(radicand);
37 const Number factor =
ryujin::pow(p_star / p, exponent) - Number(1.);
38 const auto false_value =
41 return dealii::compare_and_apply_mask<
42 dealii::SIMDComparison::greater_than_or_equal>(
43 p_star, p, true_value, false_value);
47 template <
int dim,
typename Number>
48 DEAL_II_ALWAYS_INLINE
inline Number
50 const Number &p_star)
const
52 const auto view = hyperbolic_system.view<dim, Number>();
55 const auto &gamma = view.gamma();
56 const auto &gamma_inverse = view.gamma_inverse();
57 const auto &gamma_minus_one_inverse = view.gamma_minus_one_inverse();
58 const auto &gamma_plus_one_inverse = view.gamma_plus_one_inverse();
60 const auto &[rho, u, p, a] = riemann_data;
62 const Number radicand_inverse =
ScalarNumber(0.5) * rho *
65 const Number denominator =
66 (p_star + (gamma -
ScalarNumber(1.)) * gamma_plus_one_inverse * p);
67 const Number true_value =
69 (denominator * std::sqrt(radicand_inverse));
76 const auto false_value =
79 return dealii::compare_and_apply_mask<
80 dealii::SIMDComparison::greater_than_or_equal>(
81 p_star, p, true_value, false_value);
85 template <
int dim,
typename Number>
86 DEAL_II_ALWAYS_INLINE
inline Number
89 const Number p_in)
const
91 const Number &u_i = riemann_data_i[1];
92 const Number &u_j = riemann_data_j[1];
94 return f(riemann_data_i, p_in) + f(riemann_data_j, p_in) + u_j - u_i;
98 template <
int dim,
typename Number>
99 DEAL_II_ALWAYS_INLINE
inline Number
102 const Number &p)
const
104 return df(riemann_data_i, p) + df(riemann_data_j, p);
120 template <
int dim,
typename Number>
121 DEAL_II_ALWAYS_INLINE
inline Number
126 const auto view = hyperbolic_system.view<dim, Number>();
127 const auto &gamma = view.gamma();
129 const auto &[rho_i, u_i, p_i, a_i] = riemann_data_i;
130 const auto &[rho_j, u_j, p_j, a_j] = riemann_data_j;
132 const Number p_max = std::max(p_i, p_j);
134 const Number radicand_inverse_i =
ScalarNumber(0.5) * rho_i *
138 const Number value_i = (p_max - p_i) / std::sqrt(radicand_inverse_i);
140 const Number radicand_inverse_j =
ScalarNumber(0.5) * rho_j *
144 const Number value_j = (p_max - p_j) / std::sqrt(radicand_inverse_j);
146 return value_i + value_j + u_j - u_i;
162 template <
int dim,
typename Number>
163 DEAL_II_ALWAYS_INLINE
inline Number
167 const auto view = hyperbolic_system.view<dim, Number>();
168 const auto &gamma = view.gamma();
169 const auto &gamma_inverse = view.gamma_inverse();
173 const auto &[rho, u, p, a] = riemann_data;
178 return u - a * std::sqrt(
ScalarNumber(1.0) + factor * tmp);
187 template <
int dim,
typename Number>
188 DEAL_II_ALWAYS_INLINE
inline Number
192 const auto view = hyperbolic_system.view<dim, Number>();
193 const auto &gamma = view.gamma();
194 const auto &gamma_inverse = view.gamma_inverse();
195 const Number factor =
198 const auto &[rho, u, p, a] = primitive_state;
202 return u + a * std::sqrt(Number(1.0) + factor * tmp);
215 template <
int dim,
typename Number>
216 DEAL_II_ALWAYS_INLINE
inline std::array<Number, 2>
218 const std::array<Number, 4> &riemann_data_i,
219 const std::array<Number, 4> &riemann_data_j,
221 const Number p_2)
const
223 const Number nu_11 = lambda1_minus(riemann_data_i, p_2 );
224 const Number nu_12 = lambda1_minus(riemann_data_i, p_1 );
226 const Number nu_31 = lambda3_plus(riemann_data_j, p_1);
227 const Number nu_32 = lambda3_plus(riemann_data_j, p_2);
229 const Number lambda_max =
233 std::max(std::abs(nu_32 - nu_31), std::abs(nu_12 - nu_11));
235 return {{gap, lambda_max}};
250 template <
int dim,
typename Number>
251 DEAL_II_ALWAYS_INLINE
inline Number
255 const Number p_star)
const
257 const Number nu_11 = lambda1_minus(riemann_data_i, p_star);
258 const Number nu_32 = lambda3_plus(riemann_data_j, p_star);
272 template <
int dim,
typename Number>
273 DEAL_II_ALWAYS_INLINE
inline Number
278 const auto view = hyperbolic_system.view<dim, Number>();
279 const auto &gamma = view.gamma();
280 const auto &gamma_inverse = view.gamma_inverse();
281 const auto &gamma_minus_one_inverse = view.gamma_minus_one_inverse();
283 const auto &[rho_i, u_i, p_i, a_i] = riemann_data_i;
284 const auto &[rho_j, u_j, p_j, a_j] = riemann_data_j;
304 const Number numerator =
positive_part(a_i + a_j - factor * (u_j - u_i));
305 const Number denominator =
306 a_i *
ryujin::pow(p_i * inv_p_j, -factor * gamma_inverse) + a_j;
308 const auto exponent =
ScalarNumber(2.0) * gamma * gamma_minus_one_inverse;
310 const auto p_1_tilde =
311 p_j *
ryujin::pow(numerator / denominator, exponent);
313#ifdef DEBUG_RIEMANN_SOLVER
314 std::cout <<
"p_star_two_rarefaction = " << p_1_tilde << std::endl;
328 template <
int dim,
typename Number>
329 DEAL_II_ALWAYS_INLINE
inline Number
334 const auto view = hyperbolic_system.view<dim, Number>();
335 const auto &gamma = view.gamma();
337 const auto &[rho_i, u_i, p_i, a_i] = riemann_data_i;
338 const auto &[rho_j, u_j, p_j, a_j] = riemann_data_j;
346 const Number p_max = std::max(p_i, p_j);
350 rho_i * ((gamma + Number(1.)) * p_max + (gamma - Number(1.)) * p_i);
352 const Number x_i = std::sqrt(radicand_i);
356 rho_j * ((gamma + Number(1.)) * p_max + (gamma - Number(1.)) * p_j);
358 const Number x_j = std::sqrt(radicand_j);
360 const Number a = x_i + x_j;
361 const Number b = u_j - u_i;
362 const Number c = -p_i * x_i - p_j * x_j;
364 const Number base = (-b + std::sqrt(b * b -
ScalarNumber(4.) * a * c)) /
366 const Number p_2_tilde = base * base;
368#ifdef DEBUG_RIEMANN_SOLVER
369 std::cout <<
"p_star_failsafe = " << p_2_tilde << std::endl;
375 template <
int dim,
typename Number>
376 DEAL_II_ALWAYS_INLINE
inline auto
378 const state_type &U,
const dealii::Tensor<1, dim, Number> &n_ij)
const
381 const auto view = hyperbolic_system.view<dim, Number>();
383 const auto rho = view.density(U);
384 const auto rho_inverse = Number(1.0) / rho;
386 const auto m = view.momentum(U);
387 const auto proj_m = n_ij * m;
388 const auto perp = m - proj_m * n_ij;
391 view.total_energy(U) - Number(0.5) * perp.norm_square() * rho_inverse;
393 using state_type_1d =
395 const auto view_1d = hyperbolic_system.view<1, Number>();
397 const auto state = state_type_1d{{rho, proj_m, E}};
398 const auto p = view_1d.pressure(state);
399 const auto a = view_1d.speed_of_sound(state);
400 return {{rho, proj_m * rho_inverse, p, a}};
404 template <
int dim,
typename Number>
456 const auto &[rho_i, u_i, p_i, a_i] = riemann_data_i;
457 const auto &[rho_j, u_j, p_j, a_j] = riemann_data_j;
459#ifdef DEBUG_RIEMANN_SOLVER
460 std::cout <<
"rho_left: " << rho_i << std::endl;
461 std::cout <<
"u_left: " << u_i << std::endl;
462 std::cout <<
"p_left: " << p_i << std::endl;
463 std::cout <<
"a_left: " << a_i << std::endl;
464 std::cout <<
"rho_right: " << rho_j << std::endl;
465 std::cout <<
"u_right: " << u_j << std::endl;
466 std::cout <<
"p_right: " << p_j << std::endl;
467 std::cout <<
"a_right: " << a_j << std::endl;
470 const Number p_max = std::max(p_i, p_j);
472 const Number rarefaction =
473 p_star_two_rarefaction(riemann_data_i, riemann_data_j);
474 const Number failsafe = p_star_failsafe(riemann_data_i, riemann_data_j);
475 const Number p_star_tilde = std::min(rarefaction, failsafe);
477 const Number phi_p_max = phi_of_p_max(riemann_data_i, riemann_data_j);
480 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
484 std::min(p_max, p_star_tilde));
486#ifdef DEBUG_RIEMANN_SOLVER
487 std::cout <<
" p^*_tilde = " << p_2 <<
"\n";
488 std::cout <<
" phi(p_*_t) = "
489 << phi(riemann_data_i, riemann_data_j, p_2) << std::endl;
496 if (parameters.newton_max_iterations() == 0) {
497 const auto lambda_max =
498 compute_lambda(riemann_data_i, riemann_data_j, p_2);
500#ifdef DEBUG_RIEMANN_SOLVER
501 std::cout <<
"-> lambda_max = " << lambda_max << std::endl;
512 const Number p_min = std::min(riemann_data_i[2], riemann_data_j[2]);
515 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
516 phi_p_max, Number(0.), p_max, p_min);
518 p_1 = dealii::compare_and_apply_mask<
519 dealii::SIMDComparison::less_than_or_equal>(p_1, p_2, p_1, p_2);
527 auto [gap, lambda_max] =
528 compute_gap(riemann_data_i, riemann_data_j, p_1, p_2);
530#ifdef DEBUG_RIEMANN_SOLVER
531 std::cout << std::fixed << std::setprecision(16);
532 std::cout <<
"p_1: (start) " << p_1 << std::endl;
533 std::cout <<
"p_2: (start) " << p_2 << std::endl;
534 std::cout <<
"gap: (start) " << gap << std::endl;
535 std::cout <<
"l_m: (start) " << lambda_max << std::endl;
538 for (
unsigned int i = 0; i < parameters.newton_max_iterations(); ++i) {
541 const Number tolerance(parameters.newton_tolerance());
542 if (std::max(Number(0.), gap - tolerance) == Number(0.)) {
543#ifdef DEBUG_RIEMANN_SOLVER
544 std::cout <<
"converged after " << i <<
" iterations." << std::endl;
550 const Number phi_p_1 = phi(riemann_data_i, riemann_data_j, p_1);
551 const Number phi_p_2 = phi(riemann_data_i, riemann_data_j, p_2);
552 const Number dphi_p_1 = dphi(riemann_data_i, riemann_data_j, p_1);
553 const Number dphi_p_2 = dphi(riemann_data_i, riemann_data_j, p_2);
558 auto [gap_new, lambda_max_new] =
559 compute_gap(riemann_data_i, riemann_data_j, p_1, p_2);
561 lambda_max = lambda_max_new;
563#ifdef DEBUG_RIEMANN_SOLVER
564 std::cout <<
"phi_p_1: " << phi_p_1 << std::endl;
565 std::cout <<
"phi_p_2: " << phi_p_2 << std::endl;
566 std::cout <<
"dphi_p_1: " << dphi_p_1 << std::endl;
567 std::cout <<
"dphi_p_2: " << dphi_p_2 << std::endl;
568 std::cout <<
"p_1: ( " << i <<
" ) " << p_1 << std::endl;
569 std::cout <<
"p_2: ( " << i <<
" ) " << p_2 << std::endl;
570 std::cout <<
"gap: " << gap << std::endl;
571 std::cout <<
"l_m: " << lambda_max << std::endl;
575#ifdef DEBUG_RIEMANN_SOLVER
576 std::cout <<
"-> lambda_max = " << lambda_max << std::endl;
583 template <
int dim,
typename Number>
588 const unsigned int * ,
589 const dealii::Tensor<1, dim, Number> &n_ij)
const
591 const auto riemann_data_i = riemann_data_from_state(U_i, n_ij);
592 const auto riemann_data_j = riemann_data_from_state(U_j, n_ij);
594 return compute(riemann_data_i, riemann_data_j);
dealii::Tensor< 1, problem_dimension, Number > state_type
Number phi_of_p_max(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
typename View::ScalarNumber ScalarNumber
Number df(const primitive_type &riemann_data, const Number &p_star) const
Number lambda1_minus(const primitive_type &riemann_data, const Number p_star) const
Number phi(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number p_in) const
Number p_star_two_rarefaction(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
primitive_type riemann_data_from_state(const state_type &U, const dealii::Tensor< 1, dim, Number > &n_ij) const
std::array< Number, 2 > compute_gap(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number p_1, const Number p_2) const
typename View::state_type state_type
Number compute(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
std::array< Number, riemann_data_size > primitive_type
Number p_star_failsafe(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
Number dphi(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number &p) const
Number f(const primitive_type &riemann_data, const Number p_star) const
Number lambda3_plus(const primitive_type &primitive_state, const Number p_star) const
T pow(const T x, const T b)
DEAL_II_ALWAYS_INLINE Number negative_part(const Number number)
DEAL_II_ALWAYS_INLINE Number positive_part(const Number number)
DEAL_II_ALWAYS_INLINE void quadratic_newton_step(Number &p_1, Number &p_2, const Number phi_p_1, const Number phi_p_2, const Number dphi_p_1, const Number dphi_p_2, const Number sign=Number(1.0))