ryujin 2.1.1 revision b04fb4aba7bd97ddfa5994a6b4b6e8586eb15db2
Loading...
Searching...
No Matches
initial_state_exact_riemann_solution.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2025 - 2026 by the ryujin authors
4// Copyright (C) 2025 by Triad National Security, LLC
5//
6
7#pragma once
8
9#include <compile_time_options.h>
10
12
13#include "../euler_aeos/nasg_riemann_solver.h"
14
15#include <deal.II/base/tensor.h>
16
17namespace ryujin
18{
19 namespace EulerInitialStates
20 {
46 template <typename Description, int dim, typename Number>
47 class ExactRiemannSolution : public InitialState<Description, dim, Number>
48 {
49 public:
54
55 using HyperbolicSystem = typename Description::HyperbolicSystem;
56 using View = typename HyperbolicSystem::template View<dim, Number>;
57 using state_type = typename View::state_type;
58
59 using ScalarNumber = typename View::ScalarNumber;
60
68 riemann_solver_options{.covolume = View::have_covolume_constant,
69 .pinf = View::have_covolume_constant,
70 .safe_division = true,
71 .variable_gamma = false};
72
78
79
80 ExactRiemannSolution(const HyperbolicSystem &hyperbolic_system,
81 const std::string subsection)
82 : InitialState<Description, dim, Number>("exact riemann solution",
83 subsection)
84 , hyperbolic_system_(hyperbolic_system)
85 , riemann_solver_(subsection +
86 "/exact riemann solution/riemann solver")
87 {
88 gamma_ = 1.4;
89 if constexpr (!View::have_gamma) {
90 this->add_parameter("gamma", gamma_, "The ratio of specific heats");
91 }
92
93 primitive_left_[0] = 1.4;
94 primitive_left_[1] = 0.0;
95 primitive_left_[2] = 1.0;
96 this->add_parameter("primitive state left",
97 primitive_left_,
98 "1d primitive state [rho, u, p] on the left");
99
100 primitive_right_[0] = 1.4;
101 primitive_right_[1] = 0.0;
102 primitive_right_[2] = 1.0;
103 this->add_parameter("primitive state right",
104 primitive_right_,
105 "1d primitive state [rho, u, p] on the right");
106
107 // Convert the primitive states to a full Riemann solution:
108 const auto prepare_riemann_data = [&]() {
109 const auto view = hyperbolic_system_.template view<dim, Number>();
110 if constexpr (View::have_gamma) {
111 gamma_ = view.gamma();
112 }
113
114 riemann_solver_.set_gamma(gamma_);
115
116 if constexpr (View::have_covolume_constant) {
117 riemann_solver_.set_equation_of_state(
118 view.eos_covolume_constant(),
119 view.eos_interpolation_pinfty(),
120 /*compute_expensive_bounds*/ false);
121 }
122
123 const auto riemann_solver_view =
124 riemann_solver_.template view<Number>();
125
126 riemann_data_left_ =
127 expand_state(riemann_solver_view, primitive_left_);
128 riemann_data_right_ =
129 expand_state(riemann_solver_view, primitive_right_);
130
131 riemann_solution_ = riemann_solver_view.solve(riemann_data_left_,
132 riemann_data_right_);
133 };
134
135 this->parse_parameters_call_back.connect(prepare_riemann_data);
136 prepare_riemann_data();
137 }
138
139
140 state_type compute(const dealii::Point<dim> &point, Number t) final
141 {
142 const auto view = hyperbolic_system_.template view<dim, Number>();
143
144 const double &x = point[0];
145
146 dealii::Tensor<1, 3, Number> primitive_state;
147
148 if (t < 1.e-14 && x < 0.) {
149 /* Left state: */
150 primitive_state = primitive_left_;
151
152 } else if (t < 1.e-14 && x > 0.) {
153 /* Right state: */
154 primitive_state = primitive_right_;
155
156 } else {
157 const Number xi = x / t;
158
159 const auto riemann_solver_view =
160 riemann_solver_.template view<Number>();
161 const auto sampled =
162 riemann_solver_view.sample(riemann_solution_, xi);
163
164 for (unsigned int i = 0; i < 3; ++i)
165 primitive_state[i] = sampled[i];
166 }
167
168 using state_type_1d =
169 typename HyperbolicSystem::template View<1, Number>::state_type;
170 static_assert(state_type_1d::dimension <=
171 dealii::Tensor<1, 3, Number>::dimension);
172
173 state_type_1d result;
174 for (unsigned int i = 0; i < state_type_1d::dimension; ++i)
175 result[i] = primitive_state[i];
176 return view.from_initial_state(result);
177 }
178
179 private:
181
185
186 Number gamma_;
187
188 dealii::Tensor<1, 3, Number> primitive_left_;
189 dealii::Tensor<1, 3, Number> primitive_right_;
190
192
196
197 const HyperbolicSystem &hyperbolic_system_;
198
199 RiemannSolver riemann_solver_;
200
201 primitive_type riemann_data_left_;
202 primitive_type riemann_data_right_;
203 typename RiemannSolverView::RiemannSolution riemann_solution_;
204
206
210
217 expand_state(const RiemannSolverView &riemann_solver_view,
218 const dealii::Tensor<1, 3, Number> &primitive_state) const
219 {
220 primitive_type result;
221 result[0] = primitive_state[0];
222 result[1] = primitive_state[1];
223 result[2] = primitive_state[2];
224 result[3] = gamma_;
225 result[4] =
226 riemann_solver_view.speed_of_sound(result[0], result[2], result[3]);
227 return result;
228 }
229
231 };
232 } // namespace EulerInitialStates
233} // namespace ryujin
std::array< Number, riemann_data_size > primitive_type
void set_equation_of_state(const double covolume_b, const double pinf, const bool compute_expensive_bounds)
EulerAEOS::NASGRiemannSolver< ScalarNumber, riemann_solver_options > RiemannSolver
typename HyperbolicSystem::template View< dim, Number > View
EulerAEOS::NASGRiemannSolverView< Number, riemann_solver_options > RiemannSolverView
ExactRiemannSolution(const HyperbolicSystem &hyperbolic_system, const std::string subsection)
state_type compute(const dealii::Point< dim > &point, Number t) final
static constexpr EulerAEOS::NASGRiemannSolverOptions riemann_solver_options