ryujin 2.1.1 revision ee5cbcbf2346c1299c942d0e1f13b46449973c18
Loading...
Searching...
No Matches
wave_speed_estimator.template.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0
3// [LANL Copyright Statement]
4// Copyright (C) 2022 - 2024 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
13
14#include <newton.h>
15#include <simd.h>
16
17// #define DEBUG_WAVE_SPEED_ESTIMATOR
18
19namespace ryujin
20{
21 namespace ShallowWater
22 {
23 using namespace dealii;
24
25
26 template <int dim, typename Number>
28 const primitive_type &riemann_data_i,
29 const primitive_type &riemann_data_j) const
30 {
31 const Number h_star = compute_h_star(riemann_data_i, riemann_data_j);
32
33 const Number lambda_max =
34 compute_lambda(riemann_data_i, riemann_data_j, h_star);
35
36 return lambda_max;
37 }
38
39
40 template <int dim, typename Number>
42 const PrecomputedVectorView & /*pv*/,
43 const state_type &U_i,
44 const state_type &U_j,
45 const unsigned int /*i*/,
46 const unsigned int * /*js*/,
47 const dealii::Tensor<1, dim, Number> &n_ij) const
48 {
49 const auto riemann_data_i = riemann_data_from_state(U_i, n_ij);
50 const auto riemann_data_j = riemann_data_from_state(U_j, n_ij);
51 return compute(riemann_data_i, riemann_data_j);
52 }
53
54
55 template <int dim, typename Number>
56 DEAL_II_ALWAYS_INLINE inline Number
58 const Number &h) const
59 {
60 const ScalarNumber gravity = view_.gravity();
61
62 const auto &[h_Z, u_Z, a_Z] = riemann_data_Z;
63
64 const auto left_value = ScalarNumber(2.) * (std::sqrt(gravity * h) - a_Z);
65
66 const Number radicand =
67 ScalarNumber(0.5) * gravity * (h + h_Z) / (h * h_Z);
68 const Number right_value = (h - h_Z) * std::sqrt(radicand);
69
70 return dealii::compare_and_apply_mask<
71 dealii::SIMDComparison::less_than_or_equal>(
72 h, h_Z, left_value, right_value);
73 }
74
75
76 template <int dim, typename Number>
77 DEAL_II_ALWAYS_INLINE inline Number
79 const primitive_type &riemann_data_i,
80 const primitive_type &riemann_data_j,
81 const Number &h) const
82 {
83 const Number &u_i = riemann_data_i[1];
84 const Number &u_j = riemann_data_j[1];
85
86#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
87 std::cout << "f_L --> " << f(riemann_data_i, h) << std::endl;
88 std::cout << "f_R --> " << f(riemann_data_j, h) << std::endl;
89#endif
90 return f(riemann_data_i, h) + f(riemann_data_j, h) + u_j - u_i;
91 }
92
93
94 template <int dim, typename Number>
95 DEAL_II_ALWAYS_INLINE inline Number
97 const primitive_type &riemann_data, const Number h_star) const
98 {
99 const auto &[h, u, a] = riemann_data;
100
101 const Number factor = positive_part((h_star - h) / h);
102 const Number half_factor = ScalarNumber(0.5) * factor;
103
104 return u - a * std::sqrt((ScalarNumber(1.) + half_factor) *
105 (ScalarNumber(1.) + factor));
106 }
107
108
109 template <int dim, typename Number>
110 DEAL_II_ALWAYS_INLINE inline Number
112 const primitive_type &riemann_data, const Number h_star) const
113 {
114 const auto &[h, u, a] = riemann_data;
115
116 const Number factor = positive_part((h_star - h) / h);
117 const Number half_factor = ScalarNumber(0.5) * factor;
118
119 return u + a * std::sqrt((ScalarNumber(1.) + half_factor) *
120 (ScalarNumber(1.) + factor));
121 }
122
123
124 template <int dim, typename Number>
125 DEAL_II_ALWAYS_INLINE inline Number
127 const primitive_type &riemann_data_i,
128 const primitive_type &riemann_data_j,
129 const Number h_star) const
130 {
131 const Number lambda1 = lambda1_minus(riemann_data_i, h_star);
132 const Number lambda3 = lambda3_plus(riemann_data_j, h_star);
133
134 return std::max(negative_part(lambda1), positive_part(lambda3));
135 }
136
137
138 template <int dim, typename Number>
139 DEAL_II_ALWAYS_INLINE inline Number
141 const primitive_type &riemann_data_i,
142 const primitive_type &riemann_data_j) const
143 {
144 const ScalarNumber gravity = view_.gravity();
145 const auto gravity_inverse = ScalarNumber(1.) / gravity;
146
147 const auto &[h_i, u_i, a_i] = riemann_data_i;
148 const auto &[h_j, u_j, a_j] = riemann_data_j;
149
150 const Number h_min = std::min(h_i, h_j);
151 const Number h_max = std::max(h_i, h_j);
152
153#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
154 std::cout << h_min << " <- h_min/max -> " << h_max << std::endl;
155#endif
156
157 const Number a_min = std::sqrt(gravity * h_min);
158 const Number a_max = std::sqrt(gravity * h_max);
159
160#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
161 std::cout << a_min << " <- a_min/max -> " << a_max << std::endl;
162#endif
163
164 const Number sqrt_two = std::sqrt(ScalarNumber(2.));
165
166 /* x0 = (2 sqrt(2) - 1)^2 */
167 const Number x0 = Number(9.) - ScalarNumber(4.) * sqrt_two;
168
169 const Number phi_value_min =
170 phi(riemann_data_i, riemann_data_j, x0 * h_min);
171#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
172 std::cout << "phi_value_min ->" << phi_value_min << std::endl;
173#endif
174
175 const Number phi_value_max =
176 phi(riemann_data_i, riemann_data_j, x0 * h_max);
177#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
178 std::cout << "phi_value_max ->" << phi_value_max << std::endl;
179#endif
180
181 /* We compute the three h_star quantities */
182
183 Number tmp;
184
185 /* Double rarefaction case (h_star left): */
186
187 tmp = positive_part(u_i - u_j + ScalarNumber(2.) * (a_i + a_j));
188 const Number h_star_left =
189 ScalarNumber(0.0625) * gravity_inverse * tmp * tmp;
190
191#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
192 std::cout << "left: " << h_star_left << std::endl;
193#endif
194
195 /* Double modified shock (h_star middle): */
196
197 tmp = Number(1.) + sqrt_two * (u_i - u_j) / (a_min + a_max);
198 const Number h_star_middle = std::sqrt(h_min * h_max) * tmp;
199
200#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
201 std::cout << "middle: " << h_star_middle << std::endl;
202#endif
203
204 /* Expansion and modified shock (h_star right): */
205
206 const auto left_radicand =
207 ScalarNumber(3.) * h_min +
208 ScalarNumber(2.) * sqrt_two * std::sqrt(h_min * h_max);
209
210 const auto right_radicand =
211 sqrt_two * std::sqrt(gravity_inverse * h_min) * (u_i - u_j);
212
213 tmp = std::sqrt(positive_part(left_radicand + right_radicand));
214 tmp -= sqrt_two * std::sqrt(h_min);
215
216 const Number h_star_right = tmp * tmp;
217
218#ifdef DEBUG_WAVE_SPEED_ESTIMATOR
219 std::cout << "right: " << h_star_right << std::endl;
220#endif
221
222 /* Finally define h_star */
223
224 Number h_star = dealii::compare_and_apply_mask<
225 dealii::SIMDComparison::less_than_or_equal>(
226 Number(0.), phi_value_min, h_star_left, h_star_right);
227
228 h_star =
229 dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
230 phi_value_max, Number(0.), h_star_middle, h_star_right);
231
232 return h_star;
233 }
234
235
236 template <int dim, typename Number>
237 DEAL_II_ALWAYS_INLINE inline auto
239 const state_type &U, const dealii::Tensor<1, dim, Number> &n_ij) const
241 {
242 const Number h = view_.water_depth_sharp(U);
243 const Number gravity = view_.gravity();
244
245 const auto velocity = view_.momentum(U) / h;
246 const auto projected_velocity = n_ij * velocity;
247 const auto a = std::sqrt(h * gravity);
248
249 return {{h, projected_velocity, a}};
250 }
251
252 } // namespace ShallowWater
253} // namespace ryujin
typename View::PrecomputedVectorView PrecomputedVectorView
Number compute(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
primitive_type riemann_data_from_state(const state_type &U, const dealii::Tensor< 1, dim, Number > &n_ij) const
Number compute_h_star(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j) const
Number compute_lambda(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number h_star) const
Number f(const primitive_type &primitive_state, const Number &h_star) const
Number lambda1_minus(const primitive_type &riemann_data, const Number h_star) const
Number phi(const primitive_type &riemann_data_i, const primitive_type &riemann_data_j, const Number &h) const
typename std::array< Number, riemann_data_size > primitive_type
Number lambda3_plus(const primitive_type &riemann_data, const Number h_star) const
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