void Foam::SIBS::SIMPR ( const ODE& ode, const scalar xStart, const scalarField& y, const scalarField& dydx, const scalarField& dfdx, const scalarSquareMatrix& dfdy, const scalar deltaX, const label nSteps, scalarField& yEnd ) const { scalar h = deltaX/nSteps; scalarSquareMatrix a(n_); for (register label i=0; i<n_; i++) { for (register label j=0; j<n_; j++) { a[i][j] = -h*dfdy[i][j]; } ++a[i][i]; } labelList pivotIndices(n_); LUDecompose(a, pivotIndices); for (register label i=0; i<n_; i++) { yEnd[i] = h*(dydx[i] + h*dfdx[i]); } LUBacksubstitute(a, pivotIndices, yEnd); scalarField del(yEnd); scalarField ytemp(n_); for (register label i=0; i<n_; i++) { ytemp[i] = y[i] + del[i]; } scalar x = xStart + h; ode.derivatives(x, ytemp, yEnd); for (register label nn=2; nn<=nSteps; nn++) { for (register label i=0; i<n_; i++) { yEnd[i] = h*yEnd[i] - del[i]; } LUBacksubstitute(a, pivotIndices, yEnd); for (register label i=0; i<n_; i++) { ytemp[i] += (del[i] += 2.0*yEnd[i]); } x += h; ode.derivatives(x, ytemp, yEnd); } for (register label i=0; i<n_; i++) { yEnd[i] = h*yEnd[i] - del[i]; } LUBacksubstitute(a, pivotIndices, yEnd); for (register label i=0; i<n_; i++) { yEnd[i] += ytemp[i]; } }
void Foam::ODESolver::solve ( const ODE& ode, const scalar xStart, const scalar xEnd, scalarField& y, const scalar eps, scalar& hEst ) const { const label MAXSTP = 10000; scalar x = xStart; scalar h = hEst; scalar hNext = 0; scalar hPrev = 0; for (label nStep=0; nStep<MAXSTP; nStep++) { ode.derivatives(x, y, dydx_); for (label i=0; i<n_; i++) { yScale_[i] = mag(y[i]) + mag(dydx_[i]*h) + SMALL; } if ((x + h - xEnd)*(x + h - xStart) > 0.0) { h = xEnd - x; hPrev = hNext; } hNext = 0; scalar hDid; solve(ode, x, y, dydx_, eps, yScale_, h, hDid, hNext); if ((x - xEnd)*(xEnd - xStart) >= 0.0) { if (hPrev != 0) { hEst = hPrev; } else { hEst = hNext; } return; } h = hNext; } FatalErrorIn ( "ODESolver::solve" "(const ODE& ode, const scalar xStart, const scalar xEnd," "scalarField& yStart, const scalar eps, scalar& hEst) const" ) << "Too many integration steps" << exit(FatalError); }
void Foam::KRR4::solve ( const ODE& ode, scalar& x, scalarField& y, scalarField& dydx, const scalar eps, const scalarField& yScale, const scalar hTry, scalar& hDid, scalar& hNext ) const { scalar xTemp = x; yTemp_ = y; dydxTemp_ = dydx; ode.jacobian(xTemp, yTemp_, dfdx_, dfdy_); scalar h = hTry; for (register label jtry=0; jtry<maxtry; jtry++) { for (register label i=0; i<n_; i++) { for (register label j=0; j<n_; j++) { a_[i][j] = -dfdy_[i][j]; } a_[i][i] += 1.0/(gamma*h); } LUDecompose(a_, pivotIndices_); for (register label i=0; i<n_; i++) { g1_[i] = dydxTemp_[i] + h*c1X*dfdx_[i]; } LUBacksubstitute(a_, pivotIndices_, g1_); for (register label i=0; i<n_; i++) { y[i] = yTemp_[i] + a21*g1_[i]; } x = xTemp + a2X*h; ode.derivatives(x, y, dydx_); for (register label i=0; i<n_; i++) { g2_[i] = dydx_[i] + h*c2X*dfdx_[i] + c21*g1_[i]/h; } LUBacksubstitute(a_, pivotIndices_, g2_); for (register label i=0; i<n_; i++) { y[i] = yTemp_[i] + a31*g1_[i] + a32*g2_[i]; } x = xTemp + a3X*h; ode.derivatives(x, y, dydx_); for (register label i=0; i<n_; i++) { g3_[i] = dydx[i] + h*c3X*dfdx_[i] + (c31*g1_[i] + c32*g2_[i])/h; } LUBacksubstitute(a_, pivotIndices_, g3_); for (register label i=0; i<n_; i++) { g4_[i] = dydx_[i] + h*c4X*dfdx_[i] + (c41*g1_[i] + c42*g2_[i] + c43*g3_[i])/h; } LUBacksubstitute(a_, pivotIndices_, g4_); for (register label i=0; i<n_; i++) { y[i] = yTemp_[i] + b1*g1_[i] + b2*g2_[i] + b3*g3_[i] + b4*g4_[i]; yErr_[i] = e1*g1_[i] + e2*g2_[i] + e3*g3_[i] + e4*g4_[i]; } x = xTemp + h; if (x == xTemp) { FatalErrorIn("ODES::KRR4") << "stepsize not significant" << exit(FatalError); } scalar maxErr = 0.0; for (register label i=0; i<n_; i++) { maxErr = max(maxErr, mag(yErr_[i]/yScale[i])); } maxErr /= eps; if (maxErr <= 1.0) { hDid = h; hNext = (maxErr > errcon ? safety*h*pow(maxErr, pgrow) : grow*h); return; } else { hNext = safety*h*pow(maxErr, pshrink); h = (h >= 0.0 ? max(hNext, shrink*h) : min(hNext, shrink*h)); } } FatalErrorIn("ODES::KRR4") << "exceeded maxtry" << exit(FatalError); }