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