ryujin 2.5.0 revision 3a6c8d57210175dea14d8116e1fe878f349f8c1c
Loading...
Searching...
No Matches
limiter.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
8#include <ryujin/base/compile_time_options.h>
9#include <ryujin/base/gpu.h>
10#include <ryujin/base/newton.h>
12#include <ryujin/base/simd.h>
15
16#include <deal.II/base/config.h>
17
18// #define DEBUG_OUTPUT_LIMITER
19
20namespace ryujin
21{
22 namespace Euler
23 {
24 template <int dim,
25 typename Number = double,
26 typename MemorySpace = dealii::MemorySpace::Host>
27 class LimiterView;
28
59 template <typename ScalarNumber = double>
60 class Limiter : public dealii::ParameterAcceptor
61 {
62 public:
67
71 struct Parameters {
72 unsigned int iterations;
76 };
77
79
83
87 Limiter(const HyperbolicSystem &hyperbolic_system,
88 const std::string &subsection = "/Limiter")
89 : ParameterAcceptor(subsection)
90 , parameters_("euler_limiter_parameters",
92 , hyperbolic_system_(&hyperbolic_system)
93 {
94 /* reference remains valid due to implicit_transfers_host_resident */
95 auto &parameters = *parameters_.view();
96
97 parameters.iterations = 2;
98 add_parameter("iterations",
99 parameters.iterations,
100 "Number of limiter iterations");
101
102 if constexpr (std::is_same<ScalarNumber, double>::value)
103 parameters.newton_tolerance = 1.e-10;
104 else
105 parameters.newton_tolerance = 1.e-4;
106 add_parameter("newton tolerance",
107 parameters.newton_tolerance,
108 "Tolerance for the quadratic newton stopping criterion");
109
110 parameters.newton_max_iterations = 2;
111 add_parameter("newton max iterations",
112 parameters.newton_max_iterations,
113 "Maximal number of quadratic newton iterations performed "
114 "during limiting");
115
116 parameters.relaxation_factor = 1.;
117 add_parameter("relaxation factor",
118 parameters.relaxation_factor,
119 "Factor for scaling the relaxation window with r_i = "
120 "factor * (m_i/|Omega|)^(1.5/d).");
121
122 /* invalidates view on default memory space */
123 ParameterAcceptor::parse_parameters_call_back.connect(
124 [this] { parameters_.view(); });
125 }
126
134 template <int dim,
135 typename Number,
136 typename MemorySpace = dealii::MemorySpace::Host>
137 auto view() const
138 {
140 hyperbolic_system_->template view<dim, Number, MemorySpace>(),
141 *this};
142 }
143
144 private:
146
150
151 Mirrored<Parameters> parameters_;
152
154
158
159 dealii::ObserverPointer<const HyperbolicSystem> hyperbolic_system_;
160
161 template <int, typename, typename>
162 friend class LimiterView;
163
165 };
166
167
176 template <int dim, typename Number, typename MemorySpace>
178 {
179 public:
180 static_assert(
181 std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
182 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
183 "Unexpected memory space");
184
189
191
193
194 using state_type = typename View::state_type;
195
197
199
201
203
210 static constexpr unsigned int n_bounds = 3;
211
215 using Bounds = std::array<Number, n_bounds>;
216
221 LimiterView(const View &view, const Limiter<ScalarNumber> &limiter)
222 : view_(view)
223 , parameters_(limiter.parameters_.template view<MemorySpace>())
224 {
225 }
226
230 DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int iterations() const
231 {
232 return parameters_->iterations;
233 }
234
238 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber newton_tolerance() const
239 {
240 return ScalarNumber(parameters_->newton_tolerance);
241 }
242
246 DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int
248 {
249 return parameters_->newton_max_iterations;
250 }
251
255 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber relaxation_factor() const
256 {
257 return ScalarNumber(parameters_->relaxation_factor);
258 }
259
264 DEAL_II_HOST_DEVICE Bounds
266 const unsigned int i,
267 const state_type &U_i) const;
268
274 DEAL_II_HOST_DEVICE Bounds combine_bounds(
275 const Bounds &bounds_left, const Bounds &bounds_right) const;
276
285 DEAL_II_HOST_DEVICE Bounds fully_relax_bounds(const Bounds &bounds,
286 const Number &hd) const;
287
289
308
312 DEAL_II_HOST_DEVICE void reset(const PrecomputedVectorView &pv,
313 const unsigned int i,
314 const state_type &U_i,
315 const flux_contribution_type &flux_i);
316
321 DEAL_II_HOST_DEVICE void
323 const unsigned int *js,
324 const state_type &U_j,
325 const flux_contribution_type &flux_j,
326 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
327 const state_type &affine_shift);
328
332 DEAL_II_HOST_DEVICE Bounds bounds(const Number hd_i) const;
333
335
339
355 DEAL_II_HOST_DEVICE std::tuple<Number, bool>
356 limit(const Bounds &bounds,
357 const state_type &U,
358 const state_type &P,
359 const Number t_min = Number(0.),
360 const Number t_max = Number(1.)) const;
361
362 private:
364
368
369 const View view_;
370 const Limiter<ScalarNumber>::Parameters *const parameters_;
371
372 state_type U_i_;
373
374 Bounds bounds_;
375
376 Number rho_relaxation_numerator_;
377 Number rho_relaxation_denominator_;
378 Number s_interp_max_;
379
381 };
382
383
384 /*
385 * -------------------------------------------------------------------------
386 * Inline definitions
387 * -------------------------------------------------------------------------
388 */
389
390
391 template <int dim, typename Number, typename MemorySpace>
392 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
394 const PrecomputedVectorView &pv,
395 const unsigned int i,
396 const state_type &U_i) const -> Bounds
397 {
398 const auto rho_i = view_.density(U_i);
399 const auto &[s_i, eta_i] =
400 pv.template read_tensor<Number, precomputed_type>(i);
401
402 return {/*rho_min*/ rho_i, /*rho_max*/ rho_i, /*s_min*/ s_i};
403 }
404
405
406 template <int dim, typename Number, typename MemorySpace>
407 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
409 const Bounds &bounds_left, const Bounds &bounds_right) const -> Bounds
410 {
411 const auto &[rho_min_l, rho_max_l, s_min_l] = bounds_left;
412 const auto &[rho_min_r, rho_max_r, s_min_r] = bounds_right;
413
414 return {std::min(rho_min_l, rho_min_r),
415 std::max(rho_max_l, rho_max_r),
416 std::min(s_min_l, s_min_r)};
417 }
418
419
420 template <int dim, typename Number, typename MemorySpace>
421 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
423 const Bounds &bounds, const Number &hd) const -> Bounds
424 {
425 auto relaxed_bounds = bounds;
426 auto &[rho_min, rho_max, s_min] = relaxed_bounds;
427
428 /* Use r = factor * (m_i / |Omega|) ^ (1.5 / d): */
429
430 Number r = std::sqrt(hd); // in 3D: ^ 3/6
431 if constexpr (dim == 2) //
432 r = ryujin::fixed_power<3>(std::sqrt(r)); // in 2D: ^ 3/4
433 else if constexpr (dim == 1) //
434 r = ryujin::fixed_power<3>(r); // in 1D: ^ 3/2
435 r *= relaxation_factor();
436
437 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
438 rho_min *= std::max(Number(1.) - r, Number(eps));
439 rho_max *= (Number(1.) + r);
440 s_min *= std::max(Number(1.) - r, Number(eps));
441
442 return relaxed_bounds;
443 }
444
445
446 template <int dim, typename Number, typename MemorySpace>
447 DEAL_II_HOST_DEVICE_ALWAYS_INLINE void
449 const PrecomputedVectorView & /*pv*/,
450 const unsigned int /*i*/,
451 const state_type &U_i,
452 const flux_contribution_type & /*flux_i*/)
453 {
454 U_i_ = U_i;
455
456 /* Bounds: */
457
458 auto &[rho_min, rho_max, s_min] = bounds_;
459
460 rho_min = Number(std::numeric_limits<ScalarNumber>::max());
461 rho_max = Number(0.);
462 s_min = Number(std::numeric_limits<ScalarNumber>::max());
463
464 /* Relaxation: */
465
466 rho_relaxation_numerator_ = Number(0.);
467 rho_relaxation_denominator_ = Number(0.);
468 s_interp_max_ = Number(0.);
469 }
470
471
472 template <int dim, typename Number, typename MemorySpace>
473 DEAL_II_HOST_DEVICE_ALWAYS_INLINE void
475 const PrecomputedVectorView &pv,
476 const unsigned int *js,
477 const state_type &U_j,
478 const flux_contribution_type & /*flux_j*/,
479 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
480 const state_type &affine_shift)
481 {
482 // TODO: Currently we only apply the affine_shift to U_ij_bar (which
483 // then enters all bounds), but we do not modify s_interp and
484 // rho_relaxation. When actually adding a source term to the Euler
485 // equations verify that this does the right thing.
486 Assert(std::max(affine_shift.norm(), Number(0.)) == Number(0.),
487 dealii::ExcNotImplemented());
488
489 /* Bounds: */
490 auto &[rho_min, rho_max, s_min] = bounds_;
491
492 const auto rho_i = view_.density(U_i_);
493 const auto m_i = view_.momentum(U_i_);
494 const auto rho_j = view_.density(U_j);
495 const auto m_j = view_.momentum(U_j);
496 const auto rho_affine_shift = view_.density(affine_shift);
497
498 /* bar state shifted by an affine shift: */
499 const auto rho_ij_bar =
500 ScalarNumber(0.5) * (rho_i + rho_j + (m_i - m_j) * scaled_c_ij) +
501 rho_affine_shift;
502
503 rho_min = std::min(rho_min, rho_ij_bar);
504 rho_max = std::max(rho_max, rho_ij_bar);
505
506 const auto &[s_j, eta_j] =
507 pv.template read_tensor<Number, precomputed_type>(js);
508 s_min = std::min(s_min, s_j);
509
510 /* Relaxation: */
511
512 /* Use a uniform weight. */
513 const auto beta_ij = Number(1.);
514 rho_relaxation_numerator_ += beta_ij * (rho_i + rho_j);
515 rho_relaxation_denominator_ += std::abs(beta_ij);
516
517 const Number s_interp =
518 view_.specific_entropy((U_i_ + U_j) * ScalarNumber(.5));
519 s_interp_max_ = std::max(s_interp_max_, s_interp);
520 }
521
522
523 template <int dim, typename Number, typename MemorySpace>
524 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
526 -> Bounds
527 {
528 const auto &[rho_min, rho_max, s_min] = bounds_;
529
530 auto relaxed_bounds = fully_relax_bounds(bounds_, hd_i);
531 auto &[rho_min_relaxed, rho_max_relaxed, s_min_relaxed] = relaxed_bounds;
532
533 /* Apply a stricter window: */
534
535 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
536
537 const auto rho_relaxation =
538 ScalarNumber(2. * relaxation_factor()) *
539 std::abs(rho_relaxation_numerator_) /
540 (std::abs(rho_relaxation_denominator_) + Number(eps));
541
542 const auto entropy_relaxation =
543 relaxation_factor() * (s_interp_max_ - s_min);
544
545 rho_min_relaxed = std::max(rho_min_relaxed, rho_min - rho_relaxation);
546 rho_max_relaxed = std::min(rho_max_relaxed, rho_max + rho_relaxation);
547 s_min_relaxed = std::max(s_min_relaxed, s_min - entropy_relaxation);
548
549 return relaxed_bounds;
550 }
551
552
553 template <int dim, typename Number, typename MemorySpace>
554 DEAL_II_HOST_DEVICE std::tuple<Number, bool>
556 const Bounds &bounds,
557 const state_type &U,
558 const state_type &P,
559 const Number t_min /* = Number(0.) */,
560 const Number t_max /* = Number(1.) */) const
561 {
562 bool success = true;
563 Number t_r = t_max;
564
565 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
566 const auto small = view_.vacuum_state_relaxation_small();
567 const auto large = view_.vacuum_state_relaxation_large();
568 const ScalarNumber relax_small = ScalarNumber(1. + small * eps);
569 const ScalarNumber relax = ScalarNumber(1. + large * eps);
570
571 /*
572 * First limit the density rho.
573 *
574 * See [Guermond, Nazarov, Popov, Thomas] (4.8):
575 */
576
577 {
578 const auto &rho_U = view_.density(U);
579 const auto &rho_P = view_.density(P);
580
581 const auto &rho_min = std::get<0>(bounds);
582 const auto &rho_max = std::get<1>(bounds);
583
584 /*
585 * Verify that rho_U is within bounds. This property might be
586 * violated for relative CFL numbers larger than 1.
587 */
588 const auto test_min = view_.filter_vacuum_density(
589 std::max(Number(0.), rho_U - relax * rho_max));
590 const auto test_max = view_.filter_vacuum_density(
591 std::max(Number(0.), rho_min - relax * rho_U));
592 if (!(test_min == Number(0.) && test_max == Number(0.))) {
593#ifdef DEBUG_OUTPUT
594 std::cout << std::fixed << std::setprecision(16);
595 std::cout << "Bounds violation: low-order density (critical)!"
596 << "\n\t\trho min: " << rho_min
597 << "\n\t\trho min (delta): "
598 << negative_part(rho_U - rho_min)
599 << "\n\t\trho: " << rho_U
600 << "\n\t\trho max (delta): "
601 << positive_part(rho_U - rho_max)
602 << "\n\t\trho max: " << rho_max << "\n"
603 << std::endl;
604#endif
605 success = false;
606 }
607
608 const Number denominator =
609 ScalarNumber(1.) / (std::abs(rho_P) + eps * rho_max);
610
611 constexpr auto lt = dealii::SIMDComparison::less_than;
612
613 t_r = ryujin::compare_and_apply_mask<lt>( //
614 rho_max,
615 rho_U + t_r * rho_P,
616 /*
617 * rho_P is positive.
618 *
619 * Note: Do not take an absolute value here. If we are out of
620 * bounds we have to ensure that t_r is set to t_min.
621 */
622 (rho_max - rho_U) * denominator,
623 t_r);
624
625 t_r = ryujin::compare_and_apply_mask<lt>( //
626 rho_U + t_r * rho_P,
627 rho_min,
628 /*
629 * rho_P is negative.
630 *
631 * Note: Do not take an absolute value here. If we are out of
632 * bounds we have to ensure that t_r is set to t_min.
633 */
634 (rho_U - rho_min) * denominator,
635 t_r);
636
637 /*
638 * Ensure that t_min <= t <= t_max. This might not be the case if
639 * rho_U is outside the interval [rho_min, rho_max]. Furthermore,
640 * the quotient we take above is prone to numerical cancellation in
641 * particular in the second pass of the limiter when rho_P might be
642 * small.
643 */
644 t_r = std::min(t_r, t_max);
645 t_r = std::max(t_r, t_min);
646
647#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
648 /*
649 * Verify that the new state is within bounds:
650 */
651 const auto rho_new = view_.density(U + t_r * P);
652 const auto test_new_min = view_.filter_vacuum_density(
653 std::max(Number(0.), rho_new - relax * rho_max));
654 const auto test_new_max = view_.filter_vacuum_density(
655 std::max(Number(0.), rho_min - relax * rho_new));
656 if (!(test_new_min == Number(0.) && test_new_max == Number(0.))) {
657#ifdef DEBUG_OUTPUT
658 std::cout << std::fixed << std::setprecision(16);
659 std::cout << "Bounds violation: high-order density!"
660 << "\n\t\trho min: " << rho_min
661 << "\n\t\trho min (delta): "
662 << negative_part(rho_new - rho_min)
663 << "\n\t\trho: " << rho_new
664 << "\n\t\trho max (delta): "
665 << positive_part(rho_new - rho_max)
666 << "\n\t\trho max: " << rho_max << "\n"
667 << std::endl;
668#endif
669 success = false;
670 }
671#endif
672 }
673
674 /*
675 * Then limit the specific entropy:
676 *
677 * See [Guermond, Nazarov, Popov, Thomas], Section 4.6 + Section 5.1:
678 */
679
680 Number t_l = t_min; // good state
681
682 const ScalarNumber gamma = view_.gamma();
683 const ScalarNumber gp1 = gamma + ScalarNumber(1.);
684
685 {
686 /*
687 * Prepare a quadratic Newton method:
688 *
689 * Given initial limiter values t_l and t_r with psi(t_l) > 0 and
690 * psi(t_r) < 0 we try to find t^\ast with psi(t^\ast) \approx 0.
691 *
692 * Here, psi is a 3-convex function obtained by scaling the specific
693 * entropy s:
694 *
695 * psi = \rho ^ {\gamma + 1} s
696 *
697 * (s in turn was defined as s =\varepsilon \rho ^{-\gamma}, where
698 * \varepsilon = (\rho e) is the internal energy.)
699 */
700
701 const auto &s_min = std::get<2>(bounds);
702
703#ifdef DEBUG_OUTPUT_LIMITER
704 std::cout << std::endl;
705 std::cout << std::fixed << std::setprecision(16);
706 std::cout << "t_l: (start) " << t_l << std::endl;
707 std::cout << "t_r: (start) " << t_r << std::endl;
708#endif
709
710 for (unsigned int n = 0; n < newton_max_iterations(); ++n) {
711
712 const auto U_r = U + t_r * P;
713 const auto rho_r = view_.density(U_r);
714 const auto rho_r_gamma = ryujin::pow(rho_r, gamma);
715 const auto rho_e_r = view_.internal_energy(U_r);
716
717 auto psi_r =
718 relax_small * rho_r * rho_e_r - s_min * rho_r * rho_r_gamma;
719
720#ifndef DEBUG_EXPENSIVE_BOUNDS_CHECK
721 /*
722 * If psi_r > 0 the right state is fine, force returning t_r by
723 * setting t_l = t_r:
724 */
726 dealii::SIMDComparison::greater_than>(
727 psi_r, Number(0.), t_r, t_l);
728
729 /*
730 * If we have set t_l = t_r everywhere then all states state U_r
731 * with t_r obey the specific entropy inequality and we can
732 * break.
733 *
734 * This is a very important optimization: Only for 1 in (25 to
735 * 50) cases do we actually need to limit on the specific entropy
736 * because one of the right states failed. So we can skip
737 * constructing the left state U_l, which is expensive.
738 *
739 * This implies unfortunately that we might not accurately report
740 * whether the low_order update U itself obeyed bounds because
741 * U_r = U + t_r * P pushed us back into bounds. We thus skip
742 * this shortcut if `DEBUG_EXPENSIVE_BOUNDS_CHECK` is set.
743 */
744 if (t_l == t_r) {
745#ifdef DEBUG_OUTPUT_LIMITER
746 std::cout << "shortcut: t_l == t_r" << std::endl;
747 std::cout << "psi_l: " << psi_l << std::endl;
748 std::cout << "psi_r: " << psi_r << std::endl;
749 std::cout << "t_l: ( " << n << " ) " << t_l << std::endl;
750 std::cout << "t_r: ( " << n << " ) " << t_r << std::endl;
751#endif
752 break;
753 }
754#endif
755
756 const auto U_l = U + t_l * P;
757 const auto rho_l = view_.density(U_l);
758 const auto rho_l_gamma = ryujin::pow(rho_l, gamma);
759 const auto rho_e_l = view_.internal_energy(U_l);
760
761 auto psi_l =
762 relax_small * rho_l * rho_e_l - s_min * rho_l * rho_l_gamma;
763
764 /*
765 * Verify that the left state is within bounds. This property might
766 * be violated for relative CFL numbers larger than 1.
767 */
768 const auto lower_bound =
769 (ScalarNumber(1.) - relax) * s_min * rho_l * rho_l_gamma;
770 if (n == 0 &&
771 !(std::min(Number(0.), psi_l - lower_bound) == Number(0.))) {
772#ifdef DEBUG_OUTPUT
773 std::cout << std::fixed << std::setprecision(16);
774 std::cout
775 << "Bounds violation: low-order specific entropy (critical)!\n";
776 std::cout << "\t\tPsi left: 0 <= " << psi_l << "\n" << std::endl;
777#endif
778 success = false;
779 }
780
781#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
782 /*
783 * If psi_r > 0 the right state is fine, force returning t_r by
784 * setting t_l = t_r:
785 */
787 dealii::SIMDComparison::greater_than>(
788 psi_r, Number(0.), t_r, t_l);
789#endif
790
791 /*
792 * Break if the window between t_l and t_r is within the prescribed
793 * tolerance:
794 */
795 const Number tolerance(newton_tolerance());
796 if (std::max(Number(0.), t_r - t_l - tolerance) == Number(0.)) {
797#ifdef DEBUG_OUTPUT_LIMITER
798 std::cout << "break: t_l and t_r within tolerance" << std::endl;
799 std::cout << "psi_l: " << psi_l << std::endl;
800 std::cout << "psi_r: " << psi_r << std::endl;
801 std::cout << "t_l: ( " << n << " ) " << t_l << std::endl;
802 std::cout << "t_r: ( " << n << " ) " << t_r << std::endl;
803#endif
804 break;
805 }
806
807 /* We got unlucky and have to perform a Newton step: */
808
809 const auto drho = view_.density(P);
810 const auto drho_e_l = view_.internal_energy_derivative(U_l) * P;
811 const auto drho_e_r = view_.internal_energy_derivative(U_r) * P;
812 const auto dpsi_l =
813 rho_l * drho_e_l + (rho_e_l - gp1 * s_min * rho_l_gamma) * drho;
814 const auto dpsi_r =
815 rho_r * drho_e_r + (rho_e_r - gp1 * s_min * rho_r_gamma) * drho;
816
818 t_l, t_r, psi_l, psi_r, dpsi_l, dpsi_r, Number(-1.));
819
820#ifdef DEBUG_OUTPUT_LIMITER
821 std::cout << "psi_l: " << psi_l << std::endl;
822 std::cout << "psi_r: " << psi_r << std::endl;
823 std::cout << "dpsi_l: " << dpsi_l << std::endl;
824 std::cout << "dpsi_r: " << dpsi_r << std::endl;
825 std::cout << "t_l: ( " << n << " ) " << t_l << std::endl;
826 std::cout << "t_r: ( " << n << " ) " << t_r << std::endl;
827#endif
828 }
829
830#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
831 /*
832 * Verify that the new state is within bounds:
833 */
834 {
835 const auto U_new = U + t_l * P;
836 const auto rho_new = view_.density(U_new);
837 const auto rho_new_gamma = ryujin::pow(rho_new, gamma);
838 const auto rho_e_new = view_.internal_energy(U_new);
839
840 auto psi_new = relax_small * rho_new * rho_e_new -
841 s_min * rho_new * rho_new_gamma;
842
843 const auto lower_bound =
844 (ScalarNumber(1.) - relax) * s_min * rho_new * rho_new_gamma;
845
846 const bool e_valid = std::min(Number(0.), rho_e_new) == Number(0.);
847 const bool psi_valid =
848 std::min(Number(0.), psi_new - lower_bound) == Number(0.);
849
850 if (!e_valid || !psi_valid) {
851#ifdef DEBUG_OUTPUT
852 std::cout << std::fixed << std::setprecision(16);
853 std::cout << "Bounds violation: high-order specific entropy!\n";
854 std::cout << "\t\trho e: 0 <= " << rho_e_new << "\n";
855 std::cout << "\t\tPsi: 0 <= " << psi_new << "\n" << std::endl;
856#endif
857 success = false;
858 }
859 }
860#endif
861 }
862
863 return {t_l, success};
864 }
865 } // namespace Euler
866} // namespace ryujin
VectorView< n_precomputed_values > PrecomputedVectorView
dealii::Tensor< 1, problem_dimension, Number > state_type
std::array< Number, n_precomputed_values > precomputed_type
typename get_value_type< Number >::type ScalarNumber
DEAL_II_HOST_DEVICE void reset(const PrecomputedVectorView &pv, const unsigned int i, const state_type &U_i, const flux_contribution_type &flux_i)
Definition limiter.h:448
typename View::PrecomputedVectorView PrecomputedVectorView
Definition limiter.h:200
DEAL_II_HOST_DEVICE void accumulate(const PrecomputedVectorView &pv, const unsigned int *js, const state_type &U_j, const flux_contribution_type &flux_j, const dealii::Tensor< 1, dim, Number > &scaled_c_ij, const state_type &affine_shift)
Definition limiter.h:474
typename View::state_type state_type
Definition limiter.h:194
typename View::precomputed_type precomputed_type
Definition limiter.h:198
DEAL_II_HOST_DEVICE Bounds bounds(const Number hd_i) const
Definition limiter.h:525
DEAL_II_HOST_DEVICE Bounds combine_bounds(const Bounds &bounds_left, const Bounds &bounds_right) const
Definition limiter.h:408
LimiterView(const View &view, const Limiter< ScalarNumber > &limiter)
Definition limiter.h:221
HyperbolicSystemView< dim, Number, MemorySpace > View
Definition limiter.h:190
DEAL_II_HOST_DEVICE Bounds projection_bounds_from_state(const PrecomputedVectorView &pv, const unsigned int i, const state_type &U_i) const
Definition limiter.h:393
std::array< Number, n_bounds > Bounds
Definition limiter.h:215
typename View::flux_contribution_type flux_contribution_type
Definition limiter.h:196
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber relaxation_factor() const
Definition limiter.h:255
DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int newton_max_iterations() const
Definition limiter.h:247
DEAL_II_HOST_DEVICE std::tuple< Number, bool > limit(const Bounds &bounds, const state_type &U, const state_type &P, const Number t_min=Number(0.), const Number t_max=Number(1.)) const
Definition limiter.h:555
DEAL_II_HOST_DEVICE Bounds fully_relax_bounds(const Bounds &bounds, const Number &hd) const
Definition limiter.h:422
DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int iterations() const
Definition limiter.h:230
static constexpr unsigned int n_bounds
Definition limiter.h:210
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber newton_tolerance() const
Definition limiter.h:238
typename View::ScalarNumber ScalarNumber
Definition limiter.h:192
auto view() const
Definition limiter.h:137
Limiter(const HyperbolicSystem &hyperbolic_system, const std::string &subsection="/Limiter")
Definition limiter.h:87
TransferPolicy
Definition gpu.h:88
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:134
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number negative_part(const Number number)
Definition simd.h:146
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)
Definition simd.h:182
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))
Definition newton.h:38