10#include <compile_time_options.h>
17 namespace ShallowWater
24 template <
int dim,
typename Number =
double>
32 HyperbolicSystem::problem_dimension<dim>;
43 HyperbolicSystem::n_precomputed_values<dim>;
89 using Bounds = std::array<Number, n_bounds>;
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)
111 void reset(
const unsigned int i);
122 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
123 const Number beta_ij);
148 const Number t_min = Number(0.),
149 const Number t_max = Number(1.));
178 unsigned int newton_max_iter;
184 Number h_relaxation_numerator;
185 Number kin_relaxation_numerator;
186 Number relaxation_denominator;
195 template <
int dim,
typename Number>
196 DEAL_II_ALWAYS_INLINE
inline void
199 auto &[h_min, h_max, kin_max] = bounds_;
201 h_min = Number(std::numeric_limits<ScalarNumber>::max());
203 kin_max = Number(0.);
205 h_relaxation_numerator = Number(0.);
206 kin_relaxation_numerator = Number(0.);
207 relaxation_denominator = Number(0.);
211 template <
int dim,
typename Number>
213 const unsigned int * ,
218 const dealii::Tensor<1, dim, Number> &scaled_c_ij,
219 const Number beta_ij)
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);
231 (U_star_ij + U_star_ji +
232 contract(
add(f_star_ij, -f_star_ji), scaled_c_ij));
236 auto &[h_min, h_max, kin_max] = bounds_;
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);
242 const auto kin_bar_ij = hyperbolic_system.kinetic_energy(U_ij_bar);
243 kin_max = std::max(kin_max, kin_bar_ij);
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);
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;
258 template <
int dim,
typename Number>
259 DEAL_II_ALWAYS_INLINE
inline void
262 auto &[h_min, h_max, kin_max] = bounds_;
266 Number r_i = std::sqrt(hd_i);
267 if constexpr (dim == 2)
268 r_i = dealii::Utilities::fixed_power<3>(std::sqrt(r_i));
269 else if constexpr (dim == 1)
270 r_i = dealii::Utilities::fixed_power<3>(r_i);
271 r_i *= relaxation_factor;
273 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
275 const Number h_relaxation =
276 std::abs(h_relaxation_numerator) /
277 (std::abs(relaxation_denominator) + Number(eps));
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);
282 const Number kin_relaxation =
283 std::abs(kin_relaxation_numerator) /
284 (std::abs(relaxation_denominator) + Number(eps));
287 std::min((Number(1.) + r_i) * kin_max, kin_max + kin_relaxation);
291 template <
int dim,
typename Number>
299 template <
int dim,
typename Number>
300 DEAL_II_ALWAYS_INLINE
inline bool
306 AssertThrow(
false, dealii::ExcNotImplemented());
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
HyperbolicSystem::precomputed_type< dim, Number > precomputed_type
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)
std::array< Number, n_bounds > Bounds
static constexpr unsigned int n_precomputed_values
void reset(const unsigned int i)
typename get_value_type< Number >::type ScalarNumber
static bool is_in_invariant_domain(const HyperbolicSystem &hyperbolic_system, const Bounds &bounds, const state_type &U)
HyperbolicSystem::state_type< dim, Number > state_type
HyperbolicSystem::flux_contribution_type< dim, Number > flux_contribution_type
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)
void apply_relaxation(const Number hd_i)
static constexpr unsigned int n_bounds
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)