void Foam::LUscalarMatrix::solve ( Field<Type>& x, const Field<Type>& source ) const { // If x and source are different initialize x = source if (&x != &source) { x = source; } if (Pstream::parRun()) { Field<Type> X(m()); if (Pstream::master(comm_)) { typename Field<Type>::subField ( X, x.size() ) = x; for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(comm_); slave++ ) { IPstream::read ( Pstream::scheduled, slave, reinterpret_cast<char*> ( &(X[procOffsets_[slave]]) ), (procOffsets_[slave+1]-procOffsets_[slave])*sizeof(Type), Pstream::msgType(), comm_ ); } } else { OPstream::write ( Pstream::scheduled, Pstream::masterNo(), reinterpret_cast<const char*>(x.begin()), x.byteSize(), Pstream::msgType(), comm_ ); } if (Pstream::master(comm_)) { LUBacksubstitute(*this, pivotIndices_, X); x = typename Field<Type>::subField ( X, x.size() ); for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(comm_); slave++ ) { OPstream::write ( Pstream::scheduled, slave, reinterpret_cast<const char*> ( &(X[procOffsets_[slave]]) ), (procOffsets_[slave + 1]-procOffsets_[slave])*sizeof(Type), Pstream::msgType(), comm_ ); } } else { IPstream::read ( Pstream::scheduled, Pstream::masterNo(), reinterpret_cast<char*>(x.begin()), x.byteSize(), Pstream::msgType(), comm_ ); } } else { LUBacksubstitute(*this, pivotIndices_, x); } }
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]; } }
bool Foam::seulex::seul ( const scalar x0, const scalarField& y0, const scalar dxTot, const label k, scalarField& y, const scalarField& scale ) const { label nSteps = nSeq_[k]; scalar dx = dxTot/nSteps; for (label i=0; i<n_; i++) { for (label j=0; j<n_; j++) { a_(i, j) = -dfdy_(i, j); } a_(i, i) += 1/dx; } LUDecompose(a_, pivotIndices_); scalar xnew = x0 + dx; odes_.derivatives(xnew, y0, dy_); LUBacksubstitute(a_, pivotIndices_, dy_); yTemp_ = y0; for (label nn=1; nn<nSteps; nn++) { yTemp_ += dy_; xnew += dx; if (nn == 1 && k<=1) { scalar dy1 = 0; for (label i=0; i<n_; i++) { dy1 += sqr(dy_[i]/scale[i]); } dy1 = sqrt(dy1); odes_.derivatives(x0 + dx, yTemp_, dydx_); for (label i=0; i<n_; i++) { dy_[i] = dydx_[i] - dy_[i]/dx; } LUBacksubstitute(a_, pivotIndices_, dy_); const scalar denom = min(1, dy1 + SMALL); scalar dy2 = 0; for (label i=0; i<n_; i++) { // Test of dy_[i] to avoid overflow if (mag(dy_[i]) > scale[i]*denom) { theta_ = 1; return false; } dy2 += sqr(dy_[i]/scale[i]); } dy2 = sqrt(dy2); theta_ = dy2/denom; if (theta_ > 1) { return false; } } odes_.derivatives(xnew, yTemp_, dy_); LUBacksubstitute(a_, pivotIndices_, dy_); } for (label i=0; i<n_; i++) { y[i] = yTemp_[i] + dy_[i]; } return true; }
bool Foam::seulex::seul ( const scalar x0, const scalarField& y0, const scalar dxTot, const label k, scalarField& y, const scalarField& scale ) const { label nSteps = nSeq_[k]; scalar dx = dxTot/nSteps; for (label i=0; i<n_; i++) { for (label j=0; j<n_; j++) { a_[i][j] = -dfdy_[i][j]; } a_[i][i] += 1.0/dx; } LUDecompose(a_, pivotIndices_); scalar xnew = x0 + dx; odes_.derivatives(xnew, y0, dy_); LUBacksubstitute(a_, pivotIndices_, dy_); yTemp_ = y0; for (label nn=1; nn<nSteps; nn++) { yTemp_ += dy_; xnew += dx; if (nn == 1 && k<=1) { scalar dy1 = 0.0; for (label i=0; i<n_; i++) { dy1 += sqr(dy_[i]/scale[i]); } dy1 = sqrt(dy1); odes_.derivatives(x0 + dx, yTemp_, dydx_); for (label i=0; i<n_; i++) { dy_[i] = dydx_[i] - dy_[i]/dx; } LUBacksubstitute(a_, pivotIndices_, dy_); scalar dy2 = 0.0; for (label i=0; i<n_; i++) { dy2 += sqr(dy_[i]/scale[i]); } dy2 = sqrt(dy2); theta_ = dy2/min(1.0, dy1 + SMALL); if (theta_ > 1.0) { return false; } } odes_.derivatives(xnew, yTemp_, dy_); LUBacksubstitute(a_, pivotIndices_, dy_); } for (label i=0; i<n_; i++) { y[i] = yTemp_[i] + dy_[i]; } return true; }
void Foam::LUscalarMatrix::solve(Field<Type>& sourceSol) const { if (Pstream::parRun()) { Field<Type> completeSourceSol(m()); if (Pstream::master(comm_)) { typename Field<Type>::subField ( completeSourceSol, sourceSol.size() ).assign(sourceSol); for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(comm_); slave++ ) { IPstream::read ( Pstream::scheduled, slave, reinterpret_cast<char*> ( &(completeSourceSol[procOffsets_[slave]]) ), (procOffsets_[slave+1]-procOffsets_[slave])*sizeof(Type), Pstream::msgType(), comm_ ); } } else { OPstream::write ( Pstream::scheduled, Pstream::masterNo(), reinterpret_cast<const char*>(sourceSol.begin()), sourceSol.byteSize(), Pstream::msgType(), comm_ ); } if (Pstream::master(comm_)) { LUBacksubstitute(*this, pivotIndices_, completeSourceSol); sourceSol = typename Field<Type>::subField ( completeSourceSol, sourceSol.size() ); for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(comm_); slave++ ) { OPstream::write ( Pstream::scheduled, slave, reinterpret_cast<const char*> ( &(completeSourceSol[procOffsets_[slave]]) ), (procOffsets_[slave + 1]-procOffsets_[slave])*sizeof(Type), Pstream::msgType(), comm_ ); } } else { IPstream::read ( Pstream::scheduled, Pstream::masterNo(), reinterpret_cast<char*>(sourceSol.begin()), sourceSol.byteSize(), Pstream::msgType(), comm_ ); } } else { LUBacksubstitute(*this, pivotIndices_, sourceSol); } }
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); }