ryujin 2.1.1 revision 336b16a72e829721302c626ec7071b92032b8248
initial_state_transient.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0
3// [LANL Copyright Statement]
4// Copyright (C) 2024 by the ryujin authors
5// Copyright (C) 2023 - 2024 by Triad National Security, LLC
6//
7
8#pragma once
9
11
12namespace ryujin
13{
14 namespace ShallowWaterInitialStates
15 {
21 template <typename Description, int dim, typename Number>
22 class TankExperiments : public InitialState<Description, dim, Number>
23 {
24 public:
26 using View =
27 typename Description::template HyperbolicSystemView<dim, Number>;
28 using state_type = typename View::state_type;
29
30 TankExperiments(const HyperbolicSystem &hyperbolic_system,
31 const std::string subsection)
32 : InitialState<Description, dim, Number>("transient experiments",
33 subsection)
34 , hyperbolic_system_(hyperbolic_system)
35 {
36 dealii::ParameterAcceptor::parse_parameters_call_back.connect(
38
39 state_left_[0] = 1.;
40 state_left_[1] = 0.0;
41 this->add_parameter("flow state left",
42 state_left_,
43 "Initial 1d flow state (h, q) on the left");
44
45 state_right_[0] = 1.;
46 state_right_[1] = 0.0;
47 this->add_parameter("flow state right",
48 state_right_,
49 "Initial 1d flow state (h, q) on the right");
50
51 which_case_ = "G1";
52 this->add_parameter("experimental configuration",
53 which_case_,
54 "Either 'G1', 'G2', 'G3' or 'none' for bathymetry "
55 "configuration");
56 }
57
59 {
60 AssertThrow(
61 which_case_ == "G1" || which_case_ == "G2" || which_case_ == "G3" ||
62 which_case_ == "none",
63 dealii::ExcMessage("Case must be 'G1', 'G2', 'G3' or 'none'"));
64 }
65
66 state_type compute(const dealii::Point<dim> &point, Number /* t */) final
67 {
68 const auto view = hyperbolic_system_.template view<dim, Number>();
69
70 if constexpr (dim == 1) {
71 AssertThrow(false, dealii::ExcNotImplemented());
72 __builtin_trap();
73 }
74
75 const auto temp = point[0] > 1.e-8 ? state_right_ : state_left_;
76 return view.expand_state(temp);
77 }
78
79 auto initial_precomputations(const dealii::Point<dim> &point) ->
81 initial_precomputed_type final
82 {
83 /* Compute bathymetry: */
84 return {compute_bathymetry(point)};
85 }
86
87 private:
88 const HyperbolicSystem &hyperbolic_system_;
89
90 DEAL_II_ALWAYS_INLINE
91 inline Number compute_bathymetry(const dealii::Point<dim> &point) const
92 {
93 const auto &x = point[0], &y = point[1];
94
95 /* Bathymetry base is the same for all configurations */
96 Number bath = 0.;
97 if (x >= 0. && x <= 326. / 100.)
98 bath = -0.00092 * x;
99 else if (x > 326. / 100.)
100 bath = -0.0404 * (x - 326. / 100.) - 0.00092 * 326. / 100.;
101
102 if (which_case_ == "none")
103 return bath;
104
105 /* Initialize obstacle to 0 */
106 Number obstacle = 0.;
107
108
109 // G1 -- rectangular obstacle
110 if (which_case_ == "G1") {
111
112 Number obstacle_length = 16.3 / 100.;
113 Number obstacle_width = 8. / 100.;
114
115 Number xc = 205. / 100. + (16.3 / 2. / 100.); // obstacle center
116
117 if (std::abs((x - xc) / obstacle_length + y / obstacle_width) +
118 std::abs((x - xc) / obstacle_length - y / obstacle_width) <=
119 1.)
120 obstacle = 7. / 100.;
121 } else if (which_case_ == "G2") { // circular bump + rectangle
122
123 // circular bump
124 double xc = 184.5 / 100. + 31. / 2. / 100.;
125 const double radicand =
126 positive_part(1. - std::pow((x - xc) / (31. / 2. / 100.), 2));
127
128 const double semi_circle = 7.3 / 100. * std::sqrt(radicand);
129
130 obstacle = std::max(semi_circle, 0.);
131
132 // rectangular obstacle
133 double obstacle_length = 16.3 / 100.;
134 double obstacle_width = 8. / 100.;
135
136 xc = 235. / 100. + (16.3 / 2. / 100.); // obstacle center
137
138 if (std::abs((x - xc) / obstacle_length + y / obstacle_width) +
139 std::abs((x - xc) / obstacle_length - y / obstacle_width) <=
140 1.)
141 obstacle = 7. / 100.;
142 } else if (which_case_ == "G3") { // narrowing half-circle + rectangle
143
144 // narrowing half-circles canal
145 double xc = 194 / 100. + 31. / 2. / 100.;
146 const double radicand =
147 positive_part(1. - std::pow((x - xc) / (31. / 2. / 100.), 2));
148 const double semi_circle = 7.3 / 100. * std::sqrt(radicand);
149
150 if (y < semi_circle - 24. / 2. / 100. &&
151 std::abs(x - xc) <= 31. / 2. / 100.)
152 obstacle = 21. / 100.;
153
154 if (y > -semi_circle + 24. / 2. / 100. &&
155 std::abs(x - xc) <= 31. / 2. / 100.)
156 obstacle = 21. / 100.;
157
158 // rectangular obstacle
159 double obstacle_length = 16.3 / 100.;
160 double obstacle_width = 8. / 100.;
161
162 xc = 235. / 100. + (16.3 / 2. / 100.); // obstacle center
163
164 if (std::abs((x - xc) / obstacle_length + y / obstacle_width) +
165 std::abs((x - xc) / obstacle_length - y / obstacle_width) <=
166 1.)
167 obstacle = 7. / 100.;
168 }
169
170 return bath + obstacle;
171 }
172
173 dealii::Tensor<1, 2, Number> state_left_;
174 dealii::Tensor<1, 2, Number> state_right_;
175
176 std::string which_case_;
177 std::string flow_type_;
178 };
179
180 } // namespace ShallowWaterInitialStates
181} // namespace ryujin
typename Description::template HyperbolicSystemView< dim, Number > View
auto initial_precomputations(const dealii::Point< dim > &point) -> typename InitialState< Description, dim, Number >::initial_precomputed_type final
TankExperiments(const HyperbolicSystem &hyperbolic_system, const std::string subsection)
state_type compute(const dealii::Point< dim > &point, Number) final
typename Description::HyperbolicSystem HyperbolicSystem
T pow(const T x, const T b)
DEAL_II_ALWAYS_INLINE Number positive_part(const Number number)
Definition: simd.h:112
Euler::HyperbolicSystem HyperbolicSystem
Definition: description.h:32