8#include <compile_time_options.h>
14#include <deal.II/base/parameter_acceptor.h>
57 template <
typename Number,
59 typename MemorySpace = dealii::MemorySpace::Host>
60 class NASGRiemannSolverView;
73 template <
typename ScalarNumber = double,
74 NASGRiemannSolverOptions options = NASGRiemannSolverOptions{}>
130 : ParameterAcceptor(subsection)
131 , parameters_(
"nasg_riemann_solver_parameters",
135 auto ¶meters = *parameters_.view();
137 if constexpr (std::is_same<ScalarNumber, double>::value)
138 parameters.newton_tolerance = 1.e-10;
140 parameters.newton_tolerance = 1.e-4;
141 add_parameter(
"newton tolerance",
142 parameters.newton_tolerance,
143 "Tolerance for the quadratic newton stopping criterion");
145 parameters.newton_max_iterations = 0;
146 add_parameter(
"newton max iterations",
147 parameters.newton_max_iterations,
148 "Maximal number of quadratic newton iterations performed "
151 parameters.covolume_b = ScalarNumber(0.);
152 parameters.pinf = ScalarNumber(0.);
153 parameters.compute_expensive_bounds =
false;
155 parameters.gamma = ScalarNumber(0.);
156 parameters.lambda_factor = ScalarNumber(0.);
157 parameters.rarefaction_exponent = ScalarNumber(0.);
158 parameters.rarefaction_exponent_inverse = ScalarNumber(0.);
159 parameters.half_gamma_minus_one = ScalarNumber(0.);
160 parameters.c_of_gamma = ScalarNumber(0.);
163 ParameterAcceptor::parse_parameters_call_back.connect(
164 [
this] { parameters_.view(); });
173 requires(!options.variable_gamma);
182 const bool compute_expensive_bounds);
191 template <
typename Number,
192 typename MemorySpace = dealii::MemorySpace::Host>
207 template <
typename, NASGRiemannSolverOptions,
typename>
225 template <
typename Number,
227 typename MemorySpace>
232 std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
233 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
234 "Unexpected memory space");
298 : parameters_(riemann_solver.parameters_.template view<MemorySpace>())
313 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int
316 return parameters_->newton_max_iterations;
324 return parameters_->covolume_b;
332 return parameters_->pinf;
340 return parameters_->compute_expensive_bounds;
354 DEAL_II_HOST_DEVICE Number
381 DEAL_II_HOST_DEVICE RiemannSolution
384 const Number p_star)
const;
392 DEAL_II_HOST_DEVICE RiemannSolution
395 const unsigned int max_iterations = 100)
const;
406 sample(
const RiemannSolution &solution,
408 const unsigned int max_iterations = 100)
const;
418 DEAL_II_HOST_DEVICE Number
422 const unsigned int max_iterations)
const;
433 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
436 if constexpr (options.covolume)
445 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
shift(
const Number &p)
const
447 if constexpr (options.pinf)
456 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
unshift(
const Number &p)
const
458 if constexpr (options.pinf)
468 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
471 if constexpr (options.safe_division)
474 return numerator / denominator;
487 const Number &gamma)
const;
498 const Number &p_star)
const;
513 template <
typename T>
514 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
static T
c(
const T &gamma_Z);
522 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
525 if constexpr (options.variable_gamma)
526 return riemann_data[3];
528 return parameters_->gamma;
534 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
537 if constexpr (options.variable_gamma) {
538 const auto &gamma = riemann_data[3];
541 return parameters_->lambda_factor;
547 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
550 if constexpr (options.variable_gamma) {
551 const auto &gamma = riemann_data[3];
552 return ScalarNumber(0.5) * (gamma - Number(1.)) / gamma;
554 return parameters_->rarefaction_exponent;
560 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
563 if constexpr (options.variable_gamma) {
564 const auto &gamma = riemann_data[3];
567 return parameters_->rarefaction_exponent_inverse;
573 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
576 if constexpr (options.variable_gamma) {
577 const auto &gamma = riemann_data[3];
580 return parameters_->half_gamma_minus_one;
586 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
589 if constexpr (options.variable_gamma)
590 return c(riemann_data[3]);
592 return parameters_->c_of_gamma;
602 DEAL_II_HOST_DEVICE Number
alpha(
const Number &rho,
604 const Number &a)
const;
620 const Number p_star)
const;
632 const Number &p_star)
const;
643 const Number p_in)
const;
656 const Number &p)
const;
664 DEAL_II_HOST_DEVICE Number
694 DEAL_II_HOST_DEVICE Number
697 const Number &phi_p_max)
const;
707 DEAL_II_HOST_DEVICE Number
710 const Number &phi_p_max)
const;
721 DEAL_II_HOST_DEVICE Number
732 DEAL_II_HOST_DEVICE Number
743 DEAL_II_HOST_DEVICE Number
753 DEAL_II_HOST_DEVICE Number
765 DEAL_II_HOST_DEVICE Number
797 DEAL_II_HOST_DEVICE std::array<Number, 2>
801 const Number p_2)
const;
812 DEAL_II_HOST_DEVICE Number
815 const Number p_star)
const;
829 template <
typename, NASGRiemannSolverOptions>
841 template <
typename ScalarNumber, NASGRiemannSolverOptions options>
844 requires(!options.variable_gamma)
846 auto ¶meters = *parameters_.
view();
848 parameters.gamma = ScalarNumber(gamma);
849 parameters.lambda_factor = ScalarNumber(0.5 * (gamma + 1.) / gamma);
850 parameters.rarefaction_exponent =
851 ScalarNumber(0.5 * (gamma - 1.) / gamma);
852 parameters.rarefaction_exponent_inverse =
853 ScalarNumber(2. * gamma / (gamma - 1.));
854 parameters.half_gamma_minus_one = ScalarNumber(0.5 * (gamma - 1.));
855 parameters.c_of_gamma = ScalarNumber(
860 template <
typename ScalarNumber, NASGRiemannSolverOptions options>
862 const double covolume_b,
864 const bool compute_expensive_bounds)
866 auto ¶meters = *parameters_.view();
868 parameters.covolume_b = ScalarNumber(covolume_b);
869 parameters.pinf = ScalarNumber(pinf);
870 parameters.compute_expensive_bounds = compute_expensive_bounds;
874 template <
typename Number,
876 typename MemorySpace>
877 DEAL_II_HOST_DEVICE Number
917 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
918 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
920#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
921 std::cout <<
"rho_left: " << rho_i << std::endl;
922 std::cout <<
"u_left: " << u_i << std::endl;
923 std::cout <<
"p_left: " << p_i << std::endl;
924 std::cout <<
"gamma_left: " << gamma_i << std::endl;
925 std::cout <<
"a_left: " << a_i << std::endl;
926 std::cout <<
"rho_right: " << rho_j << std::endl;
927 std::cout <<
"u_right: " << u_j << std::endl;
928 std::cout <<
"p_right: " << p_j << std::endl;
929 std::cout <<
"gamma_right: " << gamma_j << std::endl;
930 std::cout <<
"a_right: " << a_j << std::endl;
933 const Number phi_p_max = phi_of_p_max(riemann_data_i, riemann_data_j);
935 p_star_upper_bound(riemann_data_i, riemann_data_j, phi_p_max);
937#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
938 std::cout <<
" p^*_tilde = " << p_2 <<
"\n";
939 std::cout <<
" phi(p_*_t) = "
940 << phi(riemann_data_i, riemann_data_j, p_2) << std::endl;
947 if (newton_max_iterations() == 0) {
948 const auto lambda_max =
949 compute_lambda_max(riemann_data_i, riemann_data_j, p_2);
951#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
952 std::cout <<
"-> lambda_max = " << lambda_max << std::endl;
963 const Number p_min = std::min(p_i, p_j);
964 const Number p_max = std::max(p_i, p_j);
967 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
968 phi_p_max, Number(0.), p_max, p_min);
971 dealii::SIMDComparison::less_than_or_equal>(p_1, p_2, p_1, p_2);
979 auto [gap, lambda_max] =
980 compute_gap(riemann_data_i, riemann_data_j, p_1, p_2);
982#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
983 std::cout << std::fixed << std::setprecision(16);
984 std::cout <<
"p_1: (start) " << p_1 << std::endl;
985 std::cout <<
"p_2: (start) " << p_2 << std::endl;
986 std::cout <<
"gap: (start) " << gap << std::endl;
987 std::cout <<
"l_m: (start) " << lambda_max << std::endl;
990 for (
unsigned int i = 0; i < newton_max_iterations(); ++i) {
993 const Number tolerance(newton_tolerance());
994 if (std::max(Number(0.), gap - tolerance) == Number(0.)) {
995#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
996 std::cout <<
"converged after " << i <<
" iterations." << std::endl;
1001 newton_step(riemann_data_i, riemann_data_j, p_1, p_2);
1004 auto [gap_new, lambda_max_new] =
1005 compute_gap(riemann_data_i, riemann_data_j, p_1, p_2);
1007 lambda_max = lambda_max_new;
1009#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
1010 std::cout <<
"p_1: ( " << i <<
" ) " << p_1 << std::endl;
1011 std::cout <<
"p_2: ( " << i <<
" ) " << p_2 << std::endl;
1012 std::cout <<
"gap: " << gap << std::endl;
1013 std::cout <<
"l_m: " << lambda_max << std::endl;
1017#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
1018 std::cout <<
"-> lambda_max = " << lambda_max << std::endl;
1025 template <
typename Number,
1027 typename MemorySpace>
1028 DEAL_II_HOST_DEVICE
auto
1034 const auto &[rho_i, u_i, p_i, gamma_Z_i, a_i] = riemann_data_i;
1035 const auto &[rho_j, u_j, p_j, gamma_Z_j, a_j] = riemann_data_j;
1036 const auto gamm_i = gamma_of(riemann_data_i);
1037 const auto gamm_j = gamma_of(riemann_data_j);
1047 const Number u_star_left = u_i - f(riemann_data_i, p_star);
1048 const Number u_star_right = u_j + f(riemann_data_j, p_star);
1049 const Number u_star =
ScalarNumber(0.5) * (u_star_left + u_star_right);
1051 const Number rho_star_left = rho_star(riemann_data_i, p_star);
1052 const Number rho_star_right = rho_star(riemann_data_j, p_star);
1054 const Number lambda1_minus = this->lambda1_minus(riemann_data_i, p_star);
1055 const Number lambda3_plus = this->lambda3_plus(riemann_data_j, p_star);
1062 constexpr auto GTE = dealii::SIMDComparison::greater_than_or_equal;
1063 Number lambda1_plus =
1064 u_star_left - speed_of_sound(rho_star_left, p_star, Number(gamm_i));
1065 lambda1_plus = ryujin::compare_and_apply_mask<GTE>(
1066 p_star, p_i, lambda1_minus, lambda1_plus);
1068 Number lambda3_minus =
1069 u_star_right + speed_of_sound(rho_star_right, p_star, Number(gamm_j));
1070 lambda3_minus = ryujin::compare_and_apply_mask<GTE>(
1071 p_star, p_j, lambda3_plus, lambda3_minus);
1075 .riemann_data_right = riemann_data_j,
1078 .rho_star_left = rho_star_left,
1079 .rho_star_right = rho_star_right,
1080 .lambda1_minus = lambda1_minus,
1081 .lambda1_plus = lambda1_plus,
1082 .lambda3_minus = lambda3_minus,
1083 .lambda3_plus = lambda3_plus,
1088 template <
typename Number,
1090 typename MemorySpace>
1091 DEAL_II_HOST_DEVICE
auto
1102 const Number &p_i = riemann_data_i[2];
1103 const Number &p_j = riemann_data_j[2];
1105 const Number p_min = std::min(p_i, p_j);
1106 const Number p_max = std::max(p_i, p_j);
1107 const Number p_vacuum = unshift(Number(0.));
1109 const Number phi_p_max = phi_of_p_max(riemann_data_i, riemann_data_j);
1110 const Number phi_p_min = phi(riemann_data_i, riemann_data_j, p_min);
1111 const Number phi_p_vacuum = phi(riemann_data_i, riemann_data_j, p_vacuum);
1123 const Number p_lower = std::max(
1124 p_vacuum, p_star_two_rarefaction(riemann_data_i, riemann_data_j));
1127 dealii::SIMDComparison::less_than_or_equal>(
1128 phi_p_min, Number(0.), p_min, p_lower);
1130 dealii::SIMDComparison::less_than_or_equal>(
1131 phi_p_min, Number(0.), p_max, p_min);
1138 const Number p_upper = std::max(
1139 p_max, p_star_upper_bound(riemann_data_i, riemann_data_j, phi_p_max));
1141 p_1 = ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1142 phi_p_max, Number(0.), p_max, p_1);
1143 p_2 = ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1144 phi_p_max, Number(0.), p_upper, p_2);
1151 dealii::SIMDComparison::greater_than_or_equal>(
1152 phi_p_vacuum, Number(0.), p_vacuum, p_1);
1154 dealii::SIMDComparison::greater_than_or_equal>(
1155 phi_p_vacuum, Number(0.), p_vacuum, p_2);
1162 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
1164 for (
unsigned int i = 0; i < max_iterations; ++i) {
1165 const Number tolerance =
ScalarNumber(16. * eps) * shift(p_2);
1166 if (std::max(Number(0.), p_2 - p_1 - tolerance) == Number(0.))
1169 newton_step(riemann_data_i, riemann_data_j, p_1, p_2);
1172 return riemann_solution(riemann_data_i, riemann_data_j, p_2);
1176 template <
typename Number,
1178 typename MemorySpace>
1179 DEAL_II_HOST_DEVICE
auto
1185 const auto &riemann_data_left = solution.riemann_data_left;
1186 const auto &riemann_data_right = solution.riemann_data_right;
1194 const Number xi_left =
1195 std::max(solution.lambda1_minus, std::min(xi, solution.lambda1_plus));
1196 const Number p_fan_left = rarefaction_fan_pressure(
1197 riemann_data_left, xi_left,
ScalarNumber(-1.), max_iterations);
1198 const Number rho_fan_left = rho_star(riemann_data_left, p_fan_left);
1199 const Number u_fan_left =
1200 riemann_data_left[1] - f(riemann_data_left, p_fan_left);
1202 const Number xi_right =
1203 std::max(solution.lambda3_minus, std::min(xi, solution.lambda3_plus));
1204 const Number p_fan_right = rarefaction_fan_pressure(
1205 riemann_data_right, xi_right,
ScalarNumber(1.), max_iterations);
1206 const Number rho_fan_right = rho_star(riemann_data_right, p_fan_right);
1207 const Number u_fan_right =
1208 riemann_data_right[1] + f(riemann_data_right, p_fan_right);
1218 const auto select = [&](
const Number &threshold,
1222 const Number &gamma) {
1223 constexpr auto LT = dealii::SIMDComparison::less_than;
1225 ryujin::compare_and_apply_mask<LT>(xi, threshold, rho, result[0]);
1227 ryujin::compare_and_apply_mask<LT>(xi, threshold, u, result[1]);
1229 ryujin::compare_and_apply_mask<LT>(xi, threshold, p, result[2]);
1231 ryujin::compare_and_apply_mask<LT>(xi, threshold, gamma, result[3]);
1234 select(solution.lambda3_plus,
1238 riemann_data_right[3]);
1239 select(solution.lambda3_minus,
1240 solution.rho_star_right,
1243 riemann_data_right[3]);
1244 select(solution.u_star,
1245 solution.rho_star_left,
1248 riemann_data_left[3]);
1249 select(solution.lambda1_plus,
1253 riemann_data_left[3]);
1254 select(solution.lambda1_minus,
1255 riemann_data_left[0],
1256 riemann_data_left[1],
1257 riemann_data_left[2],
1258 riemann_data_left[3]);
1261 if constexpr (options.variable_gamma)
1264 gamma = Number(gamma_of(riemann_data_left));
1266 result[4] = speed_of_sound(result[0], result[2], gamma);
1272 template <
typename Number,
1274 typename MemorySpace>
1275 DEAL_II_HOST_DEVICE Number
1280 const unsigned int max_iterations)
const
1303 const auto &[rho_Z, u_Z, p_Z, gamma_Z, a_Z] = riemann_data;
1304 const Number gamma = gamma_of(riemann_data);
1306 const Number alpha_Z = alpha(rho_Z, gamma, a_Z);
1307 const Number a_tilde_Z = a_Z * one_minus_b_rho(rho_Z);
1309 const Number constant = alpha_Z + sign * (xi - u_Z);
1310 const Number linear = a_tilde_Z + alpha_Z;
1312 Number r = std::max(Number(0.),
safe_division(constant, linear));
1314 if constexpr (options.covolume) {
1315 const Number nonlinear = a_Z - a_tilde_Z;
1316 const Number k_minus_one =
1318 const Number k = k_minus_one + Number(1.);
1321 std::numeric_limits<ScalarNumber>::epsilon();
1324 for (
unsigned int i = 0; i < max_iterations; ++i) {
1325 const Number r_power =
ryujin::pow(r, k_minus_one);
1328 const Number minus_g =
1329 linear * r + nonlinear * r * r_power - constant;
1330 const Number minus_dg = linear + k * nonlinear * r_power;
1333 r = std::max(Number(0.), r - delta);
1334 if (std::max(Number(0.), delta - tolerance) == Number(0.))
1339 const Number P_Z = shift(p_Z);
1342 ryujin::pow(r, Number(rarefaction_exponent_inverse(riemann_data))));
1346 template <
typename Number,
1348 typename MemorySpace>
1349 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1351 const Number &rho,
const Number &p,
const Number &gamma)
const
1354 safe_division(gamma * shift(p), rho * one_minus_b_rho(rho)));
1358 template <
typename Number,
1360 typename MemorySpace>
1361 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1376 const auto &[rho, u, p, gamma_Z, a] = riemann_data;
1377 const auto gamma = gamma_of(riemann_data);
1379 const Number one_minus_b_rho = this->one_minus_b_rho(rho);
1380 const Number b_rho = Number(1.) - one_minus_b_rho;
1382 const Number P = shift(p);
1383 const Number P_star = shift(p_star);
1390 const Number gamma_minus_one_P_star = (gamma - Number(1.)) * P_star;
1391 const Number gamma_minus_one_P = (gamma - Number(1.)) * P;
1392 const Number gamma_plus_one_P_star = (gamma + Number(1.)) * P_star;
1393 const Number gamma_plus_one_P = (gamma + Number(1.)) * P;
1395 const Number shock_numerator = gamma_plus_one_P_star + gamma_minus_one_P;
1396 const Number shock_denominator =
1397 one_minus_b_rho * (gamma_minus_one_P_star + gamma_plus_one_P) +
1398 b_rho * shock_numerator;
1400 const Number true_value =
1412 const Number false_value =
1416 dealii::SIMDComparison::greater_than_or_equal>(
1417 p_star, p, true_value, false_value);
1421 template <
typename Number,
1423 typename MemorySpace>
1424 template <
typename T>
1425 DEAL_II_HOST_DEVICE_ALWAYS_INLINE T
1444 const T first_radicand = (
ScalarNumber(3.) * gamma + T(11.)) /
1447 const T second_radicand = T(5. / 6.) + slope * (gamma - T(3.));
1449 T radicand = std::min(first_radicand, second_radicand);
1450 radicand = std::min(T(1.), radicand);
1451 radicand = std::max(T(1. / 2.), radicand);
1453 return std::sqrt(radicand);
1457 template <
typename Number,
1459 typename MemorySpace>
1460 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1462 const Number &rho,
const Number &gamma,
const Number &a)
const
1464 const Number numerator =
ScalarNumber(2.) * a * one_minus_b_rho(rho);
1466 const Number denominator = gamma - Number(1.);
1472 template <
typename Number,
1474 typename MemorySpace>
1475 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1479 constexpr ScalarNumber min = std::numeric_limits<ScalarNumber>::min();
1481 const auto &[rho, u, p, gamma_Z, a] = riemann_data;
1482 const auto gamma = gamma_of(riemann_data);
1484 const Number one_minus_b_rho = this->one_minus_b_rho(rho);
1485 const Number gamma_minus_one = gamma - Number(1.);
1488 ScalarNumber(2.) * one_minus_b_rho / (rho * (gamma + Number(1.)));
1490 const Number Bz = gamma_minus_one / (gamma + Number(1.)) * shift(p);
1492 const Number radicand =
safe_division(Az, shift(p_star) + Bz);
1495 const Number true_value = (p_star - p) * std::sqrt(radicand);
1497 const auto exponent = rarefaction_exponent(riemann_data);
1499 const Number ratio =
safe_division(shift(p_star), shift(p));
1500 const Number factor =
ryujin::pow(ratio, exponent) - Number(1.);
1503 const auto false_value =
ScalarNumber(2.) * a * one_minus_b_rho * factor /
1504 std::max(gamma_minus_one, Number(
min));
1507 dealii::SIMDComparison::greater_than_or_equal>(
1508 p_star, p, true_value, false_value);
1512 template <
typename Number,
1514 typename MemorySpace>
1515 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1519 const auto &[rho, u, p, gamma_Z, a] = riemann_data;
1520 const auto gamma = gamma_of(riemann_data);
1522 const Number one_minus_b_rho = this->one_minus_b_rho(rho);
1524 const Number radicand_inverse =
1526 ((gamma + Number(1.)) * shift(p_star) +
1527 (gamma - Number(1.)) * shift(p));
1528 const Number denominator =
1530 ((gamma - Number(1.)) / (gamma + Number(1.)) * shift(p));
1533 const Number true_value =
1535 (denominator * std::sqrt(radicand_inverse));
1537 const auto exponent = -lambda_factor(riemann_data);
1539 const Number ratio =
safe_division(shift(p_star), shift(p));
1546 const auto false_value =
1548 Number(gamma * shift(p)));
1551 dealii::SIMDComparison::greater_than_or_equal>(
1552 p_star, p, true_value, false_value);
1556 template <
typename Number,
1558 typename MemorySpace>
1559 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1563 const Number p_in)
const
1565 const Number &u_i = riemann_data_i[1];
1566 const Number &u_j = riemann_data_j[1];
1568 return f(riemann_data_i, p_in) + f(riemann_data_j, p_in) + u_j - u_i;
1572 template <
typename Number,
1574 typename MemorySpace>
1575 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1579 const Number &p)
const
1581 return df(riemann_data_i, p) + df(riemann_data_j, p);
1585 template <
typename Number,
1587 typename MemorySpace>
1588 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1603 const auto &[rho_i, u_i, p_i, gamma_Z_i, a_i] = riemann_data_i;
1604 const auto &[rho_j, u_j, p_j, gamma_Z_j, a_j] = riemann_data_j;
1605 const auto gamma_i = gamma_of(riemann_data_i);
1606 const auto gamma_j = gamma_of(riemann_data_j);
1608 const Number p_max = std::max(p_i, p_j);
1610 const Number radicand_inverse_i =
1612 ((gamma_i + Number(1.)) * shift(p_max) +
1613 (gamma_i - Number(1.)) * shift(p_i));
1615 const Number value_i =
1618 const Number radicand_inverse_j =
1620 ((gamma_j + Number(1.)) * shift(p_max) +
1621 (gamma_j - Number(1.)) * shift(p_j));
1623 const Number value_j =
1626 return value_i + value_j + u_j - u_i;
1630 template <
typename Number,
1632 typename MemorySpace>
1633 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1637 const auto &[rho, u, p, gamma, a] = riemann_data;
1639 const auto factor = lambda_factor(riemann_data);
1641 const Number p_inverse =
safe_division(Number(1.), shift(p));
1644 return u - a * std::sqrt(Number(1.) + factor * tmp);
1648 template <
typename Number,
1650 typename MemorySpace>
1651 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1655 const auto &[rho, u, p, gamma, a] = riemann_data;
1657 const auto factor = lambda_factor(riemann_data);
1659 const Number p_inverse =
safe_division(Number(1.), shift(p));
1662 return u + a * std::sqrt(Number(1.) + factor * tmp);
1666 template <
typename Number,
1668 typename MemorySpace>
1669 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1673 const Number &phi_p_max)
const
1682 const Number &p_i = riemann_data_i[2];
1683 const Number &p_j = riemann_data_j[2];
1685 const Number p_max = std::max(p_i, p_j);
1687 if constexpr (!options.variable_gamma) {
1693 const Number p_star_tilde =
1694 p_star_single_gamma(riemann_data_i, riemann_data_j, phi_p_max);
1695 const Number p_star_backup =
1696 p_star_failsafe(riemann_data_i, riemann_data_j);
1699 dealii::SIMDComparison::less_than>(
1702 std::min(p_star_tilde, p_star_backup),
1703 std::min(p_max, p_star_tilde));
1705 }
else if (!compute_expensive_bounds()) {
1706#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
1707 const Number p_star_RS = p_star_RS_full(riemann_data_i, riemann_data_j);
1708 const Number p_star_SS = p_star_SS_full(riemann_data_i, riemann_data_j);
1709 const Number p_strict =
1710 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1711 phi_p_max, Number(0.), p_star_SS, std::min(p_max, p_star_RS));
1712 std::cout <<
" p^*_strict = " << p_strict <<
"\n";
1713 std::cout <<
" phi(p_*_s) = "
1714 << phi(riemann_data_i, riemann_data_j, p_strict) <<
"\n";
1715 std::cout <<
"-> lambda_str = "
1716 << compute_lambda_max(
1717 riemann_data_i, riemann_data_j, p_strict)
1721 const Number p_star_tilde =
1722 p_star_interpolated(riemann_data_i, riemann_data_j);
1723 const Number p_star_backup =
1724 p_star_failsafe(riemann_data_i, riemann_data_j);
1727 dealii::SIMDComparison::less_than>(
1730 std::min(p_star_tilde, p_star_backup),
1731 std::min(p_max, p_star_tilde));
1735 const Number p_star_RS = p_star_RS_full(riemann_data_i, riemann_data_j);
1736 const Number p_star_SS = p_star_SS_full(riemann_data_i, riemann_data_j);
1739 dealii::SIMDComparison::less_than>(
1740 phi_p_max, Number(0.), p_star_SS, std::min(p_max, p_star_RS));
1745 template <
typename Number,
1747 typename MemorySpace>
1748 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1752 const Number &phi_p_max)
const
1767 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
1768 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
1771 const auto c_gamma = c_of_gamma(riemann_data_i);
1777 const Number alpha_i = a_i * one_minus_b_rho(rho_i);
1778 const Number alpha_j = a_j * one_minus_b_rho(rho_j);
1780 const Number p_min = shift(std::min(p_i, p_j));
1781 const Number p_max = shift(std::max(p_i, p_j));
1783 const Number alpha_min =
1784 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1785 p_i, p_j, alpha_i, alpha_j);
1788 dealii::SIMDComparison::greater_than_or_equal>(
1789 p_i, p_j, alpha_i, alpha_j);
1791 const Number alpha_hat_min = c_gamma * alpha_min;
1797 const Number alpha_select =
1798 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1799 phi_p_max, Number(0.), c_gamma * alpha_max, alpha_max);
1801 const auto exponent = rarefaction_exponent(riemann_data_i);
1802 const auto exponent_inverse =
1803 rarefaction_exponent_inverse(riemann_data_i);
1805 const Number numerator =
1807 half_gamma_minus_one(riemann_data_i) * (u_j - u_i));
1809 const Number denominator =
1813 const Number p_tilde =
1817#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
1818 std::cout <<
"p_star_single_gamma = " << p_tilde << std::endl;
1824 template <
typename Number,
1826 typename MemorySpace>
1827 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1832 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
1833 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
1834 const auto alpha_i = alpha(rho_i, gamma_i, a_i);
1835 const auto alpha_j = alpha(rho_j, gamma_j, a_j);
1845 const Number p_min = shift(std::min(p_i, p_j));
1846 const Number p_max = shift(std::max(p_i, p_j));
1848 const Number gamma_min =
1849 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1850 p_i, p_j, gamma_i, gamma_j);
1852 const Number alpha_min =
1853 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1854 p_i, p_j, alpha_i, alpha_j);
1856 const Number alpha_hat_min = c(gamma_min) * alpha_min;
1859 dealii::SIMDComparison::greater_than_or_equal>(
1860 p_i, p_j, gamma_i, gamma_j);
1863 dealii::SIMDComparison::greater_than_or_equal>(
1864 p_i, p_j, alpha_i, alpha_j);
1866 const Number alpha_hat_max = c(gamma_max) * alpha_max;
1868 const Number gamma_m = std::min(gamma_i, gamma_j);
1869 const Number gamma_M = std::max(gamma_i, gamma_j);
1879 const Number r_exponent =
1880 (gamma_M - gamma_min) / (
ScalarNumber(2.) * gamma_min * gamma_M);
1889 const Number exponent =
1891 const Number exponent_inverse = Number(1.) / exponent;
1893 const Number numerator =
1896 Number denominator = alpha_hat_min *
ryujin::pow(p_ratio, -exponent) +
1901 const Number p_tilde =
1902 unshift(p_max *
ryujin::pow(temp, exponent_inverse));
1904#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
1905 std::cout <<
"p_star_interpolated = " << p_tilde << std::endl;
1911 template <
typename Number,
1913 typename MemorySpace>
1914 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
1919 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
1920 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
1921 const auto alpha_i = alpha(rho_i, gamma_i, a_i);
1922 const auto alpha_j = alpha(rho_j, gamma_j, a_j);
1932 const Number p_min = std::min(p_i, p_j);
1933 const Number p_max = std::max(p_i, p_j);
1935 const Number gamma_min =
1936 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1937 p_i, p_j, gamma_i, gamma_j);
1939 const Number alpha_min =
1940 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1941 p_i, p_j, alpha_i, alpha_j);
1943 const Number alpha_hat_min = c(gamma_min) * alpha_min;
1946 dealii::SIMDComparison::greater_than_or_equal>(
1947 p_i, p_j, alpha_i, alpha_j);
1949 const Number gamma_m = std::min(gamma_i, gamma_j);
1950 const Number gamma_M = std::max(gamma_i, gamma_j);
1952 const Number numerator =
1953 ryujin::compare_and_apply_mask<dealii::SIMDComparison::equal>(
1963 const Number p_ratio =
safe_division(shift(p_min), shift(p_max));
1971 const Number r_exponent =
1972 (gamma_M - gamma_min) / (
ScalarNumber(2.) * gamma_min * gamma_M);
1979 const Number first_exponent =
1982 const Number first_exponent_inverse =
1985 const Number first_denom =
1986 alpha_hat_min *
ryujin::pow(p_ratio, r_exponent - first_exponent) +
1989 const Number p_1_tilde = unshift(
1991 first_exponent_inverse));
1998 const Number second_exponent =
2001 const Number second_exponent_inverse =
2004 Number second_denom =
2005 alpha_hat_min *
ryujin::pow(p_ratio, -second_exponent) +
2008 const Number p_2_tilde = unshift(
2010 second_exponent_inverse));
2012 const Number p_star = std::min(p_1_tilde, p_2_tilde);
2014#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
2015 std::cout <<
"p_star_RS_full = " << p_star << std::endl;
2021 template <
typename Number,
2023 typename MemorySpace>
2024 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
2029 const auto &[rho_i, u_i, p_i, gamma_i, a_i] = riemann_data_i;
2030 const auto &[rho_j, u_j, p_j, gamma_j, a_j] = riemann_data_j;
2032 const Number gamma_m = std::min(gamma_i, gamma_j);
2034 const Number alpha_hat_i = c(gamma_i) * alpha(rho_i, gamma_i, a_i);
2035 const Number alpha_hat_j = c(gamma_j) * alpha(rho_j, gamma_j, a_j);
2043 const Number exponent =
2045 const Number exponent_inverse = Number(1.) / exponent;
2047 const Number numerator =
2048 ryujin::compare_and_apply_mask<dealii::SIMDComparison::equal>(
2054 const Number denominator =
2059 const Number p_1_tilde = unshift(
2063 const auto p_2_tilde = p_star_failsafe(riemann_data_i, riemann_data_j);
2065 const Number p_star = std::min(p_1_tilde, p_2_tilde);
2067#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
2068 std::cout <<
"p_star_SS_full = " << p_star << std::endl;
2074 template <
typename Number,
2076 typename MemorySpace>
2077 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
2082 const auto &[rho_i, u_i, p_i, gamma_Z_i, a_i] = riemann_data_i;
2083 const auto &[rho_j, u_j, p_j, gamma_Z_j, a_j] = riemann_data_j;
2084 const auto gamma_i = gamma_of(riemann_data_i);
2085 const auto gamma_j = gamma_of(riemann_data_j);
2093 const Number p_max = shift(std::max(p_i, p_j));
2095 const Number radicand_i =
2097 rho_i * ((gamma_i + Number(1.)) * p_max +
2098 (gamma_i - Number(1.)) * shift(p_i)));
2100 const Number x_i = std::sqrt(radicand_i);
2102 const Number radicand_j =
2104 rho_j * ((gamma_j + Number(1.)) * p_max +
2105 (gamma_j - Number(1.)) * shift(p_j)));
2107 const Number x_j = std::sqrt(radicand_j);
2109 const Number a = x_i + x_j;
2111 ryujin::compare_and_apply_mask<dealii::SIMDComparison::equal>(
2112 a, Number(0.), Number(0.), u_j - u_i);
2114 const Number c = -shift(p_i) * x_i - shift(p_j) * x_j;
2121 const Number p_2_tilde = unshift(base * base);
2123#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
2124 std::cout <<
"p_star_failsafe = " << p_2_tilde << std::endl;
2130 template <
typename Number,
2132 typename MemorySpace>
2133 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
2149 const auto &[rho_i, u_i, p_i, gamma_Z_i, a_i] = riemann_data_i;
2150 const auto &[rho_j, u_j, p_j, gamma_Z_j, a_j] = riemann_data_j;
2151 const auto gamma_i = gamma_of(riemann_data_i);
2152 const auto gamma_j = gamma_of(riemann_data_j);
2154 const Number alpha_i = alpha(rho_i, Number(gamma_i), a_i);
2155 const Number alpha_j = alpha(rho_j, Number(gamma_j), a_j);
2157 const Number p_min = shift(std::min(p_i, p_j));
2158 const Number p_max = shift(std::max(p_i, p_j));
2160 const Number alpha_min =
2161 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
2162 p_i, p_j, alpha_i, alpha_j);
2165 dealii::SIMDComparison::greater_than_or_equal>(
2166 p_i, p_j, alpha_i, alpha_j);
2169 Number exponent_inverse;
2170 if constexpr (options.variable_gamma) {
2171 const Number gamma_m = std::min(gamma_i, gamma_j);
2172 exponent = (gamma_m - Number(1.)) / (
ScalarNumber(2.) * gamma_m);
2173 exponent_inverse = Number(1.) / exponent;
2175 exponent = rarefaction_exponent(riemann_data_i);
2176 exponent_inverse = rarefaction_exponent_inverse(riemann_data_i);
2179 const Number numerator =
2182 const Number denominator =
2186 const Number p_tilde =
2190#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
2191 std::cout <<
"p_star_two_rarefaction = " << p_tilde << std::endl;
2197 template <
typename Number,
2199 typename MemorySpace>
2200 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
void
2208 const Number phi_p_1 = phi(riemann_data_i, riemann_data_j, p_1);
2209 const Number phi_p_2 = phi(riemann_data_i, riemann_data_j, p_2);
2210 const Number dphi_p_1 = dphi(riemann_data_i, riemann_data_j, p_1);
2211 const Number dphi_p_2 = dphi(riemann_data_i, riemann_data_j, p_2);
2213#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
2214 std::cout <<
"phi_p_1: " << phi_p_1 << std::endl;
2215 std::cout <<
"phi_p_2: " << phi_p_2 << std::endl;
2216 std::cout <<
"dphi_p_1: " << dphi_p_1 << std::endl;
2217 std::cout <<
"dphi_p_2: " << dphi_p_2 << std::endl;
2221 p_1, p_2, phi_p_1, phi_p_2, dphi_p_1, dphi_p_2);
2225 template <
typename Number,
2227 typename MemorySpace>
2228 DEAL_II_HOST_DEVICE_ALWAYS_INLINE std::array<Number, 2>
2233 const Number p_2)
const
2235 const Number nu_11 = lambda1_minus(riemann_data_i, p_2 );
2236 const Number nu_12 = lambda1_minus(riemann_data_i, p_1 );
2238 const Number nu_31 = lambda3_plus(riemann_data_j, p_1);
2239 const Number nu_32 = lambda3_plus(riemann_data_j, p_2);
2241 const Number lambda_max =
2245 std::max(std::abs(nu_32 - nu_31), std::abs(nu_12 - nu_11));
2247 return {{gap, lambda_max}};
2251 template <
typename Number,
2253 typename MemorySpace>
2254 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
2258 const Number p_star)
const
2260 const Number nu_11 = lambda1_minus(riemann_data_i, p_star);
2261 const Number nu_32 = lambda3_plus(riemann_data_j, p_star);
DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto half_gamma_minus_one(const primitive_type &riemann_data) const
DEAL_II_HOST_DEVICE primitive_type sample(const RiemannSolution &solution, const Number &xi, const unsigned int max_iterations=100) const
static DEAL_II_HOST_DEVICE_ALWAYS_INLINE T c(const T &gamma_Z)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int newton_max_iterations() const
DEAL_II_HOST_DEVICE Number p_star_single_gamma(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number &phi_p_max) const
static constexpr unsigned int riemann_data_size
DEAL_II_HOST_DEVICE RiemannSolution solve(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const unsigned int max_iterations=100) const
DEAL_II_HOST_DEVICE Number dphi(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number &p) const
DEAL_II_HOST_DEVICE Number f(const primitive_type &riemann_data, const Number p_star) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto rarefaction_exponent(const primitive_type &riemann_data) const
DEAL_II_HOST_DEVICE RiemannSolution riemann_solution(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number p_star) const
DEAL_II_HOST_DEVICE Number p_star_upper_bound(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number &phi_p_max) const
DEAL_II_HOST_DEVICE Number p_star_interpolated(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
DEAL_II_HOST_DEVICE Number compute_lambda_max(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number p_star) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE bool compute_expensive_bounds() const
DEAL_II_HOST_DEVICE Number df(const primitive_type &riemann_data, const Number &p_star) const
DEAL_II_HOST_DEVICE void newton_step(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, Number &p_1, Number &p_2) const
DEAL_II_HOST_DEVICE Number lambda3_plus(const primitive_type &riemann_data, const Number p_star) const
NASGRiemannSolverView(const NASGRiemannSolver< ScalarNumber, options > &riemann_solver)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number shift(const Number &p) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number unshift(const Number &p) const
DEAL_II_HOST_DEVICE Number p_star_two_rarefaction(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number one_minus_b_rho(const Number &rho) const
DEAL_II_HOST_DEVICE Number p_star_SS_full(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
std::array< Number, riemann_data_size > primitive_type
DEAL_II_HOST_DEVICE Number rarefaction_fan_pressure(const primitive_type &riemann_data, const Number &xi, const ScalarNumber sign, const unsigned int max_iterations) const
typename NASGRiemannSolver< ScalarNumber, options >::Parameters Parameters
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber newton_tolerance() const
DEAL_II_HOST_DEVICE Number compute(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
DEAL_II_HOST_DEVICE Number phi(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number p_in) const
DEAL_II_HOST_DEVICE Number p_star_failsafe(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
DEAL_II_HOST_DEVICE 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
DEAL_II_HOST_DEVICE Number phi_of_p_max(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
DEAL_II_HOST_DEVICE Number lambda1_minus(const primitive_type &riemann_data, const Number p_star) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber pinf() const
typename get_value_type< Number >::type ScalarNumber
DEAL_II_HOST_DEVICE Number alpha(const Number &rho, const Number &gamma, const Number &a) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber covolume_b() const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto c_of_gamma(const primitive_type &riemann_data) const
DEAL_II_HOST_DEVICE Number rho_star(const primitive_type &riemann_data, const Number &p_star) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto gamma_of(const primitive_type &riemann_data) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number safe_division(const Number &numerator, const Number &denominator) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto lambda_factor(const primitive_type &riemann_data) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto rarefaction_exponent_inverse(const primitive_type &riemann_data) const
DEAL_II_HOST_DEVICE Number p_star_RS_full(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
DEAL_II_HOST_DEVICE Number speed_of_sound(const Number &rho, const Number &p, const Number &gamma) const
void set_equation_of_state(const double covolume_b, const double pinf, const bool compute_expensive_bounds)
NASGRiemannSolver(const std::string &subsection)
void set_gamma(const double gamma)
@ implicit_transfers_host_resident
DEAL_II_HOST_DEVICE_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))
DEAL_II_HOST_DEVICE T pow(const T x, const T b)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number positive_part(const Number number)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number negative_part(const Number number)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number compare_and_apply_mask(const Number &left, const Number &right, const Number &true_value, const Number &false_value)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number safe_division(const Number &numerator, const Number &denominator)
primitive_type riemann_data_right
primitive_type riemann_data_left
bool compute_expensive_bounds
ScalarNumber half_gamma_minus_one
ScalarNumber rarefaction_exponent_inverse
ScalarNumber lambda_factor
unsigned int newton_max_iterations
ScalarNumber rarefaction_exponent