SIBS.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019 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 "SIBS.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(SIBS, 0);
37  addToRunTimeSelectionTable(ODESolver, SIBS, dictionary);
38 
39  const label SIBS::nSeq_[iMaxX_] = {2, 6, 10, 14, 22, 34, 50, 70};
40 
41  const scalar
42  SIBS::safe1 = 0.25,
43  SIBS::safe2 = 0.7,
44  SIBS::redMax = 1.0e-5,
45  SIBS::redMin = 0.7,
46  SIBS::scaleMX = 0.1;
47 }
48 
49 
50 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
51 
53 :
54  ODESolver(ode, dict),
55  a_(iMaxX_, Zero),
56  alpha_(kMaxX_, Zero),
57  d_p_(n_, kMaxX_, Zero),
58  x_p_(kMaxX_, Zero),
59  err_(kMaxX_, Zero),
60 
61  yTemp_(n_, Zero),
62  ySeq_(n_, Zero),
63  yErr_(n_, Zero),
64  dydx0_(n_),
65  dfdx_(n_, Zero),
66  dfdy_(n_, Zero),
67  first_(1),
68  epsOld_(-1.0)
69 {}
70 
71 
72 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
73 
75 {
76  if (ODESolver::resize())
77  {
78  resizeField(yTemp_);
79  resizeField(ySeq_);
80  resizeField(yErr_);
81  resizeField(dydx0_);
82  resizeField(dfdx_);
83  resizeMatrix(dfdy_);
84 
85  return true;
86  }
87 
88  return false;
89 }
90 
91 
93 (
94  scalar& x,
95  scalarField& y,
96  scalar& dxTry
97 ) const
98 {
99  odes_.derivatives(x, y, dydx0_);
100 
101  scalar h = dxTry;
102  bool exitflag = false;
103 
104  if (relTol_[0] != epsOld_)
105  {
106  dxTry = xNew_ = -GREAT;
107  scalar eps1 = safe1*relTol_[0];
108  a_[0] = nSeq_[0] + 1;
109 
110  for (label k=0; k<kMaxX_; k++)
111  {
112  a_[k + 1] = a_[k] + nSeq_[k + 1];
113  }
114 
115  for (label iq = 1; iq<kMaxX_; iq++)
116  {
117  for (label k=0; k<iq; k++)
118  {
119  alpha_[k][iq] =
120  pow(eps1, (a_[k + 1] - a_[iq + 1])
121  /((a_[iq + 1] - a_[0] + 1.0)*(2*k + 3)));
122  }
123  }
124 
125  epsOld_ = relTol_[0];
126  a_[0] += n_;
127 
128  for (label k=0; k<kMaxX_; k++)
129  {
130  a_[k + 1] = a_[k] + nSeq_[k + 1];
131  }
132 
133  for (kOpt_ = 1; kOpt_<kMaxX_ - 1; kOpt_++)
134  {
135  if (a_[kOpt_ + 1] > a_[kOpt_]*alpha_[kOpt_ - 1][kOpt_])
136  {
137  break;
138  }
139  }
140 
141  kMax_ = kOpt_;
142  }
143 
144  label k = 0;
145  yTemp_ = y;
146 
147  odes_.jacobian(x, y, dfdx_, dfdy_);
148 
149  if (x != xNew_ || h != dxTry)
150  {
151  first_ = 1;
152  kOpt_ = kMax_;
153  }
154 
155  label km=0;
156  label reduct=0;
157  scalar maxErr = SMALL;
158 
159  for (;;)
160  {
161  scalar red = 1.0;
162 
163  for (k=0; k <= kMax_; k++)
164  {
165  xNew_ = x + h;
166 
167  if (xNew_ == x)
168  {
170  << "step size underflow"
171  << exit(FatalError);
172  }
173 
174  SIMPR(x, yTemp_, dydx0_, dfdx_, dfdy_, h, nSeq_[k], ySeq_);
175  scalar xest = sqr(h/nSeq_[k]);
176 
177  polyExtrapolate(k, xest, ySeq_, y, yErr_, x_p_, d_p_);
178 
179  if (k != 0)
180  {
181  maxErr = SMALL;
182  for (label i=0; i<n_; i++)
183  {
184  maxErr = max
185  (
186  maxErr,
187  mag(yErr_[i])/(absTol_[i] + relTol_[i]*mag(yTemp_[i]))
188  );
189  }
190  km = k - 1;
191  err_[km] = pow(maxErr/safe1, 1.0/(2*km + 3));
192  }
193 
194  if (k != 0 && (k >= kOpt_ - 1 || first_))
195  {
196  if (maxErr < 1.0)
197  {
198  exitflag = true;
199  break;
200  }
201 
202  if (k == kMax_ || k == kOpt_ + 1)
203  {
204  red = safe2/err_[km];
205  break;
206  }
207  else if (k == kOpt_ && alpha_[kOpt_ - 1][kOpt_] < err_[km])
208  {
209  red = 1.0/err_[km];
210  break;
211  }
212  else if (kOpt_ == kMax_ && alpha_[km][kMax_ - 1] < err_[km])
213  {
214  red = alpha_[km][kMax_ - 1]*safe2/err_[km];
215  break;
216  }
217  else if (alpha_[km][kOpt_] < err_[km])
218  {
219  red = alpha_[km][kOpt_ - 1]/err_[km];
220  break;
221  }
222  }
223  }
224 
225  if (exitflag)
226  {
227  break;
228  }
229 
230  red = min(red, redMin);
231  red = max(red, redMax);
232  h *= red;
233  reduct = 1;
234  }
235 
236  x = xNew_;
237  first_ = 0;
238  scalar wrkmin = GREAT;
239  scalar scale = 1.0;
240 
241  for (label kk=0; kk<=km; kk++)
242  {
243  scalar fact = max(err_[kk], scaleMX);
244  scalar work = fact*a_[kk + 1];
245  if (work < wrkmin)
246  {
247  scale = fact;
248  wrkmin = work;
249  kOpt_ = kk + 1;
250  }
251  }
252 
253  dxTry = h/scale;
254 
255  if (kOpt_ >= k && kOpt_ != kMax_ && !reduct)
256  {
257  scalar fact = max(scale/alpha_[kOpt_ - 1][kOpt_], scaleMX);
258  if (a_[kOpt_ + 1]*fact <= wrkmin)
259  {
260  dxTry = h/fact;
261  kOpt_++;
262  }
263  }
264 }
265 
266 
267 // ************************************************************************* //
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::ODESolver
Abstract base-class for ODE system solvers.
Definition: ODESolver.H:56
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
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
Foam::Field< scalar >
Foam::constant::universal::h
const dimensionedScalar h
Planck constant.
Definition: setRegionSolidFields.H:33
Foam::SIBS::resize
virtual bool resize()
Resize the ODE solver.
Definition: SIBS.C:74
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
Foam::ode
An ODE solver for chemistry.
Definition: ode.H:52
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
Foam::SIBS::solve
virtual void solve(scalar &x, scalarField &y, scalar &dxTry) const
Solve the ODE system as far as possible up to dxTry.
Definition: SIBS.C:93
Foam::ODESystem
Abstract base class for the systems of ordinary differential equations.
Definition: ODESystem.H:49
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
x
x
Definition: LISASMDCalcMethod2.H:52
SIBS.H
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::ODESolver::resize
virtual bool resize()=0
Resize the ODE solver.
Definition: ODESolver.C:92
Foam::SIBS::SIBS
SIBS(const ODESystem &ode, const dictionary &dict)
Construct from ODE system.
Definition: SIBS.C:52
y
scalar y
Definition: LISASMDCalcMethod1.H:14