43 #ifndef BELOS_GMRES_POLY_SOLMGR_HPP
44 #define BELOS_GMRES_POLY_SOLMGR_HPP
57 #include "Teuchos_as.hpp"
58 #ifdef BELOS_TEUCHOS_TIME_MONITOR
59 #include "Teuchos_TimeMonitor.hpp"
148 template<
class ScalarType,
class MV,
class OP>
153 typedef Teuchos::ScalarTraits<ScalarType> STS;
154 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
189 const Teuchos::RCP<Teuchos::ParameterList> &pl );
195 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
222 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
223 return Teuchos::tuple(timerPoly_);
245 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
override;
261 problem_->setProblem ();
262 poly_Op_ = Teuchos::null;
303 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
306 Teuchos::RCP<std::ostream> outputStream_;
309 Teuchos::RCP<Teuchos::ParameterList> params_;
310 Teuchos::RCP<Teuchos::ParameterList> outerParams_;
313 static constexpr
int maxDegree_default_ = 25;
315 static constexpr
const char * label_default_ =
"Belos";
316 static constexpr
const char * outerSolverType_default_ =
"";
317 static constexpr
const char * polyType_default_ =
"Arnoldi";
318 static constexpr
const char * orthoType_default_ =
"DGKS";
319 static constexpr
bool addRoots_default_ =
true;
320 static constexpr
bool dampPoly_default_ =
false;
321 static constexpr
bool randomRHS_default_ =
true;
322 static constexpr std::ostream * outputStream_default_ = &std::cout;
325 MagnitudeType polyTol_;
326 int maxDegree_, numIters_;
328 bool hasOuterSolver_;
332 std::string polyType_;
333 std::string outerSolverType_;
334 std::string orthoType_;
338 Teuchos::RCP<gmres_poly_t> poly_Op_;
342 Teuchos::RCP<Teuchos::Time> timerPoly_;
349 mutable Teuchos::RCP<const Teuchos::ParameterList> validPL_;
353 template<
class ScalarType,
class MV,
class OP>
355 outputStream_ (Teuchos::rcp(outputStream_default_,false)),
357 maxDegree_ (maxDegree_default_),
359 verbosity_ (verbosity_default_),
360 hasOuterSolver_ (false),
361 randomRHS_ (randomRHS_default_),
362 damp_ (dampPoly_default_),
363 addRoots_ (addRoots_default_),
364 polyType_ (polyType_default_),
365 outerSolverType_ (outerSolverType_default_),
366 orthoType_ (orthoType_default_),
368 label_ (label_default_),
374 template<
class ScalarType,
class MV,
class OP>
377 const Teuchos::RCP<Teuchos::ParameterList> &pl) :
379 outputStream_ (Teuchos::rcp(outputStream_default_,false)),
381 maxDegree_ (maxDegree_default_),
383 verbosity_ (verbosity_default_),
384 hasOuterSolver_ (false),
385 randomRHS_ (randomRHS_default_),
386 damp_ (dampPoly_default_),
387 addRoots_ (addRoots_default_),
388 polyType_ (polyType_default_),
389 outerSolverType_ (outerSolverType_default_),
390 orthoType_ (orthoType_default_),
392 label_ (label_default_),
396 TEUCHOS_TEST_FOR_EXCEPTION(
397 problem_.is_null (), std::invalid_argument,
398 "Belos::GmresPolySolMgr: The given linear problem is null. "
399 "Please call this constructor with a nonnull LinearProblem argument, "
400 "or call the constructor that does not take a LinearProblem.");
404 if (! pl.is_null ()) {
410 template<
class ScalarType,
class MV,
class OP>
411 Teuchos::RCP<const Teuchos::ParameterList>
414 if (validPL_.is_null ()) {
415 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList ();
419 pl->set(
"Polynomial Type",
static_cast<const char *
>(polyType_default_),
420 "The type of GMRES polynomial that is used as a preconditioner: Roots, Arnoldi, or Gmres.");
422 "The relative residual tolerance that used to construct the GMRES polynomial.");
423 pl->set(
"Maximum Degree",
static_cast<int>(maxDegree_default_),
424 "The maximum degree allowed for any GMRES polynomial.");
425 pl->set(
"Outer Solver",
static_cast<const char *
>(outerSolverType_default_),
426 "The outer solver that this polynomial is used to precondition.");
427 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
428 "What type(s) of solver information should be outputted\n"
429 "to the output stream.");
430 pl->set(
"Output Stream", Teuchos::rcp(outputStream_default_,
false),
431 "A reference-counted pointer to the output stream where all\n"
432 "solver output is sent.");
433 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
434 "The string to use as a prefix for the timer labels.");
435 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
436 "The type of orthogonalization to use to generate polynomial: DGKS, ICGS, or IMGS.");
437 pl->set(
"Random RHS",
static_cast<bool>(randomRHS_default_),
438 "Add roots to polynomial for stability.");
439 pl->set(
"Add Roots",
static_cast<bool>(addRoots_default_),
440 "Add roots to polynomial for stability.");
441 pl->set(
"Damp Poly",
static_cast<bool>(dampPoly_default_),
442 "Damp polynomial for ill-conditioned problems.");
449 template<
class ScalarType,
class MV,
class OP>
451 setParameters (
const Teuchos::RCP<Teuchos::ParameterList>& params)
454 if (params_.is_null ()) {
455 params_ = Teuchos::parameterList (*getValidParameters ());
458 params->validateParameters (*getValidParameters ());
462 if (params->isParameter(
"Polynomial Type")) {
463 polyType_ = params->get(
"Polynomial Type", polyType_default_);
467 params_->set(
"Polynomial Type", polyType_);
470 if (params->isParameter(
"Outer Solver")) {
471 outerSolverType_ = params->get(
"Outer Solver", outerSolverType_default_);
475 params_->set(
"Outer Solver", outerSolverType_);
478 if (params->isSublist(
"Outer Solver Params")) {
479 outerParams_ = Teuchos::parameterList( params->get<Teuchos::ParameterList>(
"Outer Solver Params") );
483 if (params->isParameter(
"Maximum Degree")) {
484 maxDegree_ = params->get(
"Maximum Degree",maxDegree_default_);
488 params_->set(
"Maximum Degree", maxDegree_);
491 if (params->isParameter(
"Timer Label")) {
492 std::string tempLabel = params->get(
"Timer Label", label_default_);
495 if (tempLabel != label_) {
497 #ifdef BELOS_TEUCHOS_TIME_MONITOR
498 std::string polyLabel = label_ +
": GmresPolyOp creation time";
499 timerPoly_ = Teuchos::TimeMonitor::getNewCounter(polyLabel);
505 params_->set(
"Timer Label", label_);
508 if (params->isParameter(
"Orthogonalization")) {
509 std::string tempOrthoType = params->get(
"Orthogonalization",orthoType_default_);
510 TEUCHOS_TEST_FOR_EXCEPTION( tempOrthoType !=
"DGKS" && tempOrthoType !=
"ICGS" && tempOrthoType !=
"IMGS",
511 std::invalid_argument,
512 "Belos::GmresPolySolMgr: \"Orthogonalization\" must be either \"DGKS\", \"ICGS\", or \"IMGS\".");
513 if (tempOrthoType != orthoType_) {
514 orthoType_ = tempOrthoType;
518 params_->set(
"Orthogonalization", orthoType_);
521 if (params->isParameter(
"Verbosity")) {
522 if (Teuchos::isParameterType<int>(*params,
"Verbosity")) {
523 verbosity_ = params->get(
"Verbosity", verbosity_default_);
525 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,
"Verbosity");
530 params_->set(
"Verbosity", verbosity_);
533 if (params->isParameter(
"Output Stream")) {
534 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
538 params_->set(
"Output Stream", outputStream_);
542 if (params->isParameter(
"Polynomial Tolerance")) {
543 if (params->isType<MagnitudeType> (
"Polynomial Tolerance")) {
544 polyTol_ = params->get (
"Polynomial Tolerance",
553 params_->set(
"Polynomial Tolerance", polyTol_);
556 if (params->isParameter(
"Random RHS")) {
557 randomRHS_ = params->get(
"Random RHS",randomRHS_default_);
561 params_->set(
"Random RHS", randomRHS_);
565 if (params->isParameter(
"Damped Poly")) {
566 damp_ = params->get(
"Damped Poly",dampPoly_default_);
569 params_->set(
"Damped Poly", damp_);
572 if (params->isParameter(
"Add Roots")) {
573 addRoots_ = params->get(
"Add Roots",addRoots_default_);
577 params_->set(
"Add Roots", addRoots_);
580 #ifdef BELOS_TEUCHOS_TIME_MONITOR
581 if (timerPoly_ == Teuchos::null) {
582 std::string polyLabel = label_ +
": GmresPolyOp creation time";
583 timerPoly_ = Teuchos::TimeMonitor::getNewCounter(polyLabel);
588 if (outerSolverType_ !=
"") {
589 hasOuterSolver_ =
true;
597 template<
class ScalarType,
class MV,
class OP>
602 using Teuchos::rcp_const_cast;
612 setParameters (Teuchos::parameterList (*getValidParameters ()));
615 TEUCHOS_TEST_FOR_EXCEPTION(
617 "Belos::GmresPolySolMgr::solve: The linear problem has not been set yet, "
618 "or was set to null. Please call setProblem() with a nonnull input before "
621 TEUCHOS_TEST_FOR_EXCEPTION(
623 "Belos::GmresPolySolMgr::solve: The linear problem is not ready. Please "
624 "call setProblem() on the LinearProblem object before calling solve().");
628 if (!poly_dim_ && maxDegree_) {
629 #ifdef BELOS_TEUCHOS_TIME_MONITOR
630 Teuchos::TimeMonitor slvtimer(*timerPoly_);
632 poly_Op_ = Teuchos::rcp(
new gmres_poly_t( problem_, params_ ) );
633 poly_dim_ = poly_Op_->polyDegree();
636 "Belos::GmresPolyOp: Failed to generate polynomial that satisfied requirements.");
641 if (hasOuterSolver_ && maxDegree_) {
646 RCP<SolverManager<ScalarType, MultiVec<ScalarType>,
Operator<ScalarType> > > solver = factory.
create( outerSolverType_, outerParams_ );
647 TEUCHOS_TEST_FOR_EXCEPTION( solver == Teuchos::null, std::invalid_argument,
648 "Belos::GmresPolySolMgr::solve(): Selected solver is not valid.");
652 RCP<gmres_poly_mv_t> new_lhs = rcp(
new gmres_poly_mv_t( problem_->getLHS() ) );
653 RCP<gmres_poly_mv_t> new_rhs = rcp(
new gmres_poly_mv_t( rcp_const_cast<MV>( problem_->getRHS() ) ) );
654 RCP<gmres_poly_t> A = rcp(
new gmres_poly_t( problem_ ) );
657 std::string solverLabel = label_ +
": Hybrid Gmres";
658 newProblem->setLabel(solverLabel);
661 if (problem_->getLeftPrec() != Teuchos::null)
662 newProblem->setLeftPrec( poly_Op_ );
664 newProblem->setRightPrec( poly_Op_ );
667 if (problem_->getInitResVec() != Teuchos::null)
668 newProblem->setInitResVec( rcp(
new gmres_poly_mv_t( rcp_const_cast<MV>( problem_->getInitResVec() ) ) ) );
669 newProblem->setProblem();
671 solver->setProblem( newProblem );
673 ret = solver->solve();
674 numIters_ = solver->getNumIters();
675 loaDetected_ = solver->isLOADetected();
678 else if (hasOuterSolver_) {
682 RCP<SolverManager<ScalarType, MV, OP> > solver = factory.create( outerSolverType_, outerParams_ );
683 TEUCHOS_TEST_FOR_EXCEPTION( solver == Teuchos::null, std::invalid_argument,
684 "Belos::GmresPolySolMgr::solve(): Selected solver is not valid.");
686 solver->setProblem( problem_ );
688 ret = solver->solve();
689 numIters_ = solver->getNumIters();
690 loaDetected_ = solver->isLOADetected();
693 else if (maxDegree_) {
696 poly_Op_->ApplyPoly( *problem_->getRHS(), *problem_->getLHS() );
704 template<
class ScalarType,
class MV,
class OP>
707 std::ostringstream out;
709 out <<
"\"Belos::GmresPolySolMgr\": {"
710 <<
"ScalarType: " << Teuchos::TypeNameTraits<ScalarType>::name ()
711 <<
", Poly Degree: " << poly_dim_
712 <<
", Poly Max Degree: " << maxDegree_
713 <<
", Poly Tol: " << polyTol_;
720 #endif // BELOS_GMRES_POLY_SOLMGR_HPP