MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
fvcartesiansyseqndetchem.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef FvSysEqnDetChem_H_
8#define FvSysEqnDetChem_H_
9
10#include <algorithm>
11#include <array>
12#include <iterator>
13#include <memory>
14#include <numeric>
16#include "INCLUDE/maiatypes.h"
17#include "MEMORY/alloc.h"
18#include "filter.h"
19#include "fvcartesiansyseqnns.h"
20
21#if defined(WITH_CANTERA)
22
23#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-Wunused-parameter"
25#pragma GCC diagnostic ignored "-Wfloat-equal"
26#include "cantera/base/Solution.h"
27#include "cantera/thermo/IdealGasPhase.h"
28#include "cantera/thermo/Species.h"
29#include "cantera/thermo/SpeciesThermoInterpType.h"
30#include "cantera/transport.h"
31#include "cantera/zerodim.h"
32#pragma GCC diagnostic pop
33using namespace Cantera;
34
41template <MInt nDim>
42class FvSysEqnDetChem : public FvSysEqnNS<nDim> {
43 // Declare parent a friend so that CRTP can access private methods/members
44 // friend class FvSysEqn<nDim>;
45
46 public:
47 FvSysEqnDetChem(const MInt solverId, const MInt noSpecies);
48
49 template <MInt stencil = AUSM>
50 inline void Ausm(const MInt orientation, const MFloat upwindCoefficient, const MFloat A, const MFloat* const leftVars,
51 const MFloat* const rightVars, const MFloat* const srfcCoeff, MFloat* const flux);
52
53 inline void AusmBndryCorrection(const MInt orientation, const MFloat A, const MFloat* const leftVars,
54 const MFloat* const rightVars, MFloat* const flux);
55
56 // Dispatch function for classic five-point-style viscous flux schemes
57 template <MInt stencil>
58 inline void viscousFlux(const MInt orientation, const MFloat A, const MFloat* const vars0, const MFloat* const vars1,
59 const MFloat* const slope0, const MFloat* const slope1, const MFloat* const srfcCoeff,
60 const MFloat f0, const MFloat f1, MFloat* const flux) {
61 if(stencil == FIVE_POINT) {
62 viscousFluxFivePoint(orientation, A, vars0, vars1, slope0, slope1, srfcCoeff, f0, f1, flux);
63 } else {
64 TERMM(1, "Viscous Flux Scheme not implemented.");
65 }
66 }
67
68 // Dispatch function for compact viscous flux schemes
69 template <MInt stencil>
70 inline void viscousFlux(const MInt, const MFloat, const MBool, const MFloat* const, const MFloat* const,
71 const MFloat* const, const MFloat* const, const MFloat* const, const MFloat* const,
72 const MFloat* const, const MFloat* const, const MFloat* const, const MFloat, const MFloat,
73 MFloat* const) {
74 if(stencil == THREE_POINT) {
75 TERMM(1, "Three point viscous Flux Scheme not implemented for SysEqnDetChem.");
76 } else {
77 TERMM(1, "Viscous Flux Scheme not implemented.");
78 }
79 }
80
81 inline void viscousFluxFivePoint(const MInt orientation, const MFloat A, const MFloat* const vars0,
82 const MFloat* const vars1, const MFloat* const slope0, const MFloat* const slope1,
83 const MFloat* const srfcCoeff, const MFloat f0, const MFloat f1, MFloat* const flux);
84
85 inline void getSpeciesDiffusionMassFluxes(const MInt orientation, const MFloat* const vars0,
86 const MFloat* const vars1, const MFloat* const slope0,
87 const MFloat* const slope1, const MFloat* const srfcCoeff, const MFloat f0,
88 const MFloat f1, std::vector<MFloat>& J, std::vector<MFloat>& dXdn,
89 MFloat& dTdn, const MBool soretEffect);
90
91 inline void computeSurfaceCoefficients(const MInt RKStep, const MFloat* const vars0, const MFloat* const vars1,
92 MFloat* const srfcCoeff, std::shared_ptr<Cantera::ThermoPhase> gas,
93 std::shared_ptr<Cantera::Transport> trans);
94
95 inline void computeSpeciesReactionRates(const MFloat& m_timeStep, const MFloat& cellVolume,
96 const MFloat* const pvarsCell, const MFloat* const avarsCell,
97 MFloat* const reactionRatesCell, Cantera::IdealGasReactor* zeroD_reactor,
98 Cantera::ReactorNet* zeroD_reactorNet, std::shared_ptr<Cantera::Solution> sol,
99 std::shared_ptr<Cantera::ThermoPhase> gas);
100
101 inline void computePrimitiveVariables(const MFloat* const cvarsCell, MFloat* const pvarsCell,
102 const MFloat* const avarsCell);
103
104 inline void computeConservativeVariables(const MFloat* const pvarsCell, MFloat* const cvarsCell,
105 const MFloat* const avarsCell);
106
107 inline void evaluateSensibleEnergy(MFloat& sensibleEnergy, const MFloat* const pvarsCell,
108 const MFloat& meanMolarMass);
109
110 inline void iterateTemperature(MFloat& T, const MFloat* const cvarsCell, const MFloat* const pvarsCell,
111 const MFloat* const avarsCell, const MFloat& velPOW2);
112
113 inline void computeMeanMolarWeight_PV(const MFloat* const pvarsCell, MFloat* const avarsCell);
114
115 inline void computeMeanMolarWeight_CV(const MFloat* const pvarsCell, MFloat* const avarsCell);
116
117 inline void computeGamma(const MFloat* const pvarsCell, MFloat* const avarsCell,
118 std::shared_ptr<Cantera::ThermoPhase> gas);
119
120 inline MFloat computePhi(const MFloat* const Y);
121
122 inline std::vector<std::vector<MFloat>> conservativeSlopes(const MFloat* const pvarsCell,
123 const MFloat* const cvarsCell,
124 const MFloat* const avarsCell,
125 const MFloat* const slopesCell);
126
127 private:
129 using Base::index0;
130 using Base::index1;
131 using Base::m_noSpecies;
132 using Base::m_solverId;
133
134 // Equation specific values
136 using Base::m_gamma;
138 using Base::m_gFGMOrPr;
144
145 using Base::getArray012;
146
149
150
151 void readProperties();
153
154 // To be read from properties file
158
159 // Computed in allocateNoDiffusionCoefficients(noSpecies)
165
166 public:
167 using Base::m_muInfinity;
168 using Base::m_Re0;
169
170 // Stores species NASA coefficients and physical properties
171 struct NASACoefficients;
172 struct SpeciesProperties;
173
176 // Hold indices for primitive and conservative variables
178 struct FluxVariables;
179 struct PrimitiveVariables;
180 struct AdditionalVariables;
181 struct SurfaceCoefficients;
182 static constexpr MBool hasAV = true;
183 static constexpr MBool hasSC = true; // add to other sysEqn
185 FluxVariables* FV = nullptr;
190
194};
195
198template <MInt nDim>
200 static const MInt Segfault = std::numeric_limits<MInt>::min();
201
202 static constexpr MInt RHO_U = 0;
203 static constexpr MInt RHO_V = 1;
204 static constexpr MInt RHO_W = (nDim == 3) ? 2 : Segfault;
205 static constexpr std::array<MInt, nDim> RHO_VV = getArray012();
206 static constexpr MInt RHO_E = nDim;
207 static constexpr MInt RHO = nDim + 1;
208
209 static constexpr MInt RHO_C = nDim + 2;
210
213
214 MInt* RHO_Y = nullptr;
215
216 ConservativeVariables(const MInt noSpecies);
218};
219
222template <MInt nDim>
224 FluxVariables(const MInt noSpecies);
225};
226
229template <MInt nDim>
231 static const MInt Segfault = std::numeric_limits<MInt>::min();
232
233 static constexpr MInt U = 0;
234 static constexpr MInt V = 1;
235 static constexpr MInt W = (nDim == 3) ? 2 : Segfault;
236 static constexpr std::array<MInt, nDim> VV = getArray012();
237 static constexpr MInt RHO = nDim;
238 static constexpr MInt P = nDim + 1;
239
240 static constexpr MInt C = nDim + 2;
241
244
245 const std::array<MString, nDim + 3> varNames = [] {
246 IF_CONSTEXPR(nDim == 2) {
247 std::array<MString, nDim + 3> a = {"u", "v", "rho", "p", "c"};
248 return a;
249 }
250 else {
251 std::array<MString, nDim + 3> a = {"u", "v", "w", "rho", "p", "c"};
252 return a;
253 }
254 }();
255
256 MInt* Y = nullptr;
257
258 PrimitiveVariables(const MInt noSpecies);
260 for(MInt i = 0; i < noVariables; i++) {
261 names[i] = varNames[i];
262 }
263 };
265};
266
267
273template <MInt nDim>
275 const MString majorSpecies = "N2";
277
278 const MFloat referenceTemp = 298.0;
279
280 std::map<std::string, MInt> speciesMap;
281
282 std::vector<MString> speciesName;
283 MFloat* molarMass = nullptr;
284 MFloat* fMolarMass = nullptr;
285 MFloat* specificGasConstant = nullptr;
286 MFloat* fSpecificGasConstant = nullptr;
287 MFloat* standardHeatFormation = nullptr;
288
289 SpeciesProperties(const MInt noSpecies, const FvSysEqnDetChem<nDim>& sysEqn);
291
292 protected:
293 void getSpeciesProperties(const MInt noSpecies, const FvSysEqnDetChem<nDim>& sysEqn);
294};
295
303template <MInt nDim>
305 friend class FvSysEqnDetChem<nDim>;
306 static constexpr MFloat referenceTemp = 298.0;
307 static constexpr MFloat transitionTemp = 1000.0;
308
309 static constexpr MInt totalNumberCoefficientsPerSpecies = 15;
310 static constexpr MInt noNASACoefficients = 7;
311 static constexpr MInt noNASACoefficientsCpPolynomial = 5;
312
313 MFloat* lowTemp = nullptr;
314 MFloat* highTemp = nullptr;
315
316 MFloat* integralLowTemp = nullptr;
317 MFloat* integralHighTemp = nullptr;
318
319 MFloat* lowTempIntegrationConstantsEnergy = nullptr;
320 MFloat* highTempIntegrationConstantsEnergy = nullptr;
321
322 MFloat* lowTempIntegrationConstantsEnthalpy = nullptr;
323 MFloat* highTempIntegrationConstantsEnthalpy = nullptr;
324
325 NASACoefficients(const MInt noSpecies, const FvSysEqnDetChem<nDim>& sysEqn);
327
328 private:
329 void getNASACoefficients(const MInt noSpecies, const FvSysEqnDetChem<nDim>& sysEqn);
330 void computeSensibleEnergyIntegrationConstants(const FvSysEqnDetChem<nDim>& sysEqn);
331};
332
338template <MInt nDim>
340 static const MInt Segfault = std::numeric_limits<MInt>::min();
341
345
346 static constexpr MInt MU = 0;
347 static constexpr MInt LAMBDA = 1;
348 static constexpr MInt CP = 2;
349 static constexpr MInt W_MEAN = 3;
350 static constexpr MInt D0 = 4;
351
352 MInt* D = nullptr;
353 MInt* DT = nullptr;
354
355 SurfaceCoefficients(const MInt noSpecies, const MInt noDiffusionCoefficients,
356 const MInt noThermalDiffusionCoefficients);
358};
359
365template <MInt nDim>
367 static constexpr MInt noVariables = 2;
368
369 static constexpr MInt GAMMA = 0;
370 static constexpr MInt W_MEAN = 1;
371};
372
373
374template <MInt nDim>
375template <MInt stencil>
376inline void FvSysEqnDetChem<nDim>::Ausm(const MInt orientation, const MFloat upwindCoefficient, const MFloat A,
377 const MFloat* const leftVars, const MFloat* const rightVars,
378 const MFloat* const srfcCoeff, MFloat* const flux) {
379 // Multispecies specific variables and coefficients
380 const MFloat CP = srfcCoeff[SC->CP];
381
382 // compute detailed chemistry additional variables
383 MFloat fMeanMolarWeightL = 0.0;
384 MFloat fMeanMolarWeightR = 0.0;
385
386 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
387 fMeanMolarWeightL += leftVars[PV->Y[s]] * m_species->fMolarMass[s];
388 fMeanMolarWeightR += rightVars[PV->Y[s]] * m_species->fMolarMass[s];
389 }
390
391 const MFloat meanMolarWeightL = F1 / fMeanMolarWeightL;
392 const MFloat meanMolarWeightR = F1 / fMeanMolarWeightR;
393 const MFloat specificGasConstantL = m_gasConstant * fMeanMolarWeightL;
394 const MFloat specificGasConstantR = m_gasConstant * fMeanMolarWeightR;
395 const MFloat CVL = CP - specificGasConstantL;
396 const MFloat CVR = CP - specificGasConstantR;
397 const MFloat gammaL = CP / CVL;
398 const MFloat gammaR = CP / CVR;
399
400 // catch the primitive variables rho and p,
401 // compute speed of sound, and interface mach number
402 const MFloat RHOL = leftVars[PV->RHO];
403 const MFloat PL = leftVars[PV->P];
404 const MFloat AL = sqrt(gammaL * mMax(MFloatEps, PL / mMax(MFloatEps, RHOL)));
405 const MFloat ML = leftVars[orientation] / AL;
406
407 const MFloat RHOR = rightVars[PV->RHO];
408 const MFloat PR = rightVars[PV->P];
409 const MFloat AR = sqrt(gammaR * mMax(MFloatEps, PR / mMax(MFloatEps, RHOR)));
410 const MFloat MR = rightVars[orientation] / AR;
411
412 // calculation of the resulting pressure and mach number on the surface
413 const MFloat MLR = 0.5 * (ML + MR);
414 const MFloat PLR = PL * (0.5 + upwindCoefficient * ML) + PR * (0.5 - upwindCoefficient * MR);
415
416 // calculation of the left and right rho*a
417 const MFloat RHO_AL = RHOL * AL;
418 const MFloat RHO_AR = RHOR * AR;
419
420 // calculation of the resulting mass flux through the surface
421 const MFloat RHO_U2 = 0.25 * (MLR * (RHO_AL + RHO_AR) + fabs(MLR) * (RHO_AL - RHO_AR));
422 const MFloat AbsRHO_U2 = fabs(RHO_U2);
423
424 // velocity magnitudes
425 const MFloat U2L = std::inner_product(&leftVars[PV->U], &leftVars[PV->U] + nDim, &leftVars[PV->U], 0.0);
426 const MFloat U2R = std::inner_product(&rightVars[PV->U], &rightVars[PV->U] + nDim, &rightVars[PV->U], 0.0);
427
429 // Compute left sensible energy value
430 MFloat sensibleEnergyL = F0;
431 this->evaluateSensibleEnergy(sensibleEnergyL, leftVars, meanMolarWeightL);
432
433 // Compute right sensible energy value
434 MFloat sensibleEnergyR = F0;
435 this->evaluateSensibleEnergy(sensibleEnergyR, rightVars, meanMolarWeightR);
436
437 const MFloat PLfRHOL = PL / RHOL;
438 const MFloat PRfRHOR = PR / RHOR;
439
440 const MFloat e0 = sensibleEnergyL + 0.5 * U2L + PLfRHOL;
441 const MFloat e1 = sensibleEnergyR + 0.5 * U2R + PRfRHOR;
442
443 std::array<MFloat, nDim> pFactor{};
444 pFactor[orientation] = 1.0;
445
446 for(MUint n = 0; n < nDim; n++) {
447 flux[FV->RHO_VV[n]] = (RHO_U2 * (leftVars[PV->VV[n]] + rightVars[PV->VV[n]])
448 + AbsRHO_U2 * (leftVars[PV->VV[n]] - rightVars[PV->VV[n]]) + PLR * pFactor[n])
449 * A;
450 }
451
452 flux[FV->RHO_E] = (RHO_U2 * (e0 + e1) + AbsRHO_U2 * (e0 - e1)) * A;
453 flux[FV->RHO] = 2.0 * RHO_U2 * A;
454
455 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
456 const MFloat YsL = leftVars[PV->Y[s]];
457 const MFloat YsR = rightVars[PV->Y[s]];
458 flux[FV->RHO_Y[s]] = (RHO_U2 * (YsL + YsR) + AbsRHO_U2 * (YsL - YsR)) * A;
459 }
460}
461
462template <MInt nDim>
463inline void FvSysEqnDetChem<nDim>::AusmBndryCorrection(const MInt orientation, const MFloat A,
464 const MFloat* const leftVars, const MFloat* const rightVars,
465 MFloat* const flux) {
466 const MFloat PL = leftVars[PV->P];
467 const MFloat PR = rightVars[PV->P];
468 const MFloat PLR = 0.5 * (PR + PL);
469
470 std::array<MFloat, nDim> pFactor{};
471 pFactor[orientation] = 1.0;
472
473 for(MUint n = 0; n < nDim; n++) {
474 flux[FV->RHO_VV[n]] = PLR * pFactor[n] * A;
475 }
476
477 flux[FV->RHO_E] = 0.0;
478 flux[FV->RHO] = 0.0;
479
480 // Flux calculation for species transport
481 // TODO labels:FV @Julian, Make noSpecies constexpr
482 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
483 flux[FV->RHO_Y[s]] = 0.0;
484 }
485}
486
487template <MInt nDim>
488inline void FvSysEqnDetChem<nDim>::viscousFluxFivePoint(const MInt orientation, const MFloat A,
489 const MFloat* const vars0, const MFloat* const vars1,
490 const MFloat* const slope0, const MFloat* const slope1,
491 const MFloat* const srfcCoeff, const MFloat f0, const MFloat f1,
492 MFloat* const flux) {
493 std::vector<MFloat> dXdn(PV->m_noSpecies, F0);
494 std::vector<MFloat> J(PV->m_noSpecies, F0);
495 std::vector<MFloat> speciesSensibleEnthalpy(PV->m_noSpecies, F0);
496
497
498 // Constant coefficients defined at the surface from left and right values
499 const MFloat mue = srfcCoeff[SC->MU];
500 const MFloat lambda = srfcCoeff[SC->LAMBDA];
501 const MFloat meanMolarMass = srfcCoeff[SC->W_MEAN];
502
503 MFloat mue_wm = 0.0;
504
505 const std::array<MFloat, nDim> velocity = [&] {
506 std::array<MFloat, nDim> tmp{};
507 for(MUint n = 0; n < nDim; n++) {
508 tmp[n] = F1B2 * (vars0[PV->VV[n]] + vars1[PV->VV[n]]);
509 }
510 return tmp;
511 }();
512
513 const MFloat rho = F1B2 * (vars0[PV->RHO] + vars1[PV->RHO]);
514 const MFloat Frho = F1 / rho;
515 const MFloat p = F1B2 * (vars0[PV->P] + vars1[PV->P]);
516
517 // Compute the temperature through equation of state (ideal gas)
518 const MFloat T = p * Frho * meanMolarMass * m_fGasConstant;
519
520 // Indices for the orientations
521 const MUint id0 = orientation;
522 const MUint id1 = index0[orientation];
523 const MUint id2 = index1[orientation];
524
525 const MBool isLowTempRegion = (T < m_NASA->transitionTemp);
526 const MFloat* const NASAIntegralCoeffs =
527 isLowTempRegion ? ALIGNED_F(m_NASA->integralLowTemp) : ALIGNED_F(m_NASA->integralHighTemp);
528 const MFloat* const NASAIntegralConstants = isLowTempRegion ? ALIGNED_F(m_NASA->lowTempIntegrationConstantsEnthalpy)
529 : ALIGNED_F(m_NASA->highTempIntegrationConstantsEnthalpy);
530
531 // Compute species sensible enthalpy
532 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
533 const MFloat speciesSpecificGasConstant = m_species->specificGasConstant[s];
534
535 MFloat sensibleEnthalpy = F0;
536 MInt offsetIntegralCoeffs = m_NASA->noNASACoefficientsCpPolynomial * s;
537
538 for(MInt i = 4; (i < 5) && (i >= 0); --i) {
539 sensibleEnthalpy = sensibleEnthalpy * T + NASAIntegralCoeffs[offsetIntegralCoeffs + i];
540 }
541
542 sensibleEnthalpy *= speciesSpecificGasConstant * T;
543 sensibleEnthalpy -= NASAIntegralConstants[s];
544
545 speciesSensibleEnthalpy[s] = sensibleEnthalpy;
546 }
547
548
549 MFloat dTdn = F0;
550 MFloat diffEnthalpyFlux = F0;
551
552 std::fill(J.begin(), J.end(), F0);
553 std::fill(dXdn.begin(), dXdn.end(), F0);
554
555 getSpeciesDiffusionMassFluxes(orientation, vars0, vars1, slope0, slope1, srfcCoeff, f0, f1, J, dXdn, dTdn,
556 m_soretEffect);
557
558
559 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
560 diffEnthalpyFlux += speciesSensibleEnthalpy[s] * J[s];
561 }
562
563 const MFloat q = lambda * dTdn - diffEnthalpyFlux;
564
565 // Compute the stress terms
566 const MUint s00 = id0 * nDim + id0;
567 const MUint s01 = id0 * nDim + id1;
568 const MUint s10 = id1 * nDim + id0;
569 const MUint s11 = id1 * nDim + id1;
570
571 std::array<MFloat, nDim> tau{};
572 IF_CONSTEXPR(nDim == 2) {
573 tau[id0] = (mue + mue_wm)
574 * (f0 * (F4B3 * slope0[s00] - F2B3 * slope0[s11]) + f1 * (F4B3 * slope1[s00] - F2B3 * slope1[s11]));
575 tau[id1] = (mue + mue_wm) * (f0 * (slope0[s01] + slope0[s10]) + f1 * (slope1[s01] + slope1[s10]));
576 }
577 else IF_CONSTEXPR(nDim == 3) {
578 const MUint s22 = id2 * nDim + id2;
579 const MUint s02 = id0 * nDim + id2;
580 const MUint s20 = id2 * nDim + id0;
581 tau[id0] = (mue + mue_wm)
582 * (f0 * (F4B3 * slope0[s00] - F2B3 * (slope0[s11] + slope0[s22]))
583 + f1 * (F4B3 * slope1[s00] - F2B3 * (slope1[s11] + slope1[s22])));
584 tau[id1] = (mue + mue_wm) * (f0 * (slope0[s01] + slope0[s10]) + f1 * (slope1[s01] + slope1[s10]));
585 tau[id2] = (mue + mue_wm) * (f0 * (slope0[s02] + slope0[s20]) + f1 * (slope1[s02] + slope1[s20]));
586 }
587
588 // Compute the flux
589 for(MUint n = 0; n < nDim; n++) {
590 flux[FV->RHO_VV[n]] -= A * tau[n];
591 }
592 flux[FV->RHO_E] -= A * (std::inner_product(velocity.begin(), velocity.end(), tau.begin(), 0.0) + q);
593
594 // Species transport equations
596 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
597 flux[FV->RHO_Y[s]] -= -A * J[s]; // remove
598 }
599}
600
601template <MInt nDim>
603 const MInt orientation, const MFloat* const vars0, const MFloat* const vars1, const MFloat* const slope0,
604 const MFloat* const slope1, const MFloat* const srfcCoeff, const MFloat f0, const MFloat f1, std::vector<MFloat>& J,
605 std::vector<MFloat>& dXdn, MFloat& dTdn, const MBool soretEffect) {
606 std::vector<MFloat> speciesDiffusionMassFlux(PV->m_noSpecies, F0); // j_k
607 std::vector<MFloat> d(PV->m_noSpecies, F0);
608 std::vector<MFloat> VX(PV->m_noSpecies, F0);
609
610 const MFloat rho = F1B2 * (vars0[PV->RHO] + vars1[PV->RHO]);
611 const MFloat Frho = F1 / rho;
612 const MFloat p = F1B2 * (vars0[PV->P] + vars1[PV->P]);
613 const MFloat Fp = F1 / p;
614
615 const MFloat meanMolarMass = srfcCoeff[SC->W_MEAN];
616 const MFloat fMeanMolarMass = F1 / meanMolarMass;
617
618 // Compute the temperature through equation of state (ideal gas)
619 const MFloat T = p * Frho * meanMolarMass * m_fGasConstant;
620 const MFloat FT = F1 / T;
621
622 // Indices for the orientations
623 const MUint id0 = orientation;
624
625 const MUint sq0 = PV->P * nDim + id0;
626 const MUint sq1 = PV->RHO * nDim + id0;
627
628 const MFloat dPdn = f0 * slope0[sq0] + f1 * slope1[sq0];
629 const MFloat dRhodn = f0 * slope0[sq1] + f1 * slope1[sq1];
630
631 MFloat summSpeciesGradients = F0;
632 for(MUint s = 0; s < PV->m_noSpecies; s++) {
633 const MUint sqs = PV->Y[s] * nDim + id0;
634 summSpeciesGradients += m_species->fMolarMass[s] * (f0 * slope0[sqs] + f1 * slope1[sqs]);
635 }
636
637 const MFloat dWdn = -POW2(srfcCoeff[SC->W_MEAN]) * summSpeciesGradients;
638
639 for(MUint s = 0; s < PV->m_noSpecies; s++) {
640 const MUint sqs = PV->Y[s] * nDim + id0;
641 const MFloat Ys = F1B2 * (vars0[PV->Y[s]] + vars1[PV->Y[s]]);
642 dXdn[s] = m_species->fMolarMass[s] * (meanMolarMass * (f0 * slope0[sqs] + f1 * slope1[sqs]) + dWdn * Ys);
643 }
644
645 dTdn = m_fGasConstant * (p * Frho * dWdn + (Frho * meanMolarMass * (dPdn - p * Frho * dRhodn)));
646
647 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
648 const MFloat Ys = F1B2 * (vars0[PV->Y[s]] + vars1[PV->Y[s]]);
649 d[s] = dXdn[s] + (meanMolarMass * m_species->fMolarMass[s] * Ys - Ys) * Fp * dPdn;
650 }
651
652 if(m_multiDiffusion) {
653 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
654 for(MUint j = 0; j < PV->m_noSpecies; ++j) {
655 if(j == s) continue;
656 VX[s] += m_species->molarMass[j] * srfcCoeff[SC->D[PV->m_noSpecies * j + s]] * d[j];
657 }
658
659 VX[s] *= fMeanMolarMass;
660
661 if(soretEffect) VX[s] -= srfcCoeff[SC->DT[s]] * meanMolarMass * Frho * m_species->fMolarMass[s] * FT * dTdn;
662
663 J[s] = rho * m_species->molarMass[s] * fMeanMolarMass * VX[s];
664 }
665 } else {
666 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
667 // TODO labels:FV check
668 VX[s] = -srfcCoeff[SC->D[s]] * dXdn[s];
669
670 J[s] = rho * m_species->molarMass[s] * fMeanMolarMass * VX[s];
671 }
672 }
673}
674
675template <MInt nDim>
676inline void FvSysEqnDetChem<nDim>::computePrimitiveVariables(const MFloat* const cvarsCell, MFloat* const pvarsCell,
677 const MFloat* const avarsCell) {
678 const MFloat fRho = F1 / cvarsCell[CV->RHO];
679
680 MFloat velPOW2 = F0;
681 for(MInt n = 0; n < nDim; ++n) { // compute velocity
682 pvarsCell[PV->VV[n]] = cvarsCell[CV->RHO_VV[n]] * fRho;
683 velPOW2 += POW2(pvarsCell[PV->VV[n]]);
684 }
685
686 // Density
687 pvarsCell[PV->RHO] = cvarsCell[CV->RHO];
688
689 // Compute the species
690 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
691 pvarsCell[PV->Y[s]] = mMax(F0, mMin(F1, cvarsCell[CV->RHO_Y[s]] * fRho));
692 }
693
694 MFloat T = F0;
695 iterateTemperature(T, cvarsCell, pvarsCell, avarsCell, velPOW2);
696
697 pvarsCell[PV->P] = pvarsCell[PV->RHO] * T * m_gasConstant / avarsCell[AV->W_MEAN];
698
699#ifndef NDEBUG
700 if(isnan(pvarsCell[PV->P]) || isnan(pvarsCell[PV->RHO]) || isnan(T)) {
701 std::cout << "FvSysEqnDetChem<nDim>::computePrimitiveVariables has NaN value. T: " << T
702 << ", rho: " << pvarsCell[PV->RHO] << ", p: " << pvarsCell[PV->P] << std::endl;
703 }
704
705 if(pvarsCell[PV->P] < 0 || pvarsCell[PV->RHO] < 0 || T < 0) {
706 std::cout << "FvSysEqnDetChem<nDim>::computePrimitiveVariables has negative value. T: " << T
707 << ", rho: " << pvarsCell[PV->RHO] << ", p: " << pvarsCell[PV->P] << std::endl;
708 }
709#endif
710}
711
723template <MInt nDim>
724inline void FvSysEqnDetChem<nDim>::iterateTemperature(MFloat& T, const MFloat* const cvarsCell,
725 const MFloat* const NotUsed(pvarsCell),
726 const MFloat* const avarsCell, const MFloat& velPOW2) {
727 const MFloat energyZeroLevel = m_gasConstant * m_species->referenceTemp / avarsCell[AV->W_MEAN];
728
729 MFloat LHS = cvarsCell[CV->RHO_E] / cvarsCell[CV->RHO] - F1B2 * velPOW2 + energyZeroLevel;
730
731 // TODO labels:FV Change to old variables and convergence check
732 // Supply initial temperature value to start iteration
733 MFloat T_n = 300.0;
734
735 for(MInt it = 0; it < 10; ++it) {
736 const MBool isLowTempRegion = (T_n < m_NASA->transitionTemp);
737 // Assigns relevant low or high temperature coefficients and integration constants
738 const MFloat* const NASACoeffs = isLowTempRegion ? ALIGNED_F(m_NASA->lowTemp) : ALIGNED_F(m_NASA->highTemp);
739 const MFloat* const NASAIntegralCoeffs =
740 isLowTempRegion ? ALIGNED_F(m_NASA->integralLowTemp) : ALIGNED_F(m_NASA->integralHighTemp);
741 const MFloat* const NASAIntegralConstants = isLowTempRegion ? ALIGNED_F(m_NASA->lowTempIntegrationConstantsEnergy)
742 : ALIGNED_F(m_NASA->highTempIntegrationConstantsEnergy);
743
744 MFloat T_nPlus1 = F0, f_xi = F0, fS_xi = F0;
745 for(MUint s = 0; s < PV->m_noSpecies; s++) {
746 const MInt offsetIntegralCoeffs = m_NASA->noNASACoefficientsCpPolynomial * s;
747 const MInt offsetNASAPolynomial = m_NASA->noNASACoefficients * s;
748 const MFloat Y_s = cvarsCell[CV->RHO_Y[s]] / cvarsCell[CV->RHO];
749 const MFloat specificGasConstant = m_species->specificGasConstant[s];
750
751 // Calculate NASA polynomial for species s with the Horner's rule
752 MFloat NASAIntegralPolynomial = F0, NASAPolynomial = F0;
753 for(MInt i = 4; (i < 5) && (i >= 0); i--) {
754 NASAIntegralPolynomial = NASAIntegralPolynomial * T_n + NASAIntegralCoeffs[offsetIntegralCoeffs + i];
755 NASAPolynomial = NASAPolynomial * T_n + NASACoeffs[offsetNASAPolynomial + i];
756 }
757
758 NASAIntegralPolynomial *= specificGasConstant;
759 NASAPolynomial *= specificGasConstant;
760
761 NASAIntegralPolynomial = (NASAIntegralPolynomial - specificGasConstant) * T_n;
762 NASAPolynomial -= specificGasConstant;
763
764 f_xi += NASAIntegralPolynomial * Y_s;
765 f_xi -= NASAIntegralConstants[s] * Y_s;
766 fS_xi += NASAPolynomial * Y_s;
767 }
768
769 f_xi -= LHS;
770 T_nPlus1 = T_n - (f_xi / fS_xi);
771 T_n = T_nPlus1;
772 }
773
774 T = T_n;
775}
776
785template <MInt nDim>
786inline void FvSysEqnDetChem<nDim>::evaluateSensibleEnergy(MFloat& sensibleEnergy, const MFloat* const pvarsCell,
787 const MFloat& meanMolarMass) {
788 const MFloat T = pvarsCell[PV->P] / pvarsCell[PV->RHO] * meanMolarMass * m_fGasConstant;
789 const MBool isLowTempRegion = (T < m_NASA->transitionTemp);
790
791 const MFloat* const NASAIntegralCoeffs =
792 isLowTempRegion ? ALIGNED_F(m_NASA->integralLowTemp) : ALIGNED_F(m_NASA->integralHighTemp);
793 const MFloat* const NASAIntegralConstants = isLowTempRegion ? ALIGNED_F(m_NASA->lowTempIntegrationConstantsEnergy)
794 : ALIGNED_F(m_NASA->highTempIntegrationConstantsEnergy);
795
796 for(MUint s = 0; s < PV->m_noSpecies; s++) {
797 MInt offsetIntegralCoeffs = m_NASA->noNASACoefficientsCpPolynomial * s;
798
799 // Calculate NASA polynomial for species s with the Horner's rule
800 MFloat sensibleEnergySpecies = F0, NASAIntegralPolynomial = F0;
801 for(MInt i = 4; (i < 5) && (i >= 0); --i) {
802 NASAIntegralPolynomial = NASAIntegralPolynomial * T + NASAIntegralCoeffs[offsetIntegralCoeffs + i];
803 }
804
805 NASAIntegralPolynomial *= m_species->specificGasConstant[s];
806 NASAIntegralPolynomial = (NASAIntegralPolynomial - m_species->specificGasConstant[s]) * T;
807 sensibleEnergySpecies = NASAIntegralPolynomial - NASAIntegralConstants[s];
808 sensibleEnergy += sensibleEnergySpecies * pvarsCell[PV->Y[s]];
809 }
810
811 // Substract zero level sensible energy
812 sensibleEnergy -= m_gasConstant * m_NASA->referenceTemp / meanMolarMass;
813}
814
815template <MInt nDim>
817 MFloat* const cvarsCell,
818 const MFloat* const avarsCell) {
819 // Compute rho v
820 MFloat velPOW2 = F0;
821 for(MInt vel = 0; vel < nDim; ++vel) {
822 const MFloat v = pvarsCell[vel];
823 cvarsCell[vel] = v * pvarsCell[PV->RHO];
824 velPOW2 += POW2(v);
825 }
826
827 // Copy the density
828 cvarsCell[CV->RHO] = pvarsCell[PV->RHO];
829
830 MFloat sensibleEnergy = F0;
831 evaluateSensibleEnergy(sensibleEnergy, pvarsCell, avarsCell[AV->W_MEAN]);
832
833 cvarsCell[CV->RHO_E] = pvarsCell[PV->RHO] * sensibleEnergy + F1B2 * pvarsCell[PV->RHO] * velPOW2;
834
835 // compute rho Yi
836 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
837 cvarsCell[CV->RHO_Y[s]] = pvarsCell[PV->Y[s]] * pvarsCell[PV->RHO];
838 }
839}
840
858template <MInt nDim>
860 const MFloat& m_timeStep, const MFloat& NotUsed(cellVolume), const MFloat* const pvarsCell,
861 const MFloat* const avarsCell, MFloat* const reactionRatesCell, Cantera::IdealGasReactor* zeroD_reactor,
862 Cantera::ReactorNet* zeroD_reactorNet, std::shared_ptr<Cantera::Solution> sol,
863 std::shared_ptr<Cantera::ThermoPhase> gas) {
864 const MFloat p = pvarsCell[PV->P];
865 const MFloat rho = pvarsCell[PV->RHO];
866 const MFloat meanMolarMass = avarsCell[AV->W_MEAN];
867 const MFloat T = p / rho * meanMolarMass * m_fGasConstant;
868
869 gas->setState_TPY(T, p, &pvarsCell[PV->Y[0]]);
870
871 zeroD_reactor->insert(sol);
872 zeroD_reactorNet->setInitialTime(0.0);
873
874 const MFloat timeStep = m_timeStep;
875 const MFloat reactorDensity_t0 = zeroD_reactor->density();
876
877 zeroD_reactorNet->advance(timeStep);
878
879 auto reactorMassFractions = zeroD_reactor->massFractions();
880 const MFloat reactorDensity = zeroD_reactor->density();
881
882 MFloat C_k_t_0, C_k_deltaT;
883 for(MUint s = 0; s < PV->m_noSpecies; s++) {
884 C_k_t_0 = pvarsCell[PV->Y[s]] * reactorDensity_t0 * m_species->fMolarMass[s];
885 C_k_deltaT = reactorMassFractions[s] * reactorDensity * m_species->fMolarMass[s];
886 reactionRatesCell[s] = ((C_k_deltaT - C_k_t_0) / (timeStep)) * m_species->molarMass[s];
887 }
888}
889
902template <MInt nDim>
903inline void FvSysEqnDetChem<nDim>::computeSurfaceCoefficients(const MInt RKStep, const MFloat* const vars0,
904 const MFloat* const vars1, MFloat* const srfcCoeff,
905 std::shared_ptr<Cantera::ThermoPhase> gas,
906 std::shared_ptr<Cantera::Transport> trans) {
907 // Compute mean molar mass and store species vector
908 std::vector<MFloat> Y_k(PV->m_noSpecies, F0);
909 MFloat fMeanMolarMass = F0;
910 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
911 Y_k[s] = F1B2 * (vars0[PV->Y[s]] + vars1[PV->Y[s]]);
912 fMeanMolarMass += Y_k[s] * m_species->fMolarMass[s];
913 }
914
915 srfcCoeff[SC->W_MEAN] = F1 / fMeanMolarMass;
916
917 // Compute the rest of surface coefficients only at RKStep 0
918 if(RKStep == 0 || m_computeSrfcCoeffsEveryRKStep) {
919 const MFloat p = F1B2 * (vars0[PV->P] + vars1[PV->P]);
920 const MFloat rho = F1B2 * (vars0[PV->RHO] + vars1[PV->RHO]);
921 const MFloat T = p / rho * srfcCoeff[SC->W_MEAN] * m_fGasConstant;
922
923 // Set thermodynamic state of the gas
924 gas->setState_TPY(T, p, &Y_k[0]);
925
926 srfcCoeff[SC->CP] = gas->cp_mass();
927
928 srfcCoeff[SC->MU] = trans->viscosity();
929 srfcCoeff[SC->LAMBDA] = trans->thermalConductivity();
930
931 if(m_multiDiffusion) {
932 // fortran ordering for multicomponent coefficients!
933 trans->getMultiDiffCoeffs(PV->m_noSpecies, &srfcCoeff[SC->D[0]]);
934 trans->getThermalDiffCoeffs(&srfcCoeff[SC->DT[0]]);
935 } else {
936 trans->getMixDiffCoeffs(&srfcCoeff[SC->D[0]]);
937 }
938 }
939}
940
949template <MInt nDim>
950inline void FvSysEqnDetChem<nDim>::computeGamma(const MFloat* const pvarsCell, MFloat* const avarsCell,
951 std::shared_ptr<Cantera::ThermoPhase> gas) {
952 const MFloat T = pvarsCell[PV->P] / pvarsCell[PV->RHO] * avarsCell[AV->W_MEAN] * m_fGasConstant;
953
954 gas->setState_TPY(T, pvarsCell[PV->P], &pvarsCell[PV->Y[0]]);
955
956 const MFloat Cp = gas->cp_mass();
957 const MFloat Cv = Cp - m_gasConstant / avarsCell[AV->W_MEAN];
958
959 avarsCell[AV->GAMMA] = Cp / Cv;
960}
961
973template <MInt nDim>
974inline std::vector<std::vector<MFloat>>
975FvSysEqnDetChem<nDim>::conservativeSlopes(const MFloat* const pvarsCell, const MFloat* const NotUsed(cvarsCell),
976 const MFloat* const avarsCell, const MFloat* const slopesCell) {
977 MFloat U2 = F0;
978 for(MInt i = 0; i < nDim; i++) {
979 U2 += POW2(pvarsCell[PV->VV[i]]);
980 }
981
982 std::vector<std::vector<MFloat>> dQ(PV->noVariables, std::vector<MFloat>(nDim));
983 for(MInt d = 0; d < nDim; d++) {
984 MFloat term1 = F0, term2 = F0, term3 = F0;
985 const MFloat meanMolarMass = avarsCell[AV->W_MEAN];
986 const MFloat T = pvarsCell[PV->P] / pvarsCell[PV->RHO] * meanMolarMass * m_fGasConstant;
987 const MBool isLowTempRegion = (T < m_NASA->transitionTemp);
988
989 const MFloat* const NASACoeffs = isLowTempRegion ? ALIGNED_F(m_NASA->lowTemp) : ALIGNED_F(m_NASA->highTemp);
990 const MFloat* const NASAIntegralCoeffs =
991 isLowTempRegion ? ALIGNED_F(m_NASA->integralLowTemp) : ALIGNED_F(m_NASA->integralHighTemp);
992 const MFloat* const NASAIntegralConstants = isLowTempRegion ? ALIGNED_F(m_NASA->lowTempIntegrationConstantsEnergy)
993 : ALIGNED_F(m_NASA->highTempIntegrationConstantsEnergy);
994
995
996 MFloat dT0Term = F0;
997 MFloat sensibleEnergy = F0;
998 dT0Term += slopesCell[PV->RHO * nDim + d] * m_gasConstant * m_NASA->referenceTemp / meanMolarMass;
999 for(MUint s = 0; s < PV->m_noSpecies; s++) {
1000 dT0Term += pvarsCell[PV->RHO] * m_gasConstant * m_NASA->referenceTemp * slopesCell[PV->Y[s] * nDim + d]
1001 * m_species->fMolarMass[s];
1002 }
1003
1004 MFloat summ_YIntCvdT = F0;
1005 MFloat summ_dYIntCvdT = F0;
1006 for(MUint s = 0; s < PV->m_noSpecies; s++) {
1007 const MInt offsetIntegralCoeffs = m_NASA->noNASACoefficientsCpPolynomial * s;
1008
1009 // Calculate NASA polynomial for species s
1010 MFloat IntCvdT = F0;
1011 MFloat NASAIntegralPolynomial = F0;
1012
1013 // Horner's rule for polynomials
1014 for(MInt i = 4; i >= 0; --i) {
1015 NASAIntegralPolynomial = NASAIntegralPolynomial * T + NASAIntegralCoeffs[offsetIntegralCoeffs + i];
1016 }
1017
1018 NASAIntegralPolynomial *= m_species->specificGasConstant[s];
1019 NASAIntegralPolynomial = (NASAIntegralPolynomial - m_species->specificGasConstant[s]) * T;
1020 IntCvdT = NASAIntegralPolynomial - NASAIntegralConstants[s];
1021 sensibleEnergy += pvarsCell[PV->Y[s]] * IntCvdT;
1022 summ_YIntCvdT += IntCvdT * pvarsCell[PV->Y[s]];
1023 summ_dYIntCvdT += IntCvdT * slopesCell[PV->Y[s] * nDim + d];
1024 }
1025
1026 term1 = slopesCell[PV->RHO * nDim + d] * summ_YIntCvdT;
1027 term2 = pvarsCell[PV->RHO] * summ_dYIntCvdT;
1028
1029 //#####################################
1030 MFloat summSpeciesGradients = F0;
1031 for(MUint s = 0; s < PV->m_noSpecies; s++) {
1032 summSpeciesGradients += m_species->fMolarMass[s] * slopesCell[PV->Y[s] * nDim + d];
1033 }
1034
1035 const MFloat dW_dx = -(POW2(avarsCell[AV->W_MEAN])) * summSpeciesGradients;
1036
1037 const MFloat dT_dx = m_fGasConstant
1038 * (pvarsCell[PV->P] / pvarsCell[PV->RHO] * dW_dx
1039 + F1 / pvarsCell[PV->RHO] * meanMolarMass
1040 * (slopesCell[PV->P * nDim + d]
1041 - pvarsCell[PV->P] / pvarsCell[PV->RHO] * slopesCell[PV->RHO * nDim + d]));
1042
1043 // MFloat term3sub1 = F0, term3sub2 = F0;
1044 MFloat term3sub2 = F0;
1045 for(MUint s = 0; s < PV->m_noSpecies; s++) {
1046 // const MInt offsetIntegralCoeffs = m_NASA->noNASACoefficientsCpPolynomial * s;
1047 const MInt offsetNASAPolynomial = m_NASA->noNASACoefficients * s;
1048 /*
1049 MFloat intdCvdT = F0;
1050 MFloat integrationConstant = F0;
1051 //Cp = F0;
1052 MFloat t2 = F0, t1 = F0;
1053 for(MInt i = 1; i < m_NASA->noNASACoefficientsCpPolynomial; ++i) {
1054 if (isLowTempRegion) {
1055 //intdCvdT = intdCvdT * T + NASACoeffs[offsetNASAPolynomial + i];
1056 //integrationConstant = integrationConstant * m_NASA->referenceTemp + NASACoeffs[offsetNASAPolynomial + i];
1057 intdCvdT += m_species->specificGasConstant[s] * NASACoeffs[offsetNASAPolynomial + i] * std::pow(T, MFloat(i));
1058 integrationConstant += m_species->specificGasConstant[s] * NASACoeffs[offsetNASAPolynomial + i] *
1059 std::pow(m_NASA->referenceTemp, MFloat(i)); } else { intdCvdT += m_species->specificGasConstant[s] *
1060 NASACoeffs[offsetNASAPolynomial + i] * std::pow(T, MFloat(i)); integrationConstant +=
1061 m_species->specificGasConstant[s] * NASACoeffs[offsetNASAPolynomial + i] * std::pow(m_NASA->transitionTemp,
1062 MFloat(i)); t2 += m_species->specificGasConstant[s] * m_NASA->lowTemp[offsetNASAPolynomial + i] *
1063 std::pow(m_NASA->transitionTemp, MFloat(i)); t1 += m_species->specificGasConstant[s] *
1064 m_NASA->lowTemp[offsetNASAPolynomial + i] * std::pow(m_NASA->referenceTemp, MFloat(i)); integrationConstant += t1
1065 - t2;
1066 }
1067 }
1068
1069 term3sub1 += pvarsCell[PV->RHO] * pvarsCell[PV->Y[s]] * dT_dx * (intdCvdT - integrationConstant);*/
1070
1071 MFloat Cv = F0;
1072 for(MInt i = 4; i >= 0; --i) {
1073 Cv = Cv * T + NASACoeffs[offsetNASAPolynomial + i];
1074 }
1075
1076 // this computes heat capacity an constant pressure (cp)
1077 Cv *= m_species->specificGasConstant[s];
1078
1079 // this corrects the value to heat capacity at constant volume (cv = cp - R_k)
1080 Cv -= m_species->specificGasConstant[s];
1081
1082 term3sub2 += pvarsCell[PV->RHO] * pvarsCell[PV->Y[s]] * Cv * dT_dx;
1083 }
1084
1085 term3 = term3sub2;
1086
1087 MFloat sensibleEnergyTerm = term1 + term2 + term3 - dT0Term;
1088
1089 MFloat velocityTerm = F1B2 * U2 * slopesCell[PV->RHO * nDim + d];
1090
1091 for(MInt j = 0; j < nDim; j++) {
1092 velocityTerm += pvarsCell[PV->RHO] * pvarsCell[PV->VV[j]] * slopesCell[PV->VV[j] * nDim + d]; // to change
1093 }
1094
1095 dQ[CV->RHO_E][d] = sensibleEnergyTerm + velocityTerm;
1096
1097 dQ[CV->RHO][d] = slopesCell[PV->RHO * nDim + d];
1098
1099 for(MInt j = 0; j < nDim; j++) {
1100 dQ[CV->RHO_VV[j]][d] =
1101 pvarsCell[PV->VV[j]] * slopesCell[PV->RHO * nDim + d] + pvarsCell[PV->RHO] * slopesCell[PV->VV[j] * nDim + d];
1102 }
1103 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
1104 dQ[CV->RHO_Y[s]][d] =
1105 pvarsCell[PV->Y[s]] * slopesCell[PV->RHO * nDim + d] + pvarsCell[PV->RHO] * slopesCell[PV->Y[s] * nDim + d];
1106 }
1107 }
1108
1109 return dQ;
1110}
1111
1119template <MInt nDim>
1120inline void FvSysEqnDetChem<nDim>::computeMeanMolarWeight_CV(const MFloat* const cvarsCell, MFloat* const avarsCell) {
1121 MFloat fMeanMolarWeight = F0;
1122 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
1123 MFloat fRho = F1 / cvarsCell[CV->RHO];
1124 const MFloat Y_s = fRho * cvarsCell[CV->RHO_Y[s]];
1125 fMeanMolarWeight += Y_s * m_species->fMolarMass[s];
1126 }
1127 avarsCell[AV->W_MEAN] = (F1 / fMeanMolarWeight);
1128}
1129
1137template <MInt nDim>
1138inline void FvSysEqnDetChem<nDim>::computeMeanMolarWeight_PV(const MFloat* const pvarsCell, MFloat* const avarsCell) {
1139 MFloat fMeanMolarWeight = F0;
1140 for(MUint s = 0; s < PV->m_noSpecies; ++s) {
1141 fMeanMolarWeight += pvarsCell[PV->Y[s]] * m_species->fMolarMass[s];
1142 }
1143 avarsCell[AV->W_MEAN] = (F1 / fMeanMolarWeight);
1144}
1145
1146template <MInt nDim>
1148 MInt indexOxidizer = m_species->speciesMap[m_oxidizer];
1149 MInt indexFuel = m_species->speciesMap[m_fuel];
1150
1151 MFloat stochiometricMolarMassRatio = m_species->molarMass[indexFuel] / m_species->molarMass[indexOxidizer];
1152
1153 MFloat phi = (Y[indexFuel] / Y[indexOxidizer]) / (m_fuelOxidizerStochiometricRatio * stochiometricMolarMassRatio);
1154
1155 return phi;
1156}
1157
1158#else
1159
1160// To allow compilation of SysEqnDetChem when CANTERA is not defined
1161template <MInt nDim>
1162class FvSysEqnDetChem : public FvSysEqnNS<nDim> {
1163 public:
1164 FvSysEqnDetChem(const MInt solverId, const MInt noSpecies);
1165
1166 void evaluateSensibleEnergy(MFloat&, const MFloat* const, const MFloat&);
1167 void computeMeanMolarWeight_PV(const MFloat* const, MFloat* const);
1168 void computeMeanMolarWeight_CV(const MFloat* const, MFloat* const);
1169
1170 struct AdditionalVariables;
1171 struct SurfaceCoefficients;
1172 struct NASACoefficients;
1173 struct SpeciesProperties;
1176 static constexpr MBool hasAV = true;
1177 static constexpr MBool hasSC = true; // add to other sysEqn
1180};
1181
1182template <MInt nDim>
1184
1185template <MInt nDim>
1187
1188template <MInt nDim>
1190
1191// Stores species properties
1192template <MInt nDim>
1193struct FvSysEqnDetChem<nDim>::SpeciesProperties {
1194 const MString majorSpecies = "N2";
1195 MInt majorSpeciesIndex;
1196
1197 const MFloat referenceTemp = 298.0;
1198
1199 std::map<std::string, MInt> speciesMap;
1200
1201 std::vector<MString> speciesName;
1202 MFloat* molarMass = nullptr;
1203 MFloat* fMolarMass = nullptr;
1204 MFloat* specificGasConstant = nullptr;
1205 MFloat* fSpecificGasConstant = nullptr;
1206 MFloat* standardHeatFormation = nullptr;
1207};
1208
1210template <MInt nDim>
1211struct FvSysEqnDetChem<nDim>::SurfaceCoefficients {
1212 static const MInt Segfault = std::numeric_limits<MInt>::min();
1213
1217
1218 static constexpr MInt MU = 0;
1219 static constexpr MInt LAMBDA = 1;
1220 static constexpr MInt CP = 2;
1221 static constexpr MInt W_MEAN = 3;
1222 static constexpr MInt D0 = 4;
1223
1224 MInt* D = nullptr;
1225 MInt* DT = nullptr;
1226};
1227
1229template <MInt nDim>
1230struct FvSysEqnDetChem<nDim>::AdditionalVariables {
1231 static constexpr MInt noVariables = 2;
1232
1233 static constexpr MInt GAMMA = 0;
1234 static constexpr MInt W_MEAN = 1;
1235};
1236
1237#endif // WITH_CANTERA
1238
1239#endif // FvSysEqnDetChem_H_
Class containing the special methods of the detailed chemistry formulation. Inherits from the Navier-...
void computePrimitiveVariables(const MFloat *const cvarsCell, MFloat *const pvarsCell, const MFloat *const avarsCell)
PrimitiveVariables * PV
void computeConservativeVariables(const MFloat *const pvarsCell, MFloat *const cvarsCell, const MFloat *const avarsCell)
void AusmBndryCorrection(const MInt orientation, const MFloat A, const MFloat *const leftVars, const MFloat *const rightVars, MFloat *const flux)
static constexpr std::array< MInt, nDim > getArray012()
void viscousFluxFivePoint(const MInt orientation, const MFloat A, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat *const srfcCoeff, const MFloat f0, const MFloat f1, MFloat *const flux)
void Ausm(const MInt orientation, const MFloat upwindCoefficient, const MFloat A, const MFloat *const leftVars, const MFloat *const rightVars, const MFloat *const srfcCoeff, MFloat *const flux)
void computeSurfaceCoefficients(const MInt RKStep, const MFloat *const vars0, const MFloat *const vars1, MFloat *const srfcCoeff, std::shared_ptr< Cantera::ThermoPhase > gas, std::shared_ptr< Cantera::Transport > trans)
Computes the transport coefficients at the surface. These are then used in the computation of the sur...
SurfaceCoefficients * SC
void computeMeanMolarWeight_CV(const MFloat *const pvarsCell, MFloat *const avarsCell)
Computes the mean molar weight from the conservative variables at the cell.
void readProperties()
Reads important variable values from the properties.toml file.
void computeMeanMolarWeight_PV(const MFloat *const, MFloat *const)
ConservativeVariables * CV
void viscousFlux(const MInt, const MFloat, const MBool, const MFloat *const, const MFloat *const, const MFloat *const, const MFloat *const, const MFloat *const, const MFloat *const, const MFloat *const, const MFloat *const, const MFloat *const, const MFloat, const MFloat, MFloat *const)
void iterateTemperature(MFloat &T, const MFloat *const cvarsCell, const MFloat *const pvarsCell, const MFloat *const avarsCell, const MFloat &velPOW2)
Iterates the temperature from the sensible energy. Iteration is necessary, since the heat capacities ...
void allocateNoDiffusionCoefficients(const MInt)
Allocates the correct number of diffusion coefficients depending on the chosen diffusion model....
void viscousFlux(const MInt orientation, const MFloat A, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat *const srfcCoeff, const MFloat f0, const MFloat f1, MFloat *const flux)
void computeMeanMolarWeight_PV(const MFloat *const pvarsCell, MFloat *const avarsCell)
Computes the mean molar weight from the primitive variables at the cell.
FvSysEqnDetChem(const MInt solverId, const MInt noSpecies)
SpeciesProperties * m_species
NASACoefficients * m_NASA
void getSpeciesDiffusionMassFluxes(const MInt orientation, const MFloat *const vars0, const MFloat *const vars1, const MFloat *const slope0, const MFloat *const slope1, const MFloat *const srfcCoeff, const MFloat f0, const MFloat f1, std::vector< MFloat > &J, std::vector< MFloat > &dXdn, MFloat &dTdn, const MBool soretEffect)
MFloat computePhi(const MFloat *const Y)
AdditionalVariables * AV
void evaluateSensibleEnergy(MFloat &sensibleEnergy, const MFloat *const pvarsCell, const MFloat &meanMolarMass)
Computes the sensible energy. Species sensible energy is computed as: e_s = Int(cv(T)dT) - R*T_ref/W_...
static constexpr MBool hasAV
void computeGamma(const MFloat *const pvarsCell, MFloat *const avarsCell, std::shared_ptr< Cantera::ThermoPhase > gas)
Computes gamma at the cell. Used for the computation of the time step.
static constexpr MBool hasSC
void evaluateSensibleEnergy(MFloat &, const MFloat *const, const MFloat &)
std::vector< std::vector< MFloat > > conservativeSlopes(const MFloat *const pvarsCell, const MFloat *const cvarsCell, const MFloat *const avarsCell, const MFloat *const slopesCell)
Reconstructs the conservative slopes from the primitive variables and primitive slopes at the cell....
void computeSpeciesReactionRates(const MFloat &m_timeStep, const MFloat &cellVolume, const MFloat *const pvarsCell, const MFloat *const avarsCell, MFloat *const reactionRatesCell, Cantera::IdealGasReactor *zeroD_reactor, Cantera::ReactorNet *zeroD_reactorNet, std::shared_ptr< Cantera::Solution > sol, std::shared_ptr< Cantera::ThermoPhase > gas)
Computes the species reaction rates. A reactor is constructed at each cell, with equal thermodynamic ...
void computeMeanMolarWeight_CV(const MFloat *const, MFloat *const)
MFloat m_sutherlandConstant
static constexpr std::array< MInt, nDim > getArray012()
MFloat m_sutherlandPlusOneThermal
MFloat m_sutherlandPlusOne
MFloat m_referenceTemperature
MFloat m_F1BGammaMinusOne
static const MUint index1[nDim]
static const MUint index0[nDim]
MFloat m_sutherlandConstantThermal
@ FIVE_POINT
Definition: enums.h:184
@ THREE_POINT
Definition: enums.h:184
constexpr Real POW2(const Real x)
Definition: functions.h:119
constexpr T mMin(const T &x, const T &y)
Definition: functions.h:90
constexpr T mMax(const T &x, const T &y)
Definition: functions.h:94
int32_t MInt
Definition: maiatypes.h:62
uint32_t MUint
Definition: maiatypes.h:63
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
Static indices for accessing additional variables.
Static indices for accessing conservative variables in nDim spatial dimensions.
Static indices for accessing flux variables. In this SysEqn identical to the conservative variables.
Stores all NASA coefficients. NASA coefficients are used to compute the cp and cv values....
Static indices for accessing primitive variables in nDim spatial dimensions.
Struct for storing all relevant species information, which is read from a given mechanism file.
std::map< std::string, MInt > speciesMap
Static indices for accessing surface coefficients.
Definition: contexttypes.h:19