42 #ifndef BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
43 #define BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
59 #ifdef HAVE_BELOS_TSQR
61 #endif // HAVE_BELOS_TSQR
65 #include "Teuchos_BLAS.hpp"
66 #ifdef BELOS_TEUCHOS_TIME_MONITOR
67 #include "Teuchos_TimeMonitor.hpp"
125 template<
class ScalarType,
class MV,
class OP>
131 typedef Teuchos::ScalarTraits<ScalarType> SCT;
132 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
133 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
260 const Teuchos::RCP<Teuchos::ParameterList> &pl );
266 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
289 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
290 return Teuchos::tuple(timerSolve_);
380 void setParameters (
const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
override;
442 describe (Teuchos::FancyOStream& out,
443 const Teuchos::EVerbosityLevel verbLevel =
444 Teuchos::Describable::verbLevel_default)
const override;
467 bool checkStatusTest();
470 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
473 Teuchos::RCP<OutputManager<ScalarType> > printer_;
474 Teuchos::RCP<std::ostream> outputStream_;
477 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > userConvStatusTest_;
478 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > debugStatusTest_;
479 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
480 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
481 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
482 Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > impConvTest_, expConvTest_;
483 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
485 Teuchos::RCP<std::map<std::string, Teuchos::RCP<StatusTest<ScalarType, MV, OP> > > > taggedTests_;
488 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
491 Teuchos::RCP<Teuchos::ParameterList> params_;
494 static constexpr
int maxRestarts_default_ = 20;
495 static constexpr
int maxIters_default_ = 1000;
496 static constexpr
bool showMaxResNormOnly_default_ =
false;
497 static constexpr
int blockSize_default_ = 1;
498 static constexpr
int numBlocks_default_ = 300;
501 static constexpr
int outputFreq_default_ = -1;
502 static constexpr
int defQuorum_default_ = 1;
503 static constexpr
const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
504 static constexpr
const char * expResScale_default_ =
"Norm of Initial Residual";
505 static constexpr
const char * label_default_ =
"Belos";
506 static constexpr
const char * orthoType_default_ =
"ICGS";
507 static constexpr std::ostream * outputStream_default_ = &std::cout;
510 MagnitudeType convtol_, orthoKappa_, achievedTol_;
511 int maxRestarts_, maxIters_, numIters_;
512 int blockSize_, numBlocks_, verbosity_, outputStyle_, outputFreq_, defQuorum_;
513 bool showMaxResNormOnly_;
514 std::string orthoType_;
515 std::string impResScale_, expResScale_;
516 MagnitudeType resScaleFactor_;
520 Teuchos::RCP<Teuchos::Time> timerSolve_;
523 bool isSet_, isSTSet_, expResTest_;
529 template<
class ScalarType,
class MV,
class OP>
531 outputStream_(Teuchos::rcp(outputStream_default_,false)),
532 taggedTests_(Teuchos::null),
535 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
536 maxRestarts_(maxRestarts_default_),
537 maxIters_(maxIters_default_),
539 blockSize_(blockSize_default_),
540 numBlocks_(numBlocks_default_),
541 verbosity_(verbosity_default_),
542 outputStyle_(outputStyle_default_),
543 outputFreq_(outputFreq_default_),
544 defQuorum_(defQuorum_default_),
545 showMaxResNormOnly_(showMaxResNormOnly_default_),
546 orthoType_(orthoType_default_),
547 impResScale_(impResScale_default_),
548 expResScale_(expResScale_default_),
550 label_(label_default_),
558 template<
class ScalarType,
class MV,
class OP>
561 const Teuchos::RCP<Teuchos::ParameterList> &pl) :
563 outputStream_(Teuchos::rcp(outputStream_default_,false)),
564 taggedTests_(Teuchos::null),
567 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
568 maxRestarts_(maxRestarts_default_),
569 maxIters_(maxIters_default_),
571 blockSize_(blockSize_default_),
572 numBlocks_(numBlocks_default_),
573 verbosity_(verbosity_default_),
574 outputStyle_(outputStyle_default_),
575 outputFreq_(outputFreq_default_),
576 defQuorum_(defQuorum_default_),
577 showMaxResNormOnly_(showMaxResNormOnly_default_),
578 orthoType_(orthoType_default_),
579 impResScale_(impResScale_default_),
580 expResScale_(expResScale_default_),
582 label_(label_default_),
588 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument,
"Problem not given to solver manager.");
597 template<
class ScalarType,
class MV,
class OP>
600 setParameters (
const Teuchos::RCP<Teuchos::ParameterList>& params)
602 using Teuchos::ParameterList;
603 using Teuchos::parameterList;
605 using Teuchos::rcp_dynamic_cast;
608 if (params_ == Teuchos::null) {
609 params_ = parameterList (*getValidParameters ());
616 params->validateParameters (*getValidParameters (), 0);
620 if (params->isParameter (
"Maximum Restarts")) {
621 maxRestarts_ = params->get (
"Maximum Restarts", maxRestarts_default_);
624 params_->set (
"Maximum Restarts", maxRestarts_);
628 if (params->isParameter (
"Maximum Iterations")) {
629 maxIters_ = params->get (
"Maximum Iterations", maxIters_default_);
632 params_->set (
"Maximum Iterations", maxIters_);
633 if (! maxIterTest_.is_null ()) {
634 maxIterTest_->setMaxIters (maxIters_);
639 if (params->isParameter (
"Block Size")) {
640 blockSize_ = params->get (
"Block Size", blockSize_default_);
641 TEUCHOS_TEST_FOR_EXCEPTION(
642 blockSize_ <= 0, std::invalid_argument,
643 "Belos::PseudoBlockGmresSolMgr::setParameters: "
644 "The \"Block Size\" parameter must be strictly positive, "
645 "but you specified a value of " << blockSize_ <<
".");
648 params_->set (
"Block Size", blockSize_);
652 if (params->isParameter (
"Num Blocks")) {
653 numBlocks_ = params->get (
"Num Blocks", numBlocks_default_);
654 TEUCHOS_TEST_FOR_EXCEPTION(
655 numBlocks_ <= 0, std::invalid_argument,
656 "Belos::PseudoBlockGmresSolMgr::setParameters: "
657 "The \"Num Blocks\" parameter must be strictly positive, "
658 "but you specified a value of " << numBlocks_ <<
".");
661 params_->set (
"Num Blocks", numBlocks_);
665 if (params->isParameter (
"Timer Label")) {
666 const std::string tempLabel = params->get (
"Timer Label", label_default_);
669 if (tempLabel != label_) {
671 params_->set (
"Timer Label", label_);
672 const std::string solveLabel =
673 label_ +
": PseudoBlockGmresSolMgr total solve time";
674 #ifdef BELOS_TEUCHOS_TIME_MONITOR
675 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
676 #endif // BELOS_TEUCHOS_TIME_MONITOR
677 if (ortho_ != Teuchos::null) {
678 ortho_->setLabel( label_ );
684 if (params->isParameter (
"Orthogonalization")) {
685 std::string tempOrthoType = params->get (
"Orthogonalization", orthoType_default_);
686 #ifdef HAVE_BELOS_TSQR
687 TEUCHOS_TEST_FOR_EXCEPTION(
688 tempOrthoType !=
"DGKS" && tempOrthoType !=
"ICGS" &&
689 tempOrthoType !=
"IMGS" && tempOrthoType !=
"TSQR",
690 std::invalid_argument,
691 "Belos::PseudoBlockGmresSolMgr::setParameters: "
692 "The \"Orthogonalization\" parameter must be one of \"DGKS\", \"ICGS\", "
693 "\"IMGS\", or \"TSQR\".");
695 TEUCHOS_TEST_FOR_EXCEPTION(
696 tempOrthoType !=
"DGKS" && tempOrthoType !=
"ICGS" &&
697 tempOrthoType !=
"IMGS",
698 std::invalid_argument,
699 "Belos::PseudoBlockGmresSolMgr::setParameters: "
700 "The \"Orthogonalization\" parameter must be one of \"DGKS\", \"ICGS\", "
702 #endif // HAVE_BELOS_TSQR
704 if (tempOrthoType != orthoType_) {
705 orthoType_ = tempOrthoType;
706 params_->set(
"Orthogonalization", orthoType_);
708 if (orthoType_ ==
"DGKS") {
710 if (orthoKappa_ <= 0) {
711 ortho_ = rcp (
new ortho_type (label_));
714 ortho_ = rcp (
new ortho_type (label_));
715 rcp_dynamic_cast<ortho_type> (ortho_)->setDepTol (orthoKappa_);
718 else if (orthoType_ ==
"ICGS") {
720 ortho_ = rcp (
new ortho_type (label_));
722 else if (orthoType_ ==
"IMGS") {
724 ortho_ = rcp (
new ortho_type (label_));
726 #ifdef HAVE_BELOS_TSQR
727 else if (orthoType_ ==
"TSQR") {
729 ortho_ = rcp (
new ortho_type (label_));
731 #endif // HAVE_BELOS_TSQR
736 if (params->isParameter (
"Orthogonalization Constant")) {
737 if (params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
738 orthoKappa_ = params->get (
"Orthogonalization Constant",
742 orthoKappa_ = params->get (
"Orthogonalization Constant",
747 params_->set (
"Orthogonalization Constant", orthoKappa_);
748 if (orthoType_ ==
"DGKS") {
749 if (orthoKappa_ > 0 && ! ortho_.is_null ()) {
751 rcp_dynamic_cast<ortho_type> (ortho_)->
setDepTol (orthoKappa_);
757 if (params->isParameter (
"Verbosity")) {
758 if (Teuchos::isParameterType<int> (*params,
"Verbosity")) {
759 verbosity_ = params->get (
"Verbosity", verbosity_default_);
761 verbosity_ = (int) Teuchos::getParameter<Belos::MsgType> (*params,
"Verbosity");
765 params_->set (
"Verbosity", verbosity_);
766 if (! printer_.is_null ()) {
767 printer_->setVerbosity (verbosity_);
772 if (params->isParameter (
"Output Style")) {
773 if (Teuchos::isParameterType<int> (*params,
"Output Style")) {
774 outputStyle_ = params->get (
"Output Style", outputStyle_default_);
776 outputStyle_ = (int) Teuchos::getParameter<Belos::OutputType> (*params,
"Output Style");
780 params_->set (
"Output Style", verbosity_);
781 if (! outputTest_.is_null ()) {
788 if (params->isSublist (
"User Status Tests")) {
789 Teuchos::ParameterList userStatusTestsList = params->sublist(
"User Status Tests",
true);
790 if ( userStatusTestsList.numParams() > 0 ) {
791 std::string userCombo_string = params->get<std::string>(
"User Status Tests Combo Type",
"SEQ");
793 setUserConvStatusTest( testFactory->buildStatusTests(userStatusTestsList), testFactory->stringToComboType(userCombo_string) );
794 taggedTests_ = testFactory->getTaggedTests();
800 if (params->isParameter (
"Output Stream")) {
801 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> > (*params,
"Output Stream");
804 params_->set(
"Output Stream", outputStream_);
805 if (! printer_.is_null ()) {
806 printer_->setOStream (outputStream_);
812 if (params->isParameter (
"Output Frequency")) {
813 outputFreq_ = params->get (
"Output Frequency", outputFreq_default_);
817 params_->set (
"Output Frequency", outputFreq_);
818 if (! outputTest_.is_null ()) {
819 outputTest_->setOutputFrequency (outputFreq_);
824 if (printer_.is_null ()) {
831 if (params->isParameter (
"Convergence Tolerance")) {
832 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
833 convtol_ = params->get (
"Convergence Tolerance",
841 params_->set (
"Convergence Tolerance", convtol_);
842 if (! impConvTest_.is_null ()) {
843 impConvTest_->setTolerance (convtol_);
845 if (! expConvTest_.is_null ()) {
846 expConvTest_->setTolerance (convtol_);
851 bool userDefinedResidualScalingUpdated =
false;
852 if (params->isParameter (
"User Defined Residual Scaling")) {
854 if (params->isType<MagnitudeType> (
"User Defined Residual Scaling")) {
855 tempResScaleFactor = params->get (
"User Defined Residual Scaling",
859 tempResScaleFactor = params->get (
"User Defined Residual Scaling",
864 if (resScaleFactor_ != tempResScaleFactor) {
865 resScaleFactor_ = tempResScaleFactor;
866 userDefinedResidualScalingUpdated =
true;
869 if(userDefinedResidualScalingUpdated)
871 if (! params->isParameter (
"Implicit Residual Scaling") && ! impConvTest_.is_null ()) {
873 if(impResScale_ ==
"User Provided")
876 catch (std::exception& e) {
881 if (! params->isParameter (
"Explicit Residual Scaling") && ! expConvTest_.is_null ()) {
883 if(expResScale_ ==
"User Provided")
886 catch (std::exception& e) {
895 if (params->isParameter (
"Implicit Residual Scaling")) {
896 const std::string tempImpResScale =
897 Teuchos::getParameter<std::string> (*params,
"Implicit Residual Scaling");
900 if (impResScale_ != tempImpResScale) {
902 impResScale_ = tempImpResScale;
905 params_->set (
"Implicit Residual Scaling", impResScale_);
906 if (! impConvTest_.is_null ()) {
908 if(impResScale_ ==
"User Provided")
909 impConvTest_->defineScaleForm (impResScaleType,
Belos::TwoNorm, resScaleFactor_);
913 catch (std::exception& e) {
919 else if (userDefinedResidualScalingUpdated) {
922 if (! impConvTest_.is_null ()) {
924 if(impResScale_ ==
"User Provided")
925 impConvTest_->defineScaleForm (impResScaleType,
Belos::TwoNorm, resScaleFactor_);
927 catch (std::exception& e) {
935 if (params->isParameter (
"Explicit Residual Scaling")) {
936 const std::string tempExpResScale =
937 Teuchos::getParameter<std::string> (*params,
"Explicit Residual Scaling");
940 if (expResScale_ != tempExpResScale) {
942 expResScale_ = tempExpResScale;
945 params_->set (
"Explicit Residual Scaling", expResScale_);
946 if (! expConvTest_.is_null ()) {
948 if(expResScale_ ==
"User Provided")
949 expConvTest_->defineScaleForm (expResScaleType,
Belos::TwoNorm, resScaleFactor_);
953 catch (std::exception& e) {
959 else if (userDefinedResidualScalingUpdated) {
962 if (! expConvTest_.is_null ()) {
964 if(expResScale_ ==
"User Provided")
965 expConvTest_->defineScaleForm (expResScaleType,
Belos::TwoNorm, resScaleFactor_);
967 catch (std::exception& e) {
976 if (params->isParameter (
"Show Maximum Residual Norm Only")) {
977 showMaxResNormOnly_ =
978 Teuchos::getParameter<bool> (*params,
"Show Maximum Residual Norm Only");
981 params_->set (
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
982 if (! impConvTest_.is_null ()) {
983 impConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
985 if (! expConvTest_.is_null ()) {
986 expConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
993 if (params->isParameter(
"Deflation Quorum")) {
994 defQuorum_ = params->get(
"Deflation Quorum", defQuorum_);
995 TEUCHOS_TEST_FOR_EXCEPTION(
996 defQuorum_ > blockSize_, std::invalid_argument,
997 "Belos::PseudoBlockGmresSolMgr::setParameters: "
998 "The \"Deflation Quorum\" parameter (= " << defQuorum_ <<
") must not be "
999 "larger than \"Block Size\" (= " << blockSize_ <<
").");
1000 params_->set (
"Deflation Quorum", defQuorum_);
1001 if (! impConvTest_.is_null ()) {
1002 impConvTest_->setQuorum (defQuorum_);
1004 if (! expConvTest_.is_null ()) {
1005 expConvTest_->setQuorum (defQuorum_);
1010 if (ortho_.is_null ()) {
1011 params_->set(
"Orthogonalization", orthoType_);
1012 if (orthoType_ ==
"DGKS") {
1014 if (orthoKappa_ <= 0) {
1015 ortho_ = rcp (
new ortho_type (label_));
1018 ortho_ = rcp (
new ortho_type (label_));
1019 rcp_dynamic_cast<ortho_type> (ortho_)->setDepTol (orthoKappa_);
1022 else if (orthoType_ ==
"ICGS") {
1024 ortho_ = rcp (
new ortho_type (label_));
1026 else if (orthoType_ ==
"IMGS") {
1028 ortho_ = rcp (
new ortho_type (label_));
1030 #ifdef HAVE_BELOS_TSQR
1031 else if (orthoType_ ==
"TSQR") {
1033 ortho_ = rcp (
new ortho_type (label_));
1035 #endif // HAVE_BELOS_TSQR
1037 #ifdef HAVE_BELOS_TSQR
1038 TEUCHOS_TEST_FOR_EXCEPTION(
1039 orthoType_ !=
"ICGS" && orthoType_ !=
"DGKS" &&
1040 orthoType_ !=
"IMGS" && orthoType_ !=
"TSQR",
1042 "Belos::PseudoBlockGmresSolMgr::setParameters(): "
1043 "Invalid orthogonalization type \"" << orthoType_ <<
"\".");
1045 TEUCHOS_TEST_FOR_EXCEPTION(
1046 orthoType_ !=
"ICGS" && orthoType_ !=
"DGKS" &&
1047 orthoType_ !=
"IMGS",
1049 "Belos::PseudoBlockGmresSolMgr::setParameters(): "
1050 "Invalid orthogonalization type \"" << orthoType_ <<
"\".");
1051 #endif // HAVE_BELOS_TSQR
1056 if (timerSolve_ == Teuchos::null) {
1057 std::string solveLabel = label_ +
": PseudoBlockGmresSolMgr total solve time";
1058 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1059 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
1068 template<
class ScalarType,
class MV,
class OP>
1075 userConvStatusTest_ = userConvStatusTest;
1076 comboType_ = comboType;
1079 template<
class ScalarType,
class MV,
class OP>
1085 debugStatusTest_ = debugStatusTest;
1090 template<
class ScalarType,
class MV,
class OP>
1091 Teuchos::RCP<const Teuchos::ParameterList>
1094 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
1095 if (is_null(validPL)) {
1096 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
1101 pl= Teuchos::rcp(
new Teuchos::ParameterList() );
1103 "The relative residual tolerance that needs to be achieved by the\n"
1104 "iterative solver in order for the linear system to be declared converged.");
1105 pl->set(
"Maximum Restarts",
static_cast<int>(maxRestarts_default_),
1106 "The maximum number of restarts allowed for each\n"
1107 "set of RHS solved.");
1108 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
1109 "The maximum number of block iterations allowed for each\n"
1110 "set of RHS solved.");
1111 pl->set(
"Num Blocks",
static_cast<int>(numBlocks_default_),
1112 "The maximum number of vectors allowed in the Krylov subspace\n"
1113 "for each set of RHS solved.");
1114 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
1115 "The number of RHS solved simultaneously.");
1116 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
1117 "What type(s) of solver information should be outputted\n"
1118 "to the output stream.");
1119 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
1120 "What style is used for the solver information outputted\n"
1121 "to the output stream.");
1122 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
1123 "How often convergence information should be outputted\n"
1124 "to the output stream.");
1125 pl->set(
"Deflation Quorum",
static_cast<int>(defQuorum_default_),
1126 "The number of linear systems that need to converge before\n"
1127 "they are deflated. This number should be <= block size.");
1128 pl->set(
"Output Stream", Teuchos::rcp(outputStream_default_,
false),
1129 "A reference-counted pointer to the output stream where all\n"
1130 "solver output is sent.");
1131 pl->set(
"Show Maximum Residual Norm Only",
static_cast<bool>(showMaxResNormOnly_default_),
1132 "When convergence information is printed, only show the maximum\n"
1133 "relative residual norm when the block size is greater than one.");
1134 pl->set(
"Implicit Residual Scaling",
static_cast<const char *
>(impResScale_default_),
1135 "The type of scaling used in the implicit residual convergence test.");
1136 pl->set(
"Explicit Residual Scaling",
static_cast<const char *
>(expResScale_default_),
1137 "The type of scaling used in the explicit residual convergence test.");
1138 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
1139 "The string to use as a prefix for the timer labels.");
1140 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
1141 "The type of orthogonalization to use.");
1143 "The constant used by DGKS orthogonalization to determine\n"
1144 "whether another step of classical Gram-Schmidt is necessary.");
1145 pl->sublist(
"User Status Tests");
1146 pl->set(
"User Status Tests Combo Type",
"SEQ",
1147 "Type of logical combination operation of user-defined\n"
1148 "and/or solver-specific status tests.");
1155 template<
class ScalarType,
class MV,
class OP>
1167 if ( !Teuchos::is_null(problem_->getLeftPrec()) ) {
1174 Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
1175 Teuchos::rcp(
new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1176 if(impResScale_ ==
"User Provided")
1181 tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1182 impConvTest_ = tmpImpConvTest;
1185 Teuchos::RCP<StatusTestGenResNorm_t> tmpExpConvTest =
1186 Teuchos::rcp(
new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1187 tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit,
Belos::TwoNorm );
1188 if(expResScale_ ==
"User Provided")
1192 tmpExpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1193 expConvTest_ = tmpExpConvTest;
1196 convTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) );
1202 Teuchos::RCP<StatusTestImpResNorm_t> tmpImpConvTest =
1203 Teuchos::rcp(
new StatusTestImpResNorm_t( convtol_, defQuorum_ ) );
1204 if(impResScale_ ==
"User Provided")
1208 tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1209 impConvTest_ = tmpImpConvTest;
1212 expConvTest_ = impConvTest_;
1213 convTest_ = impConvTest_;
1216 if (nonnull(userConvStatusTest_) ) {
1218 convTest_ = Teuchos::rcp(
1219 new StatusTestCombo_t( comboType_, convTest_, userConvStatusTest_ ) );
1226 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
1229 if (nonnull(debugStatusTest_) ) {
1231 Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(sTest_)->addStatusTest( debugStatusTest_ );
1236 StatusTestOutputFactory<ScalarType,MV,OP> stoFactory( outputStyle_, taggedTests_ );
1240 std::string solverDesc =
" Pseudo Block Gmres ";
1241 outputTest_->setSolverDesc( solverDesc );
1252 template<
class ScalarType,
class MV,
class OP>
1258 if (!isSet_) { setParameters( params_ ); }
1260 Teuchos::BLAS<int,ScalarType> blas;
1263 "Belos::PseudoBlockGmresSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1266 if (!isSTSet_ || (!expResTest_ && !Teuchos::is_null(problem_->getLeftPrec())) ) {
1268 "Belos::BlockGmresSolMgr::solve(): Linear problem and requested status tests are incompatible.");
1273 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1274 int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1276 std::vector<int> currIdx( numCurrRHS );
1277 blockSize_ = numCurrRHS;
1278 for (
int i=0; i<numCurrRHS; ++i)
1279 { currIdx[i] = startPtr+i; }
1282 problem_->setLSIndex( currIdx );
1286 Teuchos::ParameterList plist;
1287 plist.set(
"Num Blocks",numBlocks_);
1290 outputTest_->reset();
1291 loaDetected_ =
false;
1294 bool isConverged =
true;
1299 Teuchos::RCP<PseudoBlockGmresIter<ScalarType,MV,OP> > block_gmres_iter
1304 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1305 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1308 while ( numRHS2Solve > 0 ) {
1311 std::vector<int> convRHSIdx;
1312 std::vector<int> currRHSIdx( currIdx );
1313 currRHSIdx.resize(numCurrRHS);
1316 block_gmres_iter->setNumBlocks( numBlocks_ );
1319 block_gmres_iter->resetNumIters();
1322 outputTest_->resetNumCalls();
1328 std::vector<int> index(1);
1329 Teuchos::RCP<MV> tmpV, R_0 = MVT::CloneCopy( *(problem_->getInitPrecResVec()), currIdx );
1330 newState.
V.resize( blockSize_ );
1331 newState.
Z.resize( blockSize_ );
1332 for (
int i=0; i<blockSize_; ++i) {
1334 tmpV = MVT::CloneViewNonConst( *R_0, index );
1337 Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > tmpZ
1338 = Teuchos::rcp(
new Teuchos::SerialDenseVector<int,ScalarType>( 1 ));
1341 int rank = ortho_->normalize( *tmpV, tmpZ );
1343 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors.");
1345 newState.
V[i] = tmpV;
1346 newState.
Z[i] = tmpZ;
1350 block_gmres_iter->initialize(newState);
1351 int numRestarts = 0;
1357 block_gmres_iter->iterate();
1364 if ( convTest_->getStatus() ==
Passed ) {
1366 if ( expConvTest_->getLOADetected() ) {
1376 loaDetected_ =
true;
1378 "Belos::PseudoBlockGmresSolMgr::solve(): Warning! Solver has experienced a loss of accuracy!" << std::endl;
1379 isConverged =
false;
1383 std::vector<int> convIdx = expConvTest_->convIndices();
1387 if (convIdx.size() == currRHSIdx.size())
1394 problem_->setCurrLS();
1398 int curDim = oldState.
curDim;
1403 std::vector<int> oldRHSIdx( currRHSIdx );
1404 std::vector<int> defRHSIdx;
1405 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
1407 for (
unsigned int j=0; j<convIdx.size(); ++j) {
1408 if (currRHSIdx[i] == convIdx[j]) {
1414 defRHSIdx.push_back( i );
1417 defState.
V.push_back( Teuchos::rcp_const_cast<MV>( oldState.
V[i] ) );
1418 defState.
Z.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,ScalarType> >( oldState.
Z[i] ) );
1419 defState.
H.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseMatrix<int,ScalarType> >( oldState.
H[i] ) );
1420 defState.
sn.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,ScalarType> >( oldState.
sn[i] ) );
1421 defState.
cs.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,MagnitudeType> >(oldState.
cs[i] ) );
1422 currRHSIdx[have] = currRHSIdx[i];
1426 defRHSIdx.resize(currRHSIdx.size()-have);
1427 currRHSIdx.resize(have);
1431 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1432 Teuchos::RCP<MV> defUpdate = MVT::CloneViewNonConst( *update, defRHSIdx );
1435 problem_->setLSIndex( convIdx );
1438 problem_->updateSolution( defUpdate,
true );
1442 problem_->setLSIndex( currRHSIdx );
1445 defState.
curDim = curDim;
1448 block_gmres_iter->initialize(defState);
1455 else if ( maxIterTest_->getStatus() ==
Passed ) {
1457 isConverged =
false;
1465 else if ( block_gmres_iter->getCurSubspaceDim() == block_gmres_iter->getMaxSubspaceDim() ) {
1467 if ( numRestarts >= maxRestarts_ ) {
1468 isConverged =
false;
1473 printer_->stream(
Debug) <<
" Performing restart number " << numRestarts <<
" of " << maxRestarts_ << std::endl << std::endl;
1476 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1477 problem_->updateSolution( update,
true );
1484 newstate.
V.resize(currRHSIdx.size());
1485 newstate.
Z.resize(currRHSIdx.size());
1489 R_0 = MVT::Clone( *(problem_->getInitPrecResVec()), currRHSIdx.size() );
1490 problem_->computeCurrPrecResVec( &*R_0 );
1491 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
1494 tmpV = MVT::CloneViewNonConst( *R_0, index );
1497 Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > tmpZ
1498 = Teuchos::rcp(
new Teuchos::SerialDenseVector<int,ScalarType>( 1 ));
1501 int rank = ortho_->normalize( *tmpV, tmpZ );
1503 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors after the restart.");
1505 newstate.
V[i] = tmpV;
1506 newstate.
Z[i] = tmpZ;
1511 block_gmres_iter->initialize(newstate);
1523 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
1524 "Belos::PseudoBlockGmresSolMgr::solve(): Invalid return from PseudoBlockGmresIter::iterate().");
1530 block_gmres_iter->updateLSQR( block_gmres_iter->getCurSubspaceDim() );
1533 sTest_->checkStatus( &*block_gmres_iter );
1534 if (convTest_->getStatus() !=
Passed)
1535 isConverged =
false;
1538 catch (
const std::exception &e) {
1539 printer_->stream(
Errors) <<
"Error! Caught std::exception in PseudoBlockGmresIter::iterate() at iteration "
1540 << block_gmres_iter->getNumIters() << std::endl
1541 << e.what() << std::endl;
1548 if (nonnull(userConvStatusTest_)) {
1550 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1551 problem_->updateSolution( update,
true );
1553 else if (nonnull(expConvTest_->getSolution())) {
1555 Teuchos::RCP<MV> newX = expConvTest_->getSolution();
1556 Teuchos::RCP<MV> curX = problem_->getCurrLHSVec();
1557 MVT::MvAddMv( 0.0, *newX, 1.0, *newX, *curX );
1561 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1562 problem_->updateSolution( update,
true );
1566 problem_->setCurrLS();
1569 startPtr += numCurrRHS;
1570 numRHS2Solve -= numCurrRHS;
1571 if ( numRHS2Solve > 0 ) {
1572 numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1574 blockSize_ = numCurrRHS;
1575 currIdx.resize( numCurrRHS );
1576 for (
int i=0; i<numCurrRHS; ++i)
1577 { currIdx[i] = startPtr+i; }
1580 if (defQuorum_ > blockSize_) {
1581 if (impConvTest_ != Teuchos::null)
1582 impConvTest_->setQuorum( blockSize_ );
1583 if (expConvTest_ != Teuchos::null)
1584 expConvTest_->setQuorum( blockSize_ );
1588 problem_->setLSIndex( currIdx );
1591 currIdx.resize( numRHS2Solve );
1602 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1607 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1611 numIters_ = maxIterTest_->getNumIters();
1624 const std::vector<MagnitudeType>* pTestValues = NULL;
1626 pTestValues = expConvTest_->getTestValue();
1627 if (pTestValues == NULL || pTestValues->size() < 1) {
1628 pTestValues = impConvTest_->getTestValue();
1633 pTestValues = impConvTest_->getTestValue();
1635 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1636 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1637 "getTestValue() method returned NULL. Please report this bug to the "
1638 "Belos developers.");
1639 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1640 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1641 "getTestValue() method returned a vector of length zero. Please report "
1642 "this bug to the Belos developers.");
1647 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1650 if (!isConverged || loaDetected_) {
1657 template<
class ScalarType,
class MV,
class OP>
1660 std::ostringstream out;
1662 out <<
"\"Belos::PseudoBlockGmresSolMgr\": {";
1663 if (this->getObjectLabel () !=
"") {
1664 out <<
"Label: " << this->getObjectLabel () <<
", ";
1666 out <<
"Num Blocks: " << numBlocks_
1667 <<
", Maximum Iterations: " << maxIters_
1668 <<
", Maximum Restarts: " << maxRestarts_
1669 <<
", Convergence Tolerance: " << convtol_
1675 template<
class ScalarType,
class MV,
class OP>
1678 describe (Teuchos::FancyOStream &out,
1679 const Teuchos::EVerbosityLevel verbLevel)
const
1681 using Teuchos::TypeNameTraits;
1682 using Teuchos::VERB_DEFAULT;
1683 using Teuchos::VERB_NONE;
1684 using Teuchos::VERB_LOW;
1691 const Teuchos::EVerbosityLevel vl =
1692 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
1694 if (vl != VERB_NONE) {
1695 Teuchos::OSTab tab0 (out);
1697 out <<
"\"Belos::PseudoBlockGmresSolMgr\":" << endl;
1698 Teuchos::OSTab tab1 (out);
1699 out <<
"Template parameters:" << endl;
1701 Teuchos::OSTab tab2 (out);
1702 out <<
"ScalarType: " << TypeNameTraits<ScalarType>::name () << endl
1703 <<
"MV: " << TypeNameTraits<MV>::name () << endl
1704 <<
"OP: " << TypeNameTraits<OP>::name () << endl;
1706 if (this->getObjectLabel () !=
"") {
1707 out <<
"Label: " << this->getObjectLabel () << endl;
1709 out <<
"Num Blocks: " << numBlocks_ << endl
1710 <<
"Maximum Iterations: " << maxIters_ << endl
1711 <<
"Maximum Restarts: " << maxRestarts_ << endl
1712 <<
"Convergence Tolerance: " << convtol_ << endl;