10#ifndef BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
11#define BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
29#ifdef BELOS_TEUCHOS_TIME_MONITOR
30#include "Teuchos_TimeMonitor.hpp"
91 template<
class ScalarType,
class MV,
class OP,
class DM = DefaultDenseMatrix<
int,ScalarType>>
98 typedef Teuchos::ScalarTraits<ScalarType> SCT;
99 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
100 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
227 const Teuchos::RCP<Teuchos::ParameterList> &pl );
233 Teuchos::RCP<SolverManager<ScalarType, MV, OP, DM> >
clone ()
const override {
256 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
257 return Teuchos::tuple(timerSolve_);
356 void setParameters (
const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
override;
418 describe (Teuchos::FancyOStream& out,
419 const Teuchos::EVerbosityLevel verbLevel =
420 Teuchos::Describable::verbLevel_default)
const override;
443 bool checkStatusTest();
446 Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > problem_;
449 Teuchos::RCP<OutputManager<ScalarType> > printer_;
450 Teuchos::RCP<std::ostream> outputStream_;
453 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > userConvStatusTest_;
454 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > debugStatusTest_;
455 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > sTest_;
456 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP,DM> > maxIterTest_;
457 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > convTest_;
458 Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP,DM> > impConvTest_, expConvTest_;
459 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP,DM> > outputTest_;
461 Teuchos::RCP<std::map<std::string, Teuchos::RCP<StatusTest<ScalarType, MV, OP, DM> > > > taggedTests_;
464 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > ortho_;
467 Teuchos::RCP<Teuchos::ParameterList> params_;
470 static constexpr int maxRestarts_default_ = 20;
471 static constexpr int maxIters_default_ = 1000;
472 static constexpr bool showMaxResNormOnly_default_ =
false;
473 static constexpr int blockSize_default_ = 1;
474 static constexpr int numBlocks_default_ = 300;
477 static constexpr int outputFreq_default_ = -1;
478 static constexpr int defQuorum_default_ = 1;
479 static constexpr const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
480 static constexpr const char * expResScale_default_ =
"Norm of Initial Residual";
481 static constexpr const char * label_default_ =
"Belos";
482 static constexpr const char * orthoType_default_ =
"ICGS";
485 MagnitudeType convtol_, orthoKappa_, achievedTol_;
486 int maxRestarts_, maxIters_, numIters_;
487 int blockSize_, numBlocks_, verbosity_, outputStyle_, outputFreq_, defQuorum_;
488 bool showMaxResNormOnly_;
489 std::string orthoType_;
490 std::string impResScale_, expResScale_;
491 MagnitudeType resScaleFactor_;
495 Teuchos::RCP<Teuchos::Time> timerSolve_;
498 bool isSet_, isSTSet_, expResTest_;
504template<
class ScalarType,
class MV,
class OP,
class DM>
506 outputStream_(Teuchos::rcpFromRef(std::cout)),
507 taggedTests_(Teuchos::null),
510 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
511 maxRestarts_(maxRestarts_default_),
512 maxIters_(maxIters_default_),
514 blockSize_(blockSize_default_),
515 numBlocks_(numBlocks_default_),
516 verbosity_(verbosity_default_),
517 outputStyle_(outputStyle_default_),
518 outputFreq_(outputFreq_default_),
519 defQuorum_(defQuorum_default_),
520 showMaxResNormOnly_(showMaxResNormOnly_default_),
521 orthoType_(orthoType_default_),
522 impResScale_(impResScale_default_),
523 expResScale_(expResScale_default_),
525 label_(label_default_),
533template<
class ScalarType,
class MV,
class OP,
class DM>
536 const Teuchos::RCP<Teuchos::ParameterList> &pl) :
538 outputStream_(Teuchos::rcpFromRef(std::cout)),
539 taggedTests_(Teuchos::null),
542 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
543 maxRestarts_(maxRestarts_default_),
544 maxIters_(maxIters_default_),
546 blockSize_(blockSize_default_),
547 numBlocks_(numBlocks_default_),
548 verbosity_(verbosity_default_),
549 outputStyle_(outputStyle_default_),
550 outputFreq_(outputFreq_default_),
551 defQuorum_(defQuorum_default_),
552 showMaxResNormOnly_(showMaxResNormOnly_default_),
553 orthoType_(orthoType_default_),
554 impResScale_(impResScale_default_),
555 expResScale_(expResScale_default_),
557 label_(label_default_),
563 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument,
"Problem not given to solver manager.");
572template<
class ScalarType,
class MV,
class OP,
class DM>
575setParameters (
const Teuchos::RCP<Teuchos::ParameterList>& params)
577 using Teuchos::ParameterList;
578 using Teuchos::parameterList;
580 using Teuchos::rcp_dynamic_cast;
583 if (params_ == Teuchos::null) {
595 if (params->isParameter (
"Maximum Restarts")) {
596 maxRestarts_ = params->get (
"Maximum Restarts", maxRestarts_default_);
599 params_->set (
"Maximum Restarts", maxRestarts_);
603 if (params->isParameter (
"Maximum Iterations")) {
604 maxIters_ = params->get (
"Maximum Iterations", maxIters_default_);
607 params_->set (
"Maximum Iterations", maxIters_);
608 if (! maxIterTest_.is_null ()) {
609 maxIterTest_->setMaxIters (maxIters_);
614 if (params->isParameter (
"Block Size")) {
615 blockSize_ = params->get (
"Block Size", blockSize_default_);
616 TEUCHOS_TEST_FOR_EXCEPTION(
617 blockSize_ <= 0, std::invalid_argument,
618 "Belos::PseudoBlockGmresSolMgr::setParameters: "
619 "The \"Block Size\" parameter must be strictly positive, "
620 "but you specified a value of " << blockSize_ <<
".");
623 params_->set (
"Block Size", blockSize_);
627 if (params->isParameter (
"Num Blocks")) {
628 numBlocks_ = params->get (
"Num Blocks", numBlocks_default_);
629 TEUCHOS_TEST_FOR_EXCEPTION(
630 numBlocks_ <= 0, std::invalid_argument,
631 "Belos::PseudoBlockGmresSolMgr::setParameters: "
632 "The \"Num Blocks\" parameter must be strictly positive, "
633 "but you specified a value of " << numBlocks_ <<
".");
636 params_->set (
"Num Blocks", numBlocks_);
640 if (params->isParameter (
"Timer Label")) {
641 const std::string tempLabel = params->get (
"Timer Label", label_default_);
644 if (tempLabel != label_) {
646 params_->set (
"Timer Label", label_);
647 const std::string solveLabel =
648 label_ +
": PseudoBlockGmresSolMgr total solve time";
649#ifdef BELOS_TEUCHOS_TIME_MONITOR
650 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
652 if (ortho_ != Teuchos::null) {
653 ortho_->setLabel( label_ );
660 if (params->isParameter (
"Verbosity")) {
661 if (Teuchos::isParameterType<int> (*params,
"Verbosity")) {
662 verbosity_ = params->get (
"Verbosity", verbosity_default_);
664 verbosity_ = (int) Teuchos::getParameter<Belos::MsgType> (*params,
"Verbosity");
668 params_->set (
"Verbosity", verbosity_);
669 if (! printer_.is_null ()) {
670 printer_->setVerbosity (verbosity_);
675 if (params->isParameter (
"Output Style")) {
676 if (Teuchos::isParameterType<int> (*params,
"Output Style")) {
677 outputStyle_ = params->get (
"Output Style", outputStyle_default_);
679 outputStyle_ = (int) Teuchos::getParameter<Belos::OutputType> (*params,
"Output Style");
683 params_->set (
"Output Style", outputStyle_);
684 if (! outputTest_.is_null ()) {
691 if (params->isSublist (
"User Status Tests")) {
692 Teuchos::ParameterList userStatusTestsList = params->sublist(
"User Status Tests",
true);
693 if ( userStatusTestsList.numParams() > 0 ) {
694 std::string userCombo_string = params->get<std::string>(
"User Status Tests Combo Type",
"SEQ");
696 setUserConvStatusTest( testFactory->buildStatusTests(userStatusTestsList), testFactory->stringToComboType(userCombo_string) );
697 taggedTests_ = testFactory->getTaggedTests();
703 if (params->isParameter (
"Output Stream")) {
704 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> > (*params,
"Output Stream");
707 params_->set(
"Output Stream", outputStream_);
708 if (! printer_.is_null ()) {
709 printer_->setOStream (outputStream_);
715 if (params->isParameter (
"Output Frequency")) {
716 outputFreq_ = params->get (
"Output Frequency", outputFreq_default_);
720 params_->set (
"Output Frequency", outputFreq_);
721 if (! outputTest_.is_null ()) {
722 outputTest_->setOutputFrequency (outputFreq_);
727 if (printer_.is_null ()) {
732 bool changedOrthoType =
false;
733 if (params->isParameter (
"Orthogonalization")) {
734 std::string tempOrthoType = params->get (
"Orthogonalization", orthoType_default_);
735 if (tempOrthoType != orthoType_) {
736 orthoType_ = tempOrthoType;
737 changedOrthoType =
true;
740 params_->set(
"Orthogonalization", orthoType_);
743 if (params->isParameter (
"Orthogonalization Constant")) {
744 if (params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
745 orthoKappa_ = params->get (
"Orthogonalization Constant",
749 orthoKappa_ = params->get (
"Orthogonalization Constant",
754 params_->set (
"Orthogonalization Constant", orthoKappa_);
755 if (orthoType_ ==
"DGKS") {
756 if (orthoKappa_ > 0 && ! ortho_.is_null() && !changedOrthoType) {
758 rcp_dynamic_cast<ortho_type> (ortho_)->
setDepTol (orthoKappa_);
764 if (ortho_.is_null() || changedOrthoType) {
766 Teuchos::RCP<Teuchos::ParameterList> paramsOrtho;
767 if (orthoType_==
"DGKS" && orthoKappa_ > 0) {
768 paramsOrtho = Teuchos::rcp(
new Teuchos::ParameterList());
769 paramsOrtho->set (
"depTol", orthoKappa_ );
772 ortho_ = factory.
makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_, paramsOrtho);
778 if (params->isParameter (
"Convergence Tolerance")) {
779 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
780 convtol_ = params->get (
"Convergence Tolerance",
788 params_->set (
"Convergence Tolerance", convtol_);
789 if (! impConvTest_.is_null ()) {
790 impConvTest_->setTolerance (convtol_);
792 if (! expConvTest_.is_null ()) {
793 expConvTest_->setTolerance (convtol_);
798 bool userDefinedResidualScalingUpdated =
false;
799 if (params->isParameter (
"User Defined Residual Scaling")) {
801 if (params->isType<MagnitudeType> (
"User Defined Residual Scaling")) {
802 tempResScaleFactor = params->get (
"User Defined Residual Scaling",
806 tempResScaleFactor = params->get (
"User Defined Residual Scaling",
811 if (resScaleFactor_ != tempResScaleFactor) {
812 resScaleFactor_ = tempResScaleFactor;
813 userDefinedResidualScalingUpdated =
true;
816 if(userDefinedResidualScalingUpdated)
818 if (! params->isParameter (
"Implicit Residual Scaling") && ! impConvTest_.is_null ()) {
820 if(impResScale_ ==
"User Provided")
823 catch (std::exception& e) {
828 if (! params->isParameter (
"Explicit Residual Scaling") && ! expConvTest_.is_null ()) {
830 if(expResScale_ ==
"User Provided")
833 catch (std::exception& e) {
842 if (params->isParameter (
"Implicit Residual Scaling")) {
843 const std::string tempImpResScale =
844 Teuchos::getParameter<std::string> (*params,
"Implicit Residual Scaling");
847 if (impResScale_ != tempImpResScale) {
849 impResScale_ = tempImpResScale;
852 params_->set (
"Implicit Residual Scaling", impResScale_);
853 if (! impConvTest_.is_null ()) {
855 if(impResScale_ ==
"User Provided")
856 impConvTest_->defineScaleForm (impResScaleType,
Belos::TwoNorm, resScaleFactor_);
860 catch (std::exception& e) {
866 else if (userDefinedResidualScalingUpdated) {
869 if (! impConvTest_.is_null ()) {
871 if(impResScale_ ==
"User Provided")
872 impConvTest_->defineScaleForm (impResScaleType,
Belos::TwoNorm, resScaleFactor_);
874 catch (std::exception& e) {
882 if (params->isParameter (
"Explicit Residual Scaling")) {
883 const std::string tempExpResScale =
884 Teuchos::getParameter<std::string> (*params,
"Explicit Residual Scaling");
887 if (expResScale_ != tempExpResScale) {
889 expResScale_ = tempExpResScale;
892 params_->set (
"Explicit Residual Scaling", expResScale_);
893 if (! expConvTest_.is_null ()) {
895 if(expResScale_ ==
"User Provided")
896 expConvTest_->defineScaleForm (expResScaleType,
Belos::TwoNorm, resScaleFactor_);
900 catch (std::exception& e) {
906 else if (userDefinedResidualScalingUpdated) {
909 if (! expConvTest_.is_null ()) {
911 if(expResScale_ ==
"User Provided")
912 expConvTest_->defineScaleForm (expResScaleType,
Belos::TwoNorm, resScaleFactor_);
914 catch (std::exception& e) {
923 if (params->isParameter (
"Show Maximum Residual Norm Only")) {
924 showMaxResNormOnly_ =
925 Teuchos::getParameter<bool> (*params,
"Show Maximum Residual Norm Only");
928 params_->set (
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
929 if (! impConvTest_.is_null ()) {
930 impConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
932 if (! expConvTest_.is_null ()) {
933 expConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
940 if (params->isParameter(
"Deflation Quorum")) {
941 defQuorum_ = params->get(
"Deflation Quorum", defQuorum_);
942 TEUCHOS_TEST_FOR_EXCEPTION(
943 defQuorum_ > blockSize_, std::invalid_argument,
944 "Belos::PseudoBlockGmresSolMgr::setParameters: "
945 "The \"Deflation Quorum\" parameter (= " << defQuorum_ <<
") must not be "
946 "larger than \"Block Size\" (= " << blockSize_ <<
").");
947 params_->set (
"Deflation Quorum", defQuorum_);
948 if (! impConvTest_.is_null ()) {
949 impConvTest_->setQuorum (defQuorum_);
951 if (! expConvTest_.is_null ()) {
952 expConvTest_->setQuorum (defQuorum_);
957 if (timerSolve_ == Teuchos::null) {
958 std::string solveLabel = label_ +
": PseudoBlockGmresSolMgr total solve time";
959#ifdef BELOS_TEUCHOS_TIME_MONITOR
960 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
969template<
class ScalarType,
class MV,
class OP,
class DM>
975 userConvStatusTest_ = userConvStatusTest;
976 comboType_ = comboType;
979template<
class ScalarType,
class MV,
class OP,
class DM>
984 debugStatusTest_ = debugStatusTest;
989template<
class ScalarType,
class MV,
class OP,
class DM>
990Teuchos::RCP<const Teuchos::ParameterList>
993 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
994 if (is_null(validPL)) {
995 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
1000 pl= Teuchos::rcp(
new Teuchos::ParameterList() );
1002 "The relative residual tolerance that needs to be achieved by the\n"
1003 "iterative solver in order for the linear system to be declared converged.");
1004 pl->set(
"Maximum Restarts",
static_cast<int>(maxRestarts_default_),
1005 "The maximum number of restarts allowed for each\n"
1006 "set of RHS solved.");
1007 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
1008 "The maximum number of block iterations allowed for each\n"
1009 "set of RHS solved.");
1010 pl->set(
"Num Blocks",
static_cast<int>(numBlocks_default_),
1011 "The maximum number of vectors allowed in the Krylov subspace\n"
1012 "for each set of RHS solved.");
1013 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
1014 "The number of RHS solved simultaneously.");
1015 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
1016 "What type(s) of solver information should be outputted\n"
1017 "to the output stream.");
1018 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
1019 "What style is used for the solver information outputted\n"
1020 "to the output stream.");
1021 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
1022 "How often convergence information should be outputted\n"
1023 "to the output stream.");
1024 pl->set(
"Deflation Quorum",
static_cast<int>(defQuorum_default_),
1025 "The number of linear systems that need to converge before\n"
1026 "they are deflated. This number should be <= block size.");
1027 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
1028 "A reference-counted pointer to the output stream where all\n"
1029 "solver output is sent.");
1030 pl->set(
"Show Maximum Residual Norm Only",
static_cast<bool>(showMaxResNormOnly_default_),
1031 "When convergence information is printed, only show the maximum\n"
1032 "relative residual norm when the block size is greater than one.");
1033 pl->set(
"Implicit Residual Scaling",
static_cast<const char *
>(impResScale_default_),
1034 "The type of scaling used in the implicit residual convergence test.");
1035 pl->set(
"Explicit Residual Scaling",
static_cast<const char *
>(expResScale_default_),
1036 "The type of scaling used in the explicit residual convergence test.");
1037 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
1038 "The string to use as a prefix for the timer labels.");
1039 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
1040 "The type of orthogonalization to use.");
1042 "The constant used by DGKS orthogonalization to determine\n"
1043 "whether another step of classical Gram-Schmidt is necessary.");
1044 pl->sublist(
"User Status Tests");
1045 pl->set(
"User Status Tests Combo Type",
"SEQ",
1046 "Type of logical combination operation of user-defined\n"
1047 "and/or solver-specific status tests.");
1054template<
class ScalarType,
class MV,
class OP,
class DM>
1055bool PseudoBlockGmresSolMgr<ScalarType,MV,OP,DM>::checkStatusTest() {
1066 if ( !Teuchos::is_null(problem_->getLeftPrec()) ) {
1073 Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
1074 Teuchos::rcp(
new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1075 if(impResScale_ ==
"User Provided")
1080 tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1081 impConvTest_ = tmpImpConvTest;
1084 Teuchos::RCP<StatusTestGenResNorm_t> tmpExpConvTest =
1085 Teuchos::rcp(
new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1086 tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit,
Belos::TwoNorm );
1087 if(expResScale_ ==
"User Provided")
1091 tmpExpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1092 expConvTest_ = tmpExpConvTest;
1095 convTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) );
1101 Teuchos::RCP<StatusTestImpResNorm_t> tmpImpConvTest =
1102 Teuchos::rcp(
new StatusTestImpResNorm_t( convtol_, defQuorum_ ) );
1103 if(impResScale_ ==
"User Provided")
1107 tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1108 impConvTest_ = tmpImpConvTest;
1111 expConvTest_ = impConvTest_;
1112 convTest_ = impConvTest_;
1115 if (Teuchos::nonnull(userConvStatusTest_) ) {
1117 Teuchos::RCP<StatusTestCombo_t> tmpComboTest = Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(userConvStatusTest_);
1118 if (tmpComboTest != Teuchos::null) {
1119 std::vector<Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > > tmpVec = tmpComboTest->getStatusTests();
1120 comboType_ = tmpComboTest->getComboType();
1121 const int numResTests =
static_cast<int>(tmpVec.size());
1122 auto newConvTest = Teuchos::rcp(
new StatusTestCombo_t(comboType_));
1123 newConvTest->addStatusTest(convTest_);
1124 for (
int j = 0; j < numResTests; ++j) {
1125 newConvTest->addStatusTest(tmpVec[j]);
1127 convTest_ = newConvTest;
1131 convTest_ = Teuchos::rcp(
1132 new StatusTestCombo_t( comboType_, convTest_, userConvStatusTest_ ) );
1140 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
1143 if (Teuchos::nonnull(debugStatusTest_) ) {
1145 Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(sTest_)->addStatusTest( debugStatusTest_ );
1154 std::string solverDesc =
" Pseudo Block Gmres ";
1155 outputTest_->setSolverDesc( solverDesc );
1166template<
class ScalarType,
class MV,
class OP,
class DM>
1175 "Belos::PseudoBlockGmresSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1178 if (!isSTSet_ || (!expResTest_ && !Teuchos::is_null(problem_->getLeftPrec())) ) {
1180 "Belos::BlockGmresSolMgr::solve(): Linear problem and requested status tests are incompatible.");
1186 int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1188 std::vector<int> currIdx( numCurrRHS );
1189 blockSize_ = numCurrRHS;
1190 for (
int i=0; i<numCurrRHS; ++i)
1191 { currIdx[i] = startPtr+i; }
1194 problem_->setLSIndex( currIdx );
1198 Teuchos::ParameterList plist;
1199 plist.set(
"Num Blocks",numBlocks_);
1202 outputTest_->reset();
1203 loaDetected_ =
false;
1206 bool isConverged =
true;
1211 Teuchos::RCP<PseudoBlockGmresIter<ScalarType,MV,OP,DM> > block_gmres_iter
1216#ifdef BELOS_TEUCHOS_TIME_MONITOR
1217 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1220 while ( numRHS2Solve > 0 ) {
1223 std::vector<int> convRHSIdx;
1224 std::vector<int> currRHSIdx( currIdx );
1225 currRHSIdx.resize(numCurrRHS);
1228 block_gmres_iter->setNumBlocks( numBlocks_ );
1231 block_gmres_iter->resetNumIters();
1234 outputTest_->resetNumCalls();
1240 std::vector<int> index(1);
1241 Teuchos::RCP<MV> tmpV, R_0 =
MVT::CloneCopy( *(problem_->getInitPrecResVec()), currIdx );
1242 newState.
V.resize( blockSize_ );
1243 newState.
Z.resize( blockSize_ );
1244 for (
int i=0; i<blockSize_; ++i) {
1252 int rank = ortho_->normalize( *tmpV, tmpZ );
1254 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors.");
1256 newState.
V[i] = tmpV;
1257 newState.
Z[i] = tmpZ;
1261 block_gmres_iter->initialize(newState);
1262 int numRestarts = 0;
1268 block_gmres_iter->iterate();
1275 if ( convTest_->getStatus() ==
Passed ) {
1277 if ( expConvTest_->getLOADetected() ) {
1288 loaDetected_ =
true;
1290 "Belos::PseudoBlockGmresSolMgr::solve(): Warning! Solver has experienced a loss of accuracy!" << std::endl;
1291 isConverged =
false;
1295 std::vector<int> convIdx = expConvTest_->convIndices();
1299 if (convIdx.size() == currRHSIdx.size())
1306 problem_->setCurrLS();
1310 int curDim = oldState.
curDim;
1315 std::vector<int> oldRHSIdx( currRHSIdx );
1316 std::vector<int> defRHSIdx;
1317 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
1319 for (
unsigned int j=0; j<convIdx.size(); ++j) {
1320 if (currRHSIdx[i] == convIdx[j]) {
1326 defRHSIdx.push_back( i );
1329 defState.
V.push_back( Teuchos::rcp_const_cast<MV>( oldState.
V[i] ) );
1330 defState.
Z.push_back( Teuchos::rcp_const_cast<DM>( oldState.
Z[i] ) );
1331 defState.
H.push_back( Teuchos::rcp_const_cast<DM>( oldState.
H[i] ) );
1332 defState.
sn.push_back( Teuchos::rcp_const_cast<std::vector<ScalarType> >( oldState.
sn[i] ) );
1333 defState.
cs.push_back( Teuchos::rcp_const_cast<std::vector<MagnitudeType> >(oldState.
cs[i] ) );
1334 currRHSIdx[have] = currRHSIdx[i];
1338 defRHSIdx.resize(currRHSIdx.size()-have);
1339 currRHSIdx.resize(have);
1343 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1347 problem_->setLSIndex( convIdx );
1350 problem_->updateSolution( defUpdate,
true );
1354 problem_->setLSIndex( currRHSIdx );
1357 defState.
curDim = curDim;
1360 block_gmres_iter->initialize(defState);
1367 else if ( maxIterTest_->getStatus() ==
Passed ) {
1370 isConverged =
false;
1378 else if ( block_gmres_iter->getCurSubspaceDim() == block_gmres_iter->getMaxSubspaceDim() ) {
1380 if ( numRestarts >= maxRestarts_ ) {
1382 isConverged =
false;
1387 printer_->stream(
Debug) <<
" Performing restart number " << numRestarts <<
" of " << maxRestarts_ << std::endl << std::endl;
1390 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1391 problem_->updateSolution( update,
true );
1398 newstate.
V.resize(currRHSIdx.size());
1399 newstate.
Z.resize(currRHSIdx.size());
1403 R_0 =
MVT::Clone( *(problem_->getInitPrecResVec()), currRHSIdx.size() );
1404 problem_->computeCurrPrecResVec( &*R_0 );
1405 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
1414 int rank = ortho_->normalize( *tmpV, tmpZ );
1416 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors after the restart.");
1418 newstate.
V[i] = tmpV;
1419 newstate.
Z[i] = tmpZ;
1424 block_gmres_iter->initialize(newstate);
1438 else if (Teuchos::nonnull(debugStatusTest_) &&
1439 debugStatusTest_->getStatus() ==
Passed) {
1441 isConverged =
false;
1453 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
1454 "Belos::PseudoBlockGmresSolMgr::solve(): Invalid return from PseudoBlockGmresIter::iterate().");
1460 block_gmres_iter->updateLSQR( block_gmres_iter->getCurSubspaceDim() );
1463 sTest_->checkStatus( &*block_gmres_iter );
1464 if (convTest_->getStatus() !=
Passed) {
1466 isConverged =
false;
1473 achievedTol_ = MT::one();
1474 Teuchos::RCP<MV> X = problem_->getLHS();
1476 printer_->stream(
Warnings) <<
"Belos::PseudoBlockGmresSolMgr::solve(): Warning! NaN has been detected!"
1480 catch (
const std::exception &e) {
1482 printer_->stream(
Errors) <<
"Error! Caught std::exception in PseudoBlockGmresIter::iterate() at iteration "
1483 << block_gmres_iter->getNumIters() << std::endl
1484 << e.what() << std::endl;
1491 if (Teuchos::nonnull(userConvStatusTest_)) {
1493 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1494 problem_->updateSolution( update,
true );
1496 else if (Teuchos::nonnull(expConvTest_->getSolution())) {
1498 Teuchos::RCP<MV> newX = expConvTest_->getSolution();
1499 Teuchos::RCP<MV> curX = problem_->getCurrLHSVec();
1504 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1505 problem_->updateSolution( update,
true );
1509 problem_->setCurrLS();
1512 startPtr += numCurrRHS;
1513 numRHS2Solve -= numCurrRHS;
1514 if ( numRHS2Solve > 0 ) {
1515 numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1517 blockSize_ = numCurrRHS;
1518 currIdx.resize( numCurrRHS );
1519 for (
int i=0; i<numCurrRHS; ++i)
1520 { currIdx[i] = startPtr+i; }
1523 if (defQuorum_ > blockSize_) {
1524 if (impConvTest_ != Teuchos::null)
1525 impConvTest_->setQuorum( blockSize_ );
1526 if (expConvTest_ != Teuchos::null)
1527 expConvTest_->setQuorum( blockSize_ );
1531 problem_->setLSIndex( currIdx );
1534 currIdx.resize( numRHS2Solve );
1545#ifdef BELOS_TEUCHOS_TIME_MONITOR
1550 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1554 numIters_ = maxIterTest_->getNumIters();
1567 const std::vector<MagnitudeType>* pTestValues = NULL;
1569 pTestValues = expConvTest_->getTestValue();
1570 if (pTestValues == NULL || pTestValues->size() < 1) {
1571 pTestValues = impConvTest_->getTestValue();
1576 pTestValues = impConvTest_->getTestValue();
1578 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1579 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1580 "getTestValue() method returned NULL. Please report this bug to the "
1581 "Belos developers.");
1582 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1583 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1584 "getTestValue() method returned a vector of length zero. Please report "
1585 "this bug to the Belos developers.");
1590 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1593 if (!isConverged || loaDetected_) {
1600template<
class ScalarType,
class MV,
class OP,
class DM>
1603 std::ostringstream out;
1605 out <<
"\"Belos::PseudoBlockGmresSolMgr\": {";
1606 if (this->getObjectLabel () !=
"") {
1607 out <<
"Label: " << this->getObjectLabel () <<
", ";
1609 out <<
"Num Blocks: " << numBlocks_
1610 <<
", Maximum Iterations: " << maxIters_
1611 <<
", Maximum Restarts: " << maxRestarts_
1612 <<
", Convergence Tolerance: " << convtol_
1618template<
class ScalarType,
class MV,
class OP,
class DM>
1620describe (Teuchos::FancyOStream &out,
1621 const Teuchos::EVerbosityLevel verbLevel)
const
1623 using Teuchos::TypeNameTraits;
1624 using Teuchos::VERB_DEFAULT;
1625 using Teuchos::VERB_NONE;
1626 using Teuchos::VERB_LOW;
1633 const Teuchos::EVerbosityLevel vl =
1634 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
1636 if (vl != VERB_NONE) {
1637 Teuchos::OSTab tab0 (out);
1639 out <<
"\"Belos::PseudoBlockGmresSolMgr\":" << endl;
1640 Teuchos::OSTab tab1 (out);
1641 out <<
"Template parameters:" << endl;
1643 Teuchos::OSTab tab2 (out);
1644 out <<
"ScalarType: " << TypeNameTraits<ScalarType>::name () << endl
1645 <<
"MV: " << TypeNameTraits<MV>::name () << endl
1646 <<
"OP: " << TypeNameTraits<OP>::name () << endl;
1648 if (this->getObjectLabel () !=
"") {
1649 out <<
"Label: " << this->getObjectLabel () << endl;
1651 out <<
"Num Blocks: " << numBlocks_ << endl
1652 <<
"Maximum Iterations: " << maxIters_ << endl
1653 <<
"Maximum Restarts: " << maxRestarts_ << endl
1654 <<
"Convergence Tolerance: " << convtol_ << endl;
1660#ifdef HAVE_BELOS_TPETRA
1663#define BELOS_TPETRA_PSEUDOBLOCKGMRESSOLMGR_NOEXTERN_CALL(SC, LO, GO, NT) \
1664 BELOS_TPETRA_CALL(Belos::PseudoBlockGmresSolMgr, SC, LO, GO, NT)
1666#define BELOS_TPETRA_PSEUDOBLOCKGMRESSOLMGR_EXTERN_CALL(SC, LO, GO, NT) \
1667 BELOS_TPETRA_EXTERN_CALL(Belos::PseudoBlockGmresSolMgr, SC, LO, GO, NT)
1669TPETRA_INSTANTIATE_SLGN_NO_ORDINAL_SCALAR(BELOS_TPETRA_PSEUDOBLOCKGMRESSOLMGR_EXTERN_CALL)
Belos header file which uses auto-configuration information to include necessary C++ headers.
Class which describes the linear problem to be solved by the iterative solver.
Class which manages the output and verbosity of the Belos solvers.
Belos concrete class for performing the pseudo-block GMRES iteration.
Pure virtual base class which describes the basic interface for a solver manager.
A factory class for generating StatusTestOutput objects.
Collection of types and exceptions used within the Belos solvers.
BelosError(const std::string &what_arg)
An implementation of the Belos::MatOrthoManager that performs orthogonalization using (potentially) m...
void setDepTol(const MagnitudeType dep_tol)
Set parameter for re-orthogonalization threshhold.
Virtual base class which defines basic traits for the multi-vector type.
static Teuchos::RCP< DM > Create()
Creates a new empty DM with no dimension.
Traits class which defines basic operations on multivectors.
static void MvInit(MV &mv, const ScalarType alpha=Teuchos::ScalarTraits< ScalarType >::zero())
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
static void Assign(const MV &A, MV &mv)
static Teuchos::RCP< MV > CloneViewNonConst(MV &mv, const std::vector< int > &index)
static int GetNumberVecs(const MV &mv)
Class which defines basic traits for the operator type.
Enumeration of all valid Belos (Mat)OrthoManager classes.
Teuchos::RCP< Belos::MatOrthoManager< Scalar, MV, OP, DM > > makeMatOrthoManager(const std::string &ortho, const Teuchos::RCP< const OP > &M, const Teuchos::RCP< OutputManager< Scalar > > &, const std::string &label, const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Return an instance of the specified MatOrthoManager subclass.
Belos's basic output manager for sending information of select verbosity levels to the appropriate ou...
This class implements the pseudo-block GMRES iteration, where a block Krylov subspace is constructed ...
PseudoBlockGmresIterOrthoFailure is thrown when the orthogonalization manager is unable to generate o...
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const override
Return a reference to the linear problem being solved by this solver manager.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
Teuchos::RCP< SolverManager< ScalarType, MV, OP, DM > > clone() const override
clone for Inverted Injection (DII)
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
The current parameters for this solver.
PseudoBlockGmresSolMgr()
Empty constructor.
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
virtual void setUserConvStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &userConvStatusTest, const typename StatusTestCombo< ScalarType, MV, OP, DM >::ComboType &comboType=StatusTestCombo< ScalarType, MV, OP, DM >::SEQ) override
Set a custom status test.
void setDebugStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &debugStatusTest) override
Set a debug status test that will be checked at the same time as the top-level status test.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
A list of valid default parameters for this solver.
const StatusTestResNorm< ScalarType, MV, OP, DM > * getResidualStatusTest() const
Return the residual status test.
virtual ~PseudoBlockGmresSolMgr()
Destructor.
bool isLOADetected() const override
Whether a "loss of accuracy" was detected during the last solve().
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &problem) override
Set the linear problem to solve.
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > ¶ms) override
Set the parameters the solver manager should use to solve the linear problem.
std::string description() const override
Return a one-line description of this object.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const override
Print the object with the given verbosity level to a FancyOStream.
ReturnType solve() override
This method performs possibly repeated calls to the underlying linear solver's iterate() routine unti...
int getNumIters() const override
Iteration count for the most recent call to solve().
PseudoBlockGmresSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i....
PseudoBlockGmresSolMgrLinearProblemFailure(const std::string &what_arg)
PseudoBlockGmresSolMgrOrthoFailure is thrown when the orthogonalization manager is unable to generate...
PseudoBlockGmresSolMgrOrthoFailure(const std::string &what_arg)
SolverManager()
Empty constructor.
A class for extending the status testing capabilities of Belos via logical combinations.
ComboType
The test can be either the AND of all the component tests, or the OR of all the component tests,...
Factory to build a set of status tests from a parameter list.
An implementation of StatusTestResNorm using a family of residual norms.
A pure virtual class for defining the status tests for the Belos iterative solvers.
Convergence test using the implicit residual norm(s), with an explicit residual norm(s) check for los...
A Belos::StatusTest class for specifying a maximum number of iterations.
A factory class for generating StatusTestOutput objects.
An abstract class of StatusTest for stopping criteria using residual norms.
ScaleType convertStringToScaleType(const std::string &scaleType)
Convert the given string to its ScaleType enum value.
ReturnType
Whether the Belos solve converged for all linear systems.
ScaleType
The type of scaling to use on the residual norm value.
ResetType
How to reset the solver.
Default parameters common to most Belos solvers.
static const double resScaleFactor
User-defined residual scaling factor.
static const double convTol
Default convergence tolerance.
static const double orthoKappa
DGKS orthogonalization constant.
Structure to contain pointers to PseudoBlockGmresIter state variables.
int curDim
The current dimension of the reduction.
std::vector< Teuchos::RCP< const std::vector< ScalarType > > > sn
The current Given's rotation coefficients.
std::vector< Teuchos::RCP< const DM > > Z
The current right-hand side of the least squares system RY = Z.
std::vector< Teuchos::RCP< const DM > > H
The current Hessenberg matrix.
std::vector< Teuchos::RCP< const std::vector< MagnitudeType > > > cs
std::vector< Teuchos::RCP< const MV > > V
The current Krylov basis.