// ------------------------------------------------------------- // PETScConfigurable::p_unprocessOptions // ------------------------------------------------------------- void PETScConfigurable::p_unprocessOptions(void) { boost::char_separator<char> sep(" \t\f\n\r\v", ""); boost::tokenizer<boost::char_separator<char> > opttok(p_loadedOptions, sep); boost::tokenizer<boost::char_separator<char> >::iterator o; for (o = opttok.begin(); o != opttok.end(); ++o) { if ((*o)[0] == '-' && islower((*o)[1])) { PetscErrorCode ierr(0); try { if (verbose) { std::cout << "p_unprocessOptions: removing \"" << *o << "\"" << std::endl; } ierr = PetscOptionsClearValue( #if PETSC_VERSION_GE(3,7,0) NULL, #endif o->c_str()); } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } } } p_loadedOptions.clear(); }
// ------------------------------------------------------------- // 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; } }
/// Do what is necessary to build this instance void p_build(const std::string& option_prefix) { PetscErrorCode ierr; try { parallel::Communicator comm(this->communicator()); if (this->p_doSerial) { comm = this->communicator().self(); } ierr = KSPCreate(comm, &p_KSP); CHKERRXX(ierr); if (!this->p_guessZero) { ierr = KSPSetInitialGuessNonzero(p_KSP,PETSC_TRUE); CHKERRXX(ierr); } else { ierr = KSPSetInitialGuessNonzero(p_KSP,PETSC_FALSE); CHKERRXX(ierr); } ierr = KSPSetOptionsPrefix(p_KSP, option_prefix.c_str()); CHKERRXX(ierr); PC pc; ierr = KSPGetPC(p_KSP, &pc); CHKERRXX(ierr); ierr = PCSetOptionsPrefix(pc, option_prefix.c_str()); CHKERRXX(ierr); ierr = KSPSetTolerances(p_KSP, LinearSolverImplementation<T, I>::p_relativeTolerance, LinearSolverImplementation<T, I>::p_solutionTolerance, PETSC_DEFAULT, LinearSolverImplementation<T, I>::p_maxIterations); CHKERRXX(ierr); ierr = KSPSetFromOptions(p_KSP);CHKERRXX(ierr); } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, 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; } }
/// Solve w/ the specified RHS and estimate (result in x) void p_solveImpl(MatrixType& A, const VectorType& b, VectorType& x) const { PetscErrorCode ierr(0); try { Mat *Amat(PETScMatrix(A)); if (p_matrixSet && this->p_constSerialMatrix) { // KSPSetOperators can be skipped } else { #if PETSC_VERSION_LT(3,5,0) ierr = KSPSetOperators(p_KSP, *Amat, *Amat, SAME_NONZERO_PATTERN); CHKERRXX(ierr); #else ierr = KSPSetOperators(p_KSP, *Amat, *Amat); CHKERRXX(ierr); #endif p_matrixSet = true; } this->p_resolveImpl(b, x); } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } catch (const Exception& e) { throw e; } }
// ------------------------------------------------------------- // Finalize // ------------------------------------------------------------- /// Does whatever is necessary to shut down the PETSc library void Finalize(void) { if (!Initialized()) return; PetscErrorCode ierr(0); try { ierr = PetscFinalize(); CHKERRXX(ierr); } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } }
// ------------------------------------------------------------- // Initialized // ------------------------------------------------------------- bool Initialized(void) { PetscErrorCode ierr(0); PetscBool result; try { ierr = PetscInitialized(&result); CHKERRXX(ierr); } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } return result; }
// ------------------------------------------------------------- // Initialize // ------------------------------------------------------------- /// Does whatever is necessary to start up the PETSc library void Initialize(void) { if (Initialized()) return; PetscErrorCode ierr(0); PetscBool flg; #if USE_PROGRESS_RANKS gridpack::parallel::Communicator comm; MPI_Comm world = GA_MPI_Comm(); PETSC_COMM_WORLD = world; #endif try { // Turn this on to enable PETSc logging. #if 0 int argc = 2; char **args; args = new char*[2]; args[0] = new char[32]; args[1] = new char[32]; sprintf(args[0],"powerflow.x"); sprintf(args[1],"-log_summary"); ierr = PetscInitialize(&argc,&args,NULL,NULL); CHKERRXX(ierr); delete [] args[1]; delete [] args[0]; delete [] args; #else ierr = PetscInitializeNoArguments(); CHKERRXX(ierr); #endif PetscOptionsHasName( #if PETSC_VERSION_GE(3,7,0) NULL, #endif NULL, "-log_summary", &flg); ierr = PetscOptionsInsertFile(PETSC_COMM_WORLD, #if PETSC_VERSION_GE(3,7,0) NULL, #endif "gridpack.petscrc", PETSC_FALSE); CHKERRXX(ierr); } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } // Print out some information on processor configuration int mpi_err, me, nproc; mpi_err = MPI_Comm_rank(PETSC_COMM_WORLD, &me); mpi_err = MPI_Comm_size(PETSC_COMM_WORLD, &nproc); if (mpi_err > 0) { throw gridpack::Exception("MPI initialization failed"); } if (me == 0) { printf("\nGridPACK math module configured on %d processors\n",nproc); } }
// ------------------------------------------------------------- // 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); } }
/** * * * @param comm * @param props * * @return PETSc options prefix to use */ void PETScConfigurable::p_processOptions(utility::Configuration::CursorPtr props) { if (!props) return; p_prefix = props->get(p_prefixKey, p_generatePrefix(p_comm)); if (*p_prefix.rbegin() != '_') { p_prefix.append("_"); } std::string optsorig, optsmod, optsfmt; optsorig = props->get(p_optionsKey, ""); boost::char_separator<char> sep(" \t\f\n\r\v", ""); boost::tokenizer<boost::char_separator<char> > opttok(optsorig, sep); boost::tokenizer<boost::char_separator<char> >::iterator o; for (o = opttok.begin(); o != opttok.end(); ++o) { optsfmt.append(*o); optsfmt.append(" "); optsmod.append(prefixOptionMaybe(p_prefix, *o)); optsmod.append(" "); } if (verbose) { std::cout << "p_processOptions: in: " << optsorig << std::endl; std::cout << "p_processOptions: fmt: " << optsfmt << std::endl; std::cout << "p_processOptions: out: " << optsmod << std::endl; } p_loadedOptions = optsmod; PetscErrorCode ierr(0); try { ierr = PetscOptionsInsertString( #if PETSC_VERSION_GE(3,7,0) NULL, #endif p_loadedOptions.c_str()); CHKERRXX(ierr); } catch (const PETSC_EXCEPTION_TYPE& e) { throw PETScException(ierr, e); } return; }