ryujin 2.1.1 revision ee5cbcbf2346c1299c942d0e1f13b46449973c18
Loading...
Searching...
No Matches
initial_state_becker_solution.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2022 - 2025 by the ryujin authors
4//
5
6#pragma once
7
8#include <compile_time_options.h>
9
11
12namespace ryujin
13{
14 namespace EulerInitialStates
15 {
46 template <typename Description, int dim, typename Number>
47 class BeckerSolution : public InitialState<Description, dim, Number>
48 {
49 public:
51 using View = typename HyperbolicSystem::template View<dim, Number>;
52 using state_type = typename View::state_type;
53
54 BeckerSolution(const HyperbolicSystem &hyperbolic_system,
55 const std::string &subsection)
56 : InitialState<Description, dim, Number>("becker solution",
57 subsection)
58 , hyperbolic_system_(hyperbolic_system)
59 {
60 gamma_ = 1.4;
61 if constexpr (!View::have_gamma) {
62 this->add_parameter("gamma", gamma_, "The ratio of specific heats");
63 }
64
65 velocity_ = 0.2;
66 this->add_parameter("velocity galilean frame",
67 velocity_,
68 "Velocity used to apply a Galilean transformation "
69 "to the otherwise stationary solution");
70
71 velocity_left_ = 1.0;
72 this->add_parameter(
73 "velocity left", velocity_left_, "Left limit velocity");
74
75 velocity_right_ = 7. / 27.;
76 this->add_parameter(
77 "velocity right", velocity_right_, "Right limit velocity");
78
79 density_left_ = 1.0;
80 this->add_parameter(
81 "density left", density_left_, "Left limit density");
82
83 mu_ = 0.01;
84 this->add_parameter("mu", mu_, "Shear viscosity");
85
86 /* Callback: */
87
88 dealii::ParameterAcceptor::parse_parameters_call_back.connect([this]() {
89 const auto view = hyperbolic_system_.template view<dim, Number>();
90
91 if constexpr (View::have_gamma) {
92 gamma_ = view.gamma();
93 }
94
95 AssertThrow(
96 velocity_left_ > velocity_right_,
97 dealii::ExcMessage("The left limiting velocity must be greater "
98 "than the right limiting velocity"));
99
100 AssertThrow(velocity_left_ > 0.,
101 dealii::ExcMessage(
102 "The left limiting velocity must be positive"));
103
104 /*
105 * Set up all helper functions and quantities:
106 */
107
108 const double velocity_origin =
109 std::sqrt(velocity_left_ * velocity_right_);
110
111 /* Prefactor as given in: (7.1) */
112
113 const double Pr = 0.75;
114 const double factor = 2. * gamma_ / (gamma_ + 1.) //
115 * mu_ / (density_left_ * velocity_left_ * Pr);
116
117 psi = [=, this](double x, double v) {
118 const double c_l =
119 velocity_left_ / (velocity_left_ - velocity_right_);
120 const double c_r =
121 velocity_right_ / (velocity_left_ - velocity_right_);
122 const double log_l = std::log(velocity_left_ - v) -
123 std::log(velocity_left_ - velocity_origin);
124 const double log_r = std::log(v - velocity_right_) -
125 std::log(velocity_origin - velocity_right_);
126
127 const double value = factor * (c_l * log_l - c_r * log_r) - x;
128
129 const double derivative = factor * (-c_l / (velocity_left_ - v) -
130 c_r / (v - velocity_right_));
131
132 return std::make_tuple(value, derivative);
133 };
134
135 /* Determine cut-off points: */
136
137 constexpr double tol = 1.e-12;
138
139 const double x_left = std::get<0>(
140 psi(0., (1. - tol) * velocity_left_ + tol * velocity_right_));
141
142 const double x_right = std::get<0>(
143 psi(0., tol * velocity_left_ + (1. - tol) * velocity_right_));
144
145 const double norm = (x_right - x_left) * tol;
146
147 /* Root finding algorithm: */
148
149 find_velocity = [=, this](double x) {
150 /* Return extremal cases: */
151 if (x <= x_left)
152 return double(velocity_left_);
153 if (x >= x_right)
154 return double(velocity_right_);
155
156 /* Interpolate initial guess: */
157 const auto nu =
158 0.5 * std::tanh(10. * (x - 0.5 * (x_right + x_left)) /
159 (x_right - x_left));
160 double v =
161 velocity_left_ * (0.5 - nu) + velocity_right_ * (nu + 0.5);
162
163 auto [f, df] = psi(x, v);
164
165 while (std::abs(f) > norm) {
166 const double v_next = v - f / df;
167
168 /* Also break if we made no progress: */
169 if (std::abs(v_next - v) <
170 tol * 0.5 * (velocity_right_ + velocity_left_)) {
171 v = v_next;
172 break;
173 }
174
175 if (v_next < velocity_right_)
176 v = 0.5 * (velocity_right_ + v);
177 else if (v_next > velocity_left_)
178 v = 0.5 * (velocity_left_ + v);
179 else
180 v = v_next;
181
182 const auto [new_f, new_df] = psi(x, v);
183 f = new_f;
184 df = new_df;
185 }
186
187 return v;
188 }; /* find_velocity */
189 });
190 }
191
192 state_type compute(const dealii::Point<dim> &point, Number t) final
193 {
194 const auto view = hyperbolic_system_.template view<dim, Number>();
195
196 /* (7.2) */
197 const double R_infty = (gamma_ + 1) / (gamma_ - 1);
198
199 /* (7.3) */
200 const double x = point[0] - velocity_ * t;
201 const double v = find_velocity(x);
202 Assert(v >= velocity_right_, dealii::ExcInternalError());
203 Assert(v <= velocity_left_, dealii::ExcInternalError());
204 const double rho = density_left_ * velocity_left_ / v;
205 Assert(rho > 0., dealii::ExcInternalError());
206 const double e = 1. / (2. * gamma_) *
207 (R_infty * velocity_left_ * velocity_right_ - v * v);
208 Assert(e > 0., dealii::ExcInternalError());
209
210 using state_type_1d =
211 typename HyperbolicSystem::template View<1, Number>::state_type;
212
213 state_type_1d result;
214 result[0] = Number(rho);
215 result[1] = Number(rho * (velocity_ + v));
216 if constexpr (View::have_energy_equation)
217 result[2] =
218 Number(rho * (e + 0.5 * (velocity_ + v) * (velocity_ + v)));
219
220 return view.expand_state(result);
221 }
222
223 private:
224 const HyperbolicSystem &hyperbolic_system_;
225 Number gamma_;
226
227 Number velocity_;
228 Number velocity_left_;
229 Number velocity_right_;
230 Number density_left_;
231 Number mu_;
232 std::function<std::tuple<double, double>(double, double)> psi;
233 std::function<double(double)> find_velocity;
234 };
235
236 } // namespace EulerInitialStates
237} // namespace ryujin
state_type compute(const dealii::Point< dim > &point, Number t) final
typename HyperbolicSystem::template View< dim, Number > View
BeckerSolution(const HyperbolicSystem &hyperbolic_system, const std::string &subsection)
typename Description::HyperbolicSystem HyperbolicSystem
Euler::HyperbolicSystem HyperbolicSystem
Definition description.h:34