ryujin 2.5.0 revision c64172211cf21344cb9b9b0f3a1266aa6400d392
Loading...
Searching...
No Matches
limiter.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0
3// [LANL Copyright Statement]
4// Copyright (C) 2023 - 2026 by the ryujin authors
5// Copyright (C) 2023 - 2024 by Triad National Security, LLC
6//
7
8#pragma once
9
10#include <ryujin/base/compile_time_options.h>
11#include <ryujin/base/gpu.h>
12#include <ryujin/base/newton.h>
14#include <ryujin/base/simd.h>
17
18// #define DEBUG_OUTPUT_LIMITER
19
20namespace ryujin
21{
22 namespace ShallowWater
23 {
24 template <int dim,
25 typename Number = double,
26 typename MemorySpace = dealii::MemorySpace::Host>
27 class LimiterView;
28
34 template <typename ScalarNumber = double>
35 class Limiter : public dealii::ParameterAcceptor
36 {
37 public:
42
46 struct Parameters {
47 unsigned int iterations;
51 };
52
54
58
62 Limiter(const HyperbolicSystem &hyperbolic_system,
63 const std::string &subsection = "/Limiter")
64 : ParameterAcceptor(subsection)
65 , parameters_("shallow_water_limiter_parameters",
67 , hyperbolic_system_(&hyperbolic_system)
68 {
69 /* reference remains valid due to implicit_transfers_host_resident */
70 auto &parameters = *parameters_.view();
71
72 parameters.iterations = 2;
73 add_parameter("iterations",
74 parameters.iterations,
75 "Number of limiter iterations");
76
77 if constexpr (std::is_same_v<ScalarNumber, double>)
78 parameters.newton_tolerance = 1.e-10;
79 else
80 parameters.newton_tolerance = 1.e-4;
81 add_parameter("newton tolerance",
82 parameters.newton_tolerance,
83 "Tolerance for the quadratic newton stopping criterion");
84
85 parameters.newton_max_iterations = 2;
86 add_parameter("newton max iterations",
87 parameters.newton_max_iterations,
88 "Maximal number of quadratic newton iterations performed "
89 "during limiting");
90
91 parameters.relaxation_factor = 1.;
92 add_parameter("relaxation factor",
93 parameters.relaxation_factor,
94 "Factor for scaling the relaxation window with r_i = "
95 "factor * (m_i/|Omega|)^(1.5/d).");
96
97 /* invalidates view on default memory space */
98 ParameterAcceptor::parse_parameters_call_back.connect(
99 [this] { parameters_.view(); });
100 }
101
109 template <int dim,
110 typename Number,
111 typename MemorySpace = dealii::MemorySpace::Host>
112 auto view() const
113 {
115 hyperbolic_system_->template view<dim, Number, MemorySpace>(),
116 *this};
117 }
118
119 private:
121
125
126 Mirrored<Parameters> parameters_;
127
129
133
134 dealii::ObserverPointer<const HyperbolicSystem> hyperbolic_system_;
135
136 template <int, typename, typename>
137 friend class LimiterView;
138
140 };
141
142
151 template <int dim, typename Number, typename MemorySpace>
153 {
154 public:
155 static_assert(
156 std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
157 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
158 "Unexpected memory space");
159
164
166
168
169 using state_type = typename View::state_type;
170
172
174
176
183 static constexpr unsigned int n_bounds = 3;
184
188 using Bounds = std::array<Number, n_bounds>;
189
194 LimiterView(const View &view, const Limiter<ScalarNumber> &limiter)
195 : view_(view)
196 , parameters_(limiter.parameters_.template view<MemorySpace>())
197 {
198 }
199
203 DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int iterations() const
204 {
205 return parameters_->iterations;
206 }
207
211 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber newton_tolerance() const
212 {
213 return ScalarNumber(parameters_->newton_tolerance);
214 }
215
219 DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int
221 {
222 return parameters_->newton_max_iterations;
223 }
224
228 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber relaxation_factor() const
229 {
230 return ScalarNumber(parameters_->relaxation_factor);
231 }
232
237 DEAL_II_HOST_DEVICE Bounds
239 const unsigned int i,
240 const state_type &U_i) const;
241
247 DEAL_II_HOST_DEVICE Bounds combine_bounds(
248 const Bounds &bounds_left, const Bounds &bounds_right) const;
249
257 DEAL_II_HOST_DEVICE Bounds fully_relax_bounds(const Bounds &bounds,
258 const Number &hd) const;
259
261
280
284 DEAL_II_HOST_DEVICE void reset(const PrecomputedVectorView &pv,
285 const unsigned int i,
286 const state_type &U_i,
287 const flux_contribution_type &flux_i);
288
293 DEAL_II_HOST_DEVICE void
295 const unsigned int *js,
296 const state_type &U_j,
297 const flux_contribution_type &flux_j,
298 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
299 const state_type &affine_shift);
300
304 DEAL_II_HOST_DEVICE Bounds bounds(const Number hd_i) const;
305
307
311
318 DEAL_II_HOST_DEVICE std::tuple<Number, bool>
319 limit(const Bounds &bounds,
320 const state_type &U,
321 const state_type &P,
322 const Number t_min = Number(0.),
323 const Number t_max = Number(1.)) const;
324
325 private:
327
331
332 const View view_;
333 const Limiter<ScalarNumber>::Parameters *const parameters_;
334
336
337 Bounds bounds_;
338
339 /* for relaxation */
340
341 Number h_relaxation_numerator_;
342 Number v2_relaxation_numerator_;
343 Number relaxation_denominator_;
344
346 };
347
348
349 /*
350 * -------------------------------------------------------------------------
351 * Inline definitions
352 * -------------------------------------------------------------------------
353 */
354
355
356 template <int dim, typename Number, typename MemorySpace>
357 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
359 const PrecomputedVectorView & /*pv*/,
360 const unsigned int /*i*/,
361 const state_type &U_i) const -> Bounds
362 {
363 const auto h_i = view_.water_depth(U_i);
364 const auto v_i =
365 view_.momentum(U_i) * view_.inverse_water_depth_mollified(U_i);
366 const auto v2_i = v_i.norm_square();
367
368 return {/*h_min*/ h_i, /*h_max*/ h_i, /*v2_max*/ v2_i};
369 }
370
371
372 template <int dim, typename Number, typename MemorySpace>
373 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
375 const Bounds &bounds_l, const Bounds &bounds_r) const -> Bounds
376 {
377 const auto &[h_min_l, h_max_l, v2_max_l] = bounds_l;
378 const auto &[h_min_r, h_max_r, v2_max_r] = bounds_r;
379
380 return {std::min(h_min_l, h_min_r),
381 std::max(h_max_l, h_max_r),
382 std::max(v2_max_l, v2_max_r)};
383 }
384
385
386 template <int dim, typename Number, typename MemorySpace>
387 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
389 const Bounds &bounds, const Number &hd) const -> Bounds
390 {
391 auto relaxed_bounds = bounds;
392 auto &[h_min, h_max, v2_max] = relaxed_bounds;
393
394 /* Use r = factor * (m_i / |Omega|) ^ (1.5 / d): */
395
396 Number r = std::sqrt(hd); // in 3D: ^ 3/6
397 if constexpr (dim == 2) //
398 r = dealii::Utilities::fixed_power<3>(std::sqrt(r)); // in 2D: ^ 3/4
399 else if constexpr (dim == 1) //
400 r = dealii::Utilities::fixed_power<3>(r); // in 1D: ^ 3/2
401 r *= relaxation_factor();
402
403 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
404 h_min *= std::max((Number(1.) - r), Number(eps));
405 h_max *= (Number(1.) + r);
406 v2_max *= (Number(1.) + r);
407
408 return relaxed_bounds;
409 }
410
411
412 template <int dim, typename Number, typename MemorySpace>
413 DEAL_II_HOST_DEVICE_ALWAYS_INLINE void
415 const PrecomputedVectorView & /*pv*/,
416 unsigned int /*i*/,
417 const state_type & /*U_i*/,
418 const flux_contribution_type &flux_i)
419 {
420 flux_i_ = flux_i;
421
422 auto &[h_min, h_max, v2_max] = bounds_;
423
424 h_min = Number(std::numeric_limits<ScalarNumber>::max());
425 h_max = Number(0.);
426 v2_max = Number(0.);
427
428 h_relaxation_numerator_ = Number(0.);
429 v2_relaxation_numerator_ = Number(0.);
430 relaxation_denominator_ = Number(0.);
431 }
432
433
434 template <int dim, typename Number, typename MemorySpace>
435 DEAL_II_HOST_DEVICE_ALWAYS_INLINE void
437 const PrecomputedVectorView & /*pv*/,
438 const unsigned int * /*js*/,
439 const state_type & /*U_j*/,
440 const flux_contribution_type &flux_j,
441 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
442 const state_type &affine_shift)
443 {
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);
448
449 /* bar state shifted by an affine shift: */
450
451 const auto p_star_ij = view_.pressure(U_star_ij);
452 const auto p_star_ji = view_.pressure(U_star_ji);
453
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];
458 U_ij_bar = ScalarNumber(0.5) * U_ij_bar + affine_shift;
459
460 /* Bounds: */
461
462 auto &[h_min, h_max, v2_max] = bounds_;
463
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);
467
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);
472
473 /* Relaxation: */
474
475 /* Use a uniform weight. */
476 const auto beta_ij = Number(1.);
477
478 relaxation_denominator_ += std::abs(beta_ij);
479
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);
483
484 v2_relaxation_numerator_ +=
485 beta_ij * (-V_i.norm_square() + V_j.norm_square());
486 }
487
488
489 template <int dim, typename Number, typename MemorySpace>
490 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
492 -> Bounds
493 {
494 const auto &[h_min, h_max, v2_max] = bounds_;
495
496 auto relaxed_bounds = fully_relax_bounds(bounds_, hd_i);
497 auto &[h_min_relaxed, h_max_relaxed, v2_max_relaxed] = relaxed_bounds;
498
499 /* Apply a stricter window: */
500
501 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
502
503 const Number h_relaxed = ScalarNumber(2. * relaxation_factor()) *
504 std::abs(h_relaxation_numerator_) /
505 (relaxation_denominator_ + Number(eps));
506
507 const Number v2_relaxed = ScalarNumber(2. * relaxation_factor()) *
508 std::abs(v2_relaxation_numerator_) /
509 (relaxation_denominator_ + Number(eps));
510
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);
514
515 return relaxed_bounds;
516 }
517
518
519 template <int dim, typename Number, typename MemorySpace>
520 DEAL_II_HOST_DEVICE_ALWAYS_INLINE std::tuple<Number, bool>
522 const Bounds &bounds,
523 const state_type &U,
524 const state_type &P,
525 const Number t_min /* = Number(0.) */,
526 const Number t_max /* = Number(1.) */) const
527 {
528 bool success = true;
529 Number t_l = t_min;
530 Number t_r = t_max;
531
532 const auto &[h_min, h_max, v2_max] = bounds;
533
534 constexpr ScalarNumber min = std::numeric_limits<ScalarNumber>::min();
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);
539 const auto relax = ScalarNumber(1. + large * eps);
540
541 /*
542 * We first limit the water_depth h.
543 *
544 * See [Guermond et al, 2021] (5.7).
545 */
546
547 {
548 auto h_U = view_.water_depth(U);
549 const auto &h_P = view_.water_depth(P);
550
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));
555
556 if (!(test_min == Number(0.) && test_max == Number(0.))) {
557#ifdef DEBUG_OUTPUT
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
561 << "\n\t\th min (delta): " << negative_part(h_U - h_min)
562 << "\n\t\th: " << h_U
563 << "\n\t\th max (delta): " << positive_part(h_U - h_max)
564 << "\n\t\th max: " << h_max << "\n"
565 << std::endl;
566#endif
567 success = false;
568 }
569
570 const Number denominator =
571 ScalarNumber(1.) / (std::abs(h_P) + eps * h_max + min);
572
573 constexpr auto lt = dealii::SIMDComparison::less_than;
574
575 t_r = ryujin::compare_and_apply_mask<lt>( //
576 h_max,
577 h_U + t_r * h_P,
578 /*
579 * h_P is positive.
580 *
581 * Note: Do not take an absolute value here. If we are out of
582 * bounds we have to ensure that t_r is set to t_min.
583 */
584 (h_max - h_U) * denominator,
585 t_r);
586
587 t_r = ryujin::compare_and_apply_mask<lt>( //
588 h_U + t_r * h_P,
589 h_min,
590 /*
591 * h_P is negative.
592 *
593 * Note: Do not take an absolute value here. If we are out of
594 * bounds we have to ensure that t_r is set to t_min.
595 */
596 (h_U - h_min) * denominator,
597 t_r);
598
599 /*
600 * Ensure that t_min <= t <= t_max. This might not be the case if
601 * h_U is outside the interval [h_min, h_max]. Furthermore, the
602 * quotient we take above is prone to numerical cancellation in
603 * particular in the second pass of the limiter when h_P might be
604 * small.
605 */
606 t_r = std::min(t_r, t_max);
607 t_r = std::max(t_r, t_min);
608
609
610#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
611 /*
612 * Verify that the new state is within bounds:
613 */
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));
619
620 if (!(test_new_min == Number(0.) && test_new_max == Number(0.))) {
621#ifdef DEBUG_OUTPUT
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
625 << "\n\t\th min (delta): " << negative_part(h_new - h_min)
626 << "\n\t\th: " << h_new
627 << "\n\t\th max (delta): " << positive_part(h_new - h_max)
628 << "\n\t\th max: " << h_max << "\n"
629 << std::endl;
630#endif
631 success = false;
632 }
633#endif
634 }
635
636 /*
637 * Limit the (negative) |v|^2:
638 *
639 * Given initial limiter values t_l and t_r with psi(t_l) > 0 and
640 * psi(t_r) < 0 we try to find t^\ast with psi(t^\ast) \approx 0.
641 *
642 * Here, psi is the function:
643 *
644 * psi = h^2 (|v|^2)^max - |q|^2
645 */
646
647 {
648 /* We first check if t_r is a good state */
649
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);
653
654 const auto psi_r = relax_small * h_r * h_r * v2_max - q_r.norm_square();
655
656 /*
657 * If psi_r > 0 the right state is fine, force returning t_r by
658 * setting t_l = t_r:
659 */
661 dealii::SIMDComparison::greater_than>(psi_r, Number(0.), t_r, t_l);
662
663 /* If we have set t_l = t_r everywhere we can return: */
664 if (t_l == t_r)
665 return {t_l, success};
666
667#ifdef DEBUG_OUTPUT_LIMITER
668 {
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;
673 }
674#endif
675
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);
679
680 const auto psi_l = relax_small * h_l * h_l * v2_max - q_l.norm_square();
681
682 /*
683 * Verify that the left state is within bounds. This property might
684 * be violated for relative CFL numbers larger than 1.
685 *
686 * We use a non-scaled eps here to force the lower_bound to be
687 * negative so that we do not accidentally trigger in "perfect" dry
688 * states with h_l equal to zero.
689 */
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 -
693 ScalarNumber(100.) * eps;
694 if (!(std::min(Number(0.), psi_l - lower_bound) == Number(0.))) {
695#ifdef DEBUG_OUTPUT
696 std::cout << std::fixed << std::setprecision(16);
697 std::cout
698 << "Bounds violation: low-order square velocity (critical)!\n";
699 std::cout << "\t\tPsi left: 0 <= " << psi_l << "\n" << std::endl;
700#endif
701 success = false;
702 }
703
704 /*
705 * Skip the quadratic Newton step if the window between t_l and t_r
706 * is within the prescribed tolerance:
707 */
708 const Number tolerance(newton_tolerance());
709 if (!(std::max(Number(0.), t_r - t_l - tolerance) == Number(0.))) {
710 /*
711 * If the bound is not satisfied, we need to find the root of a
712 * quadratic function:
713 *
714 * psi(t) = r (h_U + t h_P)^2 v2_max
715 * - (|q_U|^2 + 2(q_U * q_P) t + |q_P|^2 t^2)
716 *
717 * d_psi(t) = 2 r (h_U + t * h_P) * h_P v2_max
718 * - 2 (q_U * q_P) - 2 |q_P|^2 t
719 *
720 * where r = relax_small.
721 *
722 * We can compute the root of this function efficiently by using our
723 * standard quadratic_newton_step() function that will use the points
724 * [p1, p1, p2] as well as [p1, p2, p2] to construct two quadratic
725 * polynomials to compute new candiates for the bounds [t_l, t_r]. In
726 * case of a quadratic function psi(t) both polynomials will coincide
727 * so that (up to round-off error) t_l = t_r.
728 */
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);
733
734 const auto dpsi_l = ScalarNumber(2.) *
735 (relax_small * (h_U + t_l * h_P) * h_P * v2_max -
736 ((q_U * q_P) + q_P * q_P * t_l));
737 const auto dpsi_r = ScalarNumber(2.) *
738 (relax_small * (h_U + t_r * h_P) * h_P * v2_max -
739 ((q_U * q_P) + q_P * q_P * t_r));
740
742 t_l, t_r, psi_l, psi_r, dpsi_l, dpsi_r, Number(-1.));
743
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;
752 }
753#endif
754 }
755
756#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
757 /*
758 * Verify that the new state is within bounds:
759 */
760 {
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);
764
765 const auto psi_new =
766 relax_small * h_new * h_new * v2_max - q_new.norm_square();
767
768 const auto lower_bound =
769 (ScalarNumber(1.) - relax) * h_new * h_new * v2_max -
770 ScalarNumber(100.) * eps;
771
772 const bool psi_valid =
773 std::min(Number(0.), psi_new - lower_bound) == Number(0.);
774 if (!psi_valid) {
775#ifdef DEBUG_OUTPUT
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;
779#endif
780 success = false;
781 }
782 }
783#endif
784 }
785
786 return {t_l, success};
787 }
788 } // namespace ShallowWater
789} // namespace ryujin
typename get_value_type< Number >::type ScalarNumber
dealii::Tensor< 1, problem_dimension, Number > state_type
std::tuple< state_type, Number, dealii::Tensor< 1, dim, Number > > flux_contribution_type
VectorView< n_precomputed_values > PrecomputedVectorView
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:436
typename View::ScalarNumber ScalarNumber
Definition limiter.h:167
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber relaxation_factor() const
Definition limiter.h:228
typename View::flux_contribution_type flux_contribution_type
Definition limiter.h:171
typename View::state_type state_type
Definition limiter.h:169
DEAL_II_HOST_DEVICE Bounds fully_relax_bounds(const Bounds &bounds, const Number &hd) const
Definition limiter.h:388
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:414
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber newton_tolerance() const
Definition limiter.h:211
LimiterView(const View &view, const Limiter< ScalarNumber > &limiter)
Definition limiter.h:194
static constexpr unsigned int n_bounds
Definition limiter.h:183
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:358
HyperbolicSystemView< dim, Number, MemorySpace > View
Definition limiter.h:165
DEAL_II_HOST_DEVICE Bounds bounds(const Number hd_i) const
Definition limiter.h:491
DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int newton_max_iterations() const
Definition limiter.h:220
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:521
typename View::PrecomputedVectorView PrecomputedVectorView
Definition limiter.h:173
DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int iterations() const
Definition limiter.h:203
DEAL_II_HOST_DEVICE Bounds combine_bounds(const Bounds &bounds_left, const Bounds &bounds_right) const
Definition limiter.h:374
std::array< Number, n_bounds > Bounds
Definition limiter.h:188
Limiter(const HyperbolicSystem &hyperbolic_system, const std::string &subsection="/Limiter")
Definition limiter.h:62
TransferPolicy
Definition gpu.h:88
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