Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
CPO.hpp
Go to the documentation of this file.
1 // Copyright (c) 2020 Maikel Nadolski
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #ifndef FUB_EQUATINOS_PERFECT_GAS_MIX_CPOS_HPP
22 #define FUB_EQUATINOS_PERFECT_GAS_MIX_CPOS_HPP
23 
24 namespace fub {
25 
26 template <int Rank, typename State>
27 constexpr auto tag_invoke(tag_t<Depths>, const PerfectGasMix<Rank>& eq,
28  Type<State>) noexcept {
29  using Depths = typename State::Traits::template Depths<N>;
30  ToConcreteDepths<Depths> depths{};
31  if constexpr (std::is_same_v<Depths, PerfectGasMixKineticStateShape>) {
32  depths.mole_fractions = eq.n_species + 1;
33  } else {
34  depths.species = eq.n_species;
35  }
36  return depths;
37 }
38 
39 template <typename Density, typename Momentum, typename Energy,
40  typename Species>
41 constexpr auto
44  Species>&) noexcept {
45  if constexpr (std::is_same_v<double, Density>) {
46  return eq.gamma;
47  } else {
48  return Array1d::Constant(eq.gamma);
49  }
50 }
51 
52 template <typename Density, typename Momentum, typename Energy,
53  typename Species>
54 constexpr const Density&
57  q) noexcept {
58  return q.density;
59 }
60 
61 template <typename Density, typename Momentum, typename Energy,
62  typename Species>
63 constexpr auto
66  q) noexcept {
67  return (q.energy - euler::KineticEnergy(q.density, q.momentum)) / q.density;
68 }
69 
70 template <typename Density, typename Temperature, typename MoleFractions>
71 constexpr auto
74  q) noexcept {
75  // Rspec = cp - cv
76  // gamma = cp / cv
77  // cp = cv gamma
78  // Rspec = gamma cv - cv
79  // Rspec = (gamma - 1) cv
80  // Rpsec /(gamma - 1) = cv
81  const double cv = eq.Rspec * eq.gamma_minus_1_inv;
82  return cv * q.temperature;
83 }
84 
86  const PerfectGasMix& eq, Complete& q,
87  const KineticState& kin,
88  const Array<double, N, 1>& u) noexcept {
89  q.density = kin.density;
90  q.momentum = q.density * u;
91  const double e = euler::InternalEnergy(eq, kin);
92  q.energy = q.density * (e + 0.5 * u.matrix().squaredNorm());
93  const double RT = eq.Rspec * kin.temperature;
94  q.pressure = RT * q.density;
95  q.speed_of_sound = std::sqrt(eq.gamma * RT);
96  const double sum = kin.mole_fractions.sum();
97  for (int i = 0; i < eq.n_species; i++) {
98  q.species[i] = q.density * kin.mole_fractions[i] / sum;
99  }
100 }
101 
103  const PerfectGasMix& eq, KineticState& kin,
104  const Complete& q) noexcept {
105  kin.density = q.density;
106  kin.temperature = euler::Temperature(eq, q);
107  double sum = 0.0;
108  for (int i = 0; i < eq.n_species; ++i) {
109  kin.mole_fractions[i] = q.species[i] / q.density;
110  sum += kin.mole_fractions[i];
111  }
112  kin.mole_fractions[eq.n_species] = std::max(0.0, 1.0 - sum);
113 }
114 
115 template <typename Density, typename Momentum, typename Energy,
116  typename Species>
117 constexpr const Momentum&
120  q) noexcept {
121  return q.momentum;
122 }
123 
124 template <typename Density, typename Momentum, typename Energy,
125  typename Species>
126 constexpr decltype(auto) tag_invoke(
127  tag_t<euler::Momentum>, const PerfectGasMix&,
129  int d) noexcept {
130  if constexpr (std::is_same_v<double, Density>) {
131  return q.momentum[d];
132  } else {
133  return q.row(d);
134  }
135 }
136 
137 template <typename Density, typename Momentum, typename Energy,
138  typename Species>
139 constexpr Momentum
142  q) noexcept {
143  if constexpr (std::is_same_v<double, Density>) {
144  return q.momentum / q.density;
145  } else {
147  for (int i = 0; i < N; ++i) {
148  v.row(i) = q.momentum.row(i) / q.density;
149  }
150  return v;
151  }
152 }
153 
154 template <typename Density, typename Momentum, typename Energy,
155  typename Species>
156 constexpr auto tag_invoke(
159  int d) noexcept {
160  if constexpr (std::is_same_v<double, Density>) {
161  return q.momentum[d] / q.density;
162  } else {
163  return q.row(d) / q.density;
164  }
165 }
166 
167 template <typename Density, typename Momentum, typename Energy,
168  typename Species>
169 constexpr const Energy&
172  q) noexcept {
173  return q.energy;
174 }
175 
176 template <typename Density, typename Momentum, typename Energy,
177  typename Species>
178 constexpr const Species&
181  q) noexcept {
182  return q.species;
183 }
184 
185 template <typename Density, typename Velocity, typename Pressure,
186  typename Species>
187 constexpr const Species&
190  q) noexcept {
191  return q.species;
192 }
193 
194 template <typename Density, typename Momentum, typename Energy,
195  typename Species>
196 constexpr decltype(auto) tag_invoke(
197  tag_t<euler::Species>, const PerfectGasMix&,
199  int d) noexcept {
200  if constexpr (std::is_same_v<double, Density>) {
201  return q.species[d];
202  } else {
203  return q.species.row(d);
204  }
205 }
206 
207 template <typename Density, typename Momentum, typename Energy,
208  typename Species, typename Pressure, typename SpeedOfSound>
209 constexpr const Pressure&
212  Pressure, SpeedOfSound>& q) noexcept {
213  return q.pressure;
214 }
215 
216 template <typename Density, typename Momentum, typename Energy,
217  typename Species, typename Pressure, typename SpeedOfSound>
218 constexpr const SpeedOfSound&
221  Pressure, SpeedOfSound>& q) noexcept {
222  return q.speed_of_sound;
223 }
224 
225 template <typename Density, typename Momentum, typename Energy,
226  typename Species, typename Pressure, typename SpeedOfSound>
227 constexpr auto
230  SpeedOfSound>& q,
232  Pressure, SpeedOfSound>& q0,
233  Pressure p_new) noexcept {
234  const double rho_new =
235  std::pow(p_new / q0.pressure, 1 / eq.gamma) * q0.density;
236  const Array<double, N, 1> u0 = euler::Velocity(eq, q0);
237  Array<double, N, 1> u_new = u0;
238  u_new[0] = u0[0] +
239  2.0 * std::sqrt(eq.gamma * q0.pressure / q0.density) *
240  eq.gamma_minus_1_inv -
241  2.0 * std::sqrt(eq.gamma * p_new / rho_new) * eq.gamma_minus_1_inv;
242  const Array<double, N, 1> rhou_new = rho_new * u_new;
243  const double rhoE_new =
244  p_new * eq.gamma_minus_1_inv + euler::KineticEnergy(rho_new, rhou_new);
245 
246  q.density = rho_new;
247  q.momentum = rhou_new;
248  q.energy = rhoE_new;
249  q.species = q0.species;
250  q.pressure = p_new;
251  q.speed_of_sound = std::sqrt(eq.gamma * p_new / rho_new);
252 }
253 
254 } // namespace fub
255 
256 #endif
constexpr struct fub::euler::InternalEnergyFn InternalEnergy
constexpr struct fub::euler::SpeedOfSoundFn SpeedOfSound
constexpr struct fub::euler::EnergyFn Energy
double KineticEnergy(double density, const Eigen::Array< double, Dim, 1 > &momentum) noexcept
Definition: EulerEquation.hpp:28
constexpr struct fub::euler::SpeciesFn Species
constexpr struct fub::euler::PressureFn Pressure
constexpr struct fub::euler::MomentumFn Momentum
constexpr struct fub::euler::DensityFn Density
constexpr struct fub::euler::VelocityFn Velocity
constexpr struct fub::euler::TemperatureFn Temperature
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
std::conditional_t< N==1||M==1, Eigen::Array< T, N, M >, Eigen::Array< T, N, M, Eigen::RowMajor > > Array
Definition: Eigen.hpp:50
constexpr struct fub::DepthsFn Depths
std::decay_t< decltype(T)> tag_t
Definition: type_traits.hpp:350
void tag_invoke(tag_t< euler::CompleteFromKineticState >, const PerfectGasMix< Rank > &eq, CompleteArray< PerfectGasMix< Rank >> &q, const KineticStateArray< PerfectGasMix< Rank >> &kin, const Array< double, Rank > &u) noexcept
Definition: PerfectGasMix.hpp:611
boost::mp11::mp_transform< ToConcreteDepth, Depths > ToConcreteDepths
Definition: State.hpp:122
This type has a constructor which takes an equation and might allocate any dynamically sized member v...
Definition: State.hpp:335
Definition: State.hpp:301
Definition: PerfectGasMix.hpp:174
This is a template class for constructing conservative states for the perfect gas equations.
Definition: PerfectGasMix.hpp:43
Definition: PerfectGasMix.hpp:111
Definition: PerfectGasMix.hpp:79
Definition: PerfectGasMix.hpp:208
double gamma
Definition: PerfectGasMix.hpp:269
Definition: State.hpp:162