38 seulex::stepFactor1_ = 0.6,
39 seulex::stepFactor2_ = 0.93,
40 seulex::stepFactor3_ = 0.1,
41 seulex::stepFactor4_ = 4,
42 seulex::stepFactor5_ = 0.5,
43 seulex::kFactor1_ = 0.7,
44 seulex::kFactor2_ = 0.9;
53 jacRedo_(
min(1
e-4,
min(relTol_))),
56 coeff_(iMaxx_, iMaxx_),
73 const scalar cpuFunc = 1, cpuJac = 5, cpuLU = 1, cpuSolve = 1;
78 for (
int i=2; i<iMaxx_; i++)
80 nSeq_[i] = 2*nSeq_[i-2];
82 cpu_[0] = cpuJac + cpuLU + nSeq_[0]*(cpuFunc + cpuSolve);
84 for (
int k=0;
k<kMaxx_;
k++)
86 cpu_[
k+1] = cpu_[
k] + (nSeq_[
k+1]-1)*(cpuFunc + cpuSolve) + cpuLU;
90 for (
int k=0;
k<iMaxx_;
k++)
92 for (
int l=0; l<
k; l++)
94 scalar ratio = scalar(nSeq_[
k])/nSeq_[l];
95 coeff_(
k, l) = 1/(ratio - 1);
103 bool Foam::seulex::seul
115 scalar dx = dxTot/nSteps;
117 for (
label i=0; i<n_; i++)
119 for (
label j=0; j<n_; j++)
121 a_(i, j) = -dfdy_(i, j);
129 scalar xnew = x0 + dx;
130 odes_.derivatives(xnew,
y0, li, dy_);
135 for (
label nn=1; nn<nSteps; nn++)
143 for (
label i=0; i<n_; i++)
145 dy1 +=
sqr(dy_[i]/scale[i]);
149 odes_.derivatives(x0 + dx, yTemp_, li, dydx_);
150 for (
label i=0; i<n_; i++)
152 dy_[i] = dydx_[i] - dy_[i]/dx;
157 const scalar denom =
max(1, dy1);
160 for (
label i=0; i<n_; i++)
163 if (
mag(dy_[i]) > scale[i]*denom)
169 dy2 +=
sqr(dy_[i]/scale[i]);
180 odes_.derivatives(xnew, yTemp_, li, dy_);
184 for (
label i=0; i<n_; i++)
186 y[i] = yTemp_[i] + dy_[i];
193 void Foam::seulex::extrapolate
200 for (
int j=
k-1; j>0; j--)
202 for (
label i=0; i<n_; i++)
209 for (
int i=0; i<n_; i++)
220 table_.shallowResize(kMaxx_, n_);
224 resizeField(pivotIndices_);
226 resizeField(ySequence_);
250 scalar dx = step.
dxTry;
252 dxOpt_[0] =
mag(0.1*dx);
262 scalar logTol = -
log10(relTol_[0] + absTol_[0])*0.6 + 0.5;
263 kTarg_ =
max(1,
min(kMaxx_ - 1,
int(logTol)));
268 scale_[i] = absTol_[i] + relTol_[i]*
mag(
y[i]);
271 bool jacUpdated =
false;
273 if (theta_ > jacRedo_)
275 odes_.jacobian(
x,
y, li, dfdx_, dfdy_);
280 scalar dxNew =
mag(dx);
283 while (firstk || step.
reject)
285 dx = step.
forward ? dxNew : -dxNew;
292 <<
"step size underflow :" << dx <<
endl;
297 for (
k=0;
k<=kTarg_+1;
k++)
299 bool success = seul(
x, y0_, li, dx,
k, ySequence_, scale_);
304 dxNew =
mag(dx)*stepFactor5_;
316 table_[
k-1][i] = ySequence_[i];
322 extrapolate(
k, table_,
y);
326 scale_[i] = absTol_[i] + relTol_[i]*
mag(y0_[i]);
327 err +=
sqr((
y[i] - table_(0, i))/scale_[i]);
330 if (err > 1/small || (
k > 1 && err >= errOld))
333 dxNew =
mag(dx)*stepFactor5_;
336 errOld =
max(4*err, 1);
337 scalar expo = 1.0/(
k + 1);
338 scalar facmin =
pow(stepFactor3_, expo);
346 fac = stepFactor2_/
pow(err/stepFactor1_, expo);
347 fac =
max(facmin/stepFactor4_,
min(1/facmin, fac));
349 dxOpt_[
k] =
mag(dx*fac);
350 temp_[
k] = cpu_[
k]/dxOpt_[
k];
352 if ((step.
first || step.
last) && err <= 1)
368 else if (err > nSeq_[kTarg_]*nSeq_[kTarg_ + 1]*4)
372 if (kTarg_>1 && temp_[
k-1] < kFactor1_*temp_[
k])
376 dxNew = dxOpt_[kTarg_];
387 else if (err > nSeq_[
k + 1]*2)
390 if (kTarg_>1 && temp_[
k-1] < kFactor1_*temp_[
k])
394 dxNew = dxOpt_[kTarg_];
407 && temp_[kTarg_-1] < kFactor1_*temp_[kTarg_]
412 dxNew = dxOpt_[kTarg_];
425 if (theta_ > jacRedo_ && !jacUpdated)
427 odes_.jacobian(
x,
y, li, dfdx_, dfdy_);
444 else if (
k <= kTarg_)
447 if (temp_[
k-1] < kFactor1_*temp_[
k])
451 else if (temp_[
k] < kFactor2_*temp_[
k - 1])
453 kopt =
min(
k + 1, kMaxx_ - 1);
459 if (
k > 2 && temp_[
k-2] < kFactor1_*temp_[
k - 1])
463 if (temp_[
k] < kFactor2_*temp_[kopt])
465 kopt =
min(
k, kMaxx_ - 1);
471 kTarg_ =
min(kopt,
k);
472 dxNew =
min(
mag(dx), dxOpt_[kTarg_]);
479 dxNew = dxOpt_[kopt];
483 if (
k < kTarg_ && temp_[
k] < kFactor2_*temp_[
k - 1])
485 dxNew = dxOpt_[
k]*cpu_[kopt + 1]/cpu_[
k];
489 dxNew = dxOpt_[
k]*cpu_[kopt]/cpu_[
k];
#define forAll(list, i)
Loop across all elements in list.
Macros for easy insertion into run-time selection tables.
Abstract base-class for ODE system solvers.
virtual bool resize()=0
Resize the ODE solver.
Abstract base class for the systems of ordinary differential equations.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
An extrapolation-algorithm, based on the linearly implicit Euler method with step size control and or...
seulex(const ODESystem &ode, const dictionary &dict)
Construct from ODESystem.
virtual bool resize()
Resize the ODE solver.
virtual void solve(scalar &x, scalarField &y, const label li, stepState &step) const
Solve the ODE system and the update the state.
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar e
Elementary charge.
const HashTable< dimensionSet > table
Table of dimensions.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
addToRunTimeSelectionTable(polyPatch, mergedCyclicPolyPatch, word)
RectangularMatrix< scalar > scalarRectangularMatrix
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensionedScalar y0(const dimensionedScalar &ds)
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.
dimensionedScalar log10(const dimensionedScalar &ds)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
tmp< DimensionedField< typename powProduct< Type, r >::type, GeoMesh, Field > > pow(const DimensionedField< Type, GeoMesh, PrimitiveField > &df, typename powProduct< Type, r >::type)
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
void sqrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)