void Multigrid::solve() { smooth(); computeResidual(); while (error() > tol() & n < maxIter()) iterate(); if (n == maxIter()) cout << "Multigrid reached maximum number of iterations" << endl; }
SimulatorReport NonlinearSolver<PhysicalModel>:: step(const SimulatorTimerInterface& timer, const ReservoirState& initial_reservoir_state, const WellState& initial_well_state, ReservoirState& reservoir_state, WellState& well_state) { SimulatorReport iterReport; SimulatorReport report; failureReport_ = SimulatorReport(); // Do model-specific once-per-step calculations. model_->prepareStep(timer, initial_reservoir_state, initial_well_state); int iteration = 0; // Let the model do one nonlinear iteration. // Set up for main solver loop. bool converged = false; // ---------- Main nonlinear solver loop ---------- do { try { // Do the nonlinear step. If we are in a converged state, the // model will usually do an early return without an expensive // solve, unless the minIter() count has not been reached yet. iterReport = model_->nonlinearIteration(iteration, timer, *this, reservoir_state, well_state); report += iterReport; report.converged = iterReport.converged; converged = report.converged; iteration += 1; } catch (...) { // if an iteration fails during a time step, all previous iterations // count as a failure as well failureReport_ += report; failureReport_ += model_->failureReport(); throw; } } while ( (!converged && (iteration <= maxIter())) || (iteration <= minIter())); if (!converged) { failureReport_ += report; std::string msg = "Solver convergence failure - Failed to complete a time step within " + std::to_string(maxIter()) + " iterations."; OPM_THROW_NOLOG(Opm::TooManyIterations, msg); } // Do model-specific post-step actions. model_->afterStep(timer, reservoir_state, well_state); report.converged = true; return report; }
int NonlinearSolver<PhysicalModel>:: step(const SimulatorTimerInterface& timer, const ReservoirState& initial_reservoir_state, const WellState& initial_well_state, ReservoirState& reservoir_state, WellState& well_state) { // Do model-specific once-per-step calculations. model_->prepareStep(timer, initial_reservoir_state, initial_well_state); int iteration = 0; // Let the model do one nonlinear iteration. // Set up for main solver loop. int linIters = 0; bool converged = false; int wellIters = 0; // ---------- Main nonlinear solver loop ---------- do { // Do the nonlinear step. If we are in a converged state, the // model will usually do an early return without an expensive // solve, unless the minIter() count has not been reached yet. IterationReport report = model_->nonlinearIteration(iteration, timer, *this, reservoir_state, well_state); if (report.failed) { OPM_THROW(Opm::NumericalProblem, "Failed to complete a nonlinear iteration."); } converged = report.converged; linIters += report.linear_iterations; wellIters += report.well_iterations; ++iteration; } while ( (!converged && (iteration <= maxIter())) || (iteration <= minIter())); if (!converged) { if (model_->terminalOutputEnabled()) { std::cerr << "WARNING: Failed to compute converged solution in " << iteration - 1 << " iterations." << std::endl; } return -1; // -1 indicates that the solver has to be restarted } linearIterations_ += linIters; nonlinearIterations_ += iteration - 1; // Since the last one will always be trivial. linearizations_ += iteration; wellIterations_ += wellIters; linearIterationsLast_ = linIters; nonlinearIterationsLast_ = iteration; wellIterationsLast_ = wellIters; // Do model-specific post-step actions. model_->afterStep(timer, reservoir_state, well_state); return linIters; }
void Foam::MULES::implicitSolve ( const RhoType& rho, volScalarField& psi, const surfaceScalarField& phi, surfaceScalarField& phiPsi, const SpType& Sp, const SuType& Su, const scalar psiMax, const scalar psiMin ) { const fvMesh& mesh = psi.mesh(); const dictionary& MULEScontrols = mesh.solverDict(psi.name()); label maxIter ( readLabel(MULEScontrols.lookup("maxIter")) ); label nLimiterIter ( readLabel(MULEScontrols.lookup("nLimiterIter")) ); scalar maxUnboundedness ( readScalar(MULEScontrols.lookup("maxUnboundedness")) ); scalar CoCoeff ( readScalar(MULEScontrols.lookup("CoCoeff")) ); scalarField allCoLambda(mesh.nFaces()); { tmp<surfaceScalarField> Cof = mesh.time().deltaT()*mesh.surfaceInterpolation::deltaCoeffs() *mag(phi)/mesh.magSf(); slicedSurfaceScalarField CoLambda ( IOobject ( "CoLambda", mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimless, allCoLambda, false // Use slices for the couples ); CoLambda == 1.0/max(CoCoeff*Cof, scalar(1)); } scalarField allLambda(allCoLambda); //scalarField allLambda(mesh.nFaces(), 1.0); slicedSurfaceScalarField lambda ( IOobject ( "lambda", mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh, dimless, allLambda, false // Use slices for the couples ); linear<scalar> CDs(mesh); upwind<scalar> UDs(mesh, phi); //fv::uncorrectedSnGrad<scalar> snGrads(mesh); fvScalarMatrix psiConvectionDiffusion ( fvm::ddt(rho, psi) + fv::gaussConvectionScheme<scalar>(mesh, phi, UDs).fvmDiv(phi, psi) //- fv::gaussLaplacianScheme<scalar, scalar>(mesh, CDs, snGrads) //.fvmLaplacian(Dpsif, psi) - fvm::Sp(Sp, psi) - Su ); surfaceScalarField phiBD(psiConvectionDiffusion.flux()); surfaceScalarField& phiCorr = phiPsi; phiCorr -= phiBD; for (label i=0; i<maxIter; i++) { if (i != 0 && i < 4) { allLambda = allCoLambda; } limiter ( allLambda, rho, psi, phiBD, phiCorr, Sp, Su, psiMax, psiMin, nLimiterIter ); solve ( psiConvectionDiffusion + fvc::div(lambda*phiCorr), MULEScontrols ); scalar maxPsiM1 = gMax(psi.internalField()) - 1.0; scalar minPsi = gMin(psi.internalField()); scalar unboundedness = max(max(maxPsiM1, 0.0), -min(minPsi, 0.0)); if (unboundedness < maxUnboundedness) { break; } else { Info<< "MULES: max(" << psi.name() << " - 1) = " << maxPsiM1 << " min(" << psi.name() << ") = " << minPsi << endl; phiBD = psiConvectionDiffusion.flux(); /* word gammaScheme("div(phi,gamma)"); word gammarScheme("div(phirb,gamma)"); const surfaceScalarField& phir = mesh.lookupObject<surfaceScalarField>("phir"); phiCorr = fvc::flux ( phi, psi, gammaScheme ) + fvc::flux ( -fvc::flux(-phir, scalar(1) - psi, gammarScheme), psi, gammarScheme ) - phiBD; */ } } phiPsi = psiConvectionDiffusion.flux() + lambda*phiCorr; }
int NewtonSolver<PhysicalModel>:: step(const double dt, ReservoirState& reservoir_state, WellState& well_state) { // Do model-specific once-per-step calculations. model_->prepareStep(dt, reservoir_state, well_state); // For each iteration we store in a vector the norms of the residual of // the mass balance for each active phase, the well flux and the well equations. std::vector<std::vector<double>> residual_norms_history; // Assemble residual and Jacobian, store residual norms. model_->assemble(reservoir_state, well_state, true); residual_norms_history.push_back(model_->computeResidualNorms()); // Set up for main Newton loop. double omega = 1.0; int iteration = 0; bool converged = model_->getConvergence(dt, iteration); const int sizeNonLinear = model_->sizeNonLinear(); V dxOld = V::Zero(sizeNonLinear); bool isOscillate = false; bool isStagnate = false; const enum RelaxType relaxtype = relaxType(); int linearIterations = 0; // ---------- Main Newton loop ---------- while ( (!converged && (iteration < maxIter())) || (minIter() > iteration)) { // Compute the Newton update to the primary variables. V dx = model_->solveJacobianSystem(); // Store number of linear iterations used. linearIterations += model_->linearIterationsLastSolve(); // Stabilize the Newton update. detectNewtonOscillations(residual_norms_history, iteration, relaxRelTol(), isOscillate, isStagnate); if (isOscillate) { omega -= relaxIncrement(); omega = std::max(omega, relaxMax()); if (model_->terminalOutputEnabled()) { std::cout << " Oscillating behavior detected: Relaxation set to " << omega << std::endl; } } stabilizeNewton(dx, dxOld, omega, relaxtype); // Apply the update, the model may apply model-dependent // limitations and chopping of the update. model_->updateState(dx, reservoir_state, well_state); // Assemble residual and Jacobian, store residual norms. model_->assemble(reservoir_state, well_state, false); residual_norms_history.push_back(model_->computeResidualNorms()); // increase iteration counter ++iteration; converged = model_->getConvergence(dt, iteration); } if (!converged) { if (model_->terminalOutputEnabled()) { std::cerr << "WARNING: Failed to compute converged solution in " << iteration << " iterations." << std::endl; } return -1; // -1 indicates that the solver has to be restarted } linearIterations_ += linearIterations; newtonIterations_ += iteration; linearIterationsLast_ = linearIterations; newtonIterationsLast_ = iteration; // Do model-specific post-step actions. model_->afterStep(dt, reservoir_state, well_state); return linearIterations; }
void Grnn::Trainer::trainBrent(Grnn& grnn) { double a = tolerance(); double b = grnn.bandwidth(); double x = 0.5*(a + b); bracket(grnn, a, b, x); if (a > b) SWP(a, b); double fx = error(grnn, x); double w = x, fw = fx; double v = x, fv = fx; double d = 0.0, u, e = 0.0; for(unsigned iter = 1; iter <= maxIter(); ++iter) { double xm = 0.5*(a + b); double tol1 = tolerance()*fabs(x) + ZEPS; double tol2 = 2.0*(tol1); if (fabs(x - xm) <= (tol2 - 0.5*(b - a))) break; if (fabs(e) > tol1) { double p = (x-v)*(x-v)*(fx-fw) - (x-w)*(x-w)*(fx-fv); double q = 2.0*((x-v)*(fx-fw) - (x-w)*(fx-fv)); if (q > 0.0) p = -p; q = fabs(q); double etemp = e; e = d; if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a - x) || p >= q*(b - x)) { if (x >= xm) e = a - x; else e = b - x; d = CGOLD*(e); } else { d = p/q; u = x + d; if (u - a < tol2 || b - u < tol2) d = SIGN(tol1, xm - x); } } else { if (x >= xm) e = a - x; else e = b - x; d = CGOLD *(e); } double u; if(fabs(d) >= tol1) u = x + d; else u = x + SIGN(tol1, d); double fu = error(grnn, u); if (fu <= fx) { if (u >= x) a = x; else b = x; SHFT(v, w, x, u); SHFT(fv, fw, fx, fu); } else { if (u < x) a = u; else b = u; if (fu <= fw || w == x) { v = w; w = u; fv = fw; fw = fu; } else if (fu <= fv || v == x || v == w) { v = u; fv = fu; } } } grnn.setBandwidth(x); }