TDACChemistryModel.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016-2017 OpenFOAM Foundation
9  Copyright (C) 2016-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "TDACChemistryModel.H"
30 #include "UniformField.H"
31 #include "localEulerDdtScheme.H"
32 #include "clockTime.H"
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
36 template<class ReactionThermo, class ThermoType>
38 (
39  ReactionThermo& thermo
40 )
41 :
43  variableTimeStep_
44  (
45  this->mesh().time().controlDict().getOrDefault
46  (
47  "adjustTimeStep",
48  false
49  )
50  || fv::localEulerDdt::enabled(this->mesh())
51  ),
52  timeSteps_(0),
53  NsDAC_(this->nSpecie_),
54  completeC_(this->nSpecie_, 0),
55  reactionsDisabled_(this->reactions_.size(), false),
56  specieComp_(this->nSpecie_),
57  completeToSimplifiedIndex_(this->nSpecie_, -1),
58  simplifiedToCompleteIndex_(this->nSpecie_),
59  tabulationResults_
60  (
61  IOobject
62  (
63  thermo.phasePropertyName("TabulationResults"),
64  this->time().timeName(),
65  this->mesh(),
66  IOobject::NO_READ,
67  IOobject::AUTO_WRITE
68  ),
69  this->mesh(),
71  )
72 {
73  basicSpecieMixture& composition = this->thermo().composition();
74 
75  // Store the species composition according to the species index
76  speciesTable speciesTab = composition.species();
77 
78  const HashTable<List<specieElement>>& specComp =
79  dynamicCast<const reactingMixture<ThermoType>&>(this->thermo())
80  .specieComposition();
81 
82  forAll(specieComp_, i)
83  {
84  specieComp_[i] = specComp[this->Y()[i].member()];
85  }
86 
88  (
89  *this,
90  *this
91  );
92 
93  // When the mechanism reduction method is used, the 'active' flag for every
94  // species should be initialized (by default 'active' is true)
95  if (mechRed_->active())
96  {
97  forAll(this->Y(), i)
98  {
99  IOobject header
100  (
101  this->Y()[i].name(),
102  this->mesh().time().timeName(),
103  this->mesh(),
104  IOobject::NO_READ
105  );
106 
107  // Check if the species file is provided, if not set inactive
108  // and NO_WRITE
109  if (!header.typeHeaderOk<volScalarField>(true))
110  {
111  composition.setInactive(i);
112  this->Y()[i].writeOpt() = IOobject::NO_WRITE;
113  }
114  }
115  }
116 
118  (
119  *this,
120  *this
121  );
122 
123  if (mechRed_->log())
124  {
125  cpuReduceFile_ = logFile("cpu_reduce.out");
126  nActiveSpeciesFile_ = logFile("nActiveSpecies.out");
127  }
128 
129  if (tabulation_->log())
130  {
131  cpuAddFile_ = logFile("cpu_add.out");
132  cpuGrowFile_ = logFile("cpu_grow.out");
133  cpuRetrieveFile_ = logFile("cpu_retrieve.out");
134  }
135 
136  if (mechRed_->log() || tabulation_->log())
137  {
138  cpuSolveFile_ = logFile("cpu_solve.out");
139  }
140 }
141 
142 
143 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
144 
145 template<class ReactionThermo, class ThermoType>
147 {}
148 
149 
150 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
151 
152 template<class ReactionThermo, class ThermoType>
154 (
155  const scalarField& c, // Contains all species even when mechRed is active
156  const scalar T,
157  const scalar p,
158  scalarField& dcdt
159 ) const
160 {
161  const bool reduced = mechRed_->active();
162 
163  scalar pf, cf, pr, cr;
164  label lRef, rRef;
165 
166  dcdt = Zero;
167 
168  forAll(this->reactions_, i)
169  {
170  if (!reactionsDisabled_[i])
171  {
172  const Reaction<ThermoType>& R = this->reactions_[i];
173 
174  scalar omegai = omega
175  (
176  R, c, T, p, pf, cf, lRef, pr, cr, rRef
177  );
178 
179  forAll(R.lhs(), s)
180  {
181  label si = R.lhs()[s].index;
182  if (reduced)
183  {
184  si = completeToSimplifiedIndex_[si];
185  }
186 
187  const scalar sl = R.lhs()[s].stoichCoeff;
188  dcdt[si] -= sl*omegai;
189  }
190  forAll(R.rhs(), s)
191  {
192  label si = R.rhs()[s].index;
193  if (reduced)
194  {
195  si = completeToSimplifiedIndex_[si];
196  }
197 
198  const scalar sr = R.rhs()[s].stoichCoeff;
199  dcdt[si] += sr*omegai;
200  }
201  }
202  }
203 }
204 
205 
206 template<class ReactionThermo, class ThermoType>
208 (
209  const Reaction<ThermoType>& R,
210  const scalarField& c, // Contains all species even when mechRed is active
211  const scalar T,
212  const scalar p,
213  scalar& pf,
214  scalar& cf,
215  label& lRef,
216  scalar& pr,
217  scalar& cr,
218  label& rRef
219 ) const
220 {
221  const scalar kf = R.kf(p, T, c);
222  const scalar kr = R.kr(kf, p, T, c);
223 
224  const label Nl = R.lhs().size();
225  const label Nr = R.rhs().size();
226 
227  label slRef = 0;
228  lRef = R.lhs()[slRef].index;
229 
230  pf = kf;
231  for (label s=1; s<Nl; s++)
232  {
233  const label si = R.lhs()[s].index;
234 
235  if (c[si] < c[lRef])
236  {
237  const scalar exp = R.lhs()[slRef].exponent;
238  pf *= pow(max(c[lRef], 0.0), exp);
239  lRef = si;
240  slRef = s;
241  }
242  else
243  {
244  const scalar exp = R.lhs()[s].exponent;
245  pf *= pow(max(c[si], 0.0), exp);
246  }
247  }
248  cf = max(c[lRef], 0.0);
249 
250  {
251  const scalar exp = R.lhs()[slRef].exponent;
252  if (exp < 1)
253  {
254  if (cf > SMALL)
255  {
256  pf *= pow(cf, exp - 1);
257  }
258  else
259  {
260  pf = 0;
261  }
262  }
263  else
264  {
265  pf *= pow(cf, exp - 1);
266  }
267  }
268 
269  label srRef = 0;
270  rRef = R.rhs()[srRef].index;
271 
272  // Find the matrix element and element position for the rhs
273  pr = kr;
274  for (label s=1; s<Nr; s++)
275  {
276  const label si = R.rhs()[s].index;
277  if (c[si] < c[rRef])
278  {
279  const scalar exp = R.rhs()[srRef].exponent;
280  pr *= pow(max(c[rRef], 0.0), exp);
281  rRef = si;
282  srRef = s;
283  }
284  else
285  {
286  const scalar exp = R.rhs()[s].exponent;
287  pr *= pow(max(c[si], 0.0), exp);
288  }
289  }
290  cr = max(c[rRef], 0.0);
291 
292  {
293  const scalar exp = R.rhs()[srRef].exponent;
294  if (exp < 1)
295  {
296  if (cr > SMALL)
297  {
298  pr *= pow(cr, exp - 1);
299  }
300  else
301  {
302  pr = 0;
303  }
304  }
305  else
306  {
307  pr *= pow(cr, exp - 1);
308  }
309  }
310 
311  return pf*cf - pr*cr;
312 }
313 
314 
315 template<class ReactionThermo, class ThermoType>
317 (
318  const scalar time,
319  const scalarField& c,
320  scalarField& dcdt
321 ) const
322 {
323  const bool reduced = mechRed_->active();
324 
325  const scalar T = c[this->nSpecie_];
326  const scalar p = c[this->nSpecie_ + 1];
327 
328  if (reduced)
329  {
330  // When using DAC, the ODE solver submit a reduced set of species the
331  // complete set is used and only the species in the simplified mechanism
332  // are updated
333  this->c_ = completeC_;
334 
335  // Update the concentration of the species in the simplified mechanism
336  // the other species remain the same and are used only for third-body
337  // efficiencies
338  for (label i=0; i<NsDAC_; i++)
339  {
340  this->c_[simplifiedToCompleteIndex_[i]] = max(c[i], 0.0);
341  }
342  }
343  else
344  {
345  for (label i=0; i<this->nSpecie(); i++)
346  {
347  this->c_[i] = max(c[i], 0.0);
348  }
349  }
350 
351  omega(this->c_, T, p, dcdt);
352 
353  // Constant pressure
354  // dT/dt = ...
355  scalar rho = 0;
356  for (label i=0; i<this->c_.size(); i++)
357  {
358  const scalar W = this->specieThermo_[i].W();
359  rho += W*this->c_[i];
360  }
361 
362  scalar cp = 0;
363  for (label i=0; i<this->c_.size(); i++)
364  {
365  // cp function returns [J/(kmol K)]
366  cp += this->c_[i]*this->specieThermo_[i].cp(p, T);
367  }
368  cp /= rho;
369 
370  // When mechanism reduction is active
371  // dT is computed on the reduced set since dcdt is null
372  // for species not involved in the simplified mechanism
373  scalar dT = 0;
374  for (label i=0; i<this->nSpecie_; i++)
375  {
376  label si;
377  if (reduced)
378  {
379  si = simplifiedToCompleteIndex_[i];
380  }
381  else
382  {
383  si = i;
384  }
385 
386  // ha function returns [J/kmol]
387  const scalar hi = this->specieThermo_[si].ha(p, T);
388  dT += hi*dcdt[i];
389  }
390  dT /= rho*cp;
391 
392  dcdt[this->nSpecie_] = -dT;
393 
394  // dp/dt = ...
395  dcdt[this->nSpecie_ + 1] = 0;
396 }
397 
398 
399 template<class ReactionThermo, class ThermoType>
401 (
402  const scalar t,
403  const scalarField& c,
404  scalarSquareMatrix& dfdc
405 ) const
406 {
407  const bool reduced = mechRed_->active();
408 
409  // If the mechanism reduction is active, the computed Jacobian
410  // is compact (size of the reduced set of species)
411  // but according to the information of the complete set
412  // (i.e. for the third-body efficiencies)
413 
414  const label nSpecie = this->nSpecie_;
415 
416  const scalar T = c[nSpecie];
417  const scalar p = c[nSpecie + 1];
418 
419  if (reduced)
420  {
421  this->c_ = completeC_;
422  for (label i=0; i<NsDAC_; ++i)
423  {
424  this->c_[simplifiedToCompleteIndex_[i]] = max(c[i], 0.0);
425  }
426  }
427  else
428  {
429  forAll(this->c_, i)
430  {
431  this->c_[i] = max(c[i], 0.0);
432  }
433  }
434 
435  dfdc = Zero;
436 
437  forAll(this->reactions_, ri)
438  {
439  if (!reactionsDisabled_[ri])
440  {
441  const Reaction<ThermoType>& R = this->reactions_[ri];
442 
443  const scalar kf0 = R.kf(p, T, this->c_);
444  const scalar kr0 = R.kr(kf0, p, T, this->c_);
445 
446  forAll(R.lhs(), j)
447  {
448  label sj = R.lhs()[j].index;
449  if (reduced)
450  {
451  sj = completeToSimplifiedIndex_[sj];
452  }
453  scalar kf = kf0;
454  forAll(R.lhs(), i)
455  {
456  const label si = R.lhs()[i].index;
457  const scalar el = R.lhs()[i].exponent;
458  if (i == j)
459  {
460  if (el < 1)
461  {
462  if (this->c_[si] > SMALL)
463  {
464  kf *= el*pow(this->c_[si], el - 1);
465  }
466  else
467  {
468  kf = 0;
469  }
470  }
471  else
472  {
473  kf *= el*pow(this->c_[si], el - 1);
474  }
475  }
476  else
477  {
478  kf *= pow(this->c_[si], el);
479  }
480  }
481 
482  forAll(R.lhs(), i)
483  {
484  label si = R.lhs()[i].index;
485  if (reduced)
486  {
487  si = completeToSimplifiedIndex_[si];
488  }
489  const scalar sl = R.lhs()[i].stoichCoeff;
490  dfdc(si, sj) -= sl*kf;
491  }
492  forAll(R.rhs(), i)
493  {
494  label si = R.rhs()[i].index;
495  if (reduced)
496  {
497  si = completeToSimplifiedIndex_[si];
498  }
499  const scalar sr = R.rhs()[i].stoichCoeff;
500  dfdc(si, sj) += sr*kf;
501  }
502  }
503 
504  forAll(R.rhs(), j)
505  {
506  label sj = R.rhs()[j].index;
507  if (reduced)
508  {
509  sj = completeToSimplifiedIndex_[sj];
510  }
511  scalar kr = kr0;
512  forAll(R.rhs(), i)
513  {
514  const label si = R.rhs()[i].index;
515  const scalar er = R.rhs()[i].exponent;
516  if (i == j)
517  {
518  if (er < 1)
519  {
520  if (this->c_[si] > SMALL)
521  {
522  kr *= er*pow(this->c_[si], er - 1);
523  }
524  else
525  {
526  kr = 0;
527  }
528  }
529  else
530  {
531  kr *= er*pow(this->c_[si], er - 1);
532  }
533  }
534  else
535  {
536  kr *= pow(this->c_[si], er);
537  }
538  }
539 
540  forAll(R.lhs(), i)
541  {
542  label si = R.lhs()[i].index;
543  if (reduced)
544  {
545  si = completeToSimplifiedIndex_[si];
546  }
547  const scalar sl = R.lhs()[i].stoichCoeff;
548  dfdc(si, sj) += sl*kr;
549  }
550  forAll(R.rhs(), i)
551  {
552  label si = R.rhs()[i].index;
553  if (reduced)
554  {
555  si = completeToSimplifiedIndex_[si];
556  }
557  const scalar sr = R.rhs()[i].stoichCoeff;
558  dfdc(si, sj) -= sr*kr;
559  }
560  }
561  }
562  }
563 
564  // Calculate the dcdT elements numerically
565  const scalar delta = 1e-3;
566 
567  omega(this->c_, T + delta, p, this->dcdt_);
568  for (label i=0; i<nSpecie; ++i)
569  {
570  dfdc(i, nSpecie) = this->dcdt_[i];
571  }
572 
573  omega(this->c_, T - delta, p, this->dcdt_);
574  for (label i=0; i<nSpecie; ++i)
575  {
576  dfdc(i, nSpecie) = 0.5*(dfdc(i, nSpecie) - this->dcdt_[i])/delta;
577  }
578 
579  dfdc(nSpecie, nSpecie) = 0;
580  dfdc(nSpecie + 1, nSpecie) = 0;
581 }
582 
583 
584 template<class ReactionThermo, class ThermoType>
586 (
587  const scalar t,
588  const scalarField& c,
589  scalarField& dcdt,
590  scalarSquareMatrix& dfdc
591 ) const
592 {
593  jacobian(t, c, dfdc);
594 
595  const scalar T = c[this->nSpecie_];
596  const scalar p = c[this->nSpecie_ + 1];
597 
598  // Note: Uses the c_ field initialized by the call to jacobian above
599  omega(this->c_, T, p, dcdt);
600 }
601 
602 
603 template<class ReactionThermo, class ThermoType>
604 template<class DeltaTType>
606 (
607  const DeltaTType& deltaT
608 )
609 {
610  // Increment counter of time-step
611  timeSteps_++;
612 
613  const bool reduced = mechRed_->active();
614 
615  label nAdditionalEqn = (tabulation_->variableTimeStep() ? 1 : 0);
616 
617  basicSpecieMixture& composition = this->thermo().composition();
618 
619  // CPU time analysis
620  const clockTime clockTime_= clockTime();
621  clockTime_.timeIncrement();
622  scalar reduceMechCpuTime_ = 0;
623  scalar addNewLeafCpuTime_ = 0;
624  scalar growCpuTime_ = 0;
625  scalar solveChemistryCpuTime_ = 0;
626  scalar searchISATCpuTime_ = 0;
627 
628  this->resetTabulationResults();
629 
630  // Average number of active species
631  scalar nActiveSpecies = 0;
632  scalar nAvg = 0;
633 
635 
636  scalar deltaTMin = GREAT;
637 
638  if (!this->chemistry_)
639  {
640  return deltaTMin;
641  }
642 
643  const volScalarField rho
644  (
645  IOobject
646  (
647  "rho",
648  this->time().timeName(),
649  this->mesh(),
650  IOobject::NO_READ,
651  IOobject::NO_WRITE,
652  false
653  ),
654  this->thermo().rho()
655  );
656 
657  const scalarField& T = this->thermo().T();
658  const scalarField& p = this->thermo().p();
659 
660  scalarField c(this->nSpecie_);
661  scalarField c0(this->nSpecie_);
662 
663  // Composition vector (Yi, T, p)
664  scalarField phiq(this->nEqns() + nAdditionalEqn);
665 
666  scalarField Rphiq(this->nEqns() + nAdditionalEqn);
667 
668  forAll(rho, celli)
669  {
670  const scalar rhoi = rho[celli];
671  scalar pi = p[celli];
672  scalar Ti = T[celli];
673 
674  for (label i=0; i<this->nSpecie_; i++)
675  {
676  const volScalarField& Yi = this->Y_[i];
677  c[i] = rhoi*Yi[celli]/this->specieThermo_[i].W();
678  c0[i] = c[i];
679  phiq[i] = Yi[celli];
680  }
681  phiq[this->nSpecie()] = Ti;
682  phiq[this->nSpecie() + 1] = pi;
683  if (tabulation_->variableTimeStep())
684  {
685  phiq[this->nSpecie() + 2] = deltaT[celli];
686  }
687 
688 
689  // Initialise time progress
690  scalar timeLeft = deltaT[celli];
691 
692  // Not sure if this is necessary
693  Rphiq = Zero;
694 
695  clockTime_.timeIncrement();
696 
697  // When tabulation is active (short-circuit evaluation for retrieve)
698  // It first tries to retrieve the solution of the system with the
699  // information stored through the tabulation method
700  if (tabulation_->active() && tabulation_->retrieve(phiq, Rphiq))
701  {
702  // Retrieved solution stored in Rphiq
703  for (label i=0; i<this->nSpecie(); ++i)
704  {
705  c[i] = rhoi*Rphiq[i]/this->specieThermo_[i].W();
706  }
707 
708  searchISATCpuTime_ += clockTime_.timeIncrement();
709  }
710  // This position is reached when tabulation is not used OR
711  // if the solution is not retrieved.
712  // In the latter case, it adds the information to the tabulation
713  // (it will either expand the current data or add a new stored point).
714  else
715  {
716  // Store total time waiting to attribute to add or grow
717  scalar timeTmp = clockTime_.timeIncrement();
718 
719  if (reduced)
720  {
721  // Reduce mechanism change the number of species (only active)
722  mechRed_->reduceMechanism(c, Ti, pi);
723  nActiveSpecies += mechRed_->NsSimp();
724  ++nAvg;
725  scalar timeIncr = clockTime_.timeIncrement();
726  reduceMechCpuTime_ += timeIncr;
727  timeTmp += timeIncr;
728  }
729 
730  // Calculate the chemical source terms
731  while (timeLeft > SMALL)
732  {
733  scalar dt = timeLeft;
734  if (reduced)
735  {
736  // completeC_ used in the overridden ODE methods
737  // to update only the active species
738  completeC_ = c;
739 
740  // Solve the reduced set of ODE
741  this->solve
742  (
743  simplifiedC_, Ti, pi, dt, this->deltaTChem_[celli]
744  );
745 
746  for (label i=0; i<NsDAC_; ++i)
747  {
748  c[simplifiedToCompleteIndex_[i]] = simplifiedC_[i];
749  }
750  }
751  else
752  {
753  this->solve(c, Ti, pi, dt, this->deltaTChem_[celli]);
754  }
755  timeLeft -= dt;
756  }
757 
758  {
759  scalar timeIncr = clockTime_.timeIncrement();
760  solveChemistryCpuTime_ += timeIncr;
761  timeTmp += timeIncr;
762  }
763 
764  // If tabulation is used, we add the information computed here to
765  // the stored points (either expand or add)
766  if (tabulation_->active())
767  {
768  forAll(c, i)
769  {
770  Rphiq[i] = c[i]/rhoi*this->specieThermo_[i].W();
771  }
772  if (tabulation_->variableTimeStep())
773  {
774  Rphiq[Rphiq.size()-3] = Ti;
775  Rphiq[Rphiq.size()-2] = pi;
776  Rphiq[Rphiq.size()-1] = deltaT[celli];
777  }
778  else
779  {
780  Rphiq[Rphiq.size()-2] = Ti;
781  Rphiq[Rphiq.size()-1] = pi;
782  }
783  label growOrAdd =
784  tabulation_->add(phiq, Rphiq, rhoi, deltaT[celli]);
785 
786  if (growOrAdd)
787  {
788  this->setTabulationResultsAdd(celli);
789  addNewLeafCpuTime_ += clockTime_.timeIncrement() + timeTmp;
790  }
791  else
792  {
793  this->setTabulationResultsGrow(celli);
794  growCpuTime_ += clockTime_.timeIncrement() + timeTmp;
795  }
796  }
797 
798  // When operations are done and if mechanism reduction is active,
799  // the number of species (which also affects nEqns) is set back
800  // to the total number of species (stored in the mechRed object)
801  if (reduced)
802  {
803  this->nSpecie_ = mechRed_->nSpecie();
804  }
805  deltaTMin = min(this->deltaTChem_[celli], deltaTMin);
806 
807  this->deltaTChem_[celli] =
808  min(this->deltaTChem_[celli], this->deltaTChemMax_);
809  }
810 
811  // Set the RR vector (used in the solver)
812  for (label i=0; i<this->nSpecie_; ++i)
813  {
814  this->RR_[i][celli] =
815  (c[i] - c0[i])*this->specieThermo_[i].W()/deltaT[celli];
816  }
817  }
818 
819  if (mechRed_->log() || tabulation_->log())
820  {
821  cpuSolveFile_()
822  << this->time().timeOutputValue()
823  << " " << solveChemistryCpuTime_ << endl;
824  }
825 
826  if (mechRed_->log())
827  {
828  cpuReduceFile_()
829  << this->time().timeOutputValue()
830  << " " << reduceMechCpuTime_ << endl;
831  }
832 
833  if (tabulation_->active())
834  {
835  // Every time-step, look if the tabulation should be updated
836  tabulation_->update();
837 
838  // Write the performance of the tabulation
839  tabulation_->writePerformance();
840 
841  if (tabulation_->log())
842  {
843  cpuRetrieveFile_()
844  << this->time().timeOutputValue()
845  << " " << searchISATCpuTime_ << endl;
846 
847  cpuGrowFile_()
848  << this->time().timeOutputValue()
849  << " " << growCpuTime_ << endl;
850 
851  cpuAddFile_()
852  << this->time().timeOutputValue()
853  << " " << addNewLeafCpuTime_ << endl;
854  }
855  }
856 
857  if (reduced && nAvg && mechRed_->log())
858  {
859  // Write average number of species
860  nActiveSpeciesFile_()
861  << this->time().timeOutputValue()
862  << " " << nActiveSpecies/nAvg << endl;
863  }
864 
865  if (Pstream::parRun())
866  {
867  List<bool> active(composition.active());
868  Pstream::listCombineGather(active, orEqOp<bool>());
869  Pstream::listCombineScatter(active);
870 
871  forAll(active, i)
872  {
873  if (active[i])
874  {
875  composition.setActive(i);
876  }
877  }
878  }
879 
880  forAll(this->Y(), i)
881  {
882  if (composition.active(i))
883  {
884  this->Y()[i].writeOpt() = IOobject::AUTO_WRITE;
885  }
886  }
887 
888  return deltaTMin;
889 }
890 
891 
892 template<class ReactionThermo, class ThermoType>
894 (
895  const scalar deltaT
896 )
897 {
898  // Don't allow the time-step to change more than a factor of 2
899  return min
900  (
902  2*deltaT
903  );
904 }
905 
906 
907 template<class ReactionThermo, class ThermoType>
909 (
910  const scalarField& deltaT
911 )
912 {
913  return this->solve<scalarField>(deltaT);
914 }
915 
916 
917 template<class ReactionThermo, class ThermoType>
920 (
921  const label celli
922 )
923 {
924  tabulationResults_[celli] = 0.0;
925 }
926 
927 
928 template<class ReactionThermo, class ThermoType>
930 setTabulationResultsGrow(const label celli)
931 {
932  tabulationResults_[celli] = 1.0;
933 }
934 
935 
936 template<class ReactionThermo, class ThermoType>
939 (
940  const label celli
941 )
942 {
943  tabulationResults_[celli] = 2.0;
944 }
945 
946 
947 // ************************************************************************* //
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Dimensionless.
Definition: dimensionSets.H:50
Foam::TDACChemistryModel::~TDACChemistryModel
virtual ~TDACChemistryModel()
Destructor.
Definition: TDACChemistryModel.C:146
Foam::TDACChemistryModel::derivatives
virtual void derivatives(const scalar t, const scalarField &c, scalarField &dcdt) const
Definition: TDACChemistryModel.C:317
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.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))
Definition: gmvOutputSpray.H:25
cp
const volScalarField & cp
Definition: setRegionSolidFields.H:8
Foam::basicSpecieMixture
Specialization of basicMultiComponentMixture for a mixture consisting of a number for molecular speci...
Definition: basicSpecieMixture.H:54
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::IOobject::typeHeaderOk
bool typeHeaderOk(const bool checkType=true, const bool search=true, const bool verbose=true)
Read header (uses typeFilePath to find file) and check its info.
Definition: IOobjectTemplates.C:39
Foam::clockTime::timeIncrement
double timeIncrement() const
The time [seconds] since the last call to timeIncrement()
Definition: clockTimeI.H:60
TDACChemistryModel.H
thermo
psiReactionThermo & thermo
Definition: createFields.H:28
nSpecie
label nSpecie
Definition: readInitialConditions.H:17
thermo
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
Foam::orEqOp
Definition: ops.H:86
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::TDACChemistryModel::active
bool active(const label i) const
Definition: TDACChemistryModelI.H:91
Foam::exp
dimensionedScalar exp(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:261
rho
rho
Definition: readInitialConditions.H:88
composition
basicSpecieMixture & composition
Definition: createFieldRefs.H:6
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
solve
CEqn solve()
Foam::TDACChemistryModel::setTabulationResultsGrow
void setTabulationResultsGrow(const label celli)
Definition: TDACChemistryModel.C:930
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::UniformField
A class representing the concept of a uniform field which stores only the single value and providing ...
Definition: UniformField.H:49
R
#define R(A, B, C, D, E, F, K, M)
localEulerDdtScheme.H
Foam::Field< scalar >
Foam::hashedWordList
A wordList with hashed named lookup, which can be faster in some situations than using the normal lis...
Definition: hashedWordList.H:54
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
controlDict
runTime controlDict().readEntry("adjustTimeStep"
Definition: debug.C:143
correct
fvOptions correct(rho)
delta
scalar delta
Definition: LISASMDCalcMethod2.H:8
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:43
Foam::pow
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Definition: dimensionedScalar.C:75
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
timeName
word timeName
Definition: getTimeIndex.H:3
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::TDACChemistryModel::omega
virtual void omega(const scalarField &c, const scalar T, const scalar p, scalarField &dcdt) const
dc/dt = omega, rate of change in concentration, for each species
Definition: TDACChemistryModel.C:154
T
const volScalarField & T
Definition: createFieldRefs.H:2
Y
PtrList< volScalarField > & Y
Definition: createFieldRefs.H:7
Foam::HashTable
A HashTable similar to std::unordered_map.
Definition: HashTable.H:105
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
Foam::SquareMatrix< scalar >
Foam::TDACChemistryModel::setTabulationResultsAdd
void setTabulationResultsAdd(const label celli)
Definition: TDACChemistryModel.C:920
Foam::constant::mathematical::pi
constexpr scalar pi(M_PI)
Foam::List< bool >
Foam::TDACChemistryModel::jacobian
void jacobian(const scalar t, const scalarField &c, scalarSquareMatrix &dfdc) const
Pure jacobian function for tabulation.
Definition: TDACChemistryModel.C:401
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::clockTime
Starts timing and returns elapsed time from start. Uses std::chrono::high_resolution_clock for better...
Definition: clockTime.H:62
Foam::TDACChemistryModel
Extends StandardChemistryModel by adding the TDAC method.
Definition: chemistryReductionMethod.H:49
Foam::GeometricField< scalar, fvPatchField, volMesh >
Foam::Reaction
Simple extension of ReactionThermo to handle reaction kinetics in addition to the equilibrium thermod...
Definition: Reaction.H:56
clockTime.H
UniformField.H
Foam::StandardChemistryModel
Extends base chemistry model by adding a thermo package, and ODE functions. Introduces chemistry equa...
Definition: StandardChemistryModel.H:61
Foam::TDACChemistryModel::setTabulationResultsRetrieve
void setTabulationResultsRetrieve(const label celli)
Definition: TDACChemistryModel.C:939