31 template<
class ThermoType>
39 sC_(this->nSpecie_,0),
40 sH_(this->nSpecie_,0),
41 sO_(this->nSpecie_,0),
42 sN_(this->nSpecie_,0),
45 for (
label i=0; i<this->nSpecie_; i++)
48 chemistry.
mixture().specieComposition(i);
51 forAll(curSpecieComposition, j)
54 curSpecieComposition[j];
55 if (curElement.
name() ==
"C")
57 sC_[i] = curElement.
nAtoms();
59 else if (curElement.
name() ==
"H")
61 sH_[i] = curElement.
nAtoms();
63 else if (curElement.
name() ==
"O")
65 sO_[i] = curElement.
nAtoms();
67 else if (curElement.
name() ==
"N")
69 sN_[i] = curElement.
nAtoms();
73 Info<<
"element not considered"<<
endl;
77 if (this->coeffsDict_.found(
"sortPart"))
79 sortPart_ = this->coeffsDict_.template lookup<scalar>(
"sortPart");
86 template<
class ThermoType>
93 template<
class ThermoType>
102 scalarField& completeC(this->chemistry_.completeC());
105 for (
label i=0; i<this->nSpecie_; i++)
111 c1[this->nSpecie_] =
T;
112 c1[this->nSpecie_+1] =
p;
124 scalar CFlux(0.0), HFlux(0.0), OFlux(0.0), NFlux(0.0);
130 forAll(this->chemistry_.reactions(), i)
135 scalar omegaf, omegar;
136 R.
omega(p, T, c1, li, omegaf, omegar);
138 scalar fr =
mag(omegaf) +
mag(omegar);
139 scalar NCi(0.0),NHi(0.0),NOi(0.0),NNi(0.0);
143 scalar stoicCoeff = R.
lhs()[
s].stoichCoeff;
144 NCi += sC_[curIndex]*stoicCoeff;
145 NHi += sH_[curIndex]*stoicCoeff;
146 NOi += sO_[curIndex]*stoicCoeff;
147 NNi += sN_[curIndex]*stoicCoeff;
159 scalar Acoeff = R.
lhs()[Ai].stoichCoeff;
164 scalar Bcoeff = R.
rhs()[Bi].stoichCoeff;
166 if (rABPos(B, A)==-1)
168 label otherS = rABPos(A, B);
171 rABPos(A, B) = NbrABInit[A]++;
172 otherS = rABPos(A, B);
174 rABOtherSpec(A, otherS) = B;
178 CFluxAB(A, otherS) +=
179 fr*Acoeff*sC_[A]*Bcoeff*sC_[B]/NCi;
183 HFluxAB(A, otherS) +=
184 fr*Acoeff*sH_[A]*Bcoeff*sH_[B]/NHi;
188 OFluxAB(A, otherS) +=
189 fr*Acoeff*sO_[A]*Bcoeff*sO_[B]/NOi;
193 NFluxAB(A, otherS) +=
194 fr*Acoeff*sN_[A]*Bcoeff*sN_[B]/NNi;
201 label otherS = rABPos(B, A);
204 CFluxAB(B, otherS) +=
205 fr*Acoeff*sC_[A]*Bcoeff*sC_[B]/NCi;
209 HFluxAB(B, otherS) +=
210 fr*Acoeff*sH_[A]*Bcoeff*sH_[B]/NHi;
214 OFluxAB(B, otherS) +=
215 fr*Acoeff*sO_[A]*Bcoeff*sO_[B]/NOi;
219 NFluxAB(B, otherS) +=
220 fr*Acoeff*sN_[A]*Bcoeff*sN_[B]/NNi;
225 CFlux += fr*Acoeff*sC_[A]*Bcoeff*sC_[B]/NCi;
229 HFlux += fr*Acoeff*sH_[A]*Bcoeff*sH_[B]/NHi;
233 OFlux += fr*Acoeff*sO_[A]*Bcoeff*sO_[B]/NOi;
237 NFlux += fr*Acoeff*sN_[A]*Bcoeff*sN_[B]/NNi;
245 label speciesNumber = 0;
246 for (
label i=0; i<this->nSpecie_; i++)
248 this->activeSpecies_[i] =
false;
257 for (
int A=0; A<this->nSpecie_ ; A++)
259 for (
int j=0; j<NbrABInit[A]; j++)
261 label pairIndex = nP++;
262 pairsFlux[pairIndex] = 0.0;
263 label B = rABOtherSpec(A, j);
264 pairsFlux[pairIndex] += CFluxAB(A, j);
265 source[pairIndex] = A;
275 scalar threshold((1-this->tolerance())*CFlux);
277 label nbToSort(static_cast<label> (nbPairs*sortPart_));
278 nbToSort =
max(nbToSort,1);
280 bool cumRespected(
false);
283 if (startPoint >= nbPairs)
286 <<
"startPoint outside number of pairs without reaching" 291 label nbi =
min(nbToSort, nbPairs-startPoint);
294 for (
int i=0; i<nbi; i++)
296 cumFlux += pairsFlux[idx[startPoint+i]];
297 if (!this->activeSpecies_[source[idx[startPoint+i]]])
299 this->activeSpecies_[source[idx[startPoint+i]]] =
true;
302 if (!this->activeSpecies_[sink[idx[startPoint+i]]])
304 this->activeSpecies_[sink[idx[startPoint+i]]] =
true;
307 if (cumFlux >= threshold)
313 startPoint += nbToSort;
323 for (
int A=0; A<this->nSpecie_ ; A++)
325 for (
int j=0; j<NbrABInit[A]; j++)
327 label pairIndex = nP++;
328 pairsFlux[pairIndex] = 0.0;
329 label B = rABOtherSpec(A, j);
330 pairsFlux[pairIndex] += HFluxAB(A, j);
331 source[pairIndex] = A;
337 scalar threshold((1-this->tolerance())*HFlux);
339 label nbToSort(static_cast<label> (nbPairs*sortPart_));
340 nbToSort =
max(nbToSort,1);
342 bool cumRespected(
false);
345 if (startPoint >= nbPairs)
348 <<
"startPoint outside number of pairs without reaching" 353 label nbi =
min(nbToSort, nbPairs-startPoint);
356 for (
int i=0; i<nbi; i++)
358 cumFlux += pairsFlux[idx[startPoint+i]];
360 if (!this->activeSpecies_[source[idx[startPoint+i]]])
362 this->activeSpecies_[source[idx[startPoint+i]]] =
true;
365 if (!this->activeSpecies_[sink[idx[startPoint+i]]])
367 this->activeSpecies_[sink[idx[startPoint+i]]] =
true;
370 if (cumFlux >= threshold)
376 startPoint += nbToSort;
386 for (
int A=0; A<this->nSpecie_ ; A++)
388 for (
int j=0; j<NbrABInit[A]; j++)
390 label pairIndex = nP++;
391 pairsFlux[pairIndex] = 0.0;
392 label B = rABOtherSpec(A, j);
393 pairsFlux[pairIndex] += OFluxAB(A, j);
394 source[pairIndex] = A;
399 scalar threshold((1-this->tolerance())*OFlux);
401 label nbToSort(static_cast<label> (nbPairs*sortPart_));
402 nbToSort =
max(nbToSort,1);
404 bool cumRespected(
false);
407 if (startPoint >= nbPairs)
410 <<
"startPoint outside number of pairs without reaching" 415 label nbi =
min(nbToSort, nbPairs-startPoint);
418 for (
int i=0; i<nbi; i++)
420 cumFlux += pairsFlux[idx[startPoint+i]];
422 if (!this->activeSpecies_[source[idx[startPoint+i]]])
424 this->activeSpecies_[source[idx[startPoint+i]]] =
true;
427 if (!this->activeSpecies_[sink[idx[startPoint+i]]])
429 this->activeSpecies_[sink[idx[startPoint+i]]] =
true;
432 if (cumFlux >= threshold)
438 startPoint += nbToSort;
448 for (
int A=0; A<this->nSpecie_ ; A++)
450 for (
int j=0; j<NbrABInit[A]; j++)
452 label pairIndex = nP++;
453 pairsFlux[pairIndex] = 0.0;
454 label B = rABOtherSpec(A, j);
455 pairsFlux[pairIndex] += NFluxAB(A, j);
456 source[pairIndex] = A;
461 scalar threshold((1-this->tolerance())*NFlux);
463 label nbToSort(static_cast<label> (nbPairs*sortPart_));
464 nbToSort =
max(nbToSort,1);
466 bool cumRespected(
false);
469 if (startPoint >= nbPairs)
472 <<
"startPoint outside number of pairs without reaching" 477 label nbi =
min(nbToSort, nbPairs-startPoint);
480 for (
int i=0; i<nbi; i++)
482 cumFlux += pairsFlux[idx[startPoint+i]];
484 if (!this->activeSpecies_[source[idx[startPoint+i]]])
486 this->activeSpecies_[source[idx[startPoint+i]]] =
true;
489 if (!this->activeSpecies_[sink[idx[startPoint+i]]])
491 this->activeSpecies_[sink[idx[startPoint+i]]] =
true;
494 if (cumFlux >= threshold)
500 startPoint += nbToSort;
505 forAll(this->chemistry_.reactions(), i)
508 this->chemistry_.reactionsDisabled()[i] =
false;
512 if (!this->activeSpecies_[ss])
514 this->chemistry_.reactionsDisabled()[i] =
true;
518 if (!this->chemistry_.reactionsDisabled()[i])
523 if (!this->activeSpecies_[ss])
525 this->chemistry_.reactionsDisabled()[i] =
true;
532 this->NsSimp_ = speciesNumber;
533 scalarField& simplifiedC(this->chemistry_.simplifiedC());
534 simplifiedC.
setSize(this->NsSimp_+2);
537 Field<label>& c2s(this->chemistry_.completeToSimplifiedIndex());
540 for (
label i=0; i<this->nSpecie_; i++)
542 if (this->activeSpecies_[i])
545 simplifiedC[j] = c[i];
547 if (!this->chemistry_.active(i))
549 this->chemistry_.setActive(i);
557 simplifiedC[this->NsSimp_] =
T;
558 simplifiedC[this->NsSimp_+1] =
p;
559 this->chemistry_.setNsDAC(this->NsSimp_);
562 this->chemistry_.setNSpecie(this->NsSimp_);
Extends standardChemistryModel by adding the TDAC method.
#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.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Ostream & endl(Ostream &os)
Add newline and flush stream.
A list that is sorted upon construction or when explicitly requested with the sort() method...
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.
const labelList & indices() const
Return the list of sorted indices. Updated every sort.
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.
virtual void reduceMechanism(const scalar p, const scalar T, const scalarField &c, const label li)
Reduce the mechanism.
EFA(const IOdictionary &dict, TDACChemistryModel< ThermoType > &chemistry)
Construct from components.
const word & name() const
Return the name of the element.
label nAtoms() const
Return the number of atoms of this element in the specie.
A templated 2D rectangular m x n matrix of objects of <Type>.
basicChemistryModel & chemistry
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
void setSize(const label)
Reset size of List.
const List< specieCoeffs > & rhs() const
Return the components of the right hand side.
virtual ~EFA()
Destructor.
fvModels source(alpha1, mixture.thermo1().rho())
#define R(A, B, C, D, E, F, K, M)
const multiComponentMixture< ThermoType > & mixture() const
Return reference to the mixture.
dimensioned< scalar > mag(const dimensioned< Type > &)
void partialSort(int M, int start)
Partial sort the list (if changed after construction time)
An abstract class for methods of chemical mechanism reduction.