ryujin 2.5.0 revision c64172211cf21344cb9b9b0f3a1266aa6400d392
Loading...
Searching...
No Matches
wave_speed_estimator.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 <ryujin/base/compile_time_options.h>
11#include <ryujin/base/gpu.h>
13#include <ryujin/base/simd.h>
15
16#include <deal.II/base/point.h>
17#include <deal.II/base/tensor.h>
18
19// #define DEBUG_WAVE_SPEED_ESTIMATOR
20
21namespace ryujin
22{
23 namespace ShallowWater
24 {
25 template <int dim,
26 typename Number = double,
27 typename MemorySpace = dealii::MemorySpace::Host>
28 class WaveSpeedEstimatorView;
29
38 template <typename ScalarNumber = double>
39 class WaveSpeedEstimator : public dealii::ParameterAcceptor
40 {
41 public:
46
50 WaveSpeedEstimator(const HyperbolicSystem &hyperbolic_system,
51 const std::string &subsection = "/WaveSpeedEstimator")
52 : ParameterAcceptor(subsection)
53 , hyperbolic_system_(&hyperbolic_system)
54 {
55 }
56
64 template <int dim,
65 typename Number,
66 typename MemorySpace = dealii::MemorySpace::Host>
67 auto view() const
68 {
70 hyperbolic_system_->template view<dim, Number, MemorySpace>(),
71 *this};
72 }
73
74 private:
76
80
81 dealii::ObserverPointer<const HyperbolicSystem> hyperbolic_system_;
82
83 template <int, typename, typename>
85
87 };
88
89
98 template <int dim, typename Number, typename MemorySpace>
100 {
101 public:
102 static_assert(
103 std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
104 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
105 "Unexpected memory space");
106
111
113
115
116 using state_type = typename View::state_type;
117
119
124 static constexpr unsigned int riemann_data_size = 3;
125
130 using primitive_type = typename std::array<Number, riemann_data_size>;
131
133
135
139
145 const WaveSpeedEstimator<ScalarNumber> & /*wse*/)
146 : view_(view)
147 {
148 }
149
155 DEAL_II_HOST_DEVICE Number
156 compute(const primitive_type &riemann_data_i,
157 const primitive_type &riemann_data_j) const;
158
165 DEAL_II_HOST_DEVICE Number
167 const unsigned int i,
168 const unsigned int *js,
169 const state_type &U_i,
170 const state_type &U_j,
171 const flux_contribution_type &flux_i,
172 const flux_contribution_type &flux_j,
173 const dealii::Tensor<1, dim, Number> &n_ij) const;
174
175 protected:
177
181
182 DEAL_II_HOST_DEVICE Number f(const primitive_type &primitive_state,
183 const Number &h_star) const;
184
185 DEAL_II_HOST_DEVICE Number phi(const primitive_type &riemann_data_i,
186 const primitive_type &riemann_data_j,
187 const Number &h) const;
188
189 DEAL_II_HOST_DEVICE Number lambda1_minus(
190 const primitive_type &riemann_data, const Number h_star) const;
191
192 DEAL_II_HOST_DEVICE Number lambda3_plus(
193 const primitive_type &riemann_data, const Number h_star) const;
194
195 DEAL_II_HOST_DEVICE Number
196 compute_lambda(const primitive_type &riemann_data_i,
197 const primitive_type &riemann_data_j,
198 const Number h_star) const;
199
200 public:
201 DEAL_II_HOST_DEVICE Number
202 compute_h_star(const primitive_type &riemann_data_i,
203 const primitive_type &riemann_data_j) const;
204
205 private:
207
211
212 const View view_;
213
215 };
216
217
218 /*
219 * -------------------------------------------------------------------------
220 * Inline definitions
221 * -------------------------------------------------------------------------
222 */
223
224
225 template <int dim, typename Number, typename MemorySpace>
226 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
228 const primitive_type &riemann_data_i,
229 const primitive_type &riemann_data_j) const
230 {
231 const Number h_star = compute_h_star(riemann_data_i, riemann_data_j);
232
233 const Number lambda_max =
234 compute_lambda(riemann_data_i, riemann_data_j, h_star);
235
236 return lambda_max;
237 }
238
239
240 template <int dim, typename Number, typename MemorySpace>
241 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
243 const PrecomputedVectorView & /*pv*/,
244 const unsigned int /*i*/,
245 const unsigned int * /*js*/,
246 const state_type & /*U_i*/,
247 const state_type & /*U_j*/,
248 const flux_contribution_type &flux_i,
249 const flux_contribution_type &flux_j,
250 const dealii::Tensor<1, dim, Number> &n_ij) const
251 {
252 const auto &[U_i, Z_i, V_i] = flux_i;
253 const auto &[U_j, Z_j, V_j] = flux_j;
254 const auto &[U_star_ij, U_star_ji] =
255 view_.equilibrated_states(flux_i, flux_j);
256
257 const ScalarNumber gravity = view_.gravity();
258 const Number h_i = view_.water_depth_sharp(U_star_ij);
259 const Number h_j = view_.water_depth_sharp(U_star_ji);
260
261 const primitive_type riemann_data_i{
262 {h_i, V_i * n_ij, std::sqrt(gravity * h_i)}};
263 const primitive_type riemann_data_j{
264 {h_j, V_j * n_ij, std::sqrt(gravity * h_j)}};
265
266 return compute(riemann_data_i, riemann_data_j);
267 }
268
269
270 template <int dim, typename Number, typename MemorySpace>
271 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
273 const primitive_type &riemann_data_Z, const Number &h) const
274 {
275 const ScalarNumber gravity = view_.gravity();
276
277 const auto &[h_Z, u_Z, a_Z] = riemann_data_Z;
278
279 const auto left_value = ScalarNumber(2.) * (std::sqrt(gravity * h) - a_Z);
280
281 const Number radicand =
282 ScalarNumber(0.5) * gravity * (h + h_Z) / (h * h_Z);
283 const Number right_value = (h - h_Z) * std::sqrt(radicand);
284
286 dealii::SIMDComparison::less_than_or_equal>(
287 h, h_Z, left_value, right_value);
288 }
289
290
291 template <int dim, typename Number, typename MemorySpace>
292 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
294 const primitive_type &riemann_data_i,
295 const primitive_type &riemann_data_j,
296 const Number &h) const
297 {
298 const Number &u_i = riemann_data_i[1];
299 const Number &u_j = riemann_data_j[1];
300
301#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
302 std::cout << "f_L --> " << f(riemann_data_i, h) << std::endl;
303 std::cout << "f_R --> " << f(riemann_data_j, h) << std::endl;
304#endif
305 return f(riemann_data_i, h) + f(riemann_data_j, h) + u_j - u_i;
306 }
307
308
309 template <int dim, typename Number, typename MemorySpace>
310 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
312 const primitive_type &riemann_data, const Number h_star) const
313 {
314 const auto &[h, u, a] = riemann_data;
315
316 const Number factor = positive_part((h_star - h) / h);
317 const Number half_factor = ScalarNumber(0.5) * factor;
318
319 return u - a * std::sqrt((ScalarNumber(1.) + half_factor) *
320 (ScalarNumber(1.) + factor));
321 }
322
323
324 template <int dim, typename Number, typename MemorySpace>
325 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
327 const primitive_type &riemann_data, const Number h_star) const
328 {
329 const auto &[h, u, a] = riemann_data;
330
331 const Number factor = positive_part((h_star - h) / h);
332 const Number half_factor = ScalarNumber(0.5) * factor;
333
334 return u + a * std::sqrt((ScalarNumber(1.) + half_factor) *
335 (ScalarNumber(1.) + factor));
336 }
337
338
339 template <int dim, typename Number, typename MemorySpace>
340 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
342 const primitive_type &riemann_data_i,
343 const primitive_type &riemann_data_j,
344 const Number h_star) const
345 {
346 const Number lambda1 = lambda1_minus(riemann_data_i, h_star);
347 const Number lambda3 = lambda3_plus(riemann_data_j, h_star);
348
349 return std::max(negative_part(lambda1), positive_part(lambda3));
350 }
351
352
353 template <int dim, typename Number, typename MemorySpace>
354 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
356 const primitive_type &riemann_data_i,
357 const primitive_type &riemann_data_j) const
358 {
359 const ScalarNumber gravity = view_.gravity();
360 const auto gravity_inverse = ScalarNumber(1.) / gravity;
361
362 const auto &[h_i, u_i, a_i] = riemann_data_i;
363 const auto &[h_j, u_j, a_j] = riemann_data_j;
364
365 const Number h_min = std::min(h_i, h_j);
366 const Number h_max = std::max(h_i, h_j);
367
368#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
369 std::cout << h_min << " <- h_min/max -> " << h_max << std::endl;
370#endif
371
372 const Number a_min = std::min(a_i, a_j);
373 const Number a_max = std::max(a_i, a_j);
374
375#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
376 std::cout << a_min << " <- a_min/max -> " << a_max << std::endl;
377#endif
378
379 const Number sqrt_two = std::sqrt(ScalarNumber(2.));
380
381 /* x0 = (2 sqrt(2) - 1)^2 */
382 const Number x0 = Number(9.) - ScalarNumber(4.) * sqrt_two;
383
384 const Number phi_value_min =
385 phi(riemann_data_i, riemann_data_j, x0 * h_min);
386#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
387 std::cout << "phi_value_min ->" << phi_value_min << std::endl;
388#endif
389
390 const Number phi_value_max =
391 phi(riemann_data_i, riemann_data_j, x0 * h_max);
392#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
393 std::cout << "phi_value_max ->" << phi_value_max << std::endl;
394#endif
395
396 /* We compute the three h_star quantities */
397
398 Number tmp;
399
400 /* Double rarefaction case (h_star left): */
401
402 tmp = positive_part(u_i - u_j + ScalarNumber(2.) * (a_i + a_j));
403 const Number h_star_left =
404 ScalarNumber(0.0625) * gravity_inverse * tmp * tmp;
405
406#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
407 std::cout << "left: " << h_star_left << std::endl;
408#endif
409
410 /* Double modified shock (h_star middle): */
411
412 tmp = Number(1.) + sqrt_two * (u_i - u_j) / (a_min + a_max);
413 const Number h_star_middle = gravity_inverse * a_min * a_max * tmp;
414
415#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
416 std::cout << "middle: " << h_star_middle << std::endl;
417#endif
418
419 /* Expansion and modified shock (h_star right): */
420
421 const auto left_radicand =
422 ScalarNumber(3.) * h_min +
423 ScalarNumber(2.) * sqrt_two * gravity_inverse * a_min * a_max;
424
425 const auto right_radicand =
426 sqrt_two * gravity_inverse * a_min * (u_i - u_j);
427
428 tmp = std::sqrt(positive_part(left_radicand + right_radicand));
429 tmp -= sqrt_two * std::sqrt(gravity_inverse) * a_min;
430
431 const Number h_star_right = tmp * tmp;
432
433#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
434 std::cout << "right: " << h_star_right << std::endl;
435#endif
436
437 /* Finally define h_star */
438
439 Number h_star = ryujin::compare_and_apply_mask<
440 dealii::SIMDComparison::less_than_or_equal>(
441 Number(0.), phi_value_min, h_star_left, h_star_right);
442
443 h_star =
444 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
445 phi_value_max, Number(0.), h_star_middle, h_star);
446
447 return h_star;
448 }
449 } // namespace ShallowWater
450} // namespace ryujin
typename get_value_type< Number >::type ScalarNumber
dealii::Tensor< 1, problem_dimension, Number > state_type
std::tuple< state_type, Number, dealii::Tensor< 1, dim, Number > > flux_contribution_type
VectorView< n_precomputed_values > PrecomputedVectorView
DEAL_II_HOST_DEVICE Number phi(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number &h) const
DEAL_II_HOST_DEVICE Number lambda3_plus(const primitive_type &riemann_data, const Number h_star) const
WaveSpeedEstimatorView(const View &view, const WaveSpeedEstimator< ScalarNumber > &)
DEAL_II_HOST_DEVICE Number compute_h_star(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
typename View::PrecomputedVectorView PrecomputedVectorView
typename std::array< Number, riemann_data_size > primitive_type
typename View::flux_contribution_type flux_contribution_type
HyperbolicSystemView< dim, Number, MemorySpace > View
DEAL_II_HOST_DEVICE Number compute_lambda(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number h_star) const
DEAL_II_HOST_DEVICE Number compute(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
DEAL_II_HOST_DEVICE Number f(const primitive_type &primitive_state, const Number &h_star) const
DEAL_II_HOST_DEVICE Number lambda1_minus(const primitive_type &riemann_data, const Number h_star) const
WaveSpeedEstimator(const HyperbolicSystem &hyperbolic_system, const std::string &subsection="/WaveSpeedEstimator")
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