Mallard 0.8.0
Unstructured, GPU accelerated, high-order finite volume CFD solver
Mallard website
Loading...
Searching...
No Matches
thermo.h
Go to the documentation of this file.
1
13#ifndef CHEMISTRY_THERMO_H
14#define CHEMISTRY_THERMO_H
15
16#include <algorithm>
17#include <cmath>
18#include <cstdint>
19#include <limits>
20
21#include <Kokkos_Core.hpp>
22
23#include "mechanism.h"
24
25namespace chemistry {
26
29 const double * Y;
30 KOKKOS_INLINE_FUNCTION double operator()(const uint32_t k) const { return Y[k]; }
31};
32
42template <typename MemorySpace = Kokkos::DefaultExecutionSpace::memory_space>
45 Kokkos::View<double *, MemorySpace> inv_W; // kmol/kg
46 Kokkos::View<uint32_t *, MemorySpace> range_offset; // (n_species + 1): ranges of species k
47 Kokkos::View<double *, MemorySpace> range_upper; // (range): upper bound, unused for a species' last range
48 Kokkos::View<uint8_t *, MemorySpace> upper_closed; // (species): a bound belongs to the range below it (NASA-7)
49 Kokkos::View<double *[9], Kokkos::LayoutRight, MemorySpace> coeffs; // (range, coefficient)
50 double T_low = 1.0; // bracket of T(e)
51 double T_high = 1.0e5;
52
54 struct Powers {
55 double T, inv_T, inv_T2, log_T;
56 };
57
59 static Powers powers(const double T) {
60 const double inv_T = 1.0 / T;
61 return {T, inv_T, inv_T * inv_T, Kokkos::log(T)};
62 }
63
65 uint32_t range(const uint32_t k, const double T) const {
67 const uint32_t last = range_offset(k + 1) - 1;
68 if (upper_closed(k)) {
69 while (r < last && T > range_upper(r)) r++;
70 } else {
71 while (r < last && T >= range_upper(r)) r++;
72 }
73 return r;
74 }
75
78 double cp_R(const uint32_t k, const Powers & p) const {
79 const uint32_t r = range(k, p.T);
80 const double T = p.T;
81 return coeffs(r, 0) * p.inv_T2 + coeffs(r, 1) * p.inv_T +
82 (coeffs(r, 2) + T * (coeffs(r, 3) + T * (coeffs(r, 4) + T * (coeffs(r, 5) + T * coeffs(r, 6)))));
83 }
84
87 double dcp_R_dT(const uint32_t k, const Powers & p) const {
88 const uint32_t r = range(k, p.T);
89 const double T = p.T;
90 return -2.0 * coeffs(r, 0) * p.inv_T2 * p.inv_T - coeffs(r, 1) * p.inv_T2 +
91 (coeffs(r, 3) + T * (2.0 * coeffs(r, 4) + T * (3.0 * coeffs(r, 5) + T * 4.0 * coeffs(r, 6))));
92 }
93
96 double h_RT(const uint32_t k, const Powers & p) const {
97 const uint32_t r = range(k, p.T);
98 const double T = p.T;
99 return -coeffs(r, 0) * p.inv_T2 + coeffs(r, 1) * p.log_T * p.inv_T +
100 (coeffs(r, 2) + T * (coeffs(r, 3) / 2.0 + T * (coeffs(r, 4) / 3.0 +
101 T * (coeffs(r, 5) / 4.0 + T * coeffs(r, 6) / 5.0)))) +
102 coeffs(r, 7) * p.inv_T;
103 }
104
107 double s_R(const uint32_t k, const Powers & p) const {
108 const uint32_t r = range(k, p.T);
109 const double T = p.T;
110 return -0.5 * coeffs(r, 0) * p.inv_T2 - coeffs(r, 1) * p.inv_T + coeffs(r, 2) * p.log_T +
111 T * (coeffs(r, 3) + T * (coeffs(r, 4) / 2.0 + T * (coeffs(r, 5) / 3.0 + T * coeffs(r, 6) / 4.0))) +
112 coeffs(r, 8);
113 }
114
116 template <typename F_Y>
117 KOKKOS_INLINE_FUNCTION double gas_constant(const F_Y & y) const {
118 double sum = 0.0;
119 for (uint32_t k = 0; k < n_species; k++) sum += y(k) * inv_W(k);
120 return GAS_CONSTANT * sum;
121 }
122
124 template <typename F_Y>
125 KOKKOS_INLINE_FUNCTION double cp_mass(const double T, const F_Y & y) const {
126 const Powers p = powers(T);
127 double sum = 0.0;
128 for (uint32_t k = 0; k < n_species; k++) sum += y(k) * inv_W(k) * cp_R(k, p);
129 return GAS_CONSTANT * sum;
130 }
131
133 template <typename F_Y>
134 KOKKOS_INLINE_FUNCTION double h_mass(const double T, const F_Y & y) const {
135 const Powers p = powers(T);
136 double sum = 0.0;
137 for (uint32_t k = 0; k < n_species; k++) sum += y(k) * inv_W(k) * h_RT(k, p);
138 return GAS_CONSTANT * T * sum;
139 }
140
142 template <typename F_Y>
143 KOKKOS_INLINE_FUNCTION void e_cv(const double T, const F_Y & y, double & e, double & cv) const {
144 const Powers p = powers(T);
145 double sum_e = 0.0, sum_cv = 0.0;
146 for (uint32_t k = 0; k < n_species; k++) {
147 const double n = y(k) * inv_W(k);
148 sum_e += n * (h_RT(k, p) - 1.0);
149 sum_cv += n * (cp_R(k, p) - 1.0);
150 }
151 e = GAS_CONSTANT * T * sum_e;
152 cv = GAS_CONSTANT * sum_cv;
153 }
154
160 template <typename F_Y>
161 KOKKOS_INLINE_FUNCTION double T_from_e(const double e, const F_Y & y, const double T_guess) const {
162 double a = T_low, b = T_high;
163 double T = (T_guess > a && T_guess < b) ? T_guess : Kokkos::fmin(Kokkos::fmax(300.0, a), b);
164 for (int it = 0; it < 200; it++) {
165 double e_T, cv;
166 e_cv(T, y, e_T, cv);
167 const double f = e_T - e;
168 if (f > 0.0) {
169 b = T;
170 } else {
171 a = T;
172 }
173 double T_new = T - f / cv;
174 if (!(T_new >= a && T_new <= b)) T_new = 0.5 * (a + b);
175 if (Kokkos::fabs(T_new - T) <= 1e-10 * T) return T_new;
176 T = T_new;
177 }
178 return T;
179 }
180};
181
183template <typename MemorySpace = Kokkos::DefaultExecutionSpace::memory_space>
186 const uint32_t n = mechanism.n_species();
187 table.n_species = n;
188 uint32_t n_ranges = 0;
189 for (const auto & sp : mechanism.species) n_ranges += static_cast<uint32_t>(sp.thermo.coeffs.size());
190
191 table.inv_W = Kokkos::View<double *, MemorySpace>("thermo_inv_W", n);
192 table.range_offset = Kokkos::View<uint32_t *, MemorySpace>("thermo_range_offset", n + 1);
193 table.range_upper = Kokkos::View<double *, MemorySpace>("thermo_range_upper", n_ranges);
194 table.upper_closed = Kokkos::View<uint8_t *, MemorySpace>("thermo_upper_closed", n);
195 table.coeffs = Kokkos::View<double *[9], Kokkos::LayoutRight, MemorySpace>("thermo_coeffs", n_ranges);
196 auto h_inv_W = Kokkos::create_mirror_view(table.inv_W);
197 auto h_offset = Kokkos::create_mirror_view(table.range_offset);
198 auto h_upper = Kokkos::create_mirror_view(table.range_upper);
199 auto h_closed = Kokkos::create_mirror_view(table.upper_closed);
200 auto h_coeffs = Kokkos::create_mirror_view(table.coeffs);
201
202 // Common range of the fits, where every species is fitted
203 double T_min = 0.0, T_max = std::numeric_limits<double>::infinity();
204 uint32_t r = 0;
205 for (uint32_t k = 0; k < n; k++) {
206 const Species & sp = mechanism.species[k];
207 h_inv_W(k) = 1.0 / sp.molecular_weight;
208 h_offset(k) = r;
209 h_closed(k) = sp.thermo.model == ThermoModel::NASA7;
210 for (size_t i = 0; i < sp.thermo.coeffs.size(); i++, r++) {
211 h_upper(r) = sp.thermo.T_bounds[i + 1];
212 for (size_t j = 0; j < 9; j++) h_coeffs(r, j) = sp.thermo.coeffs[i][j];
213 }
214 T_min = std::max(T_min, sp.thermo.T_bounds.front());
215 T_max = std::min(T_max, sp.thermo.T_bounds.back());
216 }
217 h_offset(n) = r;
218 // T(e) may extrapolate somewhat past the common range; constant cp has no bounds
219 table.T_low = std::max(0.5 * T_min, 1.0);
220 table.T_high = std::isfinite(T_max) ? 2.0 * T_max : 1.0e5;
221
222 Kokkos::deep_copy(table.inv_W, h_inv_W);
223 Kokkos::deep_copy(table.range_offset, h_offset);
224 Kokkos::deep_copy(table.range_upper, h_upper);
225 Kokkos::deep_copy(table.upper_closed, h_closed);
226 Kokkos::deep_copy(table.coeffs, h_coeffs);
227 return table;
228}
229
230} // namespace chemistry
231
232#endif // CHEMISTRY_THERMO_H
KOKKOS_INLINE_FUNCTION rtype dot(const rtype *a, const rtype *b)
Compute the dot product of two arrays.
Definition common_math.h:32
Gas-phase mechanisms read from Cantera YAML files.
Definition kinetics.h:25
constexpr double GAS_CONSTANT
Definition mechanism.h:26
ThermoTable< MemorySpace > make_thermo_table(const Mechanism &mechanism)
Copy a mechanism's species thermodynamics to MemorySpace.
Definition thermo.h:184
Mass fractions held in a contiguous array.
Definition thermo.h:28
KOKKOS_INLINE_FUNCTION double operator()(const uint32_t k) const
Definition thermo.h:30
const double * Y
Definition thermo.h:29
One ideal-gas phase of a Cantera YAML file: its elements, species and reactions.
Definition mechanism.h:145
std::vector< Species > species
Definition mechanism.h:149
uint32_t n_species() const
Definition mechanism.h:152
Definition mechanism.h:87
Powers of T shared by all species.
Definition thermo.h:54
double inv_T
Definition thermo.h:55
double inv_T2
Definition thermo.h:55
double log_T
Definition thermo.h:55
double T
Definition thermo.h:55
Species thermodynamics of a mechanism on the device, in double precision in every build: per species ...
Definition thermo.h:43
KOKKOS_INLINE_FUNCTION double gas_constant(const F_Y &y) const
Mixture gas constant R_u sum_k Y_k / W_k [J/(kg K)].
Definition thermo.h:117
KOKKOS_INLINE_FUNCTION double cp_mass(const double T, const F_Y &y) const
Mixture cp [J/(kg K)].
Definition thermo.h:125
KOKKOS_INLINE_FUNCTION uint32_t range(const uint32_t k, const double T) const
Definition thermo.h:65
KOKKOS_INLINE_FUNCTION double h_RT(const uint32_t k, const Powers &p) const
h_k / (R T), molar enthalpy including the formation enthalpy.
Definition thermo.h:96
Kokkos::View< uint32_t *, MemorySpace > range_offset
Definition thermo.h:46
double T_high
Definition thermo.h:51
KOKKOS_INLINE_FUNCTION void e_cv(const double T, const F_Y &y, double &e, double &cv) const
Mixture internal energy e [J/kg] and cv [J/(kg K)] at T.
Definition thermo.h:143
double T_low
Definition thermo.h:50
Kokkos::View< double *, MemorySpace > inv_W
Definition thermo.h:45
KOKKOS_INLINE_FUNCTION double h_mass(const double T, const F_Y &y) const
Mixture enthalpy [J/kg].
Definition thermo.h:134
Kokkos::View< double *, MemorySpace > range_upper
Definition thermo.h:47
Kokkos::View< uint8_t *, MemorySpace > upper_closed
Definition thermo.h:48
KOKKOS_INLINE_FUNCTION double cp_R(const uint32_t k, const Powers &p) const
cp_k / R.
Definition thermo.h:78
Kokkos::View< double *[9], Kokkos::LayoutRight, MemorySpace > coeffs
Definition thermo.h:49
static KOKKOS_INLINE_FUNCTION Powers powers(const double T)
Definition thermo.h:59
KOKKOS_INLINE_FUNCTION double dcp_R_dT(const uint32_t k, const Powers &p) const
d(cp_k / R) / dT.
Definition thermo.h:87
KOKKOS_INLINE_FUNCTION double T_from_e(const double e, const F_Y &y, const double T_guess) const
Temperature at which the mixture has internal energy e: Newton from T_guess (300 K if outside the bra...
Definition thermo.h:161
KOKKOS_INLINE_FUNCTION double s_R(const uint32_t k, const Powers &p) const
s_k / R at the standard pressure.
Definition thermo.h:107
uint32_t n_species
Definition thermo.h:44
uint8_t r
Definition teno_setup.cpp:687