438 const unsigned int * ,
441 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
444 const auto &[U_i, Z_i, V_i] = flux_i_;
445 const auto &[U_j, Z_j, V_j] = flux_j;
446 const auto &[U_star_ij, U_star_ji] =
447 view_.equilibrated_states(flux_i_, flux_j);
451 const auto p_star_ij = view_.pressure(U_star_ij);
452 const auto p_star_ji = view_.pressure(U_star_ji);
454 auto U_ij_bar = U_star_ij * (Number(1.) + V_i * scaled_c_ij) +
455 U_star_ji * (Number(1.) - V_j * scaled_c_ij);
456 for (
unsigned int d = 0; d < dim; ++d)
457 U_ij_bar[1 + d] += (p_star_ij - p_star_ji) * scaled_c_ij[d];
462 auto &[h_min, h_max, v2_max] = bounds_;
464 const auto h_bar_ij = view_.water_depth(U_ij_bar);
465 h_min = std::min(h_min, h_bar_ij);
466 h_max = std::max(h_max, h_bar_ij);
468 const auto v_bar_ij = view_.momentum(U_ij_bar) *
469 view_.inverse_water_depth_mollified(U_ij_bar);
470 const auto v2_bar_ij = v_bar_ij.norm_square();
471 v2_max = std::max(v2_max, v2_bar_ij);
476 const auto beta_ij = Number(1.);
478 relaxation_denominator_ += std::abs(beta_ij);
480 const auto h_i = view_.water_depth(U_i);
481 const auto h_j = view_.water_depth(U_j);
482 h_relaxation_numerator_ += beta_ij * (h_i + h_j);
484 v2_relaxation_numerator_ +=
485 beta_ij * (-V_i.norm_square() + V_j.norm_square());
494 const auto &[h_min, h_max, v2_max] = bounds_;
496 auto relaxed_bounds = fully_relax_bounds(bounds_, hd_i);
497 auto &[h_min_relaxed, h_max_relaxed, v2_max_relaxed] = relaxed_bounds;
501 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
503 const Number h_relaxed =
ScalarNumber(2. * relaxation_factor()) *
504 std::abs(h_relaxation_numerator_) /
505 (relaxation_denominator_ + Number(eps));
507 const Number v2_relaxed =
ScalarNumber(2. * relaxation_factor()) *
508 std::abs(v2_relaxation_numerator_) /
509 (relaxation_denominator_ + Number(eps));
511 h_min_relaxed = std::max(h_min_relaxed, h_min - h_relaxed);
512 h_max_relaxed = std::min(h_max_relaxed, h_max + h_relaxed);
513 v2_max_relaxed = std::min(v2_max_relaxed, v2_max + v2_relaxed);
515 return relaxed_bounds;
526 const Number t_max )
const
532 const auto &[h_min, h_max, v2_max] = bounds;
535 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
536 const auto small = view_.dry_state_relaxation_small();
537 const auto large = view_.dry_state_relaxation_large();
538 const auto relax_small =
ScalarNumber(1. + small * eps);
548 auto h_U = view_.water_depth(U);
549 const auto &h_P = view_.water_depth(P);
551 const auto test_min = view_.filter_dry_water_depth(
552 std::max(Number(0.), h_U - relax * h_max));
553 const auto test_max = view_.filter_dry_water_depth(
554 std::max(Number(0.), h_min - relax * h_U));
556 if (!(test_min == Number(0.) && test_max == Number(0.))) {
558 std::cout << std::fixed << std::setprecision(16);
559 std::cout <<
"Bounds violation: low-order water depth (critical)!\n"
560 <<
"\n\t\th min: " << h_min
562 <<
"\n\t\th: " << h_U
564 <<
"\n\t\th max: " << h_max <<
"\n"
570 const Number denominator =
573 constexpr auto lt = dealii::SIMDComparison::less_than;
575 t_r = ryujin::compare_and_apply_mask<lt>(
584 (h_max - h_U) * denominator,
587 t_r = ryujin::compare_and_apply_mask<lt>(
596 (h_U - h_min) * denominator,
606 t_r = std::min(t_r, t_max);
607 t_r = std::max(t_r, t_min);
610#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
614 const auto h_new = view_.water_depth(U + t_r * P);
615 const auto test_new_min = view_.filter_dry_water_depth(
616 std::max(Number(0.), h_new - relax * h_max));
617 const auto test_new_max = view_.filter_dry_water_depth(
618 std::max(Number(0.), h_min - relax * h_new));
620 if (!(test_new_min == Number(0.) && test_new_max == Number(0.))) {
622 std::cout << std::fixed << std::setprecision(30);
623 std::cout <<
"Bounds violation: high-order water depth!\n"
624 <<
"\n\t\th min: " << h_min
626 <<
"\n\t\th: " << h_new
628 <<
"\n\t\th max: " << h_max <<
"\n"
650 const auto U_r = U + t_r * P;
651 const auto h_r = view_.water_depth(U_r);
652 const auto q_r = view_.momentum(U_r);
654 const auto psi_r = relax_small * h_r * h_r * v2_max - q_r.norm_square();
661 dealii::SIMDComparison::greater_than>(psi_r, Number(0.), t_r, t_l);
665 return {t_l, success};
667#ifdef DEBUG_OUTPUT_LIMITER
669 std::cout << std::endl;
670 std::cout << std::fixed << std::setprecision(16);
671 std::cout <<
"t_l: (start) " << t_l << std::endl;
672 std::cout <<
"t_r: (start) " << t_r << std::endl;
676 const auto U_l = U + t_l * P;
677 const auto h_l = view_.water_depth(U_l);
678 const auto q_l = view_.momentum(U_l);
680 const auto psi_l = relax_small * h_l * h_l * v2_max - q_l.norm_square();
690 const auto filtered_h_l = view_.filter_dry_water_depth(h_l);
691 const auto lower_bound =
692 (
ScalarNumber(1.) - relax) * filtered_h_l * filtered_h_l * v2_max -
694 if (!(std::min(Number(0.), psi_l - lower_bound) == Number(0.))) {
696 std::cout << std::fixed << std::setprecision(16);
698 <<
"Bounds violation: low-order square velocity (critical)!\n";
699 std::cout <<
"\t\tPsi left: 0 <= " << psi_l <<
"\n" << std::endl;
708 const Number tolerance(newton_tolerance());
709 if (!(std::max(Number(0.), t_r - t_l - tolerance) == Number(0.))) {
729 const auto &h_U = view_.water_depth(U);
730 const auto &h_P = view_.water_depth(P);
731 const auto &q_U = view_.momentum(U);
732 const auto &q_P = view_.momentum(P);
735 (relax_small * (h_U + t_l * h_P) * h_P * v2_max -
736 ((q_U * q_P) + q_P * q_P * t_l));
738 (relax_small * (h_U + t_r * h_P) * h_P * v2_max -
739 ((q_U * q_P) + q_P * q_P * t_r));
742 t_l, t_r, psi_l, psi_r, dpsi_l, dpsi_r, Number(-1.));
744#ifdef DEBUG_OUTPUT_LIMITER
745 if (std::max(Number(0.), psi_r + Number(eps)) == Number(0.)) {
746 std::cout <<
"psi_l: " << psi_l << std::endl;
747 std::cout <<
"psi_r: " << psi_r << std::endl;
748 std::cout <<
"dpsi_l: " << dpsi_l << std::endl;
749 std::cout <<
"dpsi_r: " << dpsi_r << std::endl;
750 std::cout <<
"t_l: (end) " << t_l << std::endl;
751 std::cout <<
"t_r: (end) " << t_r << std::endl;
756#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
761 const auto U_new = U + t_l * P;
762 const auto h_new = view_.water_depth(U_new);
763 const auto q_new = view_.momentum(U_new);
766 relax_small * h_new * h_new * v2_max - q_new.norm_square();
768 const auto lower_bound =
772 const bool psi_valid =
773 std::min(Number(0.), psi_new - lower_bound) == Number(0.);
776 std::cout << std::fixed << std::setprecision(16);
777 std::cout <<
"Bounds violation: high-order square velocity!\n";
778 std::cout <<
"\t\tPsi: 0 <= " << psi_new <<
"\n" << std::endl;
786 return {t_l, success};