ryujin 2.1.1 revision b04fb4aba7bd97ddfa5994a6b4b6e8586eb15db2
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 <compile_time_options.h>
11
12#include "hyperbolic_system.h"
13
14#include <gpu.h>
15#include <observer_pointer.h>
16#include <simd.h>
17
18#include <deal.II/base/point.h>
19#include <deal.II/base/tensor.h>
20
21// #define DEBUG_WAVE_SPEED_ESTIMATOR
22
23namespace ryujin
24{
25 namespace ShallowWater
26 {
27 template <int dim,
28 typename Number = double,
29 typename MemorySpace = dealii::MemorySpace::Host>
30 class WaveSpeedEstimatorView;
31
40 template <typename ScalarNumber = double>
41 class WaveSpeedEstimator : public dealii::ParameterAcceptor
42 {
43 public:
48
52 WaveSpeedEstimator(const HyperbolicSystem &hyperbolic_system,
53 const std::string &subsection = "/WaveSpeedEstimator")
54 : ParameterAcceptor(subsection)
55 , hyperbolic_system_(&hyperbolic_system)
56 {
57 }
58
66 template <int dim,
67 typename Number,
68 typename MemorySpace = dealii::MemorySpace::Host>
69 auto view() const
70 {
72 hyperbolic_system_->template view<dim, Number, MemorySpace>(),
73 *this};
74 }
75
76 private:
78
82
83 dealii::ObserverPointer<const HyperbolicSystem> hyperbolic_system_;
84
85 template <int, typename, typename>
87
89 };
90
91
100 template <int dim, typename Number, typename MemorySpace>
102 {
103 public:
104 static_assert(
105 std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
106 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
107 "Unexpected memory space");
108
113
115
117
118 using state_type = typename View::state_type;
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
163 DEAL_II_HOST_DEVICE Number
165 const state_type &U_i,
166 const state_type &U_j,
167 const unsigned int i,
168 const unsigned int *js,
169 const dealii::Tensor<1, dim, Number> &n_ij) const;
170
171 protected:
173
177
178 DEAL_II_HOST_DEVICE Number f(const primitive_type &primitive_state,
179 const Number &h_star) const;
180
181 DEAL_II_HOST_DEVICE Number phi(const primitive_type &riemann_data_i,
182 const primitive_type &riemann_data_j,
183 const Number &h) const;
184
185 DEAL_II_HOST_DEVICE Number lambda1_minus(
186 const primitive_type &riemann_data, const Number h_star) const;
187
188 DEAL_II_HOST_DEVICE Number lambda3_plus(
189 const primitive_type &riemann_data, const Number h_star) const;
190
191 DEAL_II_HOST_DEVICE Number
192 compute_lambda(const primitive_type &riemann_data_i,
193 const primitive_type &riemann_data_j,
194 const Number h_star) const;
195
196 public:
197 DEAL_II_HOST_DEVICE Number
198 compute_h_star(const primitive_type &riemann_data_i,
199 const primitive_type &riemann_data_j) const;
200
201 protected:
202 DEAL_II_HOST_DEVICE primitive_type
204 const dealii::Tensor<1, dim, Number> &n_ij) const;
205
206 private:
208
212
213 const View view_;
214
216 };
217
218
219 /*
220 * -------------------------------------------------------------------------
221 * Inline definitions
222 * -------------------------------------------------------------------------
223 */
224
225
226 template <int dim, typename Number, typename MemorySpace>
227 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
229 const primitive_type &riemann_data_i,
230 const primitive_type &riemann_data_j) const
231 {
232 const Number h_star = compute_h_star(riemann_data_i, riemann_data_j);
233
234 const Number lambda_max =
235 compute_lambda(riemann_data_i, riemann_data_j, h_star);
236
237 return lambda_max;
238 }
239
240
241 template <int dim, typename Number, typename MemorySpace>
242 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
244 const PrecomputedVectorView & /*pv*/,
245 const state_type &U_i,
246 const state_type &U_j,
247 const unsigned int /*i*/,
248 const unsigned int * /*js*/,
249 const dealii::Tensor<1, dim, Number> &n_ij) const
250 {
251 const auto riemann_data_i = riemann_data_from_state(U_i, n_ij);
252 const auto riemann_data_j = riemann_data_from_state(U_j, n_ij);
253 return compute(riemann_data_i, riemann_data_j);
254 }
255
256
257 template <int dim, typename Number, typename MemorySpace>
258 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
260 const primitive_type &riemann_data_Z, const Number &h) const
261 {
262 const ScalarNumber gravity = view_.gravity();
263
264 const auto &[h_Z, u_Z, a_Z] = riemann_data_Z;
265
266 const auto left_value = ScalarNumber(2.) * (std::sqrt(gravity * h) - a_Z);
267
268 const Number radicand =
269 ScalarNumber(0.5) * gravity * (h + h_Z) / (h * h_Z);
270 const Number right_value = (h - h_Z) * std::sqrt(radicand);
271
273 dealii::SIMDComparison::less_than_or_equal>(
274 h, h_Z, left_value, right_value);
275 }
276
277
278 template <int dim, typename Number, typename MemorySpace>
279 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
281 const primitive_type &riemann_data_i,
282 const primitive_type &riemann_data_j,
283 const Number &h) const
284 {
285 const Number &u_i = riemann_data_i[1];
286 const Number &u_j = riemann_data_j[1];
287
288#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
289 std::cout << "f_L --> " << f(riemann_data_i, h) << std::endl;
290 std::cout << "f_R --> " << f(riemann_data_j, h) << std::endl;
291#endif
292 return f(riemann_data_i, h) + f(riemann_data_j, h) + u_j - u_i;
293 }
294
295
296 template <int dim, typename Number, typename MemorySpace>
297 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
299 const primitive_type &riemann_data, const Number h_star) const
300 {
301 const auto &[h, u, a] = riemann_data;
302
303 const Number factor = positive_part((h_star - h) / h);
304 const Number half_factor = ScalarNumber(0.5) * factor;
305
306 return u - a * std::sqrt((ScalarNumber(1.) + half_factor) *
307 (ScalarNumber(1.) + factor));
308 }
309
310
311 template <int dim, typename Number, typename MemorySpace>
312 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
314 const primitive_type &riemann_data, const Number h_star) const
315 {
316 const auto &[h, u, a] = riemann_data;
317
318 const Number factor = positive_part((h_star - h) / h);
319 const Number half_factor = ScalarNumber(0.5) * factor;
320
321 return u + a * std::sqrt((ScalarNumber(1.) + half_factor) *
322 (ScalarNumber(1.) + factor));
323 }
324
325
326 template <int dim, typename Number, typename MemorySpace>
327 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
329 const primitive_type &riemann_data_i,
330 const primitive_type &riemann_data_j,
331 const Number h_star) const
332 {
333 const Number lambda1 = lambda1_minus(riemann_data_i, h_star);
334 const Number lambda3 = lambda3_plus(riemann_data_j, h_star);
335
336 return std::max(negative_part(lambda1), positive_part(lambda3));
337 }
338
339
340 template <int dim, typename Number, typename MemorySpace>
341 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
343 const primitive_type &riemann_data_i,
344 const primitive_type &riemann_data_j) const
345 {
346 const ScalarNumber gravity = view_.gravity();
347 const auto gravity_inverse = ScalarNumber(1.) / gravity;
348
349 const auto &[h_i, u_i, a_i] = riemann_data_i;
350 const auto &[h_j, u_j, a_j] = riemann_data_j;
351
352 const Number h_min = std::min(h_i, h_j);
353 const Number h_max = std::max(h_i, h_j);
354
355#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
356 std::cout << h_min << " <- h_min/max -> " << h_max << std::endl;
357#endif
358
359 const Number a_min = std::sqrt(gravity * h_min);
360 const Number a_max = std::sqrt(gravity * h_max);
361
362#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
363 std::cout << a_min << " <- a_min/max -> " << a_max << std::endl;
364#endif
365
366 const Number sqrt_two = std::sqrt(ScalarNumber(2.));
367
368 /* x0 = (2 sqrt(2) - 1)^2 */
369 const Number x0 = Number(9.) - ScalarNumber(4.) * sqrt_two;
370
371 const Number phi_value_min =
372 phi(riemann_data_i, riemann_data_j, x0 * h_min);
373#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
374 std::cout << "phi_value_min ->" << phi_value_min << std::endl;
375#endif
376
377 const Number phi_value_max =
378 phi(riemann_data_i, riemann_data_j, x0 * h_max);
379#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
380 std::cout << "phi_value_max ->" << phi_value_max << std::endl;
381#endif
382
383 /* We compute the three h_star quantities */
384
385 Number tmp;
386
387 /* Double rarefaction case (h_star left): */
388
389 tmp = positive_part(u_i - u_j + ScalarNumber(2.) * (a_i + a_j));
390 const Number h_star_left =
391 ScalarNumber(0.0625) * gravity_inverse * tmp * tmp;
392
393#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
394 std::cout << "left: " << h_star_left << std::endl;
395#endif
396
397 /* Double modified shock (h_star middle): */
398
399 tmp = Number(1.) + sqrt_two * (u_i - u_j) / (a_min + a_max);
400 const Number h_star_middle = std::sqrt(h_min * h_max) * tmp;
401
402#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
403 std::cout << "middle: " << h_star_middle << std::endl;
404#endif
405
406 /* Expansion and modified shock (h_star right): */
407
408 const auto left_radicand =
409 ScalarNumber(3.) * h_min +
410 ScalarNumber(2.) * sqrt_two * std::sqrt(h_min * h_max);
411
412 const auto right_radicand =
413 sqrt_two * std::sqrt(gravity_inverse * h_min) * (u_i - u_j);
414
415 tmp = std::sqrt(positive_part(left_radicand + right_radicand));
416 tmp -= sqrt_two * std::sqrt(h_min);
417
418 const Number h_star_right = tmp * tmp;
419
420#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
421 std::cout << "right: " << h_star_right << std::endl;
422#endif
423
424 /* Finally define h_star */
425
426 Number h_star = ryujin::compare_and_apply_mask<
427 dealii::SIMDComparison::less_than_or_equal>(
428 Number(0.), phi_value_min, h_star_left, h_star_right);
429
430 h_star =
431 ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
432 phi_value_max, Number(0.), h_star_middle, h_star);
433
434 return h_star;
435 }
436
437
438 template <int dim, typename Number, typename MemorySpace>
439 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
441 const state_type &U, const dealii::Tensor<1, dim, Number> &n_ij) const
443 {
444 const Number h = view_.water_depth_sharp(U);
445 const Number gravity = view_.gravity();
446
447 const auto velocity = view_.momentum(U) / h;
448 const auto projected_velocity = n_ij * velocity;
449 const auto a = std::sqrt(h * gravity);
450
451 return {{h, projected_velocity, a}};
452 }
453 } // namespace ShallowWater
454} // namespace ryujin
typename get_value_type< Number >::type ScalarNumber
dealii::Tensor< 1, problem_dimension, Number > state_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
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 primitive_type riemann_data_from_state(const state_type &U, const dealii::Tensor< 1, dim, Number > &n_ij) 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