Mallard 0.8.0
Unstructured, GPU accelerated, high-order finite volume CFD solver
Mallard website
Loading...
Searching...
No Matches
reactor.h
Go to the documentation of this file.
1
13#ifndef CHEMISTRY_REACTOR_H
14#define CHEMISTRY_REACTOR_H
15
16#include <Kokkos_Core.hpp>
17
18#include <cstdint>
19
20#include "kinetics.h"
21#include "rosenbrock.h"
22#include "sparse_lu.h"
23#include "thermo.h"
24
25namespace chemistry {
26
29 double atol_Y = 1e-10;
30 int sparse = -1; // linear solver: 0 dense LU, 1 sparse LU, -1 automatic (use_sparse_lu)
31 double C_reg = KineticsTable<Kokkos::HostSpace>::C_REG; // regularization of fractional orders (KineticsTable)
32};
33
40inline bool use_sparse_lu(const ReactorOptions & options, const Mechanism & mechanism) {
41 if (options.sparse >= 0) return options.sparse == 1;
42 const uint32_t n = mechanism.n_species() + 1;
43 if (n < 31) return false;
45 return pattern.nnz <= 0.6 * static_cast<double>(n) * n;
46}
47
66template <typename MemorySpace = Kokkos::DefaultExecutionSpace::memory_space>
70 double rho;
71 double atol_Y;
72 double * scratch; // scratch_size(kinetics) doubles
73 double * rank_one; // null: J in full; else (n_species + 1) doubles: J = J_s + u v^T with u here, v_j = 1 / W_j
74 const SparseLUPattern<MemorySpace> * sparse = nullptr; // with rank_one: J_s in the pattern's compact layout
75 const double * forcing = nullptr; // null, or g_1 .. g_Ns, g_e
76 double forcing_time = 0.0; // length of the call (with forcing)
77
80 return 6 * kinetics.n_species + kinetics.n_reactions + kinetics.derivatives_size() +
81 static_cast<uint32_t>(kinetics.chunk_end.extent(0));
82 }
83
84 KOKKOS_INLINE_FUNCTION uint32_t size() const { return thermo.n_species + 1; }
85
86 KOKKOS_INLINE_FUNCTION double atol(const uint32_t i) const { return i < thermo.n_species ? atol_Y : 0.0; }
87
88 template <typename Lanes>
89 KOKKOS_INLINE_FUNCTION bool admissible(const Lanes & lanes, const double * y) const {
90 if (forcing) {
91 const double negative = lanes.sum(thermo.n_species, [&](const uint32_t k) {
92 return y[k] < -atol_Y - forcing_time * Kokkos::fmax(0.0, -forcing[k]) ? 1.0 : 0.0;
93 });
94 return negative == 0.0 && y[thermo.n_species] > 0.0;
95 }
96 const double negative =
97 lanes.sum(thermo.n_species, [&](const uint32_t k) { return y[k] < -atol_Y ? 1.0 : 0.0; });
98 return negative == 0.0 && y[thermo.n_species] > 0.0;
99 }
100
101 template <typename Lanes>
102 KOKKOS_INLINE_FUNCTION void rhs(const Lanes & lanes, const double * y, double * f) const {
103 evaluate(lanes, y, f, nullptr);
104 }
105
106 template <typename Lanes>
107 KOKKOS_INLINE_FUNCTION void rhs_jacobian(const Lanes & lanes, const double * y, double * f, double * J) const {
108 evaluate(lanes, y, f, J);
109 }
110
112 template <typename Lanes>
113 KOKKOS_INLINE_FUNCTION double forcing_temperature_derivative(const Lanes & lanes, const double * cp_R) const {
114 return GAS_CONSTANT *
115 lanes.sum(thermo.n_species, [&](const uint32_t k) { return (cp_R[k] - 1.0) * thermo.inv_W(k) * forcing[k]; });
116 }
117
128 template <typename Lanes, typename Powers>
129 KOKKOS_INLINE_FUNCTION void compact_jacobian(const Lanes & lanes, const double * y, double * J, const double T,
130 const Powers & p, const double cv, const double inv_rho_cv,
131 const double dT_dt, const double * h_RT, const double * cp_R,
132 const double * omega, const double * domega_dT,
133 const ReactionDerivatives & d) const {
134 const uint32_t ns = thermo.n_species, ne = sparse->n_entries;
135 double * T_column = J + ne;
136 double * T_row = T_column + ns;
137 kinetics.production_jacobian_entries(lanes, d, J, rank_one);
138 const double sum_a =
139 lanes.sum(ns, [&](const uint32_t k) { return GAS_CONSTANT * T * (h_RT[k] - 1.0) * rank_one[k]; });
140 lanes.for_each(ns, [&](const uint32_t j) {
141 double sum = sum_a;
142 for (uint32_t c = sparse->column_offset(j); c < sparse->column_offset(j + 1); c++) {
143 const uint32_t e = sparse->column_entry(c);
144 sum += GAS_CONSTANT * T * (h_RT[sparse->entry_row(e)] - 1.0) * J[e];
145 }
146 const double cv_j = GAS_CONSTANT * (cp_R[j] - 1.0) * thermo.inv_W(j);
147 T_row[j] = -sum * rho * thermo.inv_W(j) * inv_rho_cv - dT_dt * cv_j / cv;
148 });
149 lanes.sync();
150 const double d_sum_dT = lanes.sum(ns, [&](const uint32_t k) {
151 return GAS_CONSTANT * ((cp_R[k] - 1.0) * omega[k] + T * (h_RT[k] - 1.0) * domega_dT[k]);
152 });
153 const double dcv_dT =
154 GAS_CONSTANT * lanes.sum(ns, [&](const uint32_t k) { return y[k] * thermo.inv_W(k) * thermo.dcp_R_dT(k, p); });
155 if (forcing) {
156 const double d_forcing_dT = forcing_temperature_derivative(lanes, cp_R);
157 lanes.single([&]() { T_row[ns] = -d_sum_dT * inv_rho_cv - dT_dt * dcv_dT / cv - d_forcing_dT / cv; });
158 } else {
159 lanes.single([&]() { T_row[ns] = -d_sum_dT * inv_rho_cv - dT_dt * dcv_dT / cv; });
160 }
161 lanes.for_each(ne, [&](const uint32_t e) {
162 J[e] *= thermo.inv_W(sparse->entry_column(e)) / thermo.inv_W(sparse->entry_row(e));
163 });
164 lanes.for_each(ns, [&](const uint32_t k) {
165 const double W_k = 1.0 / thermo.inv_W(k);
166 T_column[k] = W_k * domega_dT[k] / rho;
167 rank_one[k] *= W_k; // u_k = W_k a_k, with v_j = 1 / W_j
168 });
169 lanes.single([&]() { rank_one[ns] = 0.0; });
170 lanes.sync();
171 }
172
173 template <typename Lanes>
174 KOKKOS_INLINE_FUNCTION void evaluate(const Lanes & lanes, const double * y, double * f, double * J) const {
175 const uint32_t ns = thermo.n_species, nr = kinetics.n_reactions, n = ns + 1;
176 double * C = scratch;
177 double * g_RT = C + ns;
178 double * h_RT = g_RT + ns;
179 double * cp_R = h_RT + ns;
180 double * omega = cp_R + ns;
181 double * domega_dT = omega + ns;
182 double * q = domega_dT + ns;
183 const ReactionDerivatives d =
184 ReactionDerivatives::at(q + nr, nr, static_cast<uint32_t>(kinetics.forward_species.extent(0)),
185 static_cast<uint32_t>(kinetics.reverse_species.extent(0)));
186 double * partial = q + nr + kinetics.derivatives_size();
187
188 const double T = y[ns];
189 const auto p = ThermoTable<MemorySpace>::powers(T);
190 lanes.for_each(ns, [&](const uint32_t k) {
191 C[k] = rho * y[k] * thermo.inv_W(k);
192 h_RT[k] = thermo.h_RT(k, p);
193 g_RT[k] = h_RT[k] - thermo.s_R(k, p);
194 cp_R[k] = thermo.cp_R(k, p);
195 });
196 lanes.sync();
197 const double cv =
198 GAS_CONSTANT * lanes.sum(ns, [&](const uint32_t k) { return y[k] * thermo.inv_W(k) * (cp_R[k] - 1.0); });
199 const double C_total = lanes.sum(ns, [&](const uint32_t k) { return C[k]; });
200 kinetics.rates_of_progress(lanes, T, C, C_total, g_RT, h_RT, q, J ? &d : nullptr);
201 kinetics.production_rates(lanes, q, omega, partial);
202 // u_k = R T (h_k / RT - 1)
203 lanes.for_each(ns, [&](const uint32_t k) { f[k] = omega[k] / (rho * thermo.inv_W(k)); });
204 const double sum_u_omega =
205 lanes.sum(ns, [&](const uint32_t k) { return GAS_CONSTANT * T * (h_RT[k] - 1.0) * omega[k]; });
206 const double inv_rho_cv = 1.0 / (rho * cv);
207 double dT_dt = -sum_u_omega * inv_rho_cv;
208 if (forcing) {
209 lanes.sync();
210 lanes.for_each(ns, [&](const uint32_t k) { f[k] += forcing[k]; });
211 const double sum_e_g = lanes.sum(
212 ns, [&](const uint32_t k) { return GAS_CONSTANT * T * (h_RT[k] - 1.0) * thermo.inv_W(k) * forcing[k]; });
213 dT_dt += (forcing[ns] - sum_e_g) / cv;
214 }
215 lanes.single([&]() { f[ns] = dT_dt; });
216 lanes.sync();
217 if (!J) return;
218
219 kinetics.production_rates(lanes, d.dq_dT, domega_dT, partial);
220 if (sparse) {
221 compact_jacobian(lanes, y, J, T, p, cv, inv_rho_cv, dT_dt, h_RT, cp_R, omega, domega_dT, d);
222 return;
223 }
224 kinetics.production_jacobian(lanes, d, J, n, rank_one);
225 // With the rank-one part apart, its share of the T row: sum_k u_k a_k
226 const double sum_a =
227 rank_one ? lanes.sum(ns, [&](const uint32_t k) { return GAS_CONSTANT * T * (h_RT[k] - 1.0) * rank_one[k]; })
228 : 0.0;
229
230 // T row: d(sum u_k omega_k)/dY_j = rho / W_j sum_k u_k dw_kj; d cv / dY_j = cv_j
231 constexpr bool CM = Lanes::column_major;
232 auto Jat = [&](const uint32_t r, const uint32_t c) -> double & { return J[dense_index<CM>(n, r, c)]; };
233 lanes.for_each(ns, [&](const uint32_t j) {
234 double sum = sum_a;
235 for (uint32_t k = 0; k < ns; k++) sum += GAS_CONSTANT * T * (h_RT[k] - 1.0) * Jat(k, j);
236 const double cv_j = GAS_CONSTANT * (cp_R[j] - 1.0) * thermo.inv_W(j);
237 Jat(ns, j) = -sum * rho * thermo.inv_W(j) * inv_rho_cv - dT_dt * cv_j / cv;
238 });
239 lanes.sync();
240 const double d_sum_dT = lanes.sum(ns, [&](const uint32_t k) {
241 return GAS_CONSTANT * ((cp_R[k] - 1.0) * omega[k] + T * (h_RT[k] - 1.0) * domega_dT[k]);
242 });
243 const double dcv_dT =
244 GAS_CONSTANT * lanes.sum(ns, [&](const uint32_t k) { return y[k] * thermo.inv_W(k) * thermo.dcp_R_dT(k, p); });
245 if (forcing) {
246 const double d_forcing_dT = forcing_temperature_derivative(lanes, cp_R);
247 lanes.single([&]() { Jat(ns, ns) = -d_sum_dT * inv_rho_cv - dT_dt * dcv_dT / cv - d_forcing_dT / cv; });
248 } else {
249 lanes.single([&]() { Jat(ns, ns) = -d_sum_dT * inv_rho_cv - dT_dt * dcv_dT / cv; });
250 }
251
252 // Species rows: df_k/dY_j = W_k / W_j dw_kj, df_k/dT = W_k / rho domega_k/dT
253 lanes.for_each(ns, [&](const uint32_t k) {
254 const double W_k = 1.0 / thermo.inv_W(k);
255 for (uint32_t j = 0; j < ns; j++) Jat(k, j) *= W_k * thermo.inv_W(j);
256 Jat(k, ns) = W_k * domega_dT[k] / rho;
257 if (rank_one) rank_one[k] *= W_k; // u_k = W_k a_k, with v_j = 1 / W_j
258 });
259 if (rank_one) lanes.single([&]() { rank_one[ns] = 0.0; });
260 lanes.sync();
261 }
262};
263
269template <typename MemorySpace>
271 const SparseLUPattern<MemorySpace> * sparse = nullptr) {
272 const uint32_t n = kinetics.n_species + 1;
273 const uint32_t solver = sparse ? sparse->work_size() + 1 : n * n;
274 return n + solver + rosenbrock_vectors_size(n);
275}
276
281template <typename MemorySpace>
283 const SparseLUPattern<MemorySpace> * sparse = nullptr) {
284 const uint32_t n = kinetics.n_species + 1;
285 return (sparse ? sparse->jacobian_size() : n * n) + ConstantVolumeReactor<MemorySpace>::scratch_size(kinetics) +
286 reactor_fast_size(kinetics, sparse);
287}
288
307template <bool Sparse = false, typename Lanes, typename MemorySpace, typename Observer = NoObserver>
309 const KineticsTable<MemorySpace> & kinetics, const double rho,
310 const double dt, double * Y, double & T, double & h,
311 const ReactorOptions & options, double * work,
312 uint32_t * pivot, Observer && observer = Observer(),
313 const SparseLUPattern<MemorySpace> * sparse = nullptr,
314 double * fast = nullptr, const double * forcing = nullptr) {
315 const uint32_t ns = thermo.n_species, n = ns + 1;
316 double * J = work;
317 double * scratch = J + (Sparse ? sparse->jacobian_size() : n * n);
319 double * solver_work = y + n;
320 double * vectors = solver_work + (Sparse ? sparse->work_size() + 1 : n * n);
321 // Scalar code runs on every lane with the same values; writes go through for_each or single
322 double e, cv;
323 thermo.e_cv(T, MassFractions{Y}, e, cv);
324 lanes.for_each(ns, [&](const uint32_t k) { y[k] = Kokkos::fmax(Y[k], 0.0); });
325 lanes.sync();
326 const double negative = lanes.sum(ns, [&](const uint32_t k) { return Y[k] < 0.0 ? 1.0 : 0.0; });
327 double T0 = T;
328 if (negative > 0.0) {
329 // Small negative mass fractions (e.g. from explicit diffusion) would
330 // reject every sub-step: start from the clipped composition at the same energy
331 const double sum = lanes.sum(ns, [&](const uint32_t k) { return y[k]; });
332 lanes.for_each(ns, [&](const uint32_t k) { y[k] /= sum; });
333 lanes.sync();
334 T0 = thermo.T_from_e(e, MassFractions{y}, T);
335 }
336 lanes.single([&]() { y[ns] = T0; });
337 lanes.sync();
339 if constexpr (Sparse) {
340 // LU values, z = A_s^-1 u, u, x, beta
341 double * values = solver_work;
342 double * z = values + sparse->nnz;
343 double * u = z + n;
344 double * x = u + n;
345 const ConstantVolumeReactor<MemorySpace> reactor{thermo, kinetics, rho, options.atol_Y, scratch,
346 u, sparse, forcing, dt};
347 const SparseLU<MemorySpace> solver{*sparse, values, z, u, x, x + n};
348 result = integrate(lanes, reactor, solver, 0.0, dt, y, h, options.integrator, J, vectors,
349 static_cast<Observer &&>(observer));
350 } else {
351 const ConstantVolumeReactor<MemorySpace> reactor{thermo, kinetics, rho, options.atol_Y, scratch,
352 nullptr, nullptr, forcing, dt};
353 const DenseLU solver{n, solver_work, pivot};
354 result = integrate(lanes, reactor, solver, 0.0, dt, y, h, options.integrator, J, vectors,
355 static_cast<Observer &&>(observer));
356 }
357 lanes.for_each(ns, [&](const uint32_t k) { y[k] = Kokkos::fmax(y[k], 0.0); });
358 lanes.sync();
359 const double total = lanes.sum(ns, [&](const uint32_t k) { return y[k]; });
360 lanes.for_each(ns, [&](const uint32_t k) { Y[k] = y[k] / total; });
361 lanes.sync();
362 if (forcing) {
363 const double growth = 1.0 + dt * lanes.sum(ns, [&](const uint32_t k) { return forcing[k]; });
364 T = thermo.T_from_e((e + dt * forcing[ns]) / growth, MassFractions{Y}, y[ns]);
365 return result;
366 }
367 T = thermo.T_from_e(e, MassFractions{Y}, y[ns]);
368 return result;
369}
370
372template <typename MemorySpace, typename Observer = NoObserver>
374 const KineticsTable<MemorySpace> & kinetics, const double rho,
375 const double dt, double * Y, double & T, double & h,
376 const ReactorOptions & options, double * work,
377 uint32_t * pivot, Observer && observer = Observer(),
378 const SparseLUPattern<MemorySpace> * sparse = nullptr) {
379 if (sparse) {
380 return advance_reactor<true>(SerialLanes(), thermo, kinetics, rho, dt, Y, T, h, options, work, pivot,
381 static_cast<Observer &&>(observer), sparse);
382 }
383 return advance_reactor<false>(SerialLanes(), thermo, kinetics, rho, dt, Y, T, h, options, work, pivot,
384 static_cast<Observer &&>(observer), sparse);
385}
386
395 uint32_t index = 0; // of T in the state
396 double t_offset = 0.0; // added to the integrator's time
397 double t_ignition = 0.0;
398 double peak = 0.0; // largest sampled dT/dt
399 double t[3] = {0.0, 0.0, 0.0};
400 double g[3] = {0.0, 0.0, 0.0};
402
403 KOKKOS_INLINE_FUNCTION void operator()(const double time, const double *, const double * f) {
404 for (int i = 0; i < 2; i++) {
405 t[i] = t[i + 1];
406 g[i] = g[i + 1];
407 }
408 t[2] = t_offset + time;
409 g[2] = f[index];
410 if (++count < 3 || !(g[1] > peak && g[1] >= g[0] && g[1] >= g[2])) return;
411 peak = g[1];
412 const double num = (t[1] - t[0]) * (t[1] - t[0]) * (g[1] - g[2]) - (t[1] - t[2]) * (t[1] - t[2]) * (g[1] - g[0]);
413 const double den = (t[1] - t[0]) * (g[1] - g[2]) - (t[1] - t[2]) * (g[1] - g[0]);
414 t_ignition = den != 0.0 ? t[1] - 0.5 * num / den : t[1];
415 }
416
418 KOKKOS_INLINE_FUNCTION bool ignited() const { return peak > 0.0 && g[2] < 0.5 * peak; }
419};
420
421} // namespace chemistry
422
423#endif // CHEMISTRY_REACTOR_H
KOKKOS_INLINE_FUNCTION rtype dot(const rtype *a, const rtype *b)
Compute the dot product of two arrays.
Definition common_math.h:32
Device tables of a mechanism's reactions: rates of progress, production rates and their analytical de...
Definition kinetics.h:25
KOKKOS_INLINE_FUNCTION RosenbrockResult advance_reactor(const Lanes &lanes, const ThermoTable< MemorySpace > &thermo, const KineticsTable< MemorySpace > &kinetics, const double rho, const double dt, double *Y, double &T, double &h, const ReactorOptions &options, double *work, uint32_t *pivot, Observer &&observer=Observer(), const SparseLUPattern< MemorySpace > *sparse=nullptr, double *fast=nullptr, const double *forcing=nullptr)
Advance one adiabatic constant-volume reactor over dt: integrate (Y, T), then clip negative mass frac...
Definition reactor.h:308
bool use_sparse_lu(const ReactorOptions &options, const Mechanism &mechanism)
Whether a mechanism's reactors use the sparse LU: as options.sparse says, or automatically from 30 sp...
Definition reactor.h:40
constexpr double GAS_CONSTANT
Definition mechanism.h:26
KOKKOS_INLINE_FUNCTION RosenbrockResult integrate(const Lanes &lanes, const System &system, const Solver &solver, const double t_start, const double t_end, double *y, double &h, const RosenbrockOptions &options, double *J, double *vectors, Observer &&observer=Observer())
Integrate dy/dt = f(y) from t_start to t_end with adaptive RODAS steps and error control sqrt(mean((e...
Definition rosenbrock.h:262
KOKKOS_INLINE_FUNCTION uint32_t reactor_fast_size(const KineticsTable< MemorySpace > &kinetics, const SparseLUPattern< MemorySpace > *sparse=nullptr)
Doubles of the part of advance_reactor()'s work memory that can be in fast (team scratch) memory: the...
Definition reactor.h:270
KOKKOS_INLINE_FUNCTION constexpr uint32_t rosenbrock_vectors_size(const uint32_t n)
Doubles of the vectors integrate() needs for a system of size n (besides the dense J).
Definition rosenbrock.h:176
KOKKOS_INLINE_FUNCTION uint32_t reactor_work_size(const KineticsTable< MemorySpace > &kinetics, const SparseLUPattern< MemorySpace > *sparse=nullptr)
Doubles of work memory advance_reactor() needs, the linear solver's included: dense,...
Definition reactor.h:282
Adaptive Rosenbrock integrator (RODAS) with dense LU, for one stiff autonomous ODE system per thread.
Static-pattern sparse LU of the reactor's Newton matrix for large mechanisms, with the dense rank-one...
Adiabatic, constant-volume reactor at density rho with state y = (Y_1 .. Y_Ns, T): dY_k/dt = W_k omeg...
Definition reactor.h:67
double * scratch
Definition reactor.h:72
KOKKOS_INLINE_FUNCTION void evaluate(const Lanes &lanes, const double *y, double *f, double *J) const
Definition reactor.h:174
KOKKOS_INLINE_FUNCTION bool admissible(const Lanes &lanes, const double *y) const
Definition reactor.h:89
KOKKOS_INLINE_FUNCTION void compact_jacobian(const Lanes &lanes, const double *y, double *J, const double T, const Powers &p, const double cv, const double inv_rho_cv, const double dT_dt, const double *h_RT, const double *cp_R, const double *omega, const double *domega_dT, const ReactionDerivatives &d) const
f(y) and, if J is not null, the Jacobian df/dy (in the lanes' layout, see dense_index),...
Definition reactor.h:129
const SparseLUPattern< MemorySpace > * sparse
Definition reactor.h:74
KOKKOS_INLINE_FUNCTION double forcing_temperature_derivative(const Lanes &lanes, const double *cp_R) const
d(sum_k e_k g_k) / dT = sum_k cv_k g_k.
Definition reactor.h:113
KOKKOS_INLINE_FUNCTION uint32_t size() const
Definition reactor.h:84
KOKKOS_INLINE_FUNCTION void rhs_jacobian(const Lanes &lanes, const double *y, double *f, double *J) const
Definition reactor.h:107
const KineticsTable< MemorySpace > & kinetics
Definition reactor.h:69
double * rank_one
Definition reactor.h:73
static KOKKOS_INLINE_FUNCTION uint32_t scratch_size(const KineticsTable< MemorySpace > &kinetics)
Definition reactor.h:79
const double * forcing
Definition reactor.h:75
double rho
Definition reactor.h:70
double forcing_time
Definition reactor.h:76
double atol_Y
Definition reactor.h:71
KOKKOS_INLINE_FUNCTION void rhs(const Lanes &lanes, const double *y, double *f) const
Definition reactor.h:102
KOKKOS_INLINE_FUNCTION double atol(const uint32_t i) const
Definition reactor.h:86
const ThermoTable< MemorySpace > & thermo
Definition reactor.h:68
Dense linear solver of integrate(): A = diagonal I - J factored by lu_factor in n * n doubles (LU,...
Definition rosenbrock.h:153
Ignition delay as the time of the maximum of dT/dt: the vertex of the parabola through the largest sa...
Definition reactor.h:394
double t_offset
Definition reactor.h:396
KOKKOS_INLINE_FUNCTION void operator()(const double time, const double *, const double *f)
Definition reactor.h:403
double g[3]
Definition reactor.h:400
double t_ignition
Definition reactor.h:397
uint32_t index
Definition reactor.h:395
double peak
Definition reactor.h:398
double t[3]
Definition reactor.h:399
uint32_t count
Definition reactor.h:401
KOKKOS_INLINE_FUNCTION bool ignited() const
Whether the reactor has ignited, at t_ignition.
Definition reactor.h:418
Reactions of a mechanism as flat device tables (compressed rows per reaction), in MemorySpace....
Definition kinetics.h:70
uint32_t n_species
Definition kinetics.h:74
Mass fractions held in a contiguous array.
Definition thermo.h:28
One ideal-gas phase of a Cantera YAML file: its elements, species and reactions.
Definition mechanism.h:145
uint32_t n_species() const
Definition mechanism.h:152
Per-reaction derivatives of the rates of progress, in one block of KineticsTable::derivatives_size() ...
Definition kinetics.h:35
static KOKKOS_INLINE_FUNCTION ReactionDerivatives at(double *work, const uint32_t n_reactions, const uint32_t n_forward, const uint32_t n_reverse)
Definition kinetics.h:43
double * dq_dT
Definition kinetics.h:36
Definition reactor.h:27
int sparse
Definition reactor.h:30
double C_reg
Definition reactor.h:31
double atol_Y
Definition reactor.h:29
RosenbrockOptions integrator
Definition reactor.h:28
Definition rosenbrock.h:103
Definition rosenbrock.h:115
One thread does all the work of a cell.
Definition lanes.h:38
The pattern of a reactor Jacobian in (Y_1 .. Y_Ns, T) without its rank-one part, an elimination order...
Definition sparse_lu.h:46
uint32_t nnz
Definition sparse_lu.h:51
The linear solver of integrate() for SparseLUPattern: factor() gathers diagonal I - J_s from the comp...
Definition sparse_lu.h:449
Species thermodynamics of a mechanism on the device, in double precision in every build: per species ...
Definition thermo.h:43
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
static KOKKOS_INLINE_FUNCTION Powers powers(const double T)
Definition thermo.h:59
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
uint32_t n_species
Definition thermo.h:44
CellSetup< ExecSpace > c
Definition teno_setup.cpp:1810
uint8_t r
Definition teno_setup.cpp:687
Scratch< Space > scratch
Definition teno_setup.cpp:680
uint16_t ns
Definition teno_setup.cpp:688
Device tables of species thermodynamics and thermally perfect mixture properties.