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-------------------------------------------------------------------------------
11License
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)
36template<class CompType, class ThermoType>
38
39// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
40
41template<class CompType, class ThermoType>
43(
44 const label nCols,
45 scalarSquareMatrix& R
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
109template<class CompType, class ThermoType>
111(
112 scalarSquareMatrix& R,
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
163template<class CompType, class ThermoType>
165(
166 scalarSquareMatrix& R,
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
204template<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] =
263 }
264 for (label i=0; i<nActiveSpecies_; ++i)
265 {
266 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
323template<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
369template<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
533template<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
605template<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
791template<class CompType, class ThermoType>
793{
794 this->numRetrieve_++;
795}
796
797
798template<class CompType, class ThermoType>
800{
801 this->numRetrieve_ = 0;
802}
803
804
805template<class CompType, class ThermoType>
807{
808 this->nLifeTime_++;
809}
810
811
812template<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// ************************************************************************* //
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
scalar y
label k
#define R(A, B, C, D, E, F, K, M)
label n
Y[inertIndex] max(0.0)
surfaceScalarField & phi
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:503
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
Form T() const
Return conjugate transpose of Matrix.
Definition: Matrix.C:392
Singular value decomposition of a rectangular matrix.
Definition: SVD.H:54
const scalarRectangularMatrix & V() const
Return the square matrix V.
Definition: SVDI.H:46
const scalarRectangularMatrix & U() const
Return U.
Definition: SVDI.H:40
const scalarDiagonalMatrix & S() const
Return the singular values.
Definition: SVDI.H:52
Extends StandardChemistryModel by adding the TDAC method.
autoPtr< chemistryReductionMethod< ReactionThermo, ThermoType > > & mechRed()
DynamicList< label > & simplifiedToCompleteIndex()
Field< label > & completeToSimplifiedIndex()
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Node of the binary tree.
Definition: binaryNode.H:52
Leaf of the binary tree. The chemPoint stores the composition 'phi', the mapping of this composition ...
void resetNumRetrieve()
Resets the number of retrieves at each time step.
bool inEOA(const scalarField &phiq)
To RETRIEVE the mapping from the stored chemPoint phi, the query.
void increaseNumRetrieve()
Increases the number of retrieves the chempoint has generated.
const scalarField & scaleFactor()
label & completeSpaceSize()
const scalar & tolerance()
bool grow(const scalarField &phiq)
More details about the minimum-volume ellipsoid covering an.
void increaseNLifeTime()
Increases the "counter" of the chP life.
bool checkSolution(const scalarField &phiq, const scalarField &Rphiq)
If phiq is not in the EOA, then the mapping is computed.
bool variableTimeStep() const
List< label > & simplifiedToCompleteIndex()
TDACChemistryModel< CompType, ThermoType > & chemistry()
Access to the TDACChemistryModel.
const scalarSquareMatrix & A() const
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
A class for handling words, derived from Foam::string.
Definition: word.H:68
volScalarField & p
BasicChemistryModel< psiReactionThermo > & chemistry
const scalar gamma
Definition: EEqn.H:9
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))
const dimensionedScalar sigma
Stefan-Boltzmann constant: default SI units: [W/m2/K4].
const dimensionedScalar c
Speed of light in a vacuum.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
dimensionedScalar sign(const dimensionedScalar &ds)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void multiply(FieldField< Field, Type > &f, const FieldField< Field, Type > &f1, const FieldField< Field, scalar > &f2)
SquareMatrix< scalar > scalarSquareMatrix
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
const dimensionedScalar & D
volScalarField & b
Definition: createFields.H:27
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333