ryujin 2.1.1 revision d1a5601757449924e68a428cfd892dfe8915810d
limiter.template.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2023 - 2024 by the ryujin authors
4//
5
6#pragma once
7
8#include "limiter.h"
9
10namespace ryujin
11{
12 namespace ScalarConservation
13 {
14 template <int dim, typename Number>
15 std::tuple<Number, bool>
17 const state_type &U,
18 const state_type &P,
19 const Number t_min /* = Number(0.) */,
20 const Number t_max /* = Number(1.) */)
21 {
22 const auto view = hyperbolic_system.view<dim, Number>();
23
24 bool success = true;
25 Number t_r = t_max;
26
27 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
28 const ScalarNumber relax = ScalarNumber(1. + 10000. * eps);
29
30 const auto &u_U = view.state(U);
31 const auto &u_P = view.state(P);
32
33 const auto &u_min = std::get<0>(bounds);
34 const auto &u_max = std::get<1>(bounds);
35
36 /*
37 * Verify that u_U is within bounds. This property might be
38 * violated for relative CFL numbers larger than 1.
39 */
40 const auto test_min = std::max(Number(0.), u_U - relax * u_max);
41 const auto test_max = std::max(Number(0.), u_min - relax * u_U);
42 if (!(test_min == Number(0.) && test_max == Number(0.))) {
43#ifdef DEBUG_OUTPUT
44 std::cout << std::fixed << std::setprecision(16);
45 std::cout << "Bounds violation: low-order state (critical)!"
46 << "\n\t\tu min: " << u_min
47 << "\n\t\tu min (delta): " << negative_part(u_U - u_min)
48 << "\n\t\tu: " << u_U
49 << "\n\t\tu max (delta): " << positive_part(u_U - u_max)
50 << "\n\t\tu max: " << u_max << "\n"
51 << std::endl;
52#endif
53 success = false;
54 }
55
56 const auto regularization =
57 Number(100. * std::numeric_limits<ScalarNumber>::min());
58
59 const Number denominator =
60 ScalarNumber(1.) /
61 std::max(regularization, std::abs(u_P) + eps * u_max);
62
63 t_r = dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
64 u_max,
65 u_U + t_r * u_P,
66 /*
67 * u_P is positive.
68 *
69 * Note: Do not take an absolute value here. If we are out of
70 * bounds we have to ensure that t_r is set to t_min.
71 */
72 (u_max - u_U) * denominator,
73 t_r);
74
75 t_r = dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
76 u_U + t_r * u_P,
77 u_min,
78 /*
79 * u_P is negative.
80 *
81 * Note: Do not take an absolute value here. If we are out of
82 * bounds we have to ensure that t_r is set to t_min.
83 */
84 (u_U - u_min) * denominator,
85 t_r);
86
87 /*
88 * Ensure that t_min <= t <= t_max. This might not be the case if
89 * u_U is outside the interval [u_min, u_max]. Furthermore,
90 * the quotient we take above is prone to numerical cancellation in
91 * particular in the second pass of the limiter when u_P might be
92 * small.
93 */
94 t_r = std::min(t_r, t_max);
95 t_r = std::max(t_r, t_min);
96
97#ifdef CHECK_BOUNDS
98 /*
99 * Verify that the new state is within bounds:
100 */
101 const auto u_new = view.state(U + t_r * P);
102 const auto test_new_min = std::max(Number(0.), u_new - relax * u_max);
103 const auto test_new_max = std::max(Number(0.), u_min - relax * u_new);
104 if (!(test_new_min == Number(0.) && test_new_max == Number(0.))) {
105#ifdef DEBUG_OUTPUT
106 std::cout << std::fixed << std::setprecision(16);
107 std::cout << "Bounds violation: high-order state!"
108 << "\n\t\tu min: " << u_min
109 << "\n\t\tu min (delta): " << negative_part(u_new - u_min)
110 << "\n\t\tu: " << u_new
111 << "\n\t\tu max (delta): " << positive_part(u_new - u_max)
112 << "\n\t\tu max: " << u_max << "\n"
113 << std::endl;
114#endif
115 success = false;
116 }
117#endif
118
119 return {t_r, success};
120 }
121
122 } // namespace ScalarConservation
123} // namespace ryujin
std::array< Number, n_bounds > Bounds
Definition: limiter.h:103
typename View::state_type state_type
Definition: limiter.h:65
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.))
typename View::ScalarNumber ScalarNumber
Definition: limiter.h:61
DEAL_II_ALWAYS_INLINE Number negative_part(const Number number)
Definition: simd.h:124
DEAL_II_ALWAYS_INLINE Number positive_part(const Number number)
Definition: simd.h:112