chemPointISAT.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) 2019-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 "chemPointISAT.H"
30 #include "SVD.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 // Defined as static to be able to dynamically change it during simulations
35 // (all chemPoints refer to the same object)
36 template<class CompType, class ThermoType>
38 
39 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
40 
41 template<class CompType, class ThermoType>
43 (
44  const label nCols,
46 )
47 {
48  scalarField c(nCols);
49  scalarField d(nCols);
50  scalar scale, sigma, sum;
51 
52  for (label k=0; k<nCols-1; ++k)
53  {
54  scale = 0;
55  for (label i=k; i<nCols; ++i)
56  {
57  scale = max(scale, mag(R(i, k)));
58  }
59 
60  if (scale == 0)
61  {
62  c[k] = d[k] = 0;
63  }
64  else
65  {
66  for (label i=k; i<nCols; ++i)
67  {
68  R(i, k) /= scale;
69  }
70  sum = 0;
71  for (label i=k; i<nCols; ++i)
72  {
73  sum += sqr(R(i, k));
74  }
75  sigma = sign(R(k, k))*sqrt(sum);
76  R(k, k) += sigma;
77  c[k] = sigma*R(k, k);
78  d[k] = -scale*sigma;
79  for (label j=k+1; j<nCols; ++j)
80  {
81  sum = 0;
82  for ( label i=k; i<nCols; ++i)
83  {
84  sum += R(i, k)*R(i, j);
85  }
86  scalar tau = sum/c[k];
87  for ( label i=k; i<nCols; ++i)
88  {
89  R(i, j) -= tau*R(i, k);
90  }
91  }
92  }
93  }
94 
95  d[nCols-1] = R(nCols-1, nCols-1);
96 
97  // form R
98  for (label i=0; i<nCols; ++i)
99  {
100  R(i, i) = d[i];
101  for ( label j=0; j<i; ++j)
102  {
103  R(i, j) = 0;
104  }
105  }
106 }
107 
108 
109 template<class CompType, class ThermoType>
111 (
113  const label n,
114  const Foam::scalarField &u,
115  const Foam::scalarField &v
116 )
117 {
118  label k;
119 
120  scalarField w(u);
121  for (k=n-1; k>=0; --k)
122  {
123  if (w[k] != 0)
124  {
125  break;
126  }
127  }
128 
129  if (k < 0)
130  {
131  k = 0;
132  }
133 
134  for (label i=k-1; i>=0; --i)
135  {
136  rotate(R, i, w[i],-w[i+1], n);
137  if (w[i] == 0)
138  {
139  w[i] = mag(w[i+1]);
140  }
141  else if (mag(w[i]) > mag(w[i+1]))
142  {
143  w[i] = mag(w[i])*sqrt(1.0 + sqr(w[i+1]/w[i]));
144  }
145  else
146  {
147  w[i] = mag(w[i+1])*sqrt(1.0 + sqr(w[i]/w[i+1]));
148  }
149  }
150 
151  for (label i=0; i<n; ++i)
152  {
153  R(0, i) += w[0]*v[i];
154  }
155 
156  for (label i=0; i<k; ++i)
157  {
158  rotate(R, i, R(i, i), -R(i+1, i), n);
159  }
160 }
161 
162 
163 template<class CompType, class ThermoType>
165 (
167  const label i,
168  const scalar a,
169  const scalar b,
170  label n
171 )
172 {
173  scalar c, fact, s, w, y;
174  if (a == 0)
175  {
176  c = 0;
177  s = (b >= 0 ? 1 : -1);
178  }
179  else if (mag(a) > mag(b))
180  {
181  fact = b/a;
182  c = sign(a)/sqrt(1.0 + sqr(fact));
183  s = fact*c;
184  }
185  else
186  {
187  fact = a/b;
188  s = sign(b)/sqrt(1.0 + sqr(fact));
189  c = fact*s;
190  }
191 
192  for (label j=i; j<n ;++j)
193  {
194  y = R(i, j);
195  w = R(i+1, j);
196  R(i, j) = c*y-s*w;
197  R(i+1, j) = s*y+c*w;
198  }
199 }
200 
201 
202 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
203 
204 template<class CompType, class ThermoType>
206 (
208  const scalarField& phi,
209  const scalarField& Rphi,
210  const scalarSquareMatrix& A,
211  const scalarField& scaleFactor,
212  const scalar& tolerance,
213  const label& completeSpaceSize,
214  const dictionary& coeffsDict,
216 )
217 :
218  chemistry_(chemistry),
219  phi_(phi),
220  Rphi_(Rphi),
221  A_(A),
222  scaleFactor_(scaleFactor),
223  node_(node),
224  completeSpaceSize_(completeSpaceSize),
225  nGrowth_(0),
226  nActiveSpecies_(chemistry.mechRed()->NsSimp()),
227  simplifiedToCompleteIndex_(nActiveSpecies_),
228  timeTag_(chemistry_.timeSteps()),
229  lastTimeUsed_(chemistry_.timeSteps()),
230  toRemove_(false),
231  maxNumNewDim_(coeffsDict.getOrDefault("maxNumNewDim", 0)),
232  printProportion_(coeffsDict.getOrDefault("printProportion", false)),
233  numRetrieve_(0),
234  nLifeTime_(0),
235  completeToSimplifiedIndex_
236  (
237  completeSpaceSize - (2 + (variableTimeStep() == 1 ? 1 : 0))
238  )
239 {
240  tolerance_ = tolerance;
241 
242  if (variableTimeStep())
243  {
244  nAdditionalEqns_ = 3;
245  iddeltaT_ = completeSpaceSize - 1;
246  scaleFactor_[iddeltaT_] *= phi_[iddeltaT_] / tolerance_;
247  }
248  else
249  {
250  nAdditionalEqns_ = 2;
251  iddeltaT_ = completeSpaceSize; // will not be used
252  }
253  idT_ = completeSpaceSize - nAdditionalEqns_;
254  idp_ = completeSpaceSize - nAdditionalEqns_ + 1;
255 
256  bool isMechRedActive = chemistry_.mechRed()->active();
257  if (isMechRedActive)
258  {
259  for (label i=0; i<completeSpaceSize-nAdditionalEqns_; ++i)
260  {
261  completeToSimplifiedIndex_[i] =
262  chemistry.completeToSimplifiedIndex()[i];
263  }
264  for (label i=0; i<nActiveSpecies_; ++i)
265  {
266  simplifiedToCompleteIndex_[i] =
267  chemistry.simplifiedToCompleteIndex()[i];
268  }
269  }
270 
271  label reduOrCompDim = completeSpaceSize;
272  if (isMechRedActive)
273  {
274  reduOrCompDim = nActiveSpecies_+nAdditionalEqns_;
275  }
276 
277  // SVD decomposition A = U*D*V^T
278  SVD svdA(A);
279 
280  scalarDiagonalMatrix D(reduOrCompDim);
281  const scalarDiagonalMatrix& S = svdA.S();
282 
283  // Replace the value of vector D by max(D, 1/2), first ISAT paper
284  for (label i=0; i<reduOrCompDim; ++i)
285  {
286  D[i] = max(S[i], 0.5);
287  }
288 
289  // Rebuild A with max length, tol and scale factor before QR decomposition
290  scalarRectangularMatrix Atilde(reduOrCompDim);
291 
292  // Result stored in Atilde
293  multiply(Atilde, svdA.U(), D, svdA.V().T());
294 
295  for (label i=0; i<reduOrCompDim; ++i)
296  {
297  for (label j=0; j<reduOrCompDim; ++j)
298  {
299  label compi = i;
300 
301  if (isMechRedActive)
302  {
303  compi = simplifiedToCompleteIndex(i);
304  }
305 
306  // SF*A/tolerance
307  // (where SF is diagonal with inverse of scale factors)
308  // SF*A is the same as dividing each line by the scale factor
309  // corresponding to the species of this line
310  Atilde(i, j) /= (tolerance*scaleFactor[compi]);
311  }
312  }
313 
314  // The object LT_ (the transpose of the Q) describe the EOA, since we have
315  // A^T B^T B A that should be factorized into L Q^T Q L^T and is set in the
316  // qrDecompose function
317  LT_ = scalarSquareMatrix(Atilde);
318 
319  qrDecompose(reduOrCompDim, LT_);
320 }
321 
322 
323 template<class CompType, class ThermoType>
325 (
327 )
328 :
329  chemistry_(p.chemistry()),
330  phi_(p.phi()),
331  Rphi_(p.Rphi()),
332  LT_(p.LT()),
333  A_(p.A()),
334  scaleFactor_(p.scaleFactor()),
335  node_(p.node()),
336  completeSpaceSize_(p.completeSpaceSize()),
337  nGrowth_(p.nGrowth()),
338  nActiveSpecies_(p.nActiveSpecies()),
339  simplifiedToCompleteIndex_(p.simplifiedToCompleteIndex()),
340  timeTag_(p.timeTag()),
341  lastTimeUsed_(p.lastTimeUsed()),
342  toRemove_(p.toRemove()),
343  maxNumNewDim_(p.maxNumNewDim()),
344  numRetrieve_(0),
345  nLifeTime_(0),
346  completeToSimplifiedIndex_(p.completeToSimplifiedIndex())
347 {
348  tolerance_ = p.tolerance();
349 
350  if (variableTimeStep())
351  {
352  nAdditionalEqns_ = 3;
353  idT_ = completeSpaceSize() - 3;
354  idp_ = completeSpaceSize() - 2;
355  iddeltaT_ = completeSpaceSize() - 1;
356  }
357  else
358  {
359  nAdditionalEqns_ = 2;
360  idT_ = completeSpaceSize() - 2;
361  idp_ = completeSpaceSize() - 1;
362  iddeltaT_ = completeSpaceSize(); // will not be used
363  }
364 }
365 
366 
367 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
368 
369 template<class CompType, class ThermoType>
371 {
372  scalarField dphi(phiq-phi());
373  bool isMechRedActive = chemistry_.mechRed()->active();
374  label dim(0);
375  if (isMechRedActive)
376  {
377  dim = nActiveSpecies_;
378  }
379  else
380  {
381  dim = completeSpaceSize() - nAdditionalEqns_;
382  }
383 
384  scalar epsTemp = 0;
385  List<scalar> propEps(completeSpaceSize(), Zero);
386 
387  for (label i=0; i<completeSpaceSize()-nAdditionalEqns_; ++i)
388  {
389  scalar temp = 0;
390 
391  // When mechanism reduction is inactive OR on active species multiply L
392  // by dphi to get the distance in the active species direction else (for
393  // inactive species), just multiply the diagonal element and dphi
394  if
395  (
396  !(isMechRedActive)
397  ||(isMechRedActive && completeToSimplifiedIndex_[i] != -1)
398  )
399  {
400  label si = isMechRedActive ? completeToSimplifiedIndex_[i] : i;
401 
402  for (label j=si; j<dim; ++j)// LT is upper triangular
403  {
404  label sj = isMechRedActive ? simplifiedToCompleteIndex_[j] : j;
405  temp += LT_(si, j)*dphi[sj];
406  }
407 
408  temp += LT_(si, dim)*dphi[idT_];
409  temp += LT_(si, dim+1)*dphi[idp_];
410  if (variableTimeStep())
411  {
412  temp += LT_(si, dim+2)*dphi[iddeltaT_];
413  }
414  }
415  else
416  {
417  temp = dphi[i]/(tolerance_*scaleFactor_[i]);
418  }
419 
420  epsTemp += sqr(temp);
421 
422  if (printProportion_)
423  {
424  propEps[i] = temp;
425  }
426  }
427 
428  // Temperature
429  if (variableTimeStep())
430  {
431  epsTemp +=
432  sqr
433  (
434  LT_(dim, dim)*dphi[idT_]
435  +LT_(dim, dim+1)*dphi[idp_]
436  +LT_(dim, dim+2)*dphi[iddeltaT_]
437  );
438  }
439  else
440  {
441  epsTemp +=
442  sqr
443  (
444  LT_(dim, dim)*dphi[idT_]
445  +LT_(dim, dim+1)*dphi[idp_]
446  );
447  }
448 
449  // Pressure
450  if (variableTimeStep())
451  {
452  epsTemp +=
453  sqr
454  (
455  LT_(dim+1, dim+1)*dphi[idp_]
456  +LT_(dim+1, dim+2)*dphi[iddeltaT_]
457  );
458  }
459  else
460  {
461  epsTemp += sqr(LT_(dim+1, dim+1)*dphi[idp_]);
462  }
463 
464  if (variableTimeStep())
465  {
466  epsTemp += sqr(LT_[dim+2][dim+2]*dphi[iddeltaT_]);
467  }
468 
469  if (printProportion_)
470  {
471  propEps[idT_] = sqr
472  (
473  LT_(dim, dim)*dphi[idT_]
474  + LT_(dim, dim+1)*dphi[idp_]
475  );
476 
477  propEps[idp_] = sqr(LT_(dim+1, dim+1)*dphi[idp_]);
478 
479  if (variableTimeStep())
480  {
481  propEps[iddeltaT_] = sqr(LT_[dim+2][dim+2]*dphi[iddeltaT_]);
482  }
483 
484  }
485 
486  if (sqrt(epsTemp) > 1 + tolerance_)
487  {
488  if (printProportion_)
489  {
490  scalar max = -1;
491  label maxIndex = -1;
492  for (label i=0; i<completeSpaceSize(); ++i)
493  {
494  if (max < propEps[i])
495  {
496  max = propEps[i];
497  maxIndex = i;
498  }
499  }
500  word propName;
501  if (maxIndex >= completeSpaceSize() - nAdditionalEqns_)
502  {
503  if (maxIndex == idT_)
504  {
505  propName = "T";
506  }
507  else if (maxIndex == idp_)
508  {
509  propName = "p";
510  }
511  else if (maxIndex == iddeltaT_)
512  {
513  propName = "deltaT";
514  }
515  }
516  else
517  {
518  propName = chemistry_.Y()[maxIndex].member();
519  }
520 
521  Info<< "Direction maximum impact to error in ellipsoid: "
522  << propName << nl
523  << "Proportion to the total error on the retrieve: "
524  << max/(epsTemp+SMALL) << endl;
525  }
526  return false;
527  }
528 
529  return true;
530 }
531 
532 
533 template<class CompType, class ThermoType>
535 (
536  const scalarField& phiq,
537  const scalarField& Rphiq
538 )
539 {
540  scalar eps2 = 0;
541  scalarField dR(Rphiq - Rphi());
542  scalarField dphi(phiq - phi());
543  const scalarField& scaleFactorV(scaleFactor());
544  const scalarSquareMatrix& Avar(A());
545  bool isMechRedActive = chemistry_.mechRed()->active();
546  scalar dRl = 0;
547  label dim = completeSpaceSize() - 2;
548  if (isMechRedActive)
549  {
550  dim = nActiveSpecies_;
551  }
552 
553  // Since we build only the solution for the species, T and p are not
554  // included
555  for (label i=0; i<completeSpaceSize()-nAdditionalEqns_; ++i)
556  {
557  dRl = 0;
558  if (isMechRedActive)
559  {
560  label si = completeToSimplifiedIndex_[i];
561 
562  // If this species is active
563  if (si != -1)
564  {
565  for (label j=0; j<dim; ++j)
566  {
567  label sj=simplifiedToCompleteIndex_[j];
568  dRl += Avar(si, j)*dphi[sj];
569  }
570  dRl += Avar(si, nActiveSpecies_)*dphi[idT_];
571  dRl += Avar(si, nActiveSpecies_+1)*dphi[idp_];
572  if (variableTimeStep())
573  {
574  dRl += Avar(si, nActiveSpecies_+2)*dphi[iddeltaT_];
575  }
576  }
577  else
578  {
579  dRl = dphi[i];
580  }
581  }
582  else
583  {
584  for (label j=0; j<completeSpaceSize(); ++j)
585  {
586  dRl += Avar(i, j)*dphi[j];
587  }
588  }
589  eps2 += sqr((dR[i]-dRl)/scaleFactorV[i]);
590  }
591 
592  eps2 = sqrt(eps2);
593  if (eps2 > tolerance())
594  {
595  return false;
596  }
597  else
598  {
599  // if the solution is in the ellipsoid of accuracy
600  return true;
601  }
602 }
603 
604 
605 template<class CompType, class ThermoType>
607 {
608  scalarField dphi(phiq - phi());
609  label dim = completeSpaceSize();
610  label initNActiveSpecies(nActiveSpecies_);
611  bool isMechRedActive = chemistry_.mechRed()->active();
612 
613  if (isMechRedActive)
614  {
615  label activeAdded(0);
616  DynamicList<label> dimToAdd(0);
617 
618  // check if the difference of active species is lower than the maximum
619  // number of new dimensions allowed
620  for (label i=0; i<completeSpaceSize()-nAdditionalEqns_; ++i)
621  {
622  // first test if the current chemPoint has an inactive species
623  // corresponding to an active one in the query point
624  if
625  (
626  completeToSimplifiedIndex_[i] == -1
627  && chemistry_.completeToSimplifiedIndex()[i]!=-1
628  )
629  {
630  ++activeAdded;
631  dimToAdd.append(i);
632  }
633  // then test if an active species in the current chemPoint
634  // corresponds to an inactive on the query side
635  if
636  (
637  completeToSimplifiedIndex_[i] != -1
638  && chemistry_.completeToSimplifiedIndex()[i] == -1
639  )
640  {
641  ++activeAdded;
642  // we don't need to add a new dimension but we count it to have
643  // control on the difference through maxNumNewDim
644  }
645  // finally test if both points have inactive species but
646  // with a dphi!=0
647  if
648  (
649  completeToSimplifiedIndex_[i] == -1
650  && chemistry_.completeToSimplifiedIndex()[i] == -1
651  && dphi[i] != 0
652  )
653  {
654  ++activeAdded;
655  dimToAdd.append(i);
656  }
657  }
658 
659  // if the number of added dimension is too large, growth fail
660  if (activeAdded > maxNumNewDim_)
661  {
662  return false;
663  }
664 
665  // the number of added dimension to the current chemPoint
666  const label nDimAdd = dimToAdd.size();
667  nActiveSpecies_ += nDimAdd;
668  simplifiedToCompleteIndex_.setSize(nActiveSpecies_);
669  forAll(dimToAdd, i)
670  {
671  label si = nActiveSpecies_ - nDimAdd + i;
672  // add the new active species
673  simplifiedToCompleteIndex_[si] = dimToAdd[i];
674  completeToSimplifiedIndex_[dimToAdd[i]] = si;
675  }
676 
677  // update LT and A :
678  //-add new column and line for the new active species
679  //-transfer last two lines of the previous matrix (p and T) to the end
680  // (change the diagonal position)
681  //-set all element of the new lines and columns to zero except diagonal
682  // (=1/(tolerance*scaleFactor))
683  if (nActiveSpecies_ > initNActiveSpecies)
684  {
685  scalarSquareMatrix LTvar = LT_; // take a copy of LT_
686  scalarSquareMatrix Avar = A_; // take a copy of A_
687  LT_ = scalarSquareMatrix(nActiveSpecies_+nAdditionalEqns_, Zero);
688  A_ = scalarSquareMatrix(nActiveSpecies_+nAdditionalEqns_, Zero);
689 
690  // write the initial active species
691  for (label i=0; i<initNActiveSpecies; ++i)
692  {
693  for (label j=0; j<initNActiveSpecies; ++j)
694  {
695  LT_(i, j) = LTvar(i, j);
696  A_(i, j) = Avar(i, j);
697  }
698  }
699 
700  // write the columns for temperature and pressure
701  for (label i=0; i<initNActiveSpecies; ++i)
702  {
703  for (label j=1; j>=0; --j)
704  {
705  LT_(i, nActiveSpecies_+j) = LTvar(i, initNActiveSpecies+j);
706  A_(i, nActiveSpecies_+j) = Avar(i, initNActiveSpecies+j);
707  LT_(nActiveSpecies_+j, i) = LTvar(initNActiveSpecies+j, i);
708  A_(nActiveSpecies_+j, i) = Avar(initNActiveSpecies+j, i);
709  }
710  }
711  // end with the diagonal elements for temperature and pressure
712  LT_(nActiveSpecies_, nActiveSpecies_) =
713  LTvar(initNActiveSpecies, initNActiveSpecies);
714  A_(nActiveSpecies_, nActiveSpecies_) =
715  Avar(initNActiveSpecies, initNActiveSpecies);
716  LT_(nActiveSpecies_+1, nActiveSpecies_+1) =
717  LTvar(initNActiveSpecies+1, initNActiveSpecies+1);
718  A_(nActiveSpecies_+1, nActiveSpecies_+1) =
719  Avar(initNActiveSpecies+1, initNActiveSpecies+1);
720 
721  if (variableTimeStep())
722  {
723  LT_(nActiveSpecies_+2, nActiveSpecies_+2) =
724  LTvar(initNActiveSpecies+2, initNActiveSpecies+2);
725  A_(nActiveSpecies_+2, nActiveSpecies_+2) =
726  Avar(initNActiveSpecies+2, initNActiveSpecies+2);
727  }
728 
729  for (label i=initNActiveSpecies; i<nActiveSpecies_; ++i)
730  {
731  LT_(i, i) =
732  1.0
733  /(tolerance_*scaleFactor_[simplifiedToCompleteIndex_[i]]);
734  A_(i, i) = 1;
735  }
736  }
737 
738  dim = nActiveSpecies_ + nAdditionalEqns_;
739  }
740 
741  // beginning of grow algorithm
742  scalarField phiTilde(dim, Zero);
743  scalar normPhiTilde = 0;
744  // p' = L^T.(p-phi)
745 
746  for (label i=0; i<dim; ++i)
747  {
748  for (label j=i; j<dim-nAdditionalEqns_; ++j)// LT is upper triangular
749  {
750  label sj = j;
751  if (isMechRedActive)
752  {
753  sj = simplifiedToCompleteIndex_[j];
754  }
755  phiTilde[i] += LT_(i, j)*dphi[sj];
756  }
757 
758  phiTilde[i] += LT_(i, dim-nAdditionalEqns_)*dphi[idT_];
759  phiTilde[i] += LT_(i, dim-nAdditionalEqns_+1)*dphi[idp_];
760 
761  if (variableTimeStep())
762  {
763  phiTilde[i] += LT_(i, dim-nAdditionalEqns_ + 2)*dphi[iddeltaT_];
764  }
765  normPhiTilde += sqr(phiTilde[i]);
766  }
767 
768  scalar invSqrNormPhiTilde = 1.0/normPhiTilde;
769  normPhiTilde = sqrt(normPhiTilde);
770 
771  // gamma = (1/|p'| - 1)/|p'|^2
772  scalar gamma = (1/normPhiTilde - 1)*invSqrNormPhiTilde;
773  scalarField u(gamma*phiTilde);
774  scalarField v(dim, Zero);
775 
776  for (label i=0; i<dim; ++i)
777  {
778  for (label j=0; j<=i; ++j)
779  {
780  v[i] += phiTilde[j]*LT_(j, i);
781  }
782  }
783 
784  qrUpdate(LT_, dim, u, v);
785  ++nGrowth_;
786 
787  return true;
788 }
789 
790 
791 template<class CompType, class ThermoType>
793 {
794  this->numRetrieve_++;
795 }
796 
797 
798 template<class CompType, class ThermoType>
800 {
801  this->numRetrieve_ = 0;
802 }
803 
804 
805 template<class CompType, class ThermoType>
807 {
808  this->nLifeTime_++;
809 }
810 
811 
812 template<class CompType, class ThermoType>
815 (
816  const label i
817 )
818 {
819  if (i < nActiveSpecies_)
820  {
821  return simplifiedToCompleteIndex_[i];
822  }
823  else if (i == nActiveSpecies_)
824  {
825  return completeSpaceSize_-nAdditionalEqns_;
826  }
827  else if (i == nActiveSpecies_ + 1)
828  {
829  return completeSpaceSize_-nAdditionalEqns_ + 1;
830  }
831  else if (variableTimeStep() && (i == nActiveSpecies_ + 2))
832  {
833  return completeSpaceSize_-nAdditionalEqns_ + 2;
834  }
835 
836  return -1;
837 }
838 
839 
840 // ************************************************************************* //
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::chemPointISAT::simplifiedToCompleteIndex
List< label > & simplifiedToCompleteIndex()
Definition: chemPointISAT.H:352
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
SVD.H
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList< label >
A
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
Foam::chemPointISAT::resetNumRetrieve
void resetNumRetrieve()
Resets the number of retrieves at each time step.
Definition: chemPointISAT.C:799
chemistry
BasicChemistryModel< psiReactionThermo > & chemistry
Definition: createFieldRefs.H:1
Foam::chemPointISAT::inEOA
bool inEOA(const scalarField &phiq)
To RETRIEVE the mapping from the stored chemPoint phi, the query.
Definition: chemPointISAT.C:370
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
chemPointISAT.H
Foam::sign
dimensionedScalar sign(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:166
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::DiagonalMatrix< scalar >
Foam::chemPointISAT::increaseNLifeTime
void increaseNLifeTime()
Increases the "counter" of the chP life.
Definition: chemPointISAT.C:806
n
label n
Definition: TABSMDCalcMethod2.H:31
R
#define R(A, B, C, D, E, F, K, M)
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::Field< scalar >
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::chemPointISAT
Leaf of the binary tree. The chemPoint stores the composition 'phi', the mapping of this composition ...
Definition: chemPointISAT.H:142
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
phi
surfaceScalarField & phi
Definition: setRegionFluidFields.H:8
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
Foam::RectangularMatrix< scalar >
Foam::chemPointISAT::grow
bool grow(const scalarField &phiq)
More details about the minimum-volume ellipsoid covering an.
Definition: chemPointISAT.C:606
Foam::DynamicList::setSize
void setSize(const label n)
Same as resize()
Definition: DynamicList.H:224
Foam::scalarSquareMatrix
SquareMatrix< scalar > scalarSquareMatrix
Definition: scalarMatrices.H:57
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::chemPointISAT::chemPointISAT
chemPointISAT(TDACChemistryModel< CompType, ThermoType > &chemistry, const scalarField &phi, const scalarField &Rphi, const scalarSquareMatrix &A, const scalarField &scaleFactor, const scalar &tolerance, const label &completeSpaceSize, const dictionary &coeffsDict, binaryNode< CompType, ThermoType > *node=nullptr)
Construct from components.
Definition: chemPointISAT.C:206
Foam::Matrix::T
Form T() const
Return (conjugate) transpose of Matrix.
Definition: Matrix.C:392
Foam::SVD::S
const scalarDiagonalMatrix & S() const
Return the singular values.
Definition: SVDI.H:52
Foam::SquareMatrix< scalar >
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::binaryNode
Node of the binary tree.
Definition: binaryNode.H:51
Foam::List< scalar >
Foam::sqrt
dimensionedScalar sqrt(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:144
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
gamma
const scalar gamma
Definition: EEqn.H:9
Foam::SVD
Singular value decomposition of a rectangular matrix.
Definition: SVD.H:53
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:327
D
const dimensionedScalar & D
Definition: solveBulkSurfactant.H:4
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::chemPointISAT::checkSolution
bool checkSolution(const scalarField &phiq, const scalarField &Rphiq)
If phiq is not in the EOA, then the mapping is computed.
Definition: chemPointISAT.C:535
sigma
dimensionedScalar sigma("sigma", dimMass/sqr(dimTime), transportProperties)
Foam::TDACChemistryModel< CompType, ThermoType >
Foam::multiply
void multiply(FieldField< Field, Type > &f, const FieldField< Field, Type > &f1, const FieldField< Field, scalar > &f2)
Foam::chemPointISAT::increaseNumRetrieve
void increaseNumRetrieve()
Increases the number of retrieves the chempoint has generated.
Definition: chemPointISAT.C:792
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
Foam::SVD::V
const scalarRectangularMatrix & V() const
Return the square matrix V.
Definition: SVDI.H:46
Foam::SVD::U
const scalarRectangularMatrix & U() const
Return U.
Definition: SVDI.H:40
y
scalar y
Definition: LISASMDCalcMethod1.H:14