501 const unsigned int *js,
504 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
511 Assert(std::max(affine_shift.norm(), Number(0.)) == Number(0.),
512 dealii::ExcNotImplemented());
515 auto &[rho_min, rho_max, s_min] = bounds_;
517 const auto rho_i = view_.density(U_i_);
518 const auto m_i = view_.momentum(U_i_);
519 const auto rho_j = view_.density(U_j);
520 const auto m_j = view_.momentum(U_j);
521 const auto rho_affine_shift = view_.density(affine_shift);
524 const auto rho_ij_bar =
525 ScalarNumber(0.5) * (rho_i + rho_j + (m_i - m_j) * scaled_c_ij) +
528 rho_min = std::min(rho_min, rho_ij_bar);
529 rho_max = std::max(rho_max, rho_ij_bar);
531 const auto &[s_j, eta_j] =
532 pv.template read_tensor<Number, precomputed_type>(js);
533 s_min = std::min(s_min, s_j);
538 const auto beta_ij = Number(1.);
539 rho_relaxation_numerator_ += beta_ij * (rho_i + rho_j);
540 rho_relaxation_denominator_ += std::abs(beta_ij);
542 const Number s_interp =
543 view_.specific_entropy((U_i_ + U_j) *
ScalarNumber(.5));
544 s_interp_max_ = std::max(s_interp_max_, s_interp);
553 const auto &[rho_min, rho_max, s_min] = bounds_;
555 auto relaxed_bounds = fully_relax_bounds(bounds_, hd_i);
556 auto &[rho_min_relaxed, rho_max_relaxed, s_min_relaxed] = relaxed_bounds;
560 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
562 const auto rho_relaxation =
564 std::abs(rho_relaxation_numerator_) /
565 (std::abs(rho_relaxation_denominator_) + Number(eps));
567 const auto entropy_relaxation =
568 relaxation_factor() * (s_interp_max_ - s_min);
570 rho_min_relaxed = std::max(rho_min_relaxed, rho_min - rho_relaxation);
571 rho_max_relaxed = std::min(rho_max_relaxed, rho_max + rho_relaxation);
572 s_min_relaxed = std::max(s_min_relaxed, s_min - entropy_relaxation);
574 return relaxed_bounds;
585 const Number t_max )
const
590 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
591 const auto small = view_.vacuum_state_relaxation_small();
592 const auto large = view_.vacuum_state_relaxation_large();
603 const auto &rho_U = view_.density(U);
604 const auto &rho_P = view_.density(P);
606 const auto &rho_min = std::get<0>(bounds);
607 const auto &rho_max = std::get<1>(bounds);
613 const auto test_min = view_.filter_vacuum_density(
614 std::max(Number(0.), rho_U - relax * rho_max));
615 const auto test_max = view_.filter_vacuum_density(
616 std::max(Number(0.), rho_min - relax * rho_U));
617 if (!(test_min == Number(0.) && test_max == Number(0.))) {
619 std::cout << std::fixed << std::setprecision(16);
620 std::cout <<
"Bounds violation: low-order density (critical)!"
621 <<
"\n\t\trho min: " << rho_min
622 <<
"\n\t\trho min (delta): "
624 <<
"\n\t\trho: " << rho_U
625 <<
"\n\t\trho max (delta): "
627 <<
"\n\t\trho max: " << rho_max <<
"\n"
633 const Number denominator =
636 constexpr auto lt = dealii::SIMDComparison::less_than;
638 t_r = ryujin::compare_and_apply_mask<lt>(
647 (rho_max - rho_U) * denominator,
650 t_r = ryujin::compare_and_apply_mask<lt>(
659 (rho_U - rho_min) * denominator,
669 t_r = std::min(t_r, t_max);
670 t_r = std::max(t_r, t_min);
672#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
676 const auto rho_new = view_.density(U + t_r * P);
677 const auto test_new_min = view_.filter_vacuum_density(
678 std::max(Number(0.), rho_new - relax * rho_max));
679 const auto test_new_max = view_.filter_vacuum_density(
680 std::max(Number(0.), rho_min - relax * rho_new));
681 if (!(test_new_min == Number(0.) && test_new_max == Number(0.))) {
683 std::cout << std::fixed << std::setprecision(16);
684 std::cout <<
"Bounds violation: high-order density!"
685 <<
"\n\t\trho min: " << rho_min
686 <<
"\n\t\trho min (delta): "
688 <<
"\n\t\trho: " << rho_new
689 <<
"\n\t\trho max (delta): "
691 <<
"\n\t\trho max: " << rho_max <<
"\n"
726 const auto &s_min = std::get<2>(bounds);
728#ifdef DEBUG_OUTPUT_LIMITER
729 std::cout << std::endl;
730 std::cout << std::fixed << std::setprecision(16);
731 std::cout <<
"t_l: (start) " << t_l << std::endl;
732 std::cout <<
"t_r: (start) " << t_r << std::endl;
735 for (
unsigned int n = 0; n < newton_max_iterations(); ++n) {
737 const auto U_r = U + t_r * P;
738 const auto rho_r = view_.density(U_r);
739 const auto rho_r_gamma =
ryujin::pow(rho_r, gamma);
740 const auto rho_e_r = view_.internal_energy(U_r);
743 relax_small * rho_r * rho_e_r - s_min * rho_r * rho_r_gamma;
745#ifndef DEBUG_EXPENSIVE_BOUNDS_CHECK
751 dealii::SIMDComparison::greater_than>(
752 psi_r, Number(0.), t_r, t_l);
770#ifdef DEBUG_OUTPUT_LIMITER
771 std::cout <<
"shortcut: t_l == t_r" << std::endl;
772 std::cout <<
"psi_l: " << psi_l << std::endl;
773 std::cout <<
"psi_r: " << psi_r << std::endl;
774 std::cout <<
"t_l: ( " << n <<
" ) " << t_l << std::endl;
775 std::cout <<
"t_r: ( " << n <<
" ) " << t_r << std::endl;
781 const auto U_l = U + t_l * P;
782 const auto rho_l = view_.density(U_l);
783 const auto rho_l_gamma =
ryujin::pow(rho_l, gamma);
784 const auto rho_e_l = view_.internal_energy(U_l);
787 relax_small * rho_l * rho_e_l - s_min * rho_l * rho_l_gamma;
793 const auto lower_bound =
794 (
ScalarNumber(1.) - relax) * s_min * rho_l * rho_l_gamma;
796 !(std::min(Number(0.), psi_l - lower_bound) == Number(0.))) {
798 std::cout << std::fixed << std::setprecision(16);
800 <<
"Bounds violation: low-order specific entropy (critical)!\n";
801 std::cout <<
"\t\tPsi left: 0 <= " << psi_l <<
"\n" << std::endl;
806#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
812 dealii::SIMDComparison::greater_than>(
813 psi_r, Number(0.), t_r, t_l);
820 const Number tolerance(newton_tolerance());
821 if (std::max(Number(0.), t_r - t_l - tolerance) == Number(0.)) {
822#ifdef DEBUG_OUTPUT_LIMITER
823 std::cout <<
"break: t_l and t_r within tolerance" << std::endl;
824 std::cout <<
"psi_l: " << psi_l << std::endl;
825 std::cout <<
"psi_r: " << psi_r << std::endl;
826 std::cout <<
"t_l: ( " << n <<
" ) " << t_l << std::endl;
827 std::cout <<
"t_r: ( " << n <<
" ) " << t_r << std::endl;
834 const auto drho = view_.density(P);
835 const auto drho_e_l = view_.internal_energy_derivative(U_l) * P;
836 const auto drho_e_r = view_.internal_energy_derivative(U_r) * P;
838 rho_l * drho_e_l + (rho_e_l - gp1 * s_min * rho_l_gamma) * drho;
840 rho_r * drho_e_r + (rho_e_r - gp1 * s_min * rho_r_gamma) * drho;
843 t_l, t_r, psi_l, psi_r, dpsi_l, dpsi_r, Number(-1.));
845#ifdef DEBUG_OUTPUT_LIMITER
846 std::cout <<
"psi_l: " << psi_l << std::endl;
847 std::cout <<
"psi_r: " << psi_r << std::endl;
848 std::cout <<
"dpsi_l: " << dpsi_l << std::endl;
849 std::cout <<
"dpsi_r: " << dpsi_r << std::endl;
850 std::cout <<
"t_l: ( " << n <<
" ) " << t_l << std::endl;
851 std::cout <<
"t_r: ( " << n <<
" ) " << t_r << std::endl;
855#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
860 const auto U_new = U + t_l * P;
861 const auto rho_new = view_.density(U_new);
862 const auto rho_new_gamma =
ryujin::pow(rho_new, gamma);
863 const auto rho_e_new = view_.internal_energy(U_new);
865 auto psi_new = relax_small * rho_new * rho_e_new -
866 s_min * rho_new * rho_new_gamma;
868 const auto lower_bound =
869 (
ScalarNumber(1.) - relax) * s_min * rho_new * rho_new_gamma;
871 const bool e_valid = std::min(Number(0.), rho_e_new) == Number(0.);
872 const bool psi_valid =
873 std::min(Number(0.), psi_new - lower_bound) == Number(0.);
875 if (!e_valid || !psi_valid) {
877 std::cout << std::fixed << std::setprecision(16);
878 std::cout <<
"Bounds violation: high-order specific entropy!\n";
879 std::cout <<
"\t\trho e: 0 <= " << rho_e_new <<
"\n";
880 std::cout <<
"\t\tPsi: 0 <= " << psi_new <<
"\n" << std::endl;
888 return {t_l, success};