ryujin 2.1.1 revision ee5cbcbf2346c1299c942d0e1f13b46449973c18
Loading...
Searching...
No Matches
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 - 2025 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.) */) const
21 {
22 bool success = true;
23 Number t_r = t_max;
24
25 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
26 const ScalarNumber relax = ScalarNumber(1. + 10000. * eps);
27
28 const auto &u_U = view_.state(U);
29 const auto &u_P = view_.state(P);
30
31 const auto &u_min = std::get<0>(bounds);
32 const auto &u_max = std::get<1>(bounds);
33
34 /*
35 * Verify that u_U is within bounds. This property might be
36 * violated for relative CFL numbers larger than 1.
37 *
38 * u_min, u_U, u_max might be negative, thus relax in both directions.
39 */
40 const auto test_max = std::max(
41 Number(0.), std::min(u_U - relax * u_max, relax * u_U - u_max));
42 const auto test_min = std::max(
43 Number(0.), std::min(u_min - relax * u_U, relax * u_min - u_U));
44 if (!(test_max == Number(0.) && test_min == Number(0.))) {
45#ifdef DEBUG_OUTPUT
46 std::cout << std::fixed << std::setprecision(16);
47 std::cout << "Bounds violation: low-order state (critical)!"
48 << "\n\t\tu min: " << u_min
49 << "\n\t\tu min (delta): " << negative_part(u_U - u_min)
50 << "\n\t\tu: " << u_U
51 << "\n\t\tu max (delta): " << positive_part(u_U - u_max)
52 << "\n\t\tu max: " << u_max << "\n"
53 << std::endl;
54#endif
55 success = false;
56 }
57
58 const auto regularization =
59 Number(100. * std::numeric_limits<ScalarNumber>::min());
60
61 const Number denominator =
62 ScalarNumber(1.) /
63 std::max(regularization, std::abs(u_P) + eps * u_max);
64
65 t_r = dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
66 u_max,
67 u_U + t_r * u_P,
68 /*
69 * u_P is positive.
70 *
71 * Note: Do not take an absolute value here. If we are out of
72 * bounds we have to ensure that t_r is set to t_min.
73 */
74 (u_max - u_U) * denominator,
75 t_r);
76
77 t_r = dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
78 u_U + t_r * u_P,
79 u_min,
80 /*
81 * u_P is negative.
82 *
83 * Note: Do not take an absolute value here. If we are out of
84 * bounds we have to ensure that t_r is set to t_min.
85 */
86 (u_U - u_min) * denominator,
87 t_r);
88
89 /*
90 * Ensure that t_min <= t <= t_max. This might not be the case if
91 * u_U is outside the interval [u_min, u_max]. Furthermore,
92 * the quotient we take above is prone to numerical cancellation in
93 * particular in the second pass of the limiter when u_P might be
94 * small.
95 */
96 t_r = std::min(t_r, t_max);
97 t_r = std::max(t_r, t_min);
98
99#ifdef DEBUG_EXPENSIVE_BOUNDS_CHECK
100 /*
101 * Verify that the new state is within bounds:
102 *
103 * u_min, u_U, u_max might be negative, thus relax in both directions.
104 */
105 const auto u_new = view_.state(U + t_r * P);
106 const auto test_new_max = std::max(
107 Number(0.), std::min(u_new - relax * u_max, relax * u_new - u_max));
108 const auto test_new_min = std::max(
109 Number(0.), std::min(u_min - relax * u_new, relax * u_min - u_new));
110 if (!(test_new_max == Number(0.) && test_new_min == Number(0.))) {
111#ifdef DEBUG_OUTPUT
112 std::cout << std::fixed << std::setprecision(16);
113 std::cout << "Bounds violation: high-order state!"
114 << "\n\t\tu min: " << u_min
115 << "\n\t\tu min (delta): " << negative_part(u_new - u_min)
116 << "\n\t\tu: " << u_new
117 << "\n\t\tu max (delta): " << positive_part(u_new - u_max)
118 << "\n\t\tu max: " << u_max << "\n"
119 << std::endl;
120#endif
121 success = false;
122 }
123#endif
124
125 return {t_r, success};
126 }
127
128 } // namespace ScalarConservation
129} // namespace ryujin
typename View::state_type state_type
Definition limiter.h:129
std::array< Number, n_bounds > Bounds
Definition limiter.h:151
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
typename View::ScalarNumber ScalarNumber
Definition limiter.h:125
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number positive_part(const Number number)
Definition simd.h:149
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number negative_part(const Number number)
Definition simd.h:161