MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
fvcartesiansyseqndetchem.cpp
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
8#include "MEMORY/alloc.h"
9
10#if defined(WITH_CANTERA)
11
19template <MInt nDim>
20FvSysEqnDetChem<nDim>::FvSysEqnDetChem(const MInt solverId, const MInt noSpecies)
21 : FvSysEqnNS<nDim>(solverId, noSpecies) {
22 Cantera::addDirectory("/aia/opt/cantera/build/data");
23
24 CV = new ConservativeVariables(noSpecies);
25 PV = new PrimitiveVariables(noSpecies);
26 FV = new FluxVariables(noSpecies);
27
29
31
33
34 m_species = new SpeciesProperties(noSpecies, *this);
35 m_NASA = new NASACoefficients(noSpecies, *this);
36
37 MFloat m_eps = 1.0e-10;
39 "Unequal reference temperature values in NASA coefficients and species standard enthalpy of formation");
40}
41
48template <MInt nDim>
50 : m_noSpecies(noSpecies), noVariables(nDim + 2 + noSpecies) {
51 if(m_noSpecies > 0) {
52 mAlloc(RHO_Y, m_noSpecies, "FvSysEqnNS::ConservativeVariables::RHO_Y", AT_);
53 for(MUint i = 0; i < m_noSpecies; ++i) {
54 RHO_Y[i] = RHO_C + i;
55 }
56 }
57}
58
65template <MInt nDim>
67
73template <MInt nDim>
75 mDeallocate(RHO_Y);
76}
77
84template <MInt nDim>
86 : m_noSpecies(noSpecies), noVariables(nDim + 2 + noSpecies) {
87 if(m_noSpecies > 0) {
88 mAlloc(Y, m_noSpecies, "FvSysEqnNS::PrimitiveVariables::Y", AT_);
89 for(MUint i = 0; i < m_noSpecies; ++i) {
90 Y[i] = C + i;
91 }
92 }
93}
94
100template <MInt nDim>
102 mDeallocate(Y);
103}
104
112template <MInt nDim>
115 case Multi: {
116 m_multiDiffusion = true;
117 m_noDiffusionCoefficients = noSpecies * noSpecies;
120 } break;
121 case Mix: {
122 m_multiDiffusion = false;
123 m_noDiffusionCoefficients = noSpecies;
126 } break;
127 default: {
128 mTerm(1, AT_, "Diffusion model in properties file does not match any implemented model. Terminating.");
129 } break;
130 }
131}
132
140template <MInt nDim>
142 mAlloc(molarMass, noSpecies, "FvSysEqnDetChem::SpeciesProperties::molarMass", AT_);
143 mAlloc(fMolarMass, noSpecies, "FvSysEqnDetChem::SpeciesProperties::fMolarMass", AT_);
144 mAlloc(specificGasConstant, noSpecies, "FvSysEqnDetChem::SpeciesProperties::specificGasConstant", AT_);
145 mAlloc(fSpecificGasConstant, noSpecies, "FvSysEqnDetChem::SpeciesProperties::fSpecificGasConstant", AT_);
146 mAlloc(standardHeatFormation, noSpecies, "FvSysEqnDetChem::SpeciesProperties::standardHeatFormation", AT_);
147
148 this->getSpeciesProperties(noSpecies, sysEqn);
149}
150
156template <MInt nDim>
158 mDeallocate(molarMass);
159 mDeallocate(fMolarMass);
160 mDeallocate(specificGasConstant);
161 mDeallocate(fSpecificGasConstant);
162 mDeallocate(standardHeatFormation);
163}
164
172template <MInt nDim>
174 const FvSysEqnDetChem<nDim>& sysEqn) {
175 std::shared_ptr<Cantera::Solution> sol(
176 newSolution(sysEqn.m_reactionMechanism, sysEqn.m_phaseName, sysEqn.m_transportModel));
177 std::shared_ptr<Cantera::ThermoPhase> gas(sol->thermo());
178
179 const MInt numberMechanismSpecies = gas->nSpecies();
180
181 if(numberMechanismSpecies != noSpecies) {
182 std::cerr << "noSpecies in mechanism file: " << numberMechanismSpecies
183 << ". noSpecies in simulation properties file: " << noSpecies << std::endl;
184 mTerm(1, AT_,
185 "Number of species included in the mechanism file does not correspond to the number of species defined "
186 "in the properties-file. Terminating.");
187 }
188
189 gas->getMolecularWeights(molarMass); // SI: [kJ/kmol]]
190 speciesName = gas->speciesNames();
191
192 for(MUint s = 0; s < sysEqn.PV->m_noSpecies; s++) {
193 standardHeatFormation[s] = gas->Hf298SS(s); // SI: [J/kmol]]
194 molarMass[s] /= 1000.0; // SI: [kg/mol]
195 fMolarMass[s] = F1 / molarMass[s]; // SI: [mol/kg]
196 standardHeatFormation[s] /= 1000.0; // SI : [J/mol]
197 standardHeatFormation[s] = standardHeatFormation[s] * fMolarMass[s]; // SI : [J/kg]
198 specificGasConstant[s] = sysEqn.m_gasConstant * fMolarMass[s];
199 fSpecificGasConstant[s] = F1 / specificGasConstant[s];
200 }
201
202 auto stringIterator = std::find(speciesName.begin(), speciesName.end(), majorSpecies);
203 if(stringIterator == speciesName.end()) {
204 mTerm(1, AT_, "Given major species name was not found in the species name vector. Terminating.");
205 } else {
206 majorSpeciesIndex = std::distance(speciesName.begin(), stringIterator);
207 }
208
209 // Map an index position with each species name
210 for(MInt s = 0; s < noSpecies; s++) {
211 speciesMap.insert(std::pair<std::string, MInt>(speciesName[s], s));
212 }
213
214#ifndef NDEBUG
215 std::cout << "Detailed chemistry species properties." << std::endl;
216 for(MInt s = 0; s < numberMechanismSpecies; s++) {
217 std::cout << speciesName[s] << ". Molar mass: " << molarMass[s] << ". Heat formation: " << standardHeatFormation[s]
218 << ". Specific gas constant: " << specificGasConstant[s] << std::endl;
219 }
220#endif
221}
222
231template <MInt nDim>
233 mAlloc(lowTemp, noNASACoefficients * noSpecies, "FvSysEqnDetChem::NASACoefficients::lowTemp", AT_);
234 mAlloc(highTemp, noNASACoefficients * noSpecies, "FvSysEqnDetChem::NASACoefficients::highTemp", AT_);
235
236 mAlloc(integralLowTemp, noNASACoefficientsCpPolynomial * noSpecies,
237 "FvSysEqnDetChem::NASACoefficients::integralLowTemp", AT_);
238 mAlloc(integralHighTemp, noNASACoefficientsCpPolynomial * noSpecies,
239 "FvSysEqnDetChem::NASACoefficients::integralHighTemp", AT_);
240
241 mAlloc(lowTempIntegrationConstantsEnergy, noSpecies,
242 "FvSysEqnDetChem::NASACoefficients::lowTempIntegrationConstantsEnergy", AT_);
243 mAlloc(highTempIntegrationConstantsEnergy, noSpecies,
244 "FvSysEqnDetChem::NASACoefficients::highTempIntegrationConstantsEnergy", AT_);
245
246 mAlloc(lowTempIntegrationConstantsEnthalpy, noSpecies,
247 "FvSysEqnDetChem::NASACoefficients::lowTempIntegrationConstantsEnthalpy", AT_);
248 mAlloc(highTempIntegrationConstantsEnthalpy, noSpecies,
249 "FvSysEqnDetChem::NASACoefficients::highTempIntegrationConstantsEnthalpy", AT_);
250
251 this->getNASACoefficients(noSpecies, sysEqn);
252 this->computeSensibleEnergyIntegrationConstants(sysEqn);
253}
254
260template <MInt nDim>
262 mDeallocate(lowTemp);
263 mDeallocate(highTemp);
264
265 mDeallocate(integralLowTemp);
266 mDeallocate(integralHighTemp);
267
268 mDeallocate(lowTempIntegrationConstantsEnergy);
269 mDeallocate(highTempIntegrationConstantsEnergy);
270
271 mDeallocate(lowTempIntegrationConstantsEnthalpy);
272 mDeallocate(highTempIntegrationConstantsEnthalpy);
273}
274
285template <MInt nDim>
287 const FvSysEqnDetChem<nDim>& sysEqn) {
288 std::shared_ptr<Cantera::Solution> sol(
289 Cantera::newSolution(sysEqn.m_reactionMechanism, sysEqn.m_phaseName, sysEqn.m_transportModel));
290 std::shared_ptr<Cantera::ThermoPhase> gas(sol->thermo());
291
292 MFloat* totalNASACoefficients = nullptr;
293 mAlloc(totalNASACoefficients, totalNumberCoefficientsPerSpecies * noSpecies,
294 "FvSysEqnDetChem::NASACoefficients::getNASACoefficients::totalNASACoefficients", AT_);
295
296 MFloat* const NASACoeffs = ALIGNED_F(totalNASACoefficients);
297
298 for(MUint s = 0; s < sysEqn.PV->m_noSpecies; s++) {
299 MInt offset = totalNumberCoefficientsPerSpecies * s;
300 MFloat* const speciesNASACoeffs = ALIGNED_F(NASACoeffs + offset);
301
302 shared_ptr<Cantera::Species> species = gas->species(s);
303 shared_ptr<Cantera::SpeciesThermoInterpType> thermoPhaseInf = species->thermo;
304
305 // Dummy variables for Cantera function
306 size_t n;
307 doublereal tlow, thigh, pref;
308 int type;
309
310 thermoPhaseInf->reportParameters(n, type, tlow, thigh, pref, speciesNASACoeffs);
311 }
312 // Store the NASA coefficients for the low and high temperature regions
313 for(MUint s = 0; s < sysEqn.PV->m_noSpecies; s++) {
314 const MInt offset = totalNumberCoefficientsPerSpecies * s;
315 const MInt offsetRegion = noNASACoefficients * s;
316 for(MInt i = 0; i < totalNumberCoefficientsPerSpecies; i++) {
317 if(i == 0) {
318 continue;
319 } else if((i > 0) && (i < (noNASACoefficients + 1))) {
320 const MInt index = i - 1;
321 highTemp[offsetRegion + index] = totalNASACoefficients[offset + i]; // seems OK
322 } else {
323 const MInt index = i - 1 - noNASACoefficients;
324 lowTemp[offsetRegion + index] = totalNASACoefficients[offset + i]; // seems OK
325 }
326 }
327 }
328 // Compute and store integral coefficients
329 for(MUint s = 0; s < sysEqn.PV->m_noSpecies; s++) {
330 const MInt offsetRegion = noNASACoefficients * s;
331 const MInt offsetIntegral = noNASACoefficientsCpPolynomial * s;
332 for(MInt i = 0; i < 5; i++) {
333 integralLowTemp[offsetIntegral + i] = lowTemp[offsetRegion + i] / (i + 1);
334 integralHighTemp[offsetIntegral + i] = highTemp[offsetRegion + i] / (i + 1);
335 }
336 }
337
338#ifndef NDEBUG
339 for(MUint s = 0; s < sysEqn.PV->m_noSpecies; s++) {
340 std::cout << sysEqn.m_species->speciesName[s] << std::endl;
341
342 MInt offset = s * totalNumberCoefficientsPerSpecies;
343 MInt offset2 = s * noNASACoefficients;
344 MInt offset3 = s * noNASACoefficientsCpPolynomial;
345
346 for(MInt i = 0; i < totalNumberCoefficientsPerSpecies; i++) {
347 std::cout << totalNASACoefficients[offset + i] << " ";
348 }
349 std::cout << std::endl;
350
351 for(MInt i = 0; i < noNASACoefficients; i++) {
352 std::cout << highTemp[offset2 + i] << " ";
353 }
354 std::cout << std::endl;
355 for(MInt i = 0; i < noNASACoefficientsCpPolynomial; i++) {
356 std::cout << integralHighTemp[offset3 + i] << " ";
357 }
358 std::cout << std::endl;
359 for(MInt i = 0; i < noNASACoefficients; i++) {
360 std::cout << lowTemp[offset2 + i] << " ";
361 }
362 std::cout << std::endl;
363 for(MInt i = 0; i < noNASACoefficientsCpPolynomial; i++) {
364 std::cout << integralLowTemp[offset3 + i] << " ";
365 }
366 std::cout << std::endl;
367 }
368#endif
369
370 mDeallocate(totalNASACoefficients);
371}
372
384template <MInt nDim>
386 const FvSysEqnDetChem<nDim>& sysEqn) {
387 for(MUint s = 0; s < sysEqn.PV->m_noSpecies; s++) {
388 MFloat limitTRefEnergy = F0, limitLowTempRegionEnergy = F0, limitHighTempRegionEnergy = F0;
389 MFloat limitTRefEnthalpy = F0, limitLowTempRegionEnthalpy = F0, limitHighTempRegionEnthalpy = F0;
390
391 MFloat speciesSpecificGasConstant = sysEqn.m_species->specificGasConstant[s];
392 MInt offsetIntegralCoeffs = noNASACoefficientsCpPolynomial * s;
393
394 // Horner's rule for polynomials
395 for(MInt i = 4; (i < 5) && (i >= 0); i--) {
396 limitTRefEnergy = limitTRefEnergy * referenceTemp + integralLowTemp[offsetIntegralCoeffs + i];
397 limitLowTempRegionEnergy = limitLowTempRegionEnergy * transitionTemp + integralLowTemp[offsetIntegralCoeffs + i];
398 limitHighTempRegionEnergy =
399 limitHighTempRegionEnergy * transitionTemp + integralHighTemp[offsetIntegralCoeffs + i];
400
401 limitTRefEnthalpy = limitTRefEnthalpy * referenceTemp + integralLowTemp[offsetIntegralCoeffs + i];
402 limitLowTempRegionEnthalpy =
403 limitLowTempRegionEnthalpy * transitionTemp + integralLowTemp[offsetIntegralCoeffs + i];
404 limitHighTempRegionEnthalpy =
405 limitHighTempRegionEnthalpy * transitionTemp + integralHighTemp[offsetIntegralCoeffs + i];
406 }
407
408 limitTRefEnergy *= speciesSpecificGasConstant;
409 limitLowTempRegionEnergy *= speciesSpecificGasConstant;
410 limitHighTempRegionEnergy *= speciesSpecificGasConstant;
411
412 limitTRefEnthalpy *= speciesSpecificGasConstant * referenceTemp;
413 limitLowTempRegionEnthalpy *= speciesSpecificGasConstant * transitionTemp;
414 limitHighTempRegionEnthalpy *= speciesSpecificGasConstant * transitionTemp;
415
416 limitTRefEnergy = (limitTRefEnergy - speciesSpecificGasConstant) * referenceTemp;
417 limitLowTempRegionEnergy = (limitLowTempRegionEnergy - speciesSpecificGasConstant) * transitionTemp;
418 limitHighTempRegionEnergy = (limitHighTempRegionEnergy - speciesSpecificGasConstant) * transitionTemp;
419
420 // Integration constants as defined are SUBSTRACTED in the corresponding equations
421 lowTempIntegrationConstantsEnergy[s] = limitTRefEnergy;
422 highTempIntegrationConstantsEnergy[s] = limitTRefEnergy - limitLowTempRegionEnergy + limitHighTempRegionEnergy;
423
424 lowTempIntegrationConstantsEnthalpy[s] = limitTRefEnthalpy;
425 highTempIntegrationConstantsEnthalpy[s] =
426 limitTRefEnthalpy - limitLowTempRegionEnthalpy + limitHighTempRegionEnthalpy;
427 }
428}
429
440template <MInt nDim>
442 const MInt noDiffusionCoefficients,
443 const MInt noThermalDiffusionCoefficients)
444 : m_noDiffusionCoefficients(noDiffusionCoefficients),
445 m_noThermalDiffusionCoefficients(noThermalDiffusionCoefficients),
446 m_noSurfaceCoefficients(4 + noDiffusionCoefficients + noThermalDiffusionCoefficients) {
447 if(noSpecies > 0) {
448 mAlloc(D, m_noDiffusionCoefficients, "FvSysEqnNS::SurfaceCoefficients::D", AT_);
449 mAlloc(DT, m_noThermalDiffusionCoefficients, "FvSysEqnNS::SurfaceCoefficients::DT", AT_);
450 for(MInt i = 0; i < m_noDiffusionCoefficients; ++i) {
451 D[i] = D0 + i;
452 }
453 for(MInt i = 0; i < m_noThermalDiffusionCoefficients; ++i) {
455 }
456 }
457}
458
464template <MInt nDim>
466 mDeallocate(D);
467 mDeallocate(DT);
468}
469
475template <MInt nDim>
477 m_gasConstant = 8.314472;
478 m_gasConstant = Context::getSolverProperty<MFloat>("gasConstant", m_solverId, AT_, &m_gasConstant);
479
481
482 m_reactionMechanism = Context::getSolverProperty<MString>("reactionMechanism", m_solverId, AT_, &m_reactionMechanism);
483
484 m_transportModel = "Multi";
485 m_transportModel = Context::getSolverProperty<MString>("transportModel", m_solverId, AT_, &m_transportModel);
486
487 m_phaseName = Context::getSolverProperty<MString>("phaseName", m_solverId, AT_, &m_phaseName);
488
490 m_computeSrfcCoeffsEveryRKStep = Context::getSolverProperty<MBool>("computeSrfcCoeffsEveryRKStep", m_solverId, AT_,
492
493 m_soretEffect = true;
494 m_soretEffect = Context::getSolverProperty<MBool>("soretEffect", m_solverId, AT_, &m_soretEffect);
495
496 m_fuelOxidizerStochiometricRatio = 2.0; // default for hydrogen + oxygen
497 m_fuelOxidizerStochiometricRatio = Context::getSolverProperty<MFloat>("fuelOxidizerStochiometricRatio", m_solverId,
499
500 m_oxidizer = "O2";
501 m_oxidizer = Context::getSolverProperty<MString>("oxidizer", m_solverId, AT_, &m_oxidizer);
502
503 m_fuel = "H2";
504 m_fuel = Context::getSolverProperty<MString>("fuel", m_solverId, AT_, &m_fuel);
505}
506
507template class FvSysEqnDetChem<2>;
508template class FvSysEqnDetChem<3>;
509
510#else // WITH_CANTERA
511// To allow compilation of SysEqnDetChem when CANTERA is not defined
512template <MInt nDim>
513FvSysEqnDetChem<nDim>::FvSysEqnDetChem(const MInt solverId, const MInt noSpecies)
514 : FvSysEqnNS<nDim>(solverId, noSpecies) {
515 // Does not allow the sysEqn to be used in a simulation if CANTERA has not been compiled
516 mTerm(1, AT_,
517 "Using detailed chemistry equation system without CANTERA compilation. Recompile enabling --with-cantera in "
518 "configure.py file or select a different equation system. Terminating now.");
519}
520
521template class FvSysEqnDetChem<2>;
522template class FvSysEqnDetChem<3>;
523#endif
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
Definition: alloc.h:173
MBool mDeallocate(T *&a)
deallocates the memory previously allocated for element 'a'
Definition: alloc.h:544
Class containing the special methods of the detailed chemistry formulation. Inherits from the Navier-...
PrimitiveVariables * PV
SurfaceCoefficients * SC
void readProperties()
Reads important variable values from the properties.toml file.
ConservativeVariables * CV
void allocateNoDiffusionCoefficients(const MInt)
Allocates the correct number of diffusion coefficients depending on the chosen diffusion model....
FvSysEqnDetChem(const MInt solverId, const MInt noSpecies)
Construct a new FvSysEqnDetChem<nDim>::FvSysEqnDetChem object.
SpeciesProperties * m_species
NASACoefficients * m_NASA
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
Definition: enums.cpp:20
@ Multi
Definition: enums.h:186
@ Mix
Definition: enums.h:186
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
int32_t MInt
Definition: maiatypes.h:62
uint32_t MUint
Definition: maiatypes.h:63
double MFloat
Definition: maiatypes.h:52
Static indices for accessing conservative variables in nDim spatial dimensions.
ConservativeVariables(const MInt noSpecies)
Construct a new FvSysEqnDetChem<nDim>::ConservativeVariables::ConservativeVariables object.
~ConservativeVariables()
Destroy the FvSysEqnDetChem<nDim>::ConservativeVariables::ConservativeVariables object.
Static indices for accessing flux variables. In this SysEqn identical to the conservative variables.
FluxVariables(const MInt noSpecies)
Construct a new FvSysEqnDetChem<nDim>::FluxVariables::FluxVariables object.
Stores all NASA coefficients. NASA coefficients are used to compute the cp and cv values....
void getNASACoefficients(const MInt noSpecies, const FvSysEqnDetChem< nDim > &sysEqn)
Gets the species 7-NASA Coefficients from the given mechanism file. The NASA Coefficients are then us...
~NASACoefficients()
Destroy the FvSysEqnDetChem<nDim>::NASACoefficients::NASACoefficients object.
NASACoefficients(const MInt noSpecies, const FvSysEqnDetChem< nDim > &sysEqn)
Construct a new FvSysEqnDetChem<nDim>::NASACoefficients::NASACoefficients object. This object stores ...
void computeSensibleEnergyIntegrationConstants(const FvSysEqnDetChem< nDim > &sysEqn)
Computes the sensible energy and enthalpy integration constants to reuse later (for low and high temp...
Static indices for accessing primitive variables in nDim spatial dimensions.
PrimitiveVariables(const MInt noSpecies)
Construct a new FvSysEqnDetChem<nDim>::PrimitiveVariables::PrimitiveVariables object.
~PrimitiveVariables()
Destroy the FvSysEqnDetChem<nDim>::PrimitiveVariables::PrimitiveVariables object.
Struct for storing all relevant species information, which is read from a given mechanism file.
~SpeciesProperties()
Destroy the FvSysEqnDetChem<nDim>::SpeciesProperties::SpeciesProperties object.
SpeciesProperties(const MInt noSpecies, const FvSysEqnDetChem< nDim > &sysEqn)
Construct a new FvSysEqnDetChem<nDim>::SpeciesProperties::SpeciesProperties object.
void getSpeciesProperties(const MInt noSpecies, const FvSysEqnDetChem< nDim > &sysEqn)
Gets important species information and stores it in the member variables of the species struct.
Static indices for accessing surface coefficients.
SurfaceCoefficients(const MInt noSpecies, const MInt noDiffusionCoefficients, const MInt noThermalDiffusionCoefficients)
Construct a new FvSysEqnDetChem<nDim>::SurfaceCoefficients::SurfaceCoefficients object.
~SurfaceCoefficients()
Destroy the FvSysEqnDetChem<nDim>::SurfaceCoefficients::SurfaceCoefficients object.