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-------------------------------------------------------------------------------
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 "SIBS.H"
31
32// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33
34namespace Foam
35{
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:
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{
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,
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// ************************************************************************* //
scalar y
label k
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Abstract base-class for ODE system solvers.
Definition: ODESolver.H:57
virtual bool resize()=0
Resize the ODE solver.
Definition: ODESolver.C:92
Abstract base class for the systems of ordinary differential equations.
Definition: ODESystem.H:50
A semi-implicit mid-point solver for stiff systems of ordinary differential equations.
Definition: SIBS.H:67
virtual bool resize()
Resize the ODE solver.
Definition: SIBS.C:74
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
An ODE solver for chemistry.
Definition: ode.H:55
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Namespace for OpenFOAM.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
dictionary dict
volScalarField & h
CEqn solve()