static PetscErrorCode TSStage_EIMEX(TS ts,PetscInt istage) { TS_EIMEX *ext = (TS_EIMEX*)ts->data; PetscReal h; Vec Y=ext->Y, Z=ext->Z; SNES snes; TSAdapt adapt; PetscInt i,its,lits; PetscBool accept; PetscErrorCode ierr; PetscFunctionBegin; ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); h = ts->time_step/ext->N[istage];/* step size for the istage-th stage */ ext->shift = 1./h; ierr = SNESSetLagJacobian(snes,-2);CHKERRQ(ierr); /* Recompute the Jacobian on this solve, but not again */ ierr = VecCopy(ext->VecSolPrev,Y);CHKERRQ(ierr); /* Take the previous solution as intial step */ for(i=0; i<ext->N[istage]; i++){ ext->ctime = ts->ptime + h*i; ierr = VecCopy(Y,Z);CHKERRQ(ierr);/* Save the solution of the previous substep */ ierr = SNESSolve(snes,NULL,Y);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr); ts->snes_its += its; ts->ksp_its += lits; ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); ierr = TSAdaptCheckStage(adapt,ts,ext->ctime,Y,&accept);CHKERRQ(ierr); } PetscFunctionReturn(0); }
int main(int argc,char **argv) { SNES snes; PetscErrorCode ierr; PetscInt its,lits; PetscReal litspit; DM da; PetscInitialize(&argc,&argv,PETSC_NULL,help); /* Set the DMDA (grid structure) for the grids. */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,-5,-5,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,&da);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,PETSC_NULL);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,da);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes,0,0);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr); litspit = ((PetscReal)lits)/((PetscReal)its); ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of SNES iterations = %D\n",its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of Linear iterations = %D\n",lits);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Average Linear its / SNES = %e\n",litspit);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
std::pair<unsigned int, Real> PetscDMNonlinearSolver<T>::solve (SparseMatrix<T>& jac_in, // System Jacobian Matrix NumericVector<T>& x_in, // Solution vector NumericVector<T>& r_in, // Residual vector const double, // Stopping tolerance const unsigned int) { START_LOG("solve()", "PetscNonlinearSolver"); this->init (); // Make sure the data passed in are really of Petsc types libmesh_cast_ptr<PetscMatrix<T>*>(&jac_in); libmesh_cast_ptr<PetscVector<T>*>(&r_in); // Extract solution vector PetscVector<T>* x = libmesh_cast_ptr<PetscVector<T>*>(&x_in); int ierr=0; int n_iterations =0; // Should actually be a PetscReal, but I don't know which version of PETSc first introduced PetscReal Real final_residual_norm=0.; if (this->user_presolve) this->user_presolve(this->system()); //Set the preconditioning matrix if (this->_preconditioner) this->_preconditioner->set_matrix(jac_in); ierr = SNESSolve (this->_snes, PETSC_NULL, x->vec()); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = SNESGetIterationNumber(this->_snes,&n_iterations); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = SNESGetLinearSolveIterations(this->_snes, &this->_n_linear_iterations); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = SNESGetFunctionNorm(this->_snes,&final_residual_norm); CHKERRABORT(libMesh::COMM_WORLD,ierr); // Get and store the reason for convergence SNESGetConvergedReason(this->_snes, &this->_reason); //Based on Petsc 2.3.3 documentation all diverged reasons are negative this->converged = (this->_reason >= 0); this->clear(); STOP_LOG("solve()", "PetscNonlinearSolver"); // return the # of its. and the final residual norm. return std::make_pair(n_iterations, final_residual_norm); }
static PetscErrorCode TS_SNESSolve(TS ts,Vec b,Vec x) { PetscInt nits,lits; PetscErrorCode ierr; PetscFunctionBegin; ierr = SNESSolve(ts->snes,b,x);CHKERRQ(ierr); ierr = SNESGetIterationNumber(ts->snes,&nits);CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(ts->snes,&lits);CHKERRQ(ierr); ts->snes_its += nits; ts->ksp_its += lits; PetscFunctionReturn(0); }
PetscErrorCode SNESNoiseMonitor(SNES snes,PetscInt its,double fnorm,void *dummy) { PetscErrorCode ierr; PetscInt lin_its; PetscFunctionBegin; ierr = SNESGetLinearSolveIterations(snes,&lin_its);CHKERRQ(ierr); lin_its_total += lin_its; ierr = PetscPrintf(PetscObjectComm((PetscObject)snes), "iter = %D, SNES Function norm = %g, lin_its = %D, total_lin_its = %D\n",its,(double)fnorm,lin_its,lin_its_total);CHKERRQ(ierr); ierr = SNESUnSetMatrixFreeParameter(snes);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode TSStep_Theta(TS ts) { TS_Theta *th = (TS_Theta*)ts->data; PetscInt its,lits; PetscReal next_time_step; SNESConvergedReason snesreason; PetscErrorCode ierr; PetscFunctionBegin; next_time_step = ts->time_step; th->stage_time = ts->ptime + (th->endpoint ? 1. : th->Theta)*ts->time_step; th->shift = 1./(th->Theta*ts->time_step); ierr = TSPreStep(ts);CHKERRQ(ierr); ierr = TSPreStage(ts,th->stage_time);CHKERRQ(ierr); if (th->endpoint) { /* This formulation assumes linear time-independent mass matrix */ ierr = VecZeroEntries(th->Xdot);CHKERRQ(ierr); if (!th->affine) {ierr = VecDuplicate(ts->vec_sol,&th->affine);CHKERRQ(ierr);} ierr = TSComputeIFunction(ts,ts->ptime,ts->vec_sol,th->Xdot,th->affine,PETSC_FALSE);CHKERRQ(ierr); ierr = VecScale(th->affine,(th->Theta-1.)/th->Theta);CHKERRQ(ierr); } if (th->extrapolate) { ierr = VecWAXPY(th->X,1./th->shift,th->Xdot,ts->vec_sol);CHKERRQ(ierr); } else { ierr = VecCopy(ts->vec_sol,th->X);CHKERRQ(ierr); } ierr = SNESSolve(ts->snes,th->affine,th->X);CHKERRQ(ierr); ierr = SNESGetIterationNumber(ts->snes,&its);CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(ts->snes,&lits);CHKERRQ(ierr); ierr = SNESGetConvergedReason(ts->snes,&snesreason);CHKERRQ(ierr); ts->snes_its += its; ts->ksp_its += lits; if (snesreason < 0 && ts->max_snes_failures > 0 && ++ts->num_snes_failures >= ts->max_snes_failures) { ts->reason = TS_DIVERGED_NONLINEAR_SOLVE; ierr = PetscInfo2(ts,"Step=%D, nonlinear solve solve failures %D greater than current TS allowed, stopping solve\n",ts->steps,ts->num_snes_failures);CHKERRQ(ierr); PetscFunctionReturn(0); } if (th->endpoint) { ierr = VecCopy(th->X,ts->vec_sol);CHKERRQ(ierr); } else { ierr = VecAXPBYPCZ(th->Xdot,-th->shift,th->shift,0,ts->vec_sol,th->X);CHKERRQ(ierr); ierr = VecAXPY(ts->vec_sol,ts->time_step,th->Xdot);CHKERRQ(ierr); } ts->ptime += ts->time_step; ts->time_step = next_time_step; ts->steps++; PetscFunctionReturn(0); }
static PetscErrorCode TSStep_Pseudo(TS ts) { TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; PetscInt its,lits,reject; PetscBool stepok; PetscReal next_time_step; SNESConvergedReason snesreason = SNES_CONVERGED_ITERATING; PetscErrorCode ierr; PetscFunctionBegin; if (ts->steps == 0) pseudo->dt_initial = ts->time_step; ierr = VecCopy(ts->vec_sol,pseudo->update);CHKERRQ(ierr); next_time_step = ts->time_step; ierr = TSPseudoComputeTimeStep(ts,&next_time_step);CHKERRQ(ierr); for (reject=0; reject<ts->max_reject; reject++,ts->reject++) { ts->time_step = next_time_step; ierr = TSPreStep(ts);CHKERRQ(ierr); ierr = TSPreStage(ts,ts->ptime+ts->time_step);CHKERRQ(ierr); ierr = SNESSolve(ts->snes,NULL,pseudo->update);CHKERRQ(ierr); ierr = SNESGetConvergedReason(ts->snes,&snesreason);CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(ts->snes,&lits);CHKERRQ(ierr); ierr = SNESGetIterationNumber(ts->snes,&its);CHKERRQ(ierr); ierr = TSPostStage(ts,ts->ptime+ts->time_step,0,&(pseudo->update));CHKERRQ(ierr); ts->snes_its += its; ts->ksp_its += lits; ierr = PetscInfo3(ts,"step=%D, nonlinear solve iterations=%D, linear solve iterations=%D\n",ts->steps,its,lits);CHKERRQ(ierr); pseudo->fnorm = -1; /* The current norm is no longer valid, monitor must recompute it. */ ierr = TSPseudoVerifyTimeStep(ts,pseudo->update,&next_time_step,&stepok);CHKERRQ(ierr); if (stepok) break; } if (snesreason < 0 && ts->max_snes_failures > 0 && ++ts->num_snes_failures >= ts->max_snes_failures) { ts->reason = TS_DIVERGED_NONLINEAR_SOLVE; ierr = PetscInfo2(ts,"step=%D, nonlinear solve solve failures %D greater than current TS allowed, stopping solve\n",ts->steps,ts->num_snes_failures);CHKERRQ(ierr); PetscFunctionReturn(0); } if (reject >= ts->max_reject) { ts->reason = TS_DIVERGED_STEP_REJECTED; ierr = PetscInfo2(ts,"step=%D, step rejections %D greater than current TS allowed, stopping solve\n",ts->steps,reject);CHKERRQ(ierr); PetscFunctionReturn(0); } ierr = VecCopy(pseudo->update,ts->vec_sol);CHKERRQ(ierr); ts->ptime += ts->time_step; ts->time_step = next_time_step; ts->steps++; PetscFunctionReturn(0); }
static PetscErrorCode MonitorObjective(TS ts,PetscInt step,PetscReal t,Vec X,void *ictx) { Ctx *ctx = (Ctx*)ictx; PetscErrorCode ierr; const PetscScalar *x; PetscScalar f; PetscReal dt,gnorm; PetscInt i,snesit,linit; SNES snes; Vec Xdot,F; PetscFunctionBeginUser; /* Compute objective functional */ ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); f = 0; for (i=0; i<ctx->n-1; i++) { f += PetscSqr(1. - x[i]) + 100. * PetscSqr(x[i+1] - PetscSqr(x[i])); } ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); /* Compute norm of gradient */ ierr = VecDuplicate(X,&Xdot);CHKERRQ(ierr); ierr = VecDuplicate(X,&F);CHKERRQ(ierr); ierr = VecZeroEntries(Xdot);CHKERRQ(ierr); ierr = FormIFunction(ts,t,X,Xdot,F,ictx);CHKERRQ(ierr); ierr = VecNorm(F,NORM_2,&gnorm);CHKERRQ(ierr); ierr = VecDestroy(&Xdot);CHKERRQ(ierr); ierr = VecDestroy(&F);CHKERRQ(ierr); ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr); ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&snesit);CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(snes,&linit);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, (ctx->monitor_short ? "%3D t=%10.1e dt=%10.1e f=%10.1e df=%10.1e it=(%2D,%3D)\n" : "%3D t=%10.4e dt=%10.4e f=%10.4e df=%10.4e it=(%2D,%3D)\n"), step,(double)t,(double)dt,(double)PetscRealPart(f),(double)gnorm,snesit,linit);CHKERRQ(ierr); PetscFunctionReturn(0); }
std::pair<unsigned int, Real> PetscNonlinearSolver<T>::solve (SparseMatrix<T>& jac_in, // System Jacobian Matrix NumericVector<T>& x_in, // Solution vector NumericVector<T>& r_in, // Residual vector const double, // Stopping tolerance const unsigned int) { START_LOG("solve()", "PetscNonlinearSolver"); this->init (); // Make sure the data passed in are really of Petsc types PetscMatrix<T>* jac = libmesh_cast_ptr<PetscMatrix<T>*>(&jac_in); PetscVector<T>* x = libmesh_cast_ptr<PetscVector<T>*>(&x_in); PetscVector<T>* r = libmesh_cast_ptr<PetscVector<T>*>(&r_in); PetscErrorCode ierr=0; PetscInt n_iterations =0; // Should actually be a PetscReal, but I don't know which version of PETSc first introduced PetscReal Real final_residual_norm=0.; ierr = SNESSetFunction (_snes, r->vec(), __libmesh_petsc_snes_residual, this); LIBMESH_CHKERRABORT(ierr); // Only set the jacobian function if we've been provided with something to call. // This allows a user to set their own jacobian function if they want to if (this->jacobian || this->jacobian_object || this->residual_and_jacobian_object) { ierr = SNESSetJacobian (_snes, jac->mat(), jac->mat(), __libmesh_petsc_snes_jacobian, this); LIBMESH_CHKERRABORT(ierr); } #if !PETSC_VERSION_LESS_THAN(3,3,0) // Only set the nullspace if we have a way of computing it and the result is non-empty. if (this->nullspace || this->nullspace_object) { MatNullSpace msp; this->build_mat_null_space(this->nullspace_object, this->nullspace, &msp); if (msp) { ierr = MatSetNullSpace(jac->mat(), msp); LIBMESH_CHKERRABORT(ierr); ierr = MatNullSpaceDestroy(&msp); LIBMESH_CHKERRABORT(ierr); } } // Only set the nearnullspace if we have a way of computing it and the result is non-empty. if (this->nearnullspace || this->nearnullspace_object) { MatNullSpace msp = PETSC_NULL; this->build_mat_null_space(this->nearnullspace_object, this->nearnullspace, &msp); if(msp) { ierr = MatSetNearNullSpace(jac->mat(), msp); LIBMESH_CHKERRABORT(ierr); ierr = MatNullSpaceDestroy(&msp); LIBMESH_CHKERRABORT(ierr); } } #endif // Have the Krylov subspace method use our good initial guess rather than 0 KSP ksp; ierr = SNESGetKSP (_snes, &ksp); LIBMESH_CHKERRABORT(ierr); // Set the tolerances for the iterative solver. Use the user-supplied // tolerance for the relative residual & leave the others at default values ierr = KSPSetTolerances (ksp, this->initial_linear_tolerance, PETSC_DEFAULT, PETSC_DEFAULT, this->max_linear_iterations); LIBMESH_CHKERRABORT(ierr); // Set the tolerances for the non-linear solver. ierr = SNESSetTolerances(_snes, this->absolute_residual_tolerance, this->relative_residual_tolerance, this->relative_step_tolerance, this->max_nonlinear_iterations, this->max_function_evaluations); LIBMESH_CHKERRABORT(ierr); //Pull in command-line options KSPSetFromOptions(ksp); SNESSetFromOptions(_snes); if (this->user_presolve) this->user_presolve(this->system()); //Set the preconditioning matrix if(this->_preconditioner) { this->_preconditioner->set_matrix(jac_in); this->_preconditioner->init(); } // ierr = KSPSetInitialGuessNonzero (ksp, PETSC_TRUE); // LIBMESH_CHKERRABORT(ierr); // Older versions (at least up to 2.1.5) of SNESSolve took 3 arguments, // the last one being a pointer to an int to hold the number of iterations required. # if PETSC_VERSION_LESS_THAN(2,2,0) ierr = SNESSolve (_snes, x->vec(), &n_iterations); LIBMESH_CHKERRABORT(ierr); // 2.2.x style #elif PETSC_VERSION_LESS_THAN(2,3,0) ierr = SNESSolve (_snes, x->vec()); LIBMESH_CHKERRABORT(ierr); // 2.3.x & newer style #else ierr = SNESSolve (_snes, PETSC_NULL, x->vec()); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetIterationNumber(_snes,&n_iterations); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetLinearSolveIterations(_snes, &_n_linear_iterations); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetFunctionNorm(_snes,&final_residual_norm); LIBMESH_CHKERRABORT(ierr); #endif // Get and store the reason for convergence SNESGetConvergedReason(_snes, &_reason); //Based on Petsc 2.3.3 documentation all diverged reasons are negative this->converged = (_reason >= 0); this->clear(); STOP_LOG("solve()", "PetscNonlinearSolver"); // return the # of its. and the final residual norm. return std::make_pair(n_iterations, final_residual_norm); }
static PetscErrorCode TSStep_Alpha(TS ts) { TS_Alpha *th = (TS_Alpha*)ts->data; PetscInt its,lits,reject; PetscReal next_time_step; SNESConvergedReason snesreason = SNES_CONVERGED_ITERATING; PetscErrorCode ierr; PetscFunctionBegin; if (ts->steps == 0) { ierr = VecSet(th->V0,0.0);CHKERRQ(ierr); } else { ierr = VecCopy(th->V1,th->V0);CHKERRQ(ierr); } ierr = VecCopy(ts->vec_sol,th->X0);CHKERRQ(ierr); next_time_step = ts->time_step; for (reject=0; reject<ts->max_reject; reject++,ts->reject++) { ts->time_step = next_time_step; th->stage_time = ts->ptime + th->Alpha_f*ts->time_step; th->shift = th->Alpha_m/(th->Alpha_f*th->Gamma*ts->time_step); ierr = TSPreStep(ts);CHKERRQ(ierr); ierr = TSPreStage(ts,th->stage_time);CHKERRQ(ierr); /* predictor */ ierr = VecCopy(th->X0,th->X1);CHKERRQ(ierr); /* solve R(X,V) = 0 */ ierr = SNESSolve(ts->snes,PETSC_NULL,th->X1);CHKERRQ(ierr); /* V1 = (1-1/Gamma)*V0 + 1/(Gamma*dT)*(X1-X0) */ ierr = VecWAXPY(th->V1,-1,th->X0,th->X1);CHKERRQ(ierr); ierr = VecAXPBY(th->V1,1-1/th->Gamma,1/(th->Gamma*ts->time_step),th->V0);CHKERRQ(ierr); /* nonlinear solve convergence */ ierr = SNESGetConvergedReason(ts->snes,&snesreason);CHKERRQ(ierr); if (snesreason < 0 && !th->adapt) break; ierr = SNESGetIterationNumber(ts->snes,&its);CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(ts->snes,&lits);CHKERRQ(ierr); ts->snes_its += its; ts->ksp_its += lits; ierr = PetscInfo3(ts,"step=%D, nonlinear solve iterations=%D, linear solve iterations=%D\n",ts->steps,its,lits);CHKERRQ(ierr); /* time step adaptativity */ if (!th->adapt) break; else { PetscReal t1 = ts->ptime + ts->time_step; PetscBool stepok = (reject==0) ? PETSC_TRUE : PETSC_FALSE; ierr = th->adapt(ts,t1,th->X1,th->V1,&next_time_step,&stepok,th->adaptctx);CHKERRQ(ierr); ierr = PetscInfo5(ts,"Step %D (t=%G,dt=%G) %s, next dt=%G\n",ts->steps,ts->ptime,ts->time_step,stepok?"accepted":"rejected",next_time_step);CHKERRQ(ierr); if (stepok) break; } } if (snesreason < 0 && ts->max_snes_failures > 0 && ++ts->num_snes_failures >= ts->max_snes_failures) { ts->reason = TS_DIVERGED_NONLINEAR_SOLVE; ierr = PetscInfo2(ts,"Step=%D, nonlinear solve solve failures %D greater than current TS allowed, stopping solve\n",ts->steps,ts->num_snes_failures);CHKERRQ(ierr); PetscFunctionReturn(0); } if (reject >= ts->max_reject) { ts->reason = TS_DIVERGED_STEP_REJECTED; ierr = PetscInfo2(ts,"Step=%D, step rejections %D greater than current TS allowed, stopping solve\n",ts->steps,reject);CHKERRQ(ierr); PetscFunctionReturn(0); } ierr = VecCopy(th->X1,ts->vec_sol);CHKERRQ(ierr); ts->ptime += ts->time_step; ts->time_step = next_time_step; ts->steps++; PetscFunctionReturn(0); }
bool PETScNewtonKrylovSolver::solveSystem(SAMRAIVectorReal<NDIM, double>& x, SAMRAIVectorReal<NDIM, double>& b) { IBTK_TIMER_START(t_solve_system); int ierr; // Initialize the solver, when necessary. const bool deallocate_after_solve = !d_is_initialized; if (deallocate_after_solve) initializeSolverState(x, b); #if !defined(NDEBUG) TBOX_ASSERT(d_petsc_snes); #endif resetSNESOptions(); Pointer<PETScKrylovLinearSolver> p_krylov_solver = d_krylov_solver; if (p_krylov_solver) p_krylov_solver->resetKSPOptions(); // Allocate scratch data. if (d_b) d_b->allocateVectorData(); if (d_r) d_r->allocateVectorData(); // Solve the system using a PETSc SNES object. PETScSAMRAIVectorReal::replaceSAMRAIVector( d_petsc_x, Pointer<SAMRAIVectorReal<NDIM, double> >(&x, false)); Pointer<LinearOperator> A = d_F; if (A) { d_b->copyVector(Pointer<SAMRAIVectorReal<NDIM, double> >(&b, false)); A->modifyRhsForInhomogeneousBc(*d_b); ierr = PetscObjectStateIncrease(reinterpret_cast<PetscObject>(d_petsc_b)); IBTK_CHKERRQ(ierr); PETScSAMRAIVectorReal::replaceSAMRAIVector(d_petsc_b, d_b); } else { PETScSAMRAIVectorReal::replaceSAMRAIVector( d_petsc_b, Pointer<SAMRAIVectorReal<NDIM, double> >(&b, false)); } ierr = SNESSolve(d_petsc_snes, d_petsc_b, d_petsc_x); IBTK_CHKERRQ(ierr); ierr = SNESGetIterationNumber(d_petsc_snes, &d_current_iterations); IBTK_CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(d_petsc_snes, &d_current_linear_iterations); IBTK_CHKERRQ(ierr); ierr = SNESGetFunctionNorm(d_petsc_snes, &d_current_residual_norm); IBTK_CHKERRQ(ierr); // Determine the convergence reason. SNESConvergedReason reason; ierr = SNESGetConvergedReason(d_petsc_snes, &reason); IBTK_CHKERRQ(ierr); const bool converged = (static_cast<int>(reason) > 0); if (d_enable_logging) reportSNESConvergedReason(reason, plog); // Deallocate scratch data. if (d_b) d_b->deallocateVectorData(); if (d_r) d_r->deallocateVectorData(); // Deallocate the solver, when necessary. if (deallocate_after_solve) deallocateSolverState(); IBTK_TIMER_STOP(t_solve_system); return converged; } // solveSystem
static PetscErrorCode TSStep_Theta(TS ts) { TS_Theta *th = (TS_Theta*)ts->data; PetscInt its,lits,reject,next_scheme; PetscReal next_time_step; TSAdapt adapt; PetscBool stageok,accept = PETSC_TRUE; PetscErrorCode ierr; PetscFunctionBegin; th->status = TS_STEP_INCOMPLETE; ierr = VecCopy(ts->vec_sol,th->X0);CHKERRQ(ierr); for (reject=0; !ts->reason && th->status != TS_STEP_COMPLETE; ts->reject++) { PetscReal shift = 1./(th->Theta*ts->time_step); th->stage_time = ts->ptime + (th->endpoint ? 1. : th->Theta)*ts->time_step; ierr = TSPreStep(ts);CHKERRQ(ierr); ierr = TSPreStage(ts,th->stage_time);CHKERRQ(ierr); if (th->endpoint) { /* This formulation assumes linear time-independent mass matrix */ ierr = VecZeroEntries(th->Xdot);CHKERRQ(ierr); if (!th->affine) {ierr = VecDuplicate(ts->vec_sol,&th->affine);CHKERRQ(ierr);} ierr = TSComputeIFunction(ts,ts->ptime,ts->vec_sol,th->Xdot,th->affine,PETSC_FALSE);CHKERRQ(ierr); ierr = VecScale(th->affine,(th->Theta-1.)/th->Theta);CHKERRQ(ierr); } if (th->extrapolate) { ierr = VecWAXPY(th->X,1./shift,th->Xdot,ts->vec_sol);CHKERRQ(ierr); } else { ierr = VecCopy(ts->vec_sol,th->X);CHKERRQ(ierr); } ierr = SNESSolve(ts->snes,th->affine,th->X);CHKERRQ(ierr); ierr = SNESGetIterationNumber(ts->snes,&its);CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(ts->snes,&lits);CHKERRQ(ierr); ts->snes_its += its; ts->ksp_its += lits; ierr = TSPostStage(ts,th->stage_time,0,&(th->X));CHKERRQ(ierr); ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); ierr = TSAdaptCheckStage(adapt,ts,&stageok);CHKERRQ(ierr); if (!stageok) {accept = PETSC_FALSE; goto reject_step;} ierr = TSEvaluateStep(ts,th->order,ts->vec_sol,NULL);CHKERRQ(ierr); th->status = TS_STEP_PENDING; /* Register only the current method as a candidate because we're not supporting multiple candidates yet. */ ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); ierr = TSAdaptCandidatesClear(adapt);CHKERRQ(ierr); ierr = TSAdaptCandidateAdd(adapt,NULL,th->order,1,th->ccfl,1.0,PETSC_TRUE);CHKERRQ(ierr); ierr = TSAdaptChoose(adapt,ts,ts->time_step,&next_scheme,&next_time_step,&accept);CHKERRQ(ierr); if (!accept) { /* Roll back the current step */ ts->ptime += next_time_step; /* This will be undone in rollback */ th->status = TS_STEP_INCOMPLETE; ierr = TSRollBack(ts);CHKERRQ(ierr); goto reject_step; } /* ignore next_scheme for now */ ts->ptime += ts->time_step; ts->time_step = next_time_step; ts->steps++; th->status = TS_STEP_COMPLETE; break; reject_step: if (!ts->reason && ++reject > ts->max_reject && ts->max_reject >= 0) { ts->reason = TS_DIVERGED_STEP_REJECTED; ierr = PetscInfo2(ts,"Step=%D, step rejections %D greater than current TS allowed, stopping solve\n",ts->steps,reject);CHKERRQ(ierr); } continue; } PetscFunctionReturn(0); }
std::pair<unsigned int, Real> PetscDMNonlinearSolver<T>::solve (SparseMatrix<T>& jac_in, // System Jacobian Matrix NumericVector<T>& x_in, // Solution vector NumericVector<T>& r_in, // Residual vector const double, // Stopping tolerance const unsigned int) { START_LOG("solve()", "PetscNonlinearSolver"); this->init (); // Make sure the data passed in are really of Petsc types libmesh_cast_ptr<PetscMatrix<T>*>(&jac_in); libmesh_cast_ptr<PetscVector<T>*>(&r_in); // Extract solution vector PetscVector<T>* x = libmesh_cast_ptr<PetscVector<T>*>(&x_in); PetscErrorCode ierr=0; PetscInt n_iterations =0; PetscReal final_residual_norm=0.; if (this->user_presolve) this->user_presolve(this->system()); //Set the preconditioning matrix if (this->_preconditioner) this->_preconditioner->set_matrix(jac_in); ierr = SNESSolve (this->_snes, PETSC_NULL, x->vec()); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetIterationNumber(this->_snes,&n_iterations); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetLinearSolveIterations(this->_snes, &this->_n_linear_iterations); LIBMESH_CHKERRABORT(ierr); #if PETSC_VERSION_LESS_THAN(3,5,0) // SNESGetFunctionNorm was removed in PETSc 3.5.0 ierr = SNESGetFunctionNorm(this->_snes,&final_residual_norm); LIBMESH_CHKERRABORT(ierr); #else { /* PB: Not sure where r_in is coming from and it's not used here, so we'll just get the residual from PETSc */ Vec r; ierr = SNESGetFunction(this->_snes,&r,NULL,NULL);LIBMESH_CHKERRABORT(ierr); ierr = VecNorm(r,NORM_2,&final_residual_norm);LIBMESH_CHKERRABORT(ierr); } #endif // Get and store the reason for convergence SNESGetConvergedReason(this->_snes, &this->_reason); //Based on Petsc 2.3.3 documentation all diverged reasons are negative this->converged = (this->_reason >= 0); this->clear(); STOP_LOG("solve()", "PetscNonlinearSolver"); // return the # of its. and the final residual norm. return std::make_pair(n_iterations, final_residual_norm); }