chemPointISAT.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2016-2024 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Class
25  Foam::chemPointISAT
26 
27 Description
28  Leaf of the binary tree.
29  The chemPoint stores the composition 'phi', the mapping of this
30  composition Rphi, the mapping gradient matrix A and the matrix describing
31  the Ellipsoid Of Accuracy (EOA).
32 
33  1) When the chemPoint is created the region of accuracy is approximated by
34  an ellipsoid E centered in 'phi' (obtained with the constant):
35  E = {x| ||L^T.(x-phi)|| <= 1},
36  with x a point in the composition space and L^T the transpose of an
37  upper triangular matrix describing the EOA (see below: "Computation of
38  L" ).
39 
40  2) To RETRIEVE the mapping from the chemPoint phi, the query point phiq has
41  to be in the EOA of phi. It follows that, dphi=phiq-phi and to test if
42  phiq is in the ellipsoid there are two methods. First, compare
43  r=||dphi|| with rmin and rmax. If r < rmin, phiq is in the EOA. If r >
44  rmax, phiq is out of the EOA. This operations is O(completeSpaceSize)
45  and is performed first. If rmin < r < rmax, then the second method is
46  used:
47  ||L^T.dphi|| <= 1 to be in the EOA.
48  If phiq is in the EOA, Rphiq is obtained by linear interpolation:
49  Rphiq= Rphi + A.dphi.
50 
51  3) If phiq is not in the EOA, then the mapping is computed. But as the EOA
52  is a conservative approximation of the region of accuracy surrounding
53  the point phi, we could expand it by comparing the computed results with
54  the one obtained by linear interpolation. The error epsGrow is
55  calculated:
56  epsGrow = ||B.(dR - dRl)||,
57  with dR = Rphiq - Rphi, dRl = A.dphi and B the diagonal scale factor
58  matrix. If epsGrow <= tolerance, the EOA is too conservative and a GROW
59  is performed otherwise, the newly computed mapping is associated to the
60  initial composition and added to the tree.
61 
62  4) To GROW the EOA, we expand it to include the previous EOA and the query
63  point phiq. The rank-one matrix method is used. The EOA is transformed
64  to a hypersphere centered at the origin. Then it is expanded to include
65  the transformed point phiq' on its boundary. Then the inverse
66  transformation give the modified matrix L' (see below: "Grow the EOA").
67 
68 
69  Computation of L :
70  In [1], the EOA of the constant approximation is given by
71  E = {x| ||B.A/tolerance.(x-phi)|| <= 1},
72 
73  with B a scale factor diagonal matrix, A the mapping gradient matrix and
74  tolerance the absolute tolerance. If we take the QR decomposition of
75  (B.A)/tolerance= Q.R, with Q an orthogonal matrix and R an upper
76  triangular matrix such that the EOA is described by
77  (phiq-phi0)^T.R^T.R.(phiq-phi0) <= 1
78  L^T = R, both Cholesky decomposition of A^T.B^T.B.A/tolerance^2
79  This representation of the ellipsoid is used in [2] and in order to avoid
80  large value of semi-axe length in certain direction, a Singular Value
81  Decomposition (SVD) is performed on the L matrix:
82  L = UDV^T,
83  with the orthogonal matrix U giving the directions of the principal axes
84  and 1/di the inverse of the element of the diagonal matrix D giving the
85  length of the principal semi-axes. To avoid very large value of those
86  length, di' = max(di, 1/(alphaEOA*sqrt(tolerance))), with alphaEOA = 0.1
87  (see [2]) di' = max(di, 1/2), see [1]. The latter will be used in this
88  implementation. And L' = UD'V^T, with D' the diagonal matrix with the
89  modified di'.
90 
91  Grow the EOA :
92  More details about the minimum-volume ellipsoid covering an ellipsoid E
93  and a point p are found in [3]. Here is the main steps to obtain the
94  modified matrix L' describing the new ellipsoid.
95 
96  1) calculate the point p' in the transformed space :
97  p' = L^T.(p-phi)
98  2) compute the rank-one decomposition:
99  G = I + gamma.p'.p'^T,
100  with gamma = (1/|p'|-1)*1/|p'|^2
101  3) compute L':
102  L' = L.G.
103 
104  References:
105  \verbatim
106  [1] Pope, S. B. (1997).
107  Computationally efficient implementation of combustion chemistry using
108  in situ adaptive tabulation.
109  Combustion Theory and Modelling, 1, 41-63.
110 
111  [2] Lu, L., & Pope, S. B. (2009).
112  An improved algorithm for in situ adaptive tabulation.
113  Journal of Computational Physics, 228(2), 361-386.
114 
115  [3] Pope, S. B. (2008).
116  Algorithms for ellipsoids.
117  Cornell University Report No. FDA, 08-01.
118  \endverbatim
119 
120 \*---------------------------------------------------------------------------*/
121 
122 #ifndef chemPointISAT_H
123 #define chemPointISAT_H
124 
125 #include "scalarField.H"
126 #include "LUscalarMatrix.H"
127 #include "Switch.H"
128 
129 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
130 
131 namespace Foam
132 {
133 
134 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
135 
136 class binaryNode;
137 
138 namespace chemistryTabulationMethods
139 {
140  class ISAT;
141 }
142 
143 
144 /*---------------------------------------------------------------------------*\
145  Class chemPointISAT Declaration
146 \*---------------------------------------------------------------------------*/
147 
148 class chemPointISAT
149 {
150  // Private Data
151 
152  //- Reference to the ISAT table
154 
155  //- Vector storing the composition, temperature and pressure
156  // and deltaT if a variable time step is set on
157  scalarField phi_;
158 
159  //- Vector storing the mapping of the composition phi
160  scalarField Rphi_;
161 
162  //- LT the transpose of the L matrix describing the Ellipsoid Of
163  // Accuracy use List of Lists to be able to change size if DAC is used
164  scalarSquareMatrix LT_;
165 
166  //- A the mapping gradient matrix
168 
169  //- Vector storing the scale factor
170  scalarField scaleFactor_;
171 
172  //- Reference to the node in the binary tree holding this chemPoint
173  binaryNode* node_;
174 
175  //- The size of the composition space (size of the vector phi)
176  label completeSpaceSize_;
177 
178  //- Number of times the element has been grown
179  label nGrowth_;
180 
181  //- Tolerance for the Ellipsoid of accuracy
182  static scalar tolerance_;
183 
184  //- Number of active species stored in the chemPoint
185  label nActive_;
186 
187  //- Vectors that store the index conversion between the simplified
188  // and the complete chemical mechanism
189  List<label> simplifiedToCompleteIndex_;
190 
191  label timeTag_;
192  label lastTimeUsed_;
193 
194  bool toRemove_;
195 
196  label maxNumNewDim_;
197 
198  Switch printProportion_;
199 
200  //- Variable to store the number of retrieves the chemPoint
201  // will generate at each time step
202  label numRetrieve_;
203 
204  //- Variable to store the number of time steps the chempoint is allowed
205  // to still live according to the maxChPLifeTime_ parameter
206  label nLifeTime_;
207 
208  List<label> completeToSimplifiedIndex_;
209 
210  label idT_;
211  label idp_;
212  label iddeltaT_;
213 
214  //- QR decomposition of a matrix
215  // Input : nCols cols number
216  // R the matrix to decompose
217  // QT an empty matrix that stores the transpose of the Q matrix
218  // R is returned in the given R matrix
219  // which is used to store the ellipsoid of accuracy
220  void qrDecompose
221  (
222  const label nCols,
224  );
225 
226  //- QR update of the matrix A
227  void qrUpdate
228  (
230  const label n,
231  const scalarField& u,
232  const scalarField& v
233  );
234 
235  void rotate
236  (
238  const label i,
239  const scalar a,
240  const scalar b,
241  label n
242  );
243 
244 
245 public:
246 
247  // Constructors
248 
249  //- Construct from components
251  (
253  const scalarField& phi,
254  const scalarField& Rphi,
255  const scalarSquareMatrix& A,
256  const scalarField& scaleFactor,
257  const scalar tolerance,
258  const label completeSpaceSize,
259  const label nActive,
260  const label maxNumNewDim,
261  const Switch printProportion,
262  binaryNode* node = nullptr
263  );
264 
265  //- Construct from another chemPoint and reference to a binary node
267  (
268  const chemPointISAT& p,
270  );
271 
272  //- Construct from another chemPoint
274 
275 
276  // Member Functions
277 
278  //- Access to the ISAT table
279  inline const chemistryTabulationMethods::ISAT& table() const;
280 
281  inline label nGrowth() const;
282 
283  inline label& completeSpaceSize();
284 
285  inline const label& completeSpaceSize() const;
286 
287  inline const scalarField& phi() const;
288 
289  inline const scalarField& Rphi() const;
290 
291  inline const scalarField& scaleFactor() const;
292 
293  inline const scalar& tolerance() const;
294 
295  inline static void changeTolerance(scalar newTol);
296 
297  inline binaryNode*& node();
298 
299  inline const scalarSquareMatrix& A() const;
300 
301  inline scalarSquareMatrix& A();
302 
303  inline const scalarSquareMatrix& LT() const;
304 
305  inline scalarSquareMatrix& LT();
306 
307  inline label nActive() const;
308 
309  inline const List<label>& completeToSimplifiedIndex() const;
310 
311  inline const List<label>& simplifiedToCompleteIndex() const;
312 
313  //- Increases the number of retrieves the chempoint has generated
314  inline void increaseNumRetrieve();
315 
316  //- Resets the number of retrieves at each time step
317  inline void resetNumRetrieve();
318 
319  //- Increases the "counter" of the chP life
320  inline void increaseNLifeTime();
321 
322  inline label simplifiedToCompleteIndex(const label i);
323 
324  inline const label& timeTag();
325 
326  inline label& lastTimeUsed();
327 
328  inline bool& toRemove();
329 
330  inline label& maxNumNewDim();
331 
332  inline const label& numRetrieve();
333 
334  inline const label& nLifeTime();
335 
336  // ISAT functions
337 
338  //- To RETRIEVE the mapping from the stored chemPoint phi, the query
339  // point phiq has to be in the EOA of phi.
340  // To test if phiq is in the ellipsoid:
341  // ||L^T.dphi|| <= 1
342  bool inEOA(const scalarField& phiq);
343 
344  //- More details about the minimum-volume ellipsoid covering an
345  // ellipsoid E and a point p are found in [1].
346  // Here is the main steps to obtain the
347  // modified matrix L' describing the new ellipsoid.
348  // 1) calculate the point p' in the transformed space :
349  // p' = L^T.(p-phi)
350  // 2) compute the rank-one decomposition:
351  // G = I + gamma.p'.p'^T,
352  // with gamma = (1/|p'|-1)*1/|p'|^2
353  // 3) compute L':
354  // L'L'^T = (L.G)(L.G)^T,
355  // L'^T is then obtained by QR decomposition of (L.G)^T = G^T.L^T
356  // [1] Stephen B. Pope, "Algorithms for ellipsoids", FDA 08-01,
357  // Cornell University, 2008
358  bool grow(const scalarField& phiq);
359 
360  //- If phiq is not in the EOA, then the mapping is computed.
361  // But as the EOA is a conservative approximation of the region of
362  // accuracy surrounding the point phi, we could expand it by
363  // comparing the computed results with the one obtained by linear
364  // interpolation. The error eps is calculated:
365  // eps = ||B.(dR - dRl)||,
366  // with dR = Rphiq - Rphi, dRl = A.dphi and B the diagonal scale
367  // factor matrix.
368  // If eps <= tolerance, the EOA is too conservative and a GROW is
369  // performed,
370  // otherwise, the newly computed mapping is associated to the
371  // initial composition and added to the tree.
372  bool checkSolution
373  (
374  const scalarField& phiq,
375  const scalarField& Rphiq
376  );
377 };
378 
379 
380 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
381 
382 } // End namespace Foam
383 
384 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
385 
386 #include "chemPointISATI.H"
387 
388 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
389 
390 #endif
391 
392 // ************************************************************************* //
label n
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:61
Node of the binary tree.
Definition: binaryNode.H:49
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 label & timeTag()
const List< label > & completeToSimplifiedIndex() const
binaryNode *& node()
label nActive() const
const scalarField & Rphi() const
const scalarField & phi() const
const scalarField & scaleFactor() const
bool grow(const scalarField &phiq)
More details about the minimum-volume ellipsoid covering an.
void increaseNLifeTime()
Increases the "counter" of the chP life.
const scalarSquareMatrix & LT() const
const label & nLifeTime()
bool checkSolution(const scalarField &phiq, const scalarField &Rphiq)
If phiq is not in the EOA, then the mapping is computed.
chemPointISAT(chemistryTabulationMethods::ISAT &table, const scalarField &phi, const scalarField &Rphi, const scalarSquareMatrix &A, const scalarField &scaleFactor, const scalar tolerance, const label completeSpaceSize, const label nActive, const label maxNumNewDim, const Switch printProportion, binaryNode *node=nullptr)
Construct from components.
const scalarSquareMatrix & A() const
const scalar & tolerance() const
static void changeTolerance(scalar newTol)
label nGrowth() const
const chemistryTabulationMethods::ISAT & table() const
Access to the ISAT table.
label & completeSpaceSize()
const List< label > & simplifiedToCompleteIndex() const
const label & numRetrieve()
Implementation of the ISAT (In-situ adaptive tabulation), for chemistry calculation.
Definition: ISAT.H:63
volScalarField & b
Definition: createFields.H:27
Namespace for OpenFOAM.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
static scalar R(const scalar a, const scalar x)
Definition: invIncGamma.C:102
volScalarField & p