ryujin 2.1.1 revision 9dcb748690310d6a540ebb8b066d1a0834fc7604
limiter.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: MIT
3// Copyright (C) 2020 - 2023 by the ryujin authors
4//
5
6#pragma once
7
8#include "hyperbolic_system.h"
9
10#include <compile_time_options.h>
12#include <newton.h>
13#include <simd.h>
14
15namespace ryujin
16{
17 namespace ShallowWater
18 {
24 template <int dim, typename Number = double>
25 class Limiter
26 {
27 public:
31 static constexpr unsigned int problem_dimension =
32 HyperbolicSystem::problem_dimension<dim>;
33
38
42 static constexpr unsigned int n_precomputed_values =
43 HyperbolicSystem::n_precomputed_values<dim>;
44
49
55
60
80
84 static constexpr unsigned int n_bounds = 3;
85
89 using Bounds = std::array<Number, n_bounds>;
90
94 Limiter(const HyperbolicSystem &hyperbolic_system,
96 &precomputed_values,
97 const ScalarNumber relaxation_factor,
98 const ScalarNumber newton_tolerance,
99 const unsigned int newton_max_iter)
100 : hyperbolic_system(hyperbolic_system)
101 , precomputed_values(precomputed_values)
102 , relaxation_factor(relaxation_factor)
103 , newton_tolerance(newton_tolerance)
104 , newton_max_iter(newton_max_iter)
105 {
106 }
107
111 void reset(const unsigned int i);
112
117 void accumulate(const unsigned int *js,
118 const state_type &U_i,
119 const state_type &U_j,
120 const flux_contribution_type &prec_i,
121 const flux_contribution_type &prec_j,
122 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
123 const Number beta_ij);
124
128 void apply_relaxation(const Number hd_i);
129
133 const Bounds bounds(const Number hd_i) const;
134
135 //*}
138
145 std::tuple<Number, bool> limit(const Bounds &bounds,
146 const state_type &U,
147 const state_type &P,
148 const Number t_min = Number(0.),
149 const Number t_max = Number(1.));
150 //*}
155
162 static bool
163 is_in_invariant_domain(const HyperbolicSystem &hyperbolic_system,
164 const Bounds &bounds,
165 const state_type &U);
166
167 private:
169
171 const HyperbolicSystem &hyperbolic_system;
172
174 &precomputed_values;
175
176 ScalarNumber relaxation_factor;
177 ScalarNumber newton_tolerance;
178 unsigned int newton_max_iter;
179
180 Bounds bounds_;
181
182 /* for relaxation */
183
184 Number h_relaxation_numerator;
185 Number kin_relaxation_numerator;
186 Number relaxation_denominator;
187
189 };
190
191
192 /* Inline definitions */
193
194
195 template <int dim, typename Number>
196 DEAL_II_ALWAYS_INLINE inline void
197 Limiter<dim, Number>::reset(unsigned int /*i*/)
198 {
199 auto &[h_min, h_max, kin_max] = bounds_;
200
201 h_min = Number(std::numeric_limits<ScalarNumber>::max());
202 h_max = Number(0.);
203 kin_max = Number(0.);
204
205 h_relaxation_numerator = Number(0.);
206 kin_relaxation_numerator = Number(0.);
207 relaxation_denominator = Number(0.);
208 }
209
210
211 template <int dim, typename Number>
212 DEAL_II_ALWAYS_INLINE inline void Limiter<dim, Number>::accumulate(
213 const unsigned int * /*js*/,
214 const state_type & /*U_i*/,
215 const state_type & /*U_j*/,
216 const flux_contribution_type &prec_i,
217 const flux_contribution_type &prec_j,
218 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
219 const Number beta_ij)
220 {
221 /* The bar states: */
222
223 const auto &[U_i, Z_i] = prec_i;
224 const auto &[U_j, Z_j] = prec_j;
225 const auto U_star_ij = hyperbolic_system.star_state(U_i, Z_i, Z_j);
226 const auto U_star_ji = hyperbolic_system.star_state(U_j, Z_j, Z_i);
227 const auto f_star_ij = hyperbolic_system.f(U_star_ij);
228 const auto f_star_ji = hyperbolic_system.f(U_star_ji);
229
230 const auto U_ij_bar = ScalarNumber(0.5) *
231 (U_star_ij + U_star_ji +
232 contract(add(f_star_ij, -f_star_ji), scaled_c_ij));
233
234 /* Bounds: */
235
236 auto &[h_min, h_max, kin_max] = bounds_;
237
238 const auto h_bar_ij = hyperbolic_system.water_depth(U_ij_bar);
239 h_min = std::min(h_min, h_bar_ij);
240 h_max = std::max(h_max, h_bar_ij);
241
242 const auto kin_bar_ij = hyperbolic_system.kinetic_energy(U_ij_bar);
243 kin_max = std::max(kin_max, kin_bar_ij);
244
245 /* Relaxation: */
246
247 const auto h_i = hyperbolic_system.water_depth(U_i);
248 const auto h_j = hyperbolic_system.water_depth(U_j);
249 h_relaxation_numerator += beta_ij * (h_i + h_j);
250
251 const auto kin_i = hyperbolic_system.kinetic_energy(U_i);
252 const auto kin_j = hyperbolic_system.kinetic_energy(U_j);
253 kin_relaxation_numerator += beta_ij * (kin_i + kin_j);
254 relaxation_denominator += beta_ij;
255 }
256
257
258 template <int dim, typename Number>
259 DEAL_II_ALWAYS_INLINE inline void
261 {
262 auto &[h_min, h_max, kin_max] = bounds_;
263
264 /* Use r_i = factor * (m_i / |Omega|) ^ (1.5 / d): */
265
266 Number r_i = std::sqrt(hd_i); // in 3D: ^ 3/6
267 if constexpr (dim == 2) //
268 r_i = dealii::Utilities::fixed_power<3>(std::sqrt(r_i)); // in 2D: ^ 3/4
269 else if constexpr (dim == 1) //
270 r_i = dealii::Utilities::fixed_power<3>(r_i); // in 1D: ^ 3/2
271 r_i *= relaxation_factor;
272
273 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
274
275 const Number h_relaxation =
276 std::abs(h_relaxation_numerator) /
277 (std::abs(relaxation_denominator) + Number(eps));
278
279 h_min = std::max((Number(1.) - r_i) * h_min, h_min - h_relaxation);
280 h_max = std::min((Number(1.) + r_i) * h_max, h_max + h_relaxation);
281
282 const Number kin_relaxation =
283 std::abs(kin_relaxation_numerator) /
284 (std::abs(relaxation_denominator) + Number(eps));
285
286 kin_max =
287 std::min((Number(1.) + r_i) * kin_max, kin_max + kin_relaxation);
288 }
289
290
291 template <int dim, typename Number>
292 DEAL_II_ALWAYS_INLINE inline const typename Limiter<dim, Number>::Bounds &
294 {
295 return bounds_;
296 }
297
298
299 template <int dim, typename Number>
300 DEAL_II_ALWAYS_INLINE inline bool
302 const HyperbolicSystem & /*hyperbolic_system*/,
303 const Bounds & /*bounds*/,
304 const state_type & /*U*/)
305 {
306 AssertThrow(false, dealii::ExcNotImplemented());
307 __builtin_trap();
308 return true;
309 }
310
311 } // namespace ShallowWater
312} // namespace ryujin
std::tuple< state_type< dim, Number >, Number > flux_contribution_type
std::array< Number, n_precomputed_values< dim > > precomputed_type
dealii::Tensor< 1, problem_dimension< dim >, Number > state_type
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.))
static constexpr unsigned int problem_dimension
Definition: limiter.h:31
HyperbolicSystem::precomputed_type< dim, Number > precomputed_type
Definition: limiter.h:48
void accumulate(const unsigned int *js, const state_type &U_i, const state_type &U_j, const flux_contribution_type &prec_i, const flux_contribution_type &prec_j, const dealii::Tensor< 1, dim, Number > &scaled_c_ij, const Number beta_ij)
Definition: limiter.h:212
std::array< Number, n_bounds > Bounds
Definition: limiter.h:89
static constexpr unsigned int n_precomputed_values
Definition: limiter.h:42
void reset(const unsigned int i)
Definition: limiter.h:197
typename get_value_type< Number >::type ScalarNumber
Definition: limiter.h:59
static bool is_in_invariant_domain(const HyperbolicSystem &hyperbolic_system, const Bounds &bounds, const state_type &U)
Definition: limiter.h:301
HyperbolicSystem::state_type< dim, Number > state_type
Definition: limiter.h:37
HyperbolicSystem::flux_contribution_type< dim, Number > flux_contribution_type
Definition: limiter.h:54
Limiter(const HyperbolicSystem &hyperbolic_system, const MultiComponentVector< ScalarNumber, n_precomputed_values > &precomputed_values, const ScalarNumber relaxation_factor, const ScalarNumber newton_tolerance, const unsigned int newton_max_iter)
Definition: limiter.h:94
void apply_relaxation(const Number hd_i)
Definition: limiter.h:260
static constexpr unsigned int n_bounds
Definition: limiter.h:84
const Bounds bounds(const Number hd_i) const
DEAL_II_ALWAYS_INLINE FT add(const FT &flux_left_ij, const FT &flux_right_ij)
DEAL_II_ALWAYS_INLINE dealii::Tensor< 1, problem_dim, T > contract(const FT &flux_ij, const TT &c_ij)