ryujin 2.1.1 revision b04fb4aba7bd97ddfa5994a6b4b6e8586eb15db2
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 <compile_time_options.h>
11
12#include "hyperbolic_system.h"
13
14#include <gpu.h>
16#include <newton.h>
17#include <observer_pointer.h>
18#include <simd.h>
19
20// #define DEBUG_OUTPUT_LIMITER
21
22namespace ryujin
23{
24 namespace ShallowWater
25 {
26 template <int dim,
27 typename Number = double,
28 typename MemorySpace = dealii::MemorySpace::Host>
29 class LimiterView;
30
36 template <typename ScalarNumber = double>
37 class Limiter : public dealii::ParameterAcceptor
38 {
39 public:
44
48 struct Parameters {
49 unsigned int iterations;
53 };
54
56
60
64 Limiter(const HyperbolicSystem &hyperbolic_system,
65 const std::string &subsection = "/Limiter")
66 : ParameterAcceptor(subsection)
67 , parameters_("shallow_water_limiter_parameters",
69 , hyperbolic_system_(&hyperbolic_system)
70 {
71 /* reference remains valid due to implicit_transfers_host_resident */
72 auto &parameters = *parameters_.view();
73
74 parameters.iterations = 2;
75 add_parameter("iterations",
76 parameters.iterations,
77 "Number of limiter iterations");
78
79 if constexpr (std::is_same_v<ScalarNumber, double>)
80 parameters.newton_tolerance = 1.e-10;
81 else
82 parameters.newton_tolerance = 1.e-4;
83 add_parameter("newton tolerance",
84 parameters.newton_tolerance,
85 "Tolerance for the quadratic newton stopping criterion");
86
87 parameters.newton_max_iterations = 2;
88 add_parameter("newton max iterations",
89 parameters.newton_max_iterations,
90 "Maximal number of quadratic newton iterations performed "
91 "during limiting");
92
93 parameters.relaxation_factor = 1.;
94 add_parameter("relaxation factor",
95 parameters.relaxation_factor,
96 "Factor for scaling the relaxation window with r_i = "
97 "factor * (m_i/|Omega|)^(1.5/d).");
98
99 /* invalidates view on default memory space */
100 ParameterAcceptor::parse_parameters_call_back.connect(
101 [this] { parameters_.view(); });
102 }
103
111 template <int dim,
112 typename Number,
113 typename MemorySpace = dealii::MemorySpace::Host>
114 auto view() const
115 {
117 hyperbolic_system_->template view<dim, Number, MemorySpace>(),
118 *this};
119 }
120
121 private:
123
127
128 Mirrored<Parameters> parameters_;
129
131
135
136 dealii::ObserverPointer<const HyperbolicSystem> hyperbolic_system_;
137
138 template <int, typename, typename>
139 friend class LimiterView;
140
142 };
143
144
153 template <int dim, typename Number, typename MemorySpace>
155 {
156 public:
157 static_assert(
158 std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
159 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
160 "Unexpected memory space");
161
166
168
170
171 using state_type = typename View::state_type;
172
174
176
178
185 static constexpr unsigned int n_bounds = 3;
186
190 using Bounds = std::array<Number, n_bounds>;
191
196 LimiterView(const View &view, const Limiter<ScalarNumber> &limiter)
197 : view_(view)
198 , parameters_(limiter.parameters_.template view<MemorySpace>())
199 {
200 }
201
205 DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int iterations() const
206 {
207 return parameters_->iterations;
208 }
209
213 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber newton_tolerance() const
214 {
215 return ScalarNumber(parameters_->newton_tolerance);
216 }
217
221 DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int
223 {
224 return parameters_->newton_max_iterations;
225 }
226
230 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber relaxation_factor() const
231 {
232 return ScalarNumber(parameters_->relaxation_factor);
233 }
234
239 DEAL_II_HOST_DEVICE Bounds
241 const unsigned int i,
242 const state_type &U_i) const;
243
249 DEAL_II_HOST_DEVICE Bounds combine_bounds(
250 const Bounds &bounds_left, const Bounds &bounds_right) const;
251
259 DEAL_II_HOST_DEVICE Bounds fully_relax_bounds(const Bounds &bounds,
260 const Number &hd) const;
261
263
282
286 DEAL_II_HOST_DEVICE void reset(const PrecomputedVectorView &pv,
287 const unsigned int i,
288 const state_type &U_i,
289 const flux_contribution_type &flux_i);
290
295 DEAL_II_HOST_DEVICE void
297 const state_type &U_j,
298 const state_type &U_star_ij,
299 const state_type &U_star_ji,
300 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
301 const state_type &affine_shift);
302
306 DEAL_II_HOST_DEVICE Bounds bounds(const Number hd_i) const;
307
309
313
320 DEAL_II_HOST_DEVICE std::tuple<Number, bool>
321 limit(const Bounds &bounds,
322 const state_type &U,
323 const state_type &P,
324 const Number t_min = Number(0.),
325 const Number t_max = Number(1.)) const;
326
327 private:
329
333
334 const View view_;
335 const Limiter<ScalarNumber>::Parameters *const parameters_;
336
337 state_type U_i_;
338
339 Bounds bounds_;
340
341 /* for relaxation */
342
343 Number h_relaxation_numerator_;
344 Number v2_relaxation_numerator_;
345 Number relaxation_denominator_;
346
348 };
349
350
351 /*
352 * -------------------------------------------------------------------------
353 * Inline definitions
354 * -------------------------------------------------------------------------
355 */
356
357
358 template <int dim, typename Number, typename MemorySpace>
359 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
361 const PrecomputedVectorView & /*pv*/,
362 const unsigned int /*i*/,
363 const state_type &U_i) const -> Bounds
364 {
365 const auto h_i = view_.water_depth(U_i);
366 const auto v_i =
367 view_.momentum(U_i) * view_.inverse_water_depth_mollified(U_i);
368 const auto v2_i = v_i.norm_square();
369
370 return {/*h_min*/ h_i, /*h_max*/ h_i, /*v2_max*/ v2_i};
371 }
372
373
374 template <int dim, typename Number, typename MemorySpace>
375 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
377 const Bounds &bounds_l, const Bounds &bounds_r) const -> Bounds
378 {
379 const auto &[h_min_l, h_max_l, v2_max_l] = bounds_l;
380 const auto &[h_min_r, h_max_r, v2_max_r] = bounds_r;
381
382 return {std::min(h_min_l, h_min_r),
383 std::max(h_max_l, h_max_r),
384 std::max(v2_max_l, v2_max_r)};
385 }
386
387
388 template <int dim, typename Number, typename MemorySpace>
389 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
391 const Bounds &bounds, const Number &hd) const -> Bounds
392 {
393 auto relaxed_bounds = bounds;
394 auto &[h_min, h_max, v2_max] = relaxed_bounds;
395
396 /* Use r = factor * (m_i / |Omega|) ^ (1.5 / d): */
397
398 Number r = std::sqrt(hd); // in 3D: ^ 3/6
399 if constexpr (dim == 2) //
400 r = dealii::Utilities::fixed_power<3>(std::sqrt(r)); // in 2D: ^ 3/4
401 else if constexpr (dim == 1) //
402 r = dealii::Utilities::fixed_power<3>(r); // in 1D: ^ 3/2
403 r *= relaxation_factor();
404
405 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
406 h_min *= std::max((Number(1.) - r), Number(eps));
407 h_max *= (Number(1.) + r);
408 v2_max *= (Number(1.) + r);
409
410 return relaxed_bounds;
411 }
412
413
414 template <int dim, typename Number, typename MemorySpace>
415 DEAL_II_HOST_DEVICE_ALWAYS_INLINE void
417 const PrecomputedVectorView & /*pv*/,
418 unsigned int /*i*/,
419 const state_type &U_i,
420 const flux_contribution_type & /*flux_i*/)
421 {
422 U_i_ = U_i;
423
424 auto &[h_min, h_max, v2_max] = bounds_;
425
426 h_min = Number(std::numeric_limits<ScalarNumber>::max());
427 h_max = Number(0.);
428 v2_max = Number(0.);
429
430 h_relaxation_numerator_ = Number(0.);
431 v2_relaxation_numerator_ = Number(0.);
432 relaxation_denominator_ = Number(0.);
433 }
434
435
436 template <int dim, typename Number, typename MemorySpace>
437 DEAL_II_HOST_DEVICE_ALWAYS_INLINE void
439 const PrecomputedVectorView & /*pv*/,
440 const state_type &U_j,
441 const state_type &U_star_ij,
442 const state_type &U_star_ji,
443 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
444 const state_type &affine_shift)
445 {
446 /* The bar states: */
447
448 const auto f_star_ij = view_.f(U_star_ij);
449 const auto f_star_ji = view_.f(U_star_ji);
450
451 /* bar state shifted by an affine shift: */
452 const auto U_ij_bar =
453 ScalarNumber(0.5) *
454 (U_star_ij + U_star_ji +
455 contract(add(f_star_ij, -f_star_ji), scaled_c_ij)) +
456 affine_shift;
457
458 /* Bounds: */
459
460 auto &[h_min, h_max, v2_max] = bounds_;
461
462 const auto h_bar_ij = view_.water_depth(U_ij_bar);
463 h_min = std::min(h_min, h_bar_ij);
464 h_max = std::max(h_max, h_bar_ij);
465
466 const auto v_bar_ij = view_.momentum(U_ij_bar) *
467 view_.inverse_water_depth_mollified(U_ij_bar);
468 const auto v2_bar_ij = v_bar_ij.norm_square();
469 v2_max = std::max(v2_max, v2_bar_ij);
470
471 /* Relaxation: */
472
473 /* Use a uniform weight. */
474 const auto beta_ij = Number(1.);
475
476 relaxation_denominator_ += std::abs(beta_ij);
477
478 const auto h_i = view_.water_depth(U_i_);
479 const auto h_j = view_.water_depth(U_j);
480 h_relaxation_numerator_ += beta_ij * (h_i + h_j);
481
482 const auto vel_i =
483 view_.momentum(U_i_) * view_.inverse_water_depth_mollified(U_i_);
484 const auto vel_j =
485 view_.momentum(U_j) * view_.inverse_water_depth_mollified(U_j);
486 v2_relaxation_numerator_ +=
487 beta_ij * (-vel_i.norm_square() + vel_j.norm_square());
488 }
489
490
491 template <int dim, typename Number, typename MemorySpace>
492 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
494 -> Bounds
495 {
496 const auto &[h_min, h_max, v2_max] = bounds_;
497
498 auto relaxed_bounds = fully_relax_bounds(bounds_, hd_i);
499 auto &[h_min_relaxed, h_max_relaxed, v2_max_relaxed] = relaxed_bounds;
500
501 /* Apply a stricter window: */
502
503 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
504
505 const Number h_relaxed = ScalarNumber(2. * relaxation_factor()) *
506 std::abs(h_relaxation_numerator_) /
507 (relaxation_denominator_ + Number(eps));
508
509 const Number v2_relaxed = ScalarNumber(2. * relaxation_factor()) *
510 std::abs(v2_relaxation_numerator_) /
511 (relaxation_denominator_ + Number(eps));
512
513 h_min_relaxed = std::max(h_min_relaxed, h_min - h_relaxed);
514 h_max_relaxed = std::min(h_max_relaxed, h_max + h_relaxed);
515 v2_max_relaxed = std::min(v2_max_relaxed, v2_max + v2_relaxed);
516
517 return relaxed_bounds;
518 }
519
520
521 template <int dim, typename Number, typename MemorySpace>
522 DEAL_II_HOST_DEVICE_ALWAYS_INLINE std::tuple<Number, bool>
524 const Bounds &bounds,
525 const state_type &U,
526 const state_type &P,
527 const Number t_min /* = Number(0.) */,
528 const Number t_max /* = Number(1.) */) const
529 {
530 bool success = true;
531 Number t_l = t_min;
532 Number t_r = t_max;
533
534 const auto &[h_min, h_max, v2_max] = bounds;
535
536 constexpr ScalarNumber min = std::numeric_limits<ScalarNumber>::min();
537 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
538 const auto small = view_.dry_state_relaxation_small();
539 const auto large = view_.dry_state_relaxation_large();
540 const auto relax_small = ScalarNumber(1. + small * eps);
541 const auto relax = ScalarNumber(1. + large * eps);
542
543 /*
544 * We first limit the water_depth h.
545 *
546 * See [Guermond et al, 2021] (5.7).
547 */
548
549 {
550 auto h_U = view_.water_depth(U);
551 const auto &h_P = view_.water_depth(P);
552
553 const auto test_min = view_.filter_dry_water_depth(
554 std::max(Number(0.), h_U - relax * h_max));
555 const auto test_max = view_.filter_dry_water_depth(
556 std::max(Number(0.), h_min - relax * h_U));
557
558 if (!(test_min == Number(0.) && test_max == Number(0.))) {
559#ifdef DEBUG_OUTPUT
560 std::cout << std::fixed << std::setprecision(16);
561 std::cout << "Bounds violation: low-order water depth (critical)!\n"
562 << "\n\t\th min: " << h_min
563 << "\n\t\th min (delta): " << negative_part(h_U - h_min)
564 << "\n\t\th: " << h_U
565 << "\n\t\th max (delta): " << positive_part(h_U - h_max)
566 << "\n\t\th max: " << h_max << "\n"
567 << std::endl;
568#endif
569 success = false;
570 }
571
572 const Number denominator =
573 ScalarNumber(1.) / (std::abs(h_P) + eps * h_max + min);
574
575 constexpr auto lt = dealii::SIMDComparison::less_than;
576
577 t_r = ryujin::compare_and_apply_mask<lt>( //
578 h_max,
579 h_U + t_r * h_P,
580 /*
581 * h_P is positive.
582 *
583 * Note: Do not take an absolute value here. If we are out of
584 * bounds we have to ensure that t_r is set to t_min.
585 */
586 (h_max - h_U) * denominator,
587 t_r);
588
589 t_r = ryujin::compare_and_apply_mask<lt>( //
590 h_U + t_r * h_P,
591 h_min,
592 /*
593 * h_P is negative.
594 *
595 * Note: Do not take an absolute value here. If we are out of
596 * bounds we have to ensure that t_r is set to t_min.
597 */
598 (h_U - h_min) * denominator,
599 t_r);
600
601 /*
602 * Ensure that t_min <= t <= t_max. This might not be the case if
603 * h_U is outside the interval [h_min, h_max]. Furthermore, the
604 * quotient we take above is prone to numerical cancellation in
605 * particular in the second pass of the limiter when h_P might be
606 * small.
607 */
608 t_r = std::min(t_r, t_max);
609 t_r = std::max(t_r, t_min);
610
611
612#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
613 /*
614 * Verify that the new state is within bounds:
615 */
616 const auto h_new = view_.water_depth(U + t_r * P);
617 const auto test_new_min = view_.filter_dry_water_depth(
618 std::max(Number(0.), h_new - relax * h_max));
619 const auto test_new_max = view_.filter_dry_water_depth(
620 std::max(Number(0.), h_min - relax * h_new));
621
622 if (!(test_new_min == Number(0.) && test_new_max == Number(0.))) {
623#ifdef DEBUG_OUTPUT
624 std::cout << std::fixed << std::setprecision(30);
625 std::cout << "Bounds violation: high-order water depth!\n"
626 << "\n\t\th min: " << h_min
627 << "\n\t\th min (delta): " << negative_part(h_new - h_min)
628 << "\n\t\th: " << h_new
629 << "\n\t\th max (delta): " << positive_part(h_new - h_max)
630 << "\n\t\th max: " << h_max << "\n"
631 << std::endl;
632#endif
633 success = false;
634 }
635#endif
636 }
637
638 /*
639 * Limit the (negative) |v|^2:
640 *
641 * Given initial limiter values t_l and t_r with psi(t_l) > 0 and
642 * psi(t_r) < 0 we try to find t^\ast with psi(t^\ast) \approx 0.
643 *
644 * Here, psi is the function:
645 *
646 * psi = h^2 (|v|^2)^max - |q|^2
647 */
648
649 {
650 /* We first check if t_r is a good state */
651
652 const auto U_r = U + t_r * P;
653 const auto h_r = view_.water_depth(U_r);
654 const auto q_r = view_.momentum(U_r);
655
656 const auto psi_r = relax_small * h_r * h_r * v2_max - q_r.norm_square();
657
658 /*
659 * If psi_r > 0 the right state is fine, force returning t_r by
660 * setting t_l = t_r:
661 */
663 dealii::SIMDComparison::greater_than>(psi_r, Number(0.), t_r, t_l);
664
665 /* If we have set t_l = t_r everywhere we can return: */
666 if (t_l == t_r)
667 return {t_l, success};
668
669#ifdef DEBUG_OUTPUT_LIMITER
670 {
671 std::cout << std::endl;
672 std::cout << std::fixed << std::setprecision(16);
673 std::cout << "t_l: (start) " << t_l << std::endl;
674 std::cout << "t_r: (start) " << t_r << std::endl;
675 }
676#endif
677
678 const auto U_l = U + t_l * P;
679 const auto h_l = view_.water_depth(U_l);
680 const auto q_l = view_.momentum(U_l);
681
682 const auto psi_l = relax_small * h_l * h_l * v2_max - q_l.norm_square();
683
684 /*
685 * Verify that the left state is within bounds. This property might
686 * be violated for relative CFL numbers larger than 1.
687 *
688 * We use a non-scaled eps here to force the lower_bound to be
689 * negative so that we do not accidentally trigger in "perfect" dry
690 * states with h_l equal to zero.
691 */
692 const auto filtered_h_l = view_.filter_dry_water_depth(h_l);
693 const auto lower_bound =
694 (ScalarNumber(1.) - relax) * filtered_h_l * filtered_h_l * v2_max -
695 ScalarNumber(100.) * eps;
696 if (!(std::min(Number(0.), psi_l - lower_bound) == Number(0.))) {
697#ifdef DEBUG_OUTPUT
698 std::cout << std::fixed << std::setprecision(16);
699 std::cout
700 << "Bounds violation: low-order square velocity (critical)!\n";
701 std::cout << "\t\tPsi left: 0 <= " << psi_l << "\n" << std::endl;
702#endif
703 success = false;
704 }
705
706 /*
707 * Skip the quadratic Newton step if the window between t_l and t_r
708 * is within the prescribed tolerance:
709 */
710 const Number tolerance(newton_tolerance());
711 if (!(std::max(Number(0.), t_r - t_l - tolerance) == Number(0.))) {
712 /*
713 * If the bound is not satisfied, we need to find the root of a
714 * quadratic function:
715 *
716 * psi(t) = r (h_U + t h_P)^2 v2_max
717 * - (|q_U|^2 + 2(q_U * q_P) t + |q_P|^2 t^2)
718 *
719 * d_psi(t) = 2 r (h_U + t * h_P) * h_P v2_max
720 * - 2 (q_U * q_P) - 2 |q_P|^2 t
721 *
722 * where r = relax_small.
723 *
724 * We can compute the root of this function efficiently by using our
725 * standard quadratic_newton_step() function that will use the points
726 * [p1, p1, p2] as well as [p1, p2, p2] to construct two quadratic
727 * polynomials to compute new candiates for the bounds [t_l, t_r]. In
728 * case of a quadratic function psi(t) both polynomials will coincide
729 * so that (up to round-off error) t_l = t_r.
730 */
731 const auto &h_U = view_.water_depth(U);
732 const auto &h_P = view_.water_depth(P);
733 const auto &q_U = view_.momentum(U);
734 const auto &q_P = view_.momentum(P);
735
736 const auto dpsi_l = ScalarNumber(2.) *
737 (relax_small * (h_U + t_l * h_P) * h_P * v2_max -
738 ((q_U * q_P) + q_P * q_P * t_l));
739 const auto dpsi_r = ScalarNumber(2.) *
740 (relax_small * (h_U + t_r * h_P) * h_P * v2_max -
741 ((q_U * q_P) + q_P * q_P * t_r));
742
744 t_l, t_r, psi_l, psi_r, dpsi_l, dpsi_r, Number(-1.));
745
746#ifdef DEBUG_OUTPUT_LIMITER
747 if (std::max(Number(0.), psi_r + Number(eps)) == Number(0.)) {
748 std::cout << "psi_l: " << psi_l << std::endl;
749 std::cout << "psi_r: " << psi_r << std::endl;
750 std::cout << "dpsi_l: " << dpsi_l << std::endl;
751 std::cout << "dpsi_r: " << dpsi_r << std::endl;
752 std::cout << "t_l: (end) " << t_l << std::endl;
753 std::cout << "t_r: (end) " << t_r << std::endl;
754 }
755#endif
756 }
757
758#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
759 /*
760 * Verify that the new state is within bounds:
761 */
762 {
763 const auto U_new = U + t_l * P;
764 const auto h_new = view_.water_depth(U_new);
765 const auto q_new = view_.momentum(U_new);
766
767 const auto psi_new =
768 relax_small * h_new * h_new * v2_max - q_new.norm_square();
769
770 const auto lower_bound =
771 (ScalarNumber(1.) - relax) * h_new * h_new * v2_max -
772 ScalarNumber(100.) * eps;
773
774 const bool psi_valid =
775 std::min(Number(0.), psi_new - lower_bound) == Number(0.);
776 if (!psi_valid) {
777#ifdef DEBUG_OUTPUT
778 std::cout << std::fixed << std::setprecision(16);
779 std::cout << "Bounds violation: high-order square velocity!\n";
780 std::cout << "\t\tPsi: 0 <= " << psi_new << "\n" << std::endl;
781#endif
782 success = false;
783 }
784 }
785#endif
786 }
787
788 return {t_l, success};
789 }
790 } // namespace ShallowWater
791} // namespace ryujin
typename get_value_type< Number >::type ScalarNumber
std::tuple< state_type, Number > flux_contribution_type
dealii::Tensor< 1, problem_dimension, Number > state_type
VectorView< n_precomputed_values > PrecomputedVectorView
typename View::ScalarNumber ScalarNumber
Definition limiter.h:169
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber relaxation_factor() const
Definition limiter.h:230
DEAL_II_HOST_DEVICE void accumulate(const PrecomputedVectorView &pv, const state_type &U_j, const state_type &U_star_ij, const state_type &U_star_ji, const dealii::Tensor< 1, dim, Number > &scaled_c_ij, const state_type &affine_shift)
Definition limiter.h:438
typename View::flux_contribution_type flux_contribution_type
Definition limiter.h:173
typename View::state_type state_type
Definition limiter.h:171
DEAL_II_HOST_DEVICE Bounds fully_relax_bounds(const Bounds &bounds, const Number &hd) const
Definition limiter.h:390
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:416
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber newton_tolerance() const
Definition limiter.h:213
LimiterView(const View &view, const Limiter< ScalarNumber > &limiter)
Definition limiter.h:196
static constexpr unsigned int n_bounds
Definition limiter.h:185
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:360
HyperbolicSystemView< dim, Number, MemorySpace > View
Definition limiter.h:167
DEAL_II_HOST_DEVICE Bounds bounds(const Number hd_i) const
Definition limiter.h:493
DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int newton_max_iterations() const
Definition limiter.h:222
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:523
typename View::PrecomputedVectorView PrecomputedVectorView
Definition limiter.h:175
DEAL_II_HOST_DEVICE_ALWAYS_INLINE unsigned int iterations() const
Definition limiter.h:205
DEAL_II_HOST_DEVICE Bounds combine_bounds(const Bounds &bounds_left, const Bounds &bounds_right) const
Definition limiter.h:376
std::array< Number, n_bounds > Bounds
Definition limiter.h:190
Limiter(const HyperbolicSystem &hyperbolic_system, const std::string &subsection="/Limiter")
Definition limiter.h:64
TransferPolicy
Definition gpu.h:88
DEAL_II_HOST_DEVICE_ALWAYS_INLINE dealii::Tensor< 1, problem_dim, T > contract(const FT &flux_ij, const TT &c_ij)
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:39
DEAL_II_HOST_DEVICE_ALWAYS_INLINE FT add(const FT &flux_left_ij, const FT &flux_right_ij)
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