30 template<
class ThermoType>
41 sC_(this->nSpecie_,0),
42 sH_(this->nSpecie_,0),
43 sO_(this->nSpecie_,0),
44 sN_(this->nSpecie_,0),
51 phiTol_(this->tolerance()),
55 dict.subDict(
"reduction").lookupOrDefault<
word>
62 dict.subDict(
"reduction").lookupOrDefault<
word>
69 dict.subDict(
"reduction").lookupOrDefault<
word>
76 dict.subDict(
"reduction").lookupOrDefault<
word>
83 dict.subDict(
"reduction").lookupOrDefault<
word>
88 forceFuelInclusion_(
false)
90 const wordHashSet initSet(this->coeffsDict_.lookup(
"initialSet"));
93 searchInitSet_.append(chemistry.
mixture().species()[iter.key()]);
96 if (this->coeffsDict_.found(
"automaticSIS"))
98 automaticSIS_.readIfPresent(
"automaticSIS", this->coeffsDict_);
101 if (this->coeffsDict_.found(
"forceFuelInclusion"))
103 forceFuelInclusion_.readIfPresent
105 "forceFuelInclusion",this->coeffsDict_
109 if (this->coeffsDict_.found(
"phiTol"))
111 phiTol_ = this->coeffsDict_.template lookup<scalar>(
"phiTol");
114 if (this->coeffsDict_.found(
"NOxThreshold"))
117 this->coeffsDict_.template lookup<scalar>(
"NOxThreshold");
120 for (
label i=0; i<this->nSpecie_; i++)
123 chemistry.
mixture().specieComposition(i);
126 forAll(curSpecieComposition, j)
129 curSpecieComposition[j];
130 if (curElement.
name() ==
"C")
132 sC_[i] = curElement.
nAtoms();
134 else if (curElement.
name() ==
"H")
136 sH_[i] = curElement.
nAtoms();
138 else if (curElement.
name() ==
"O")
140 sO_[i] = curElement.
nAtoms();
142 else if (curElement.
name() ==
"N")
144 sN_[i] = curElement.
nAtoms();
148 Info<<
"element not considered"<<
endl;
151 if (this->chemistry_.Y()[i].member() == CO2Name_)
155 else if (this->chemistry_.Y()[i].member() == COName_)
159 else if (this->chemistry_.Y()[i].member() == HO2Name_)
163 else if (this->chemistry_.Y()[i].member() == H2OName_)
167 else if (this->chemistry_.Y()[i].member() == NOName_)
173 if ((CO2Id_==-1 || COId_==-1 || HO2Id_==-1 || H2OId_==-1) && automaticSIS_)
176 <<
"The name of the species used in automatic SIS are not found in " 177 <<
" the mechanism. You should either set the name for CO2, CO, H2O" 178 <<
" and HO2 properly or set automaticSIS to off " 188 this->coeffsDict_.lookup(
"fuelSpecies")
191 fuelSpecies_.
setSize(fuelSpeciesEntry.size());
192 fuelSpeciesID_.setSize(fuelSpeciesEntry.size());
193 fuelSpeciesProp_.setSize(fuelSpeciesEntry.size());
196 forAll(fuelSpeciesEntry, i)
198 fuelSpecies_[i] = fuelSpeciesEntry[i].first();
199 fuelSpeciesProp_[i] = fuelSpeciesEntry[i].second();
201 this->chemistry_.mixture().species()[fuelSpecies_[i]];
203 this->chemistry_.specieThermos()[fuelSpeciesID_[i]].W();
204 Mmtot += fuelSpeciesProp_[i]/curMm;
207 this->coeffsDict_.readIfPresent(
"nbCLarge", nbCLarge_);
214 label curID = fuelSpeciesID_[i];
215 scalar curMm = this->chemistry_.specieThermos()[curID].W();
217 nbC += fuelSpeciesProp_[i]*Mmtot/curMm*sC_[curID];
218 nbO += fuelSpeciesProp_[i]*Mmtot/curMm*sO_[curID];
227 template<
class ThermoType>
234 template<
class ThermoType>
243 scalarField& completeC(this->chemistry_.completeC());
245 for(
label i=0; i<this->nSpecie_; i++)
251 c1[this->nSpecie_] =
T;
252 c1[this->nSpecie_+1] =
p;
266 forAll(this->chemistry_.reactions(), i)
271 scalar omegaf, omegar;
272 const scalar omegai = R.
omega(p, T, c1, li, omegaf, omegar);
290 scalar sl = -R.
lhs()[
s].stoichCoeff;
309 while(!usedIndex.empty())
312 if (deltaBi[curIndex])
315 deltaBi[curIndex] =
false;
317 if (rABPos(ss, curIndex)==-1)
320 rABPos(ss, curIndex) = NbrABInit[ss];
323 rABNum(ss, rABPos(ss, curIndex)) = sl*omegai;
325 rABOtherSpec(ss, rABPos(ss, curIndex)) = curIndex;
329 rABNum(ss, rABPos(ss, curIndex)) += sl*omegai;
345 wA.append(sl*omegai);
353 scalar sl = R.
rhs()[
s].stoichCoeff;
372 while(!usedIndex.empty())
375 if (deltaBi[curIndex])
378 deltaBi[curIndex] =
false;
381 if (rABPos(ss, curIndex) == -1)
384 rABPos(ss, curIndex) = NbrABInit[ss];
386 rABNum(ss, rABPos(ss, curIndex)) = sl*omegai;
387 rABOtherSpec(ss, rABPos(ss, curIndex)) = curIndex;
391 rABNum(ss, rABPos(ss, curIndex)) += sl*omegai;
407 wA.append(sl*omegai);
420 if (PA[wAID[
id]] == 0.0)
422 PA[wAID[id]] = wA[id];
426 PA[wAID[id]] += wA[id];
431 if (CA[wAID[
id]] == 0.0)
433 CA[wAID[id]] = -wA[id];
437 CA[wAID[id]] += -wA[id];
444 scalar phiLarge(0.0);
445 scalar phiProgress(0.0);
456 for (
label i=0; i<this->nSpecie_; i++)
461 this->chemistry_.Y()[i].member() ==
"CO2" 462 || this->chemistry_.Y()[i].member() ==
"H2O" 467 Na[0] += sC_[i]*c[i];
468 Na[1] += sH_[i]*c[i];
469 Na[2] += sO_[i]*c[i];
470 if (sC_[i]>nbCLarge_ || this->chemistry_.Y()[i].member() ==
"O2")
472 Nal[0] += sC_[i]*c[i];
473 Nal[1] += sH_[i]*c[i];
474 Nal[2] += sO_[i]*c[i];
483 phiProgress = (2*Na[0]+Na[1]/2-zprime_*Na[0])/(Na[2]-zprime_*Na[0]);
488 phiLarge = (2*Nal[0]+Nal[1]/2)/Nal[2];
494 label speciesNumber = 0;
498 for (
label i=0; i<this->nSpecie_; i++)
500 this->activeSpecies_[i] =
false;
512 if (phiLarge >= phiTol_ && phiProgress >= phiTol_)
518 this->activeSpecies_[COId_] =
true;
522 this->activeSpecies_[HO2Id_] =
true;
523 Rvalue[HO2Id_] = 1.0;
526 Q.
push(fuelSpeciesID_[i]);
528 this->activeSpecies_[fuelSpeciesID_[i]] =
true;
529 Rvalue[fuelSpeciesID_[i]] = 1.0;
533 else if (phiLarge < phiTol_ && phiProgress >= phiTol_)
539 this->activeSpecies_[COId_] =
true;
543 this->activeSpecies_[HO2Id_] =
true;
544 Rvalue[HO2Id_] = 1.0;
546 if (forceFuelInclusion_)
550 Q.
push(fuelSpeciesID_[i]);
552 this->activeSpecies_[fuelSpeciesID_[i]] =
true;
553 Rvalue[fuelSpeciesID_[i]] = 1.0;
563 this->activeSpecies_[CO2Id_] =
true;
564 Rvalue[CO2Id_] = 1.0;
568 this->activeSpecies_[H2OId_] =
true;
569 Rvalue[H2OId_] = 1.0;
570 if (forceFuelInclusion_)
574 Q.
push(fuelSpeciesID_[i]);
576 this->activeSpecies_[fuelSpeciesID_[i]] =
true;
577 Rvalue[fuelSpeciesID_[i]] = 1.0;
582 if (T>NOxThreshold_ && NOId_!=-1)
586 this->activeSpecies_[NOId_] =
true;
595 this->activeSpecies_[q] =
true;
606 scalar Den =
max(PA[u],CA[u]);
609 for (
label v=0; v<NbrABInit[u]; v++)
611 label otherSpec = rABOtherSpec(u, v);
612 scalar rAB =
mag(rABNum(u, v))/Den;
618 if (rAB >= this->tolerance())
620 scalar Rtemp = Rvalue[u]*rAB;
624 if ((Rvalue[otherSpec]<Rtemp) && (Rtemp>=this->tolerance()))
627 Rvalue[otherSpec] = Rtemp;
628 if (!this->activeSpecies_[otherSpec])
630 this->activeSpecies_[otherSpec] =
true;
640 forAll(this->chemistry_.reactions(), i)
643 this->chemistry_.reactionsDisabled()[i] =
false;
648 if (!this->activeSpecies_[ss])
651 this->chemistry_.reactionsDisabled()[i] =
true;
655 if (!this->chemistry_.reactionsDisabled()[i])
660 if (!this->activeSpecies_[ss])
663 this->chemistry_.reactionsDisabled()[i] =
true;
670 this->NsSimp_ = speciesNumber;
671 scalarField& simplifiedC(this->chemistry_.simplifiedC());
672 simplifiedC.
setSize(this->NsSimp_+2);
675 Field<label>& c2s(this->chemistry_.completeToSimplifiedIndex());
678 for (
label i=0; i<this->nSpecie_; i++)
680 if (this->activeSpecies_[i])
683 simplifiedC[j] = c[i];
685 if (!this->chemistry_.active(i))
687 this->chemistry_.setActive(i);
696 simplifiedC[this->NsSimp_] =
T;
697 simplifiedC[this->NsSimp_+1] =
p;
698 this->chemistry_.setNsDAC(this->NsSimp_);
702 this->chemistry_.setNSpecie(this->NsSimp_);
A FIFO stack based on a singly-linked list.
Extends standardChemistryModel by adding the TDAC method.
A HashTable with keys but without contents.
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual void reduceMechanism(const scalar p, const scalar T, const scalarField &c, const label li)
Reduce the mechanism.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void size(const label)
Override size to be inconsistent with allocated storage.
Ostream & endl(Ostream &os)
Add newline and flush stream.
const List< specieCoeffs > & lhs() const
Return the components of the left hand side.
Simple extension of ReactionThermo to handle reaction kinetics in addition to the equilibrium thermod...
void omega(const scalar p, const scalar T, const scalarField &c, const label li, scalarField &dcdt) const
Net reaction rate for individual species.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
const dimensionedScalar c1
First radiation constant: default SI units: [W/m^2].
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
void setSize(const label)
Alter the addressed list size.
A class for handling words, derived from string.
const word & name() const
Return the name of the element.
label nAtoms() const
Return the number of atoms of this element in the specie.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
basicChemistryModel & chemistry
virtual ~DAC()
Destructor.
void setSize(const label)
Reset size of List.
DAC(const IOdictionary &dict, TDACChemistryModel< ThermoType > &chemistry)
Construct from components.
const List< specieCoeffs > & rhs() const
Return the components of the right hand side.
#define R(A, B, C, D, E, F, K, M)
void push(const T &a)
Push an element onto the stack.
const multiComponentMixture< ThermoType > & mixture() const
Return reference to the mixture.
dimensioned< scalar > mag(const dimensioned< Type > &)
T pop()
Pop the bottom element off the stack.
An abstract class for methods of chemical mechanism reduction.