Go to the documentation of this file.
53 jacRedo_(
min(1.0
e-4,
min(relTol_))),
56 coeff_(iMaxx_, iMaxx_),
73 const scalar cpuFunc = 1.0, cpuJac = 5.0, cpuLU = 1.0, cpuSolve = 1.0;
78 for (
int i=2; i<
iMaxx_; i++)
82 cpu_[0] = cpuJac + cpuLU +
nSeq_[0]*(cpuFunc + cpuSolve);
92 for (
int l=0; l<
k; l++)
95 coeff_[
k][l] = 1.0/(ratio - 1.0);
114 scalar dx = dxTot/nSteps;
116 for (
label i=0; i<n_; i++)
118 for (
label j=0; j<n_; j++)
120 a_[i][j] = -dfdy_[i][j];
128 scalar xnew = x0 + dx;
129 odes_.derivatives(xnew,
y0, dy_);
134 for (
label nn=1; nn<nSteps; nn++)
142 for (
label i=0; i<n_; i++)
144 dy1 +=
sqr(dy_[i]/scale[i]);
148 odes_.derivatives(x0 + dx, yTemp_, dydx_);
149 for (
label i=0; i<n_; i++)
151 dy_[i] = dydx_[i] - dy_[i]/dx;
157 for (
label i=0; i<n_; i++)
159 dy2 +=
sqr(dy_[i]/scale[i]);
162 theta_ = dy2/
min(1.0, dy1 + SMALL);
170 odes_.derivatives(xnew, yTemp_, dy_);
174 for (
label i=0; i<n_; i++)
176 y[i] = yTemp_[i] + dy_[i];
190 for (
int j=
k-1; j>0; j--)
192 for (
label i=0; i<n_; i++)
195 table[j][i] + coeff_[
k][j]*(table[j][i] - table[j-1][i]);
199 for (
int i=0; i<n_; i++)
201 y[i] = table[0][i] + coeff_[
k][0]*(table[0][i] -
y[i]);
214 scalar dx = step.
dxTry;
216 dxOpt_[0] =
mag(0.1*dx);
220 theta_ = 2.0*jacRedo_;
226 scalar logTol = -
log10(relTol_[0] + absTol_[0])*0.6 + 0.5;
227 kTarg_ =
max(1,
min(kMaxx_ - 1,
int(logTol)));
232 scale_[i] = absTol_[i] + relTol_[i]*
mag(
y[i]);
235 bool jacUpdated =
false;
237 if (theta_ > jacRedo_)
239 odes_.jacobian(
x,
y, dfdx_, dfdy_);
244 scalar dxNew =
mag(dx);
247 while (firstk || step.
reject)
249 dx = step.
forward ? dxNew : -dxNew;
256 <<
"step size underflow :" << dx <<
endl;
261 for (
k=0;
k<=kTarg_+1;
k++)
263 bool success = seul(
x, y0_, dx,
k, ySequence_, scale_);
268 dxNew =
mag(dx)*stepFactor5_;
280 table_[
k-1][i] = ySequence_[i];
286 extrapolate(
k, table_,
y);
290 scale_[i] = absTol_[i] + relTol_[i]*
mag(y0_[i]);
291 err +=
sqr((
y[i] - table_[0][i])/scale_[i]);
294 if (err > 1.0/SMALL || (
k > 1 && err >= errOld))
297 dxNew =
mag(dx)*stepFactor5_;
300 errOld =
min(4*err, 1);
301 scalar expo = 1.0/(
k + 1);
302 scalar facmin =
pow(stepFactor3_, expo);
310 fac = stepFactor2_/
pow(err/stepFactor1_, expo);
311 fac =
max(facmin/stepFactor4_,
min(1.0/facmin, fac));
313 dxOpt_[
k] =
mag(dx*fac);
314 temp_[
k] = cpu_[
k]/dxOpt_[
k];
316 if ((step.
first || step.
last) && err <= 1.0)
332 else if (err > nSeq_[kTarg_]*nSeq_[kTarg_ + 1]*4.0)
336 if (kTarg_>1 && temp_[
k-1] < kFactor1_*temp_[
k])
340 dxNew = dxOpt_[kTarg_];
351 else if (err > nSeq_[
k + 1]*2.0)
354 if (kTarg_>1 && temp_[
k-1] < kFactor1_*temp_[
k])
358 dxNew = dxOpt_[kTarg_];
371 && temp_[kTarg_-1] < kFactor1_*temp_[kTarg_]
376 dxNew = dxOpt_[kTarg_];
387 theta_ = 2.0*jacRedo_;
389 if (theta_ > jacRedo_ && !jacUpdated)
391 odes_.jacobian(
x,
y, dfdx_, dfdy_);
408 else if (
k <= kTarg_)
411 if (temp_[
k-1] < kFactor1_*temp_[
k])
415 else if (temp_[
k] < kFactor2_*temp_[
k - 1])
417 kopt =
min(
k + 1, kMaxx_ - 1);
423 if (
k > 2 && temp_[
k-2] < kFactor1_*temp_[
k - 1])
427 if (temp_[
k] < kFactor2_*temp_[kopt])
429 kopt =
min(
k, kMaxx_ - 1);
435 kTarg_ =
min(kopt,
k);
436 dxNew =
min(
mag(dx), dxOpt_[kTarg_]);
443 dxNew = dxOpt_[kopt];
447 if (
k < kTarg_ && temp_[
k] < kFactor2_*temp_[
k - 1])
449 dxNew = dxOpt_[
k]*cpu_[kopt + 1]/cpu_[
k];
453 dxNew = dxOpt_[
k]*cpu_[kopt]/cpu_[
k];
static const scalar stepFactor3_
static const scalar stepFactor5_
scalarSquareMatrix coeff_
Abstract base-class for ODE system solvers.
#define forAll(list, i)
Loop across all elements in list.
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
static const scalar stepFactor4_
static const label kMaxx_
Ostream & endl(Ostream &os)
Add newline and flush stream.
void solve(scalar &x, scalarField &y, stepState &step) const
Solve the ODE system and the update the state.
static const scalar stepFactor1_
dimensioned< scalar > mag(const dimensioned< Type > &)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Pre-declare SubField and related Field type.
dimensionedScalar log10(const dimensionedScalar &ds)
dimensionedScalar y0(const dimensionedScalar &ds)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
An ODE solver for chemistry.
A list of keyword definitions, which are a keyword followed by any number of values (e....
Macros for easy insertion into run-time selection tables.
static const label iMaxx_
void LUBacksubstitute(const scalarSquareMatrix &luMmatrix, const labelList &pivotIndices, List< Type > &source)
LU back-substitution with given source, returning the solution.
void LUDecompose(scalarSquareMatrix &matrix, labelList &pivotIndices)
LU decompose the matrix with pivoting.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
void extrapolate(const label k, scalarRectangularMatrix &table, scalarField &y) const
Polynomial extrpolation.
static const scalar stepFactor2_
Abstract base class for the systems of ordinary differential equations.
dimensionedScalar sqrt(const dimensionedScalar &ds)
static const scalar kFactor1_
label k
Boltzmann constant.
const dimensionedScalar e
Elementary charge.
bool seul(const scalar x0, const scalarField &y0, const scalar dxTot, const label k, scalarField &y, const scalarField &scale) const
Computes the j-th line of the extrapolation table.
static const scalar kFactor2_
defineTypeNameAndDebug(combustionModel, 0)
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
#define WarningInFunction
Report a warning using Foam::Warning.
seulex(const ODESystem &ode, const dictionary &dict)
Construct from ODE.