// ------------------------------------------------------------- // PetscNonlinearSolverImplementation::p_solve // ------------------------------------------------------------- void PetscNonlinearSolverImplementation::p_solve(void) { PetscErrorCode ierr(0); p_petsc_X = PETScVector(*p_X); int me(this->processor_rank()); try { ierr = SNESSolve(p_snes, NULL, *p_petsc_X); CHKERRXX(ierr); SNESConvergedReason reason; PetscInt iter; ierr = SNESGetConvergedReason(p_snes, &reason); CHKERRXX(ierr); ierr = SNESGetIterationNumber(p_snes, &iter); CHKERRXX(ierr); std::string msg; if (reason < 0) { msg = boost::str(boost::format("%d: PETSc SNES diverged after %d iterations, reason: %d") % me % iter % reason); throw Exception(msg); } else if (me == 0) { msg = boost::str(boost::format("%d: PETSc SNES converged after %d iterations, reason: %d") % me % iter % reason); std::cerr << msg << std::endl; } } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } catch (const Exception& e) { throw e; } }
/// Solve again w/ the specified RHS, put result in specified vector (specialized) void p_resolveImpl(const VectorType& b, VectorType& x) const { PetscErrorCode ierr(0); int me(this->processor_rank()); try { const Vec *bvec(PETScVector(b)); Vec *xvec(PETScVector(x)); ierr = KSPSolve(p_KSP, *bvec, *xvec); CHKERRXX(ierr); int its; KSPConvergedReason reason; PetscReal rnorm; ierr = KSPGetIterationNumber(p_KSP, &its); CHKERRXX(ierr); ierr = KSPGetConvergedReason(p_KSP, &reason); CHKERRXX(ierr); ierr = KSPGetResidualNorm(p_KSP, &rnorm); CHKERRXX(ierr); std::string msg; if (reason < 0) { msg = boost::str(boost::format("%d: PETSc KSP diverged after %d iterations, reason: %d") % me % its % reason); throw Exception(msg); } else if (me == 0) { msg = boost::str(boost::format("%d: PETSc KSP converged after %d iterations, reason: %d") % me % its % reason); std::cerr << msg << std::endl; } } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } catch (const Exception& e) { throw e; } }
// ------------------------------------------------------------- // PetscNonlinearSolverImplementation::p_build // ------------------------------------------------------------- void PetscNonlinearSolverImplementation::p_build(const std::string& option_prefix) { PetscErrorCode ierr(0); try { ierr = SNESCreate(this->communicator(), &p_snes); CHKERRXX(ierr); p_petsc_F = PETScVector(*p_F); if (!p_function.empty()) { ierr = SNESSetFunction(p_snes, *p_petsc_F, FormFunction, static_cast<void *>(this)); CHKERRXX(ierr); } p_petsc_J = PETScMatrix(*p_J); if (!p_jacobian.empty()) { ierr = SNESSetJacobian(p_snes, *p_petsc_J, *p_petsc_J, FormJacobian, static_cast<void *>(this)); CHKERRXX(ierr); } // set the ierr = SNESSetOptionsPrefix(p_snes, option_prefix.c_str()); CHKERRXX(ierr); KSP ksp; ierr = SNESGetKSP(p_snes, &ksp); CHKERRXX(ierr); ierr = KSPSetOptionsPrefix(ksp, option_prefix.c_str()); CHKERRXX(ierr); PC pc; ierr = KSPGetPC(ksp, &pc); CHKERRXX(ierr); ierr = PCSetOptionsPrefix(pc, option_prefix.c_str()); CHKERRXX(ierr); ierr = SNESMonitorSet(p_snes, MonitorNorms, PETSC_NULL, PETSC_NULL); CHKERRXX(ierr); ierr = SNESSetTolerances(p_snes, p_functionTolerance, PETSC_DEFAULT, p_solutionTolerance, p_maxIterations, PETSC_DEFAULT); ierr = SNESSetFromOptions(p_snes); CHKERRXX(ierr); } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } }