ryujin 2.1.1 revision 0348cbb53a3e4b1da2a4c037e81f88f2d21ce219
initial_state_icf_like.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// [LANL Copyright Statement]
4// Copyright (C) 2024 by the ryujin authors
5// Copyright (C) 2024 by Triad National Security, LLC
6//
7
8#pragma once
9
11
12namespace ryujin
13{
14 namespace EulerInitialStates
15 {
27 template <typename Description, int dim, typename Number>
28 class ICFLike : public InitialState<Description, dim, Number>
29 {
30 public:
32 using View =
33 typename Description::template HyperbolicSystemView<dim, Number>;
34 using state_type = typename View::state_type;
35
36 ICFLike(const HyperbolicSystem &hyperbolic_system,
37 const std::string subsection)
38 : InitialState<Description, dim, Number>("icf like", subsection)
39 , hyperbolic_system_(hyperbolic_system)
40 {
41 gamma_ = 1.4;
42 if constexpr (!View::have_gamma) {
43 this->add_parameter("gamma", gamma_, "The ratio of specific heats");
44 }
45
46 primitive_inside_[0] = 0.1;
47 primitive_inside_[1] = 0.0;
48 primitive_inside_[2] = 1.0;
49 this->add_parameter(
50 "primitive state inside",
51 primitive_inside_,
52 "Initial primitive state (rho, u, p) inside perturbed interface");
53
54 primitive_outside_[0] = 1.0;
55 primitive_outside_[1] = 0.0;
56 primitive_outside_[2] = 1.0;
57 this->add_parameter(
58 "primitive state outside",
59 primitive_outside_,
60 "Initial primitive state (rho, u, p) outside perturbed interface");
61
62 interface_radius_ = 1.0;
63 this->add_parameter(
64 "interface radius", interface_radius_, "Radius of interface");
65
66 num_modes_ = 8.0;
67 this->add_parameter("number of modes",
68 num_modes_,
69 "Number of modes for pertburation of interface");
70
71 amplitude_ = 0.02;
72 this->add_parameter(
73 "amplitude", amplitude_, "Amplitude for interface pertburation");
74
75 mach_number_ = 3.0;
76 this->add_parameter(
77 "mach number", mach_number_, "Mach number of incoming shock front");
78
79 shock_radius_ = 1.2;
80 this->add_parameter("shock radius",
81 shock_radius_,
82 "Radial location of incoming shock front");
83
84 const auto convert_states = [&]() {
85 const auto view = hyperbolic_system_.template view<dim, Number>();
86 state_inside_ = view.from_initial_state(primitive_inside_);
87 state_outside_ = view.from_initial_state(primitive_outside_);
88 };
89 this->parse_parameters_call_back.connect(convert_states);
90 convert_states();
91 };
92
93 state_type compute(const dealii::Point<dim> &point, Number) final
94 {
95 const auto view = hyperbolic_system_.template view<dim, Number>();
96
97 /* Compute incoming shock state */
98 state_type conserved_shock_state;
99 const auto r_hat = point / point.norm();
100 {
101 auto b = Number(0.);
102 if constexpr (View::have_eos_interpolation_b)
103 b = view.eos_interpolation_b();
104
105 const auto &rho_R = primitive_outside_[0];
106 const auto &u_R = primitive_outside_[1];
107 const auto &p_R = primitive_outside_[2];
108 /* a_R^2 = gamma * p / rho / (1 - b * rho) */
109 const Number a_R = std::sqrt(gamma_ * p_R / rho_R / (1 - b * rho_R));
110 const Number mach_R = u_R / a_R;
111
112 auto S3_ = mach_number_ * a_R;
113 const Number delta_mach = mach_R - mach_number_;
114
115 const Number rho_L =
116 rho_R * (gamma_ + Number(1.)) * delta_mach * delta_mach /
117 ((gamma_ - Number(1.)) * delta_mach * delta_mach + Number(2.));
118 const Number u_L =
119 (Number(1.) - rho_R / rho_L) * S3_ + rho_R / rho_L * u_R;
120 const Number p_L = p_R *
121 (Number(2.) * gamma_ * delta_mach * delta_mach -
122 (gamma_ - Number(1.))) /
123 (gamma_ + Number(1.));
124
125 state_type primitive_shock_state;
126 primitive_shock_state[0] = rho_L;
127
128 for (unsigned int i = 0; i < dim; ++i) {
129 primitive_shock_state[i + 1] = 0.;
130 }
131
132 if (point.norm() > 0.) {
133 for (unsigned int i = 0; i < dim; ++i) {
134 primitive_shock_state[i + 1] = -u_L * r_hat[i];
135 }
136 }
137 primitive_shock_state[1 + dim] = p_L;
138
139 conserved_shock_state =
140 view.from_initial_state(primitive_shock_state);
141 }
142
143 /* Compute polar (and potentially azimuthal) angle */
144 const auto x = point[0];
145 const auto y = dim > 1 ? point[1] : 0.;
146
147 const double theta = std::atan2(y, x);
148
149 double phi = 0.;
150 if constexpr (dim == 3)
151 phi = std::atan2(point[2], std::sqrt(x * x + y * y));
152
153 /* Compute perturbation for interface */
154 const auto omega = num_modes_;
155 const double perturbation =
156 amplitude_ * std::cos(omega * theta) * std::cos(omega * phi);
157
158 /* Compute state depending on location */
159 auto full_state =
160 (point.norm() > interface_radius_ + perturbation ? state_outside_
161 : state_inside_);
162
163 if (point.norm() > shock_radius_) {
164 full_state = conserved_shock_state;
165 }
166
167 /* Set final state */
168 return full_state;
169 }
170
171 private:
172 const HyperbolicSystem &hyperbolic_system_;
173
174 Number gamma_;
175
176 dealii::Tensor<1, 3, Number> primitive_inside_;
177 dealii::Tensor<1, 3, Number> primitive_outside_;
178 state_type state_inside_;
179 state_type state_outside_;
180
181 double interface_radius_;
182 double num_modes_;
183 double amplitude_;
184 double shock_radius_;
185 double mach_number_;
186 };
187
188
189 } // namespace EulerInitialStates
190} // namespace ryujin
ICFLike(const HyperbolicSystem &hyperbolic_system, const std::string subsection)
state_type compute(const dealii::Point< dim > &point, Number) final
typename Description::HyperbolicSystem HyperbolicSystem
typename Description::template HyperbolicSystemView< dim, Number > View
Euler::HyperbolicSystem HyperbolicSystem
Definition: description.h:32