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