10#ifndef BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
11#define BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
28#ifdef BELOS_TEUCHOS_TIME_MONITOR
29#include "Teuchos_TimeMonitor.hpp"
90 template<
class ScalarType,
class MV,
class OP>
96 typedef Teuchos::ScalarTraits<ScalarType> SCT;
97 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
98 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
225 const Teuchos::RCP<Teuchos::ParameterList> &pl );
231 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
254 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
255 return Teuchos::tuple(timerSolve_);
348 void setParameters (
const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
override;
410 describe (Teuchos::FancyOStream& out,
411 const Teuchos::EVerbosityLevel verbLevel =
412 Teuchos::Describable::verbLevel_default)
const override;
435 bool checkStatusTest();
438 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
441 Teuchos::RCP<OutputManager<ScalarType> > printer_;
442 Teuchos::RCP<std::ostream> outputStream_;
445 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > userConvStatusTest_;
446 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > debugStatusTest_;
447 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
448 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
449 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
450 Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > impConvTest_, expConvTest_;
451 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
453 Teuchos::RCP<std::map<std::string, Teuchos::RCP<StatusTest<ScalarType, MV, OP> > > > taggedTests_;
456 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
459 Teuchos::RCP<Teuchos::ParameterList> params_;
462 static constexpr int maxRestarts_default_ = 20;
463 static constexpr int maxIters_default_ = 1000;
464 static constexpr bool showMaxResNormOnly_default_ =
false;
465 static constexpr int blockSize_default_ = 1;
466 static constexpr int numBlocks_default_ = 300;
469 static constexpr int outputFreq_default_ = -1;
470 static constexpr int defQuorum_default_ = 1;
471 static constexpr const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
472 static constexpr const char * expResScale_default_ =
"Norm of Initial Residual";
473 static constexpr const char * label_default_ =
"Belos";
474 static constexpr const char * orthoType_default_ =
"ICGS";
477 MagnitudeType convtol_, orthoKappa_, achievedTol_;
478 int maxRestarts_, maxIters_, numIters_;
479 int blockSize_, numBlocks_, verbosity_, outputStyle_, outputFreq_, defQuorum_;
480 bool showMaxResNormOnly_;
481 std::string orthoType_;
482 std::string impResScale_, expResScale_;
483 MagnitudeType resScaleFactor_;
487 Teuchos::RCP<Teuchos::Time> timerSolve_;
490 bool isSet_, isSTSet_, expResTest_;
496template<
class ScalarType,
class MV,
class OP>
498 outputStream_(Teuchos::rcpFromRef(std::cout)),
499 taggedTests_(Teuchos::null),
502 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
503 maxRestarts_(maxRestarts_default_),
504 maxIters_(maxIters_default_),
506 blockSize_(blockSize_default_),
507 numBlocks_(numBlocks_default_),
508 verbosity_(verbosity_default_),
509 outputStyle_(outputStyle_default_),
510 outputFreq_(outputFreq_default_),
511 defQuorum_(defQuorum_default_),
512 showMaxResNormOnly_(showMaxResNormOnly_default_),
513 orthoType_(orthoType_default_),
514 impResScale_(impResScale_default_),
515 expResScale_(expResScale_default_),
517 label_(label_default_),
525template<
class ScalarType,
class MV,
class OP>
528 const Teuchos::RCP<Teuchos::ParameterList> &pl) :
530 outputStream_(Teuchos::rcpFromRef(std::cout)),
531 taggedTests_(Teuchos::null),
534 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
535 maxRestarts_(maxRestarts_default_),
536 maxIters_(maxIters_default_),
538 blockSize_(blockSize_default_),
539 numBlocks_(numBlocks_default_),
540 verbosity_(verbosity_default_),
541 outputStyle_(outputStyle_default_),
542 outputFreq_(outputFreq_default_),
543 defQuorum_(defQuorum_default_),
544 showMaxResNormOnly_(showMaxResNormOnly_default_),
545 orthoType_(orthoType_default_),
546 impResScale_(impResScale_default_),
547 expResScale_(expResScale_default_),
549 label_(label_default_),
555 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument,
"Problem not given to solver manager.");
564template<
class ScalarType,
class MV,
class OP>
567setParameters (
const Teuchos::RCP<Teuchos::ParameterList>& params)
569 using Teuchos::ParameterList;
570 using Teuchos::parameterList;
572 using Teuchos::rcp_dynamic_cast;
575 if (params_ == Teuchos::null) {
587 if (params->isParameter (
"Maximum Restarts")) {
588 maxRestarts_ = params->get (
"Maximum Restarts", maxRestarts_default_);
591 params_->set (
"Maximum Restarts", maxRestarts_);
595 if (params->isParameter (
"Maximum Iterations")) {
596 maxIters_ = params->get (
"Maximum Iterations", maxIters_default_);
599 params_->set (
"Maximum Iterations", maxIters_);
600 if (! maxIterTest_.is_null ()) {
601 maxIterTest_->setMaxIters (maxIters_);
606 if (params->isParameter (
"Block Size")) {
607 blockSize_ = params->get (
"Block Size", blockSize_default_);
608 TEUCHOS_TEST_FOR_EXCEPTION(
609 blockSize_ <= 0, std::invalid_argument,
610 "Belos::PseudoBlockGmresSolMgr::setParameters: "
611 "The \"Block Size\" parameter must be strictly positive, "
612 "but you specified a value of " << blockSize_ <<
".");
615 params_->set (
"Block Size", blockSize_);
619 if (params->isParameter (
"Num Blocks")) {
620 numBlocks_ = params->get (
"Num Blocks", numBlocks_default_);
621 TEUCHOS_TEST_FOR_EXCEPTION(
622 numBlocks_ <= 0, std::invalid_argument,
623 "Belos::PseudoBlockGmresSolMgr::setParameters: "
624 "The \"Num Blocks\" parameter must be strictly positive, "
625 "but you specified a value of " << numBlocks_ <<
".");
628 params_->set (
"Num Blocks", numBlocks_);
632 if (params->isParameter (
"Timer Label")) {
633 const std::string tempLabel = params->get (
"Timer Label", label_default_);
636 if (tempLabel != label_) {
638 params_->set (
"Timer Label", label_);
639 const std::string solveLabel =
640 label_ +
": PseudoBlockGmresSolMgr total solve time";
641#ifdef BELOS_TEUCHOS_TIME_MONITOR
642 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
644 if (ortho_ != Teuchos::null) {
645 ortho_->setLabel( label_ );
652 if (params->isParameter (
"Verbosity")) {
653 if (Teuchos::isParameterType<int> (*params,
"Verbosity")) {
654 verbosity_ = params->get (
"Verbosity", verbosity_default_);
656 verbosity_ = (int) Teuchos::getParameter<Belos::MsgType> (*params,
"Verbosity");
660 params_->set (
"Verbosity", verbosity_);
661 if (! printer_.is_null ()) {
662 printer_->setVerbosity (verbosity_);
667 if (params->isParameter (
"Output Style")) {
668 if (Teuchos::isParameterType<int> (*params,
"Output Style")) {
669 outputStyle_ = params->get (
"Output Style", outputStyle_default_);
671 outputStyle_ = (int) Teuchos::getParameter<Belos::OutputType> (*params,
"Output Style");
675 params_->set (
"Output Style", outputStyle_);
676 if (! outputTest_.is_null ()) {
683 if (params->isSublist (
"User Status Tests")) {
684 Teuchos::ParameterList userStatusTestsList = params->sublist(
"User Status Tests",
true);
685 if ( userStatusTestsList.numParams() > 0 ) {
686 std::string userCombo_string = params->get<std::string>(
"User Status Tests Combo Type",
"SEQ");
688 setUserConvStatusTest( testFactory->buildStatusTests(userStatusTestsList), testFactory->stringToComboType(userCombo_string) );
689 taggedTests_ = testFactory->getTaggedTests();
695 if (params->isParameter (
"Output Stream")) {
696 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> > (*params,
"Output Stream");
699 params_->set(
"Output Stream", outputStream_);
700 if (! printer_.is_null ()) {
701 printer_->setOStream (outputStream_);
707 if (params->isParameter (
"Output Frequency")) {
708 outputFreq_ = params->get (
"Output Frequency", outputFreq_default_);
712 params_->set (
"Output Frequency", outputFreq_);
713 if (! outputTest_.is_null ()) {
714 outputTest_->setOutputFrequency (outputFreq_);
719 if (printer_.is_null ()) {
724 bool changedOrthoType =
false;
725 if (params->isParameter (
"Orthogonalization")) {
726 std::string tempOrthoType = params->get (
"Orthogonalization", orthoType_default_);
727 if (tempOrthoType != orthoType_) {
728 orthoType_ = tempOrthoType;
729 changedOrthoType =
true;
732 params_->set(
"Orthogonalization", orthoType_);
735 if (params->isParameter (
"Orthogonalization Constant")) {
736 if (params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
737 orthoKappa_ = params->get (
"Orthogonalization Constant",
741 orthoKappa_ = params->get (
"Orthogonalization Constant",
746 params_->set (
"Orthogonalization Constant", orthoKappa_);
747 if (orthoType_ ==
"DGKS") {
748 if (orthoKappa_ > 0 && ! ortho_.is_null() && !changedOrthoType) {
750 rcp_dynamic_cast<ortho_type> (ortho_)->
setDepTol (orthoKappa_);
756 if (ortho_.is_null() || changedOrthoType) {
758 Teuchos::RCP<Teuchos::ParameterList> paramsOrtho;
759 if (orthoType_==
"DGKS" && orthoKappa_ > 0) {
760 paramsOrtho = Teuchos::rcp(
new Teuchos::ParameterList());
761 paramsOrtho->set (
"depTol", orthoKappa_ );
764 ortho_ = factory.
makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_, paramsOrtho);
770 if (params->isParameter (
"Convergence Tolerance")) {
771 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
772 convtol_ = params->get (
"Convergence Tolerance",
780 params_->set (
"Convergence Tolerance", convtol_);
781 if (! impConvTest_.is_null ()) {
782 impConvTest_->setTolerance (convtol_);
784 if (! expConvTest_.is_null ()) {
785 expConvTest_->setTolerance (convtol_);
790 bool userDefinedResidualScalingUpdated =
false;
791 if (params->isParameter (
"User Defined Residual Scaling")) {
793 if (params->isType<MagnitudeType> (
"User Defined Residual Scaling")) {
794 tempResScaleFactor = params->get (
"User Defined Residual Scaling",
798 tempResScaleFactor = params->get (
"User Defined Residual Scaling",
803 if (resScaleFactor_ != tempResScaleFactor) {
804 resScaleFactor_ = tempResScaleFactor;
805 userDefinedResidualScalingUpdated =
true;
808 if(userDefinedResidualScalingUpdated)
810 if (! params->isParameter (
"Implicit Residual Scaling") && ! impConvTest_.is_null ()) {
812 if(impResScale_ ==
"User Provided")
815 catch (std::exception& e) {
820 if (! params->isParameter (
"Explicit Residual Scaling") && ! expConvTest_.is_null ()) {
822 if(expResScale_ ==
"User Provided")
825 catch (std::exception& e) {
834 if (params->isParameter (
"Implicit Residual Scaling")) {
835 const std::string tempImpResScale =
836 Teuchos::getParameter<std::string> (*params,
"Implicit Residual Scaling");
839 if (impResScale_ != tempImpResScale) {
841 impResScale_ = tempImpResScale;
844 params_->set (
"Implicit Residual Scaling", impResScale_);
845 if (! impConvTest_.is_null ()) {
847 if(impResScale_ ==
"User Provided")
848 impConvTest_->defineScaleForm (impResScaleType,
Belos::TwoNorm, resScaleFactor_);
852 catch (std::exception& e) {
858 else if (userDefinedResidualScalingUpdated) {
861 if (! impConvTest_.is_null ()) {
863 if(impResScale_ ==
"User Provided")
864 impConvTest_->defineScaleForm (impResScaleType,
Belos::TwoNorm, resScaleFactor_);
866 catch (std::exception& e) {
874 if (params->isParameter (
"Explicit Residual Scaling")) {
875 const std::string tempExpResScale =
876 Teuchos::getParameter<std::string> (*params,
"Explicit Residual Scaling");
879 if (expResScale_ != tempExpResScale) {
881 expResScale_ = tempExpResScale;
884 params_->set (
"Explicit Residual Scaling", expResScale_);
885 if (! expConvTest_.is_null ()) {
887 if(expResScale_ ==
"User Provided")
888 expConvTest_->defineScaleForm (expResScaleType,
Belos::TwoNorm, resScaleFactor_);
892 catch (std::exception& e) {
898 else if (userDefinedResidualScalingUpdated) {
901 if (! expConvTest_.is_null ()) {
903 if(expResScale_ ==
"User Provided")
904 expConvTest_->defineScaleForm (expResScaleType,
Belos::TwoNorm, resScaleFactor_);
906 catch (std::exception& e) {
915 if (params->isParameter (
"Show Maximum Residual Norm Only")) {
916 showMaxResNormOnly_ =
917 Teuchos::getParameter<bool> (*params,
"Show Maximum Residual Norm Only");
920 params_->set (
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
921 if (! impConvTest_.is_null ()) {
922 impConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
924 if (! expConvTest_.is_null ()) {
925 expConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
932 if (params->isParameter(
"Deflation Quorum")) {
933 defQuorum_ = params->get(
"Deflation Quorum", defQuorum_);
934 TEUCHOS_TEST_FOR_EXCEPTION(
935 defQuorum_ > blockSize_, std::invalid_argument,
936 "Belos::PseudoBlockGmresSolMgr::setParameters: "
937 "The \"Deflation Quorum\" parameter (= " << defQuorum_ <<
") must not be "
938 "larger than \"Block Size\" (= " << blockSize_ <<
").");
939 params_->set (
"Deflation Quorum", defQuorum_);
940 if (! impConvTest_.is_null ()) {
941 impConvTest_->setQuorum (defQuorum_);
943 if (! expConvTest_.is_null ()) {
944 expConvTest_->setQuorum (defQuorum_);
949 if (timerSolve_ == Teuchos::null) {
950 std::string solveLabel = label_ +
": PseudoBlockGmresSolMgr total solve time";
951#ifdef BELOS_TEUCHOS_TIME_MONITOR
952 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
961template<
class ScalarType,
class MV,
class OP>
968 userConvStatusTest_ = userConvStatusTest;
969 comboType_ = comboType;
972template<
class ScalarType,
class MV,
class OP>
978 debugStatusTest_ = debugStatusTest;
983template<
class ScalarType,
class MV,
class OP>
984Teuchos::RCP<const Teuchos::ParameterList>
987 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
988 if (is_null(validPL)) {
989 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
994 pl= Teuchos::rcp(
new Teuchos::ParameterList() );
996 "The relative residual tolerance that needs to be achieved by the\n"
997 "iterative solver in order for the linear system to be declared converged.");
998 pl->set(
"Maximum Restarts",
static_cast<int>(maxRestarts_default_),
999 "The maximum number of restarts allowed for each\n"
1000 "set of RHS solved.");
1001 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
1002 "The maximum number of block iterations allowed for each\n"
1003 "set of RHS solved.");
1004 pl->set(
"Num Blocks",
static_cast<int>(numBlocks_default_),
1005 "The maximum number of vectors allowed in the Krylov subspace\n"
1006 "for each set of RHS solved.");
1007 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
1008 "The number of RHS solved simultaneously.");
1009 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
1010 "What type(s) of solver information should be outputted\n"
1011 "to the output stream.");
1012 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
1013 "What style is used for the solver information outputted\n"
1014 "to the output stream.");
1015 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
1016 "How often convergence information should be outputted\n"
1017 "to the output stream.");
1018 pl->set(
"Deflation Quorum",
static_cast<int>(defQuorum_default_),
1019 "The number of linear systems that need to converge before\n"
1020 "they are deflated. This number should be <= block size.");
1021 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
1022 "A reference-counted pointer to the output stream where all\n"
1023 "solver output is sent.");
1024 pl->set(
"Show Maximum Residual Norm Only",
static_cast<bool>(showMaxResNormOnly_default_),
1025 "When convergence information is printed, only show the maximum\n"
1026 "relative residual norm when the block size is greater than one.");
1027 pl->set(
"Implicit Residual Scaling",
static_cast<const char *
>(impResScale_default_),
1028 "The type of scaling used in the implicit residual convergence test.");
1029 pl->set(
"Explicit Residual Scaling",
static_cast<const char *
>(expResScale_default_),
1030 "The type of scaling used in the explicit residual convergence test.");
1031 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
1032 "The string to use as a prefix for the timer labels.");
1033 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
1034 "The type of orthogonalization to use.");
1036 "The constant used by DGKS orthogonalization to determine\n"
1037 "whether another step of classical Gram-Schmidt is necessary.");
1038 pl->sublist(
"User Status Tests");
1039 pl->set(
"User Status Tests Combo Type",
"SEQ",
1040 "Type of logical combination operation of user-defined\n"
1041 "and/or solver-specific status tests.");
1048template<
class ScalarType,
class MV,
class OP>
1049bool PseudoBlockGmresSolMgr<ScalarType,MV,OP>::checkStatusTest() {
1060 if ( !Teuchos::is_null(problem_->getLeftPrec()) ) {
1067 Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
1068 Teuchos::rcp(
new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1069 if(impResScale_ ==
"User Provided")
1074 tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1075 impConvTest_ = tmpImpConvTest;
1078 Teuchos::RCP<StatusTestGenResNorm_t> tmpExpConvTest =
1079 Teuchos::rcp(
new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1080 tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit,
Belos::TwoNorm );
1081 if(expResScale_ ==
"User Provided")
1085 tmpExpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1086 expConvTest_ = tmpExpConvTest;
1089 convTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) );
1095 Teuchos::RCP<StatusTestImpResNorm_t> tmpImpConvTest =
1096 Teuchos::rcp(
new StatusTestImpResNorm_t( convtol_, defQuorum_ ) );
1097 if(impResScale_ ==
"User Provided")
1101 tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1102 impConvTest_ = tmpImpConvTest;
1105 expConvTest_ = impConvTest_;
1106 convTest_ = impConvTest_;
1109 if (nonnull(userConvStatusTest_) ) {
1111 Teuchos::RCP<StatusTestCombo_t> tmpComboTest = Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(userConvStatusTest_);
1112 if (tmpComboTest != Teuchos::null) {
1113 std::vector<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > tmpVec = tmpComboTest->getStatusTests();
1114 comboType_ = tmpComboTest->getComboType();
1115 const int numResTests =
static_cast<int>(tmpVec.size());
1116 auto newConvTest = Teuchos::rcp(
new StatusTestCombo_t(comboType_));
1117 newConvTest->addStatusTest(convTest_);
1118 for (
int j = 0; j < numResTests; ++j) {
1119 newConvTest->addStatusTest(tmpVec[j]);
1121 convTest_ = newConvTest;
1125 convTest_ = Teuchos::rcp(
1126 new StatusTestCombo_t( comboType_, convTest_, userConvStatusTest_ ) );
1134 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
1137 if (nonnull(debugStatusTest_) ) {
1139 Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(sTest_)->addStatusTest( debugStatusTest_ );
1148 std::string solverDesc =
" Pseudo Block Gmres ";
1149 outputTest_->setSolverDesc( solverDesc );
1160template<
class ScalarType,
class MV,
class OP>
1169 "Belos::PseudoBlockGmresSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1172 if (!isSTSet_ || (!expResTest_ && !Teuchos::is_null(problem_->getLeftPrec())) ) {
1174 "Belos::BlockGmresSolMgr::solve(): Linear problem and requested status tests are incompatible.");
1180 int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1182 std::vector<int> currIdx( numCurrRHS );
1183 blockSize_ = numCurrRHS;
1184 for (
int i=0; i<numCurrRHS; ++i)
1185 { currIdx[i] = startPtr+i; }
1188 problem_->setLSIndex( currIdx );
1192 Teuchos::ParameterList plist;
1193 plist.set(
"Num Blocks",numBlocks_);
1196 outputTest_->reset();
1197 loaDetected_ =
false;
1200 bool isConverged =
true;
1205 Teuchos::RCP<PseudoBlockGmresIter<ScalarType,MV,OP> > block_gmres_iter
1210#ifdef BELOS_TEUCHOS_TIME_MONITOR
1211 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1214 while ( numRHS2Solve > 0 ) {
1217 std::vector<int> convRHSIdx;
1218 std::vector<int> currRHSIdx( currIdx );
1219 currRHSIdx.resize(numCurrRHS);
1222 block_gmres_iter->setNumBlocks( numBlocks_ );
1225 block_gmres_iter->resetNumIters();
1228 outputTest_->resetNumCalls();
1234 std::vector<int> index(1);
1235 Teuchos::RCP<MV> tmpV, R_0 =
MVT::CloneCopy( *(problem_->getInitPrecResVec()), currIdx );
1236 newState.
V.resize( blockSize_ );
1237 newState.
Z.resize( blockSize_ );
1238 for (
int i=0; i<blockSize_; ++i) {
1243 Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > tmpZ
1244 = Teuchos::rcp(
new Teuchos::SerialDenseVector<int,ScalarType>( 1 ));
1247 int rank = ortho_->normalize( *tmpV, tmpZ );
1249 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors.");
1251 newState.
V[i] = tmpV;
1252 newState.
Z[i] = tmpZ;
1256 block_gmres_iter->initialize(newState);
1257 int numRestarts = 0;
1263 block_gmres_iter->iterate();
1270 if ( convTest_->getStatus() ==
Passed ) {
1272 if ( expConvTest_->getLOADetected() ) {
1282 loaDetected_ =
true;
1284 "Belos::PseudoBlockGmresSolMgr::solve(): Warning! Solver has experienced a loss of accuracy!" << std::endl;
1285 isConverged =
false;
1289 std::vector<int> convIdx = expConvTest_->convIndices();
1293 if (convIdx.size() == currRHSIdx.size())
1300 problem_->setCurrLS();
1304 int curDim = oldState.
curDim;
1309 std::vector<int> oldRHSIdx( currRHSIdx );
1310 std::vector<int> defRHSIdx;
1311 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
1313 for (
unsigned int j=0; j<convIdx.size(); ++j) {
1314 if (currRHSIdx[i] == convIdx[j]) {
1320 defRHSIdx.push_back( i );
1323 defState.
V.push_back( Teuchos::rcp_const_cast<MV>( oldState.
V[i] ) );
1324 defState.
Z.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,ScalarType> >( oldState.
Z[i] ) );
1325 defState.
H.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseMatrix<int,ScalarType> >( oldState.
H[i] ) );
1326 defState.
sn.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,ScalarType> >( oldState.
sn[i] ) );
1327 defState.
cs.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,MagnitudeType> >(oldState.
cs[i] ) );
1328 currRHSIdx[have] = currRHSIdx[i];
1332 defRHSIdx.resize(currRHSIdx.size()-have);
1333 currRHSIdx.resize(have);
1337 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1341 problem_->setLSIndex( convIdx );
1344 problem_->updateSolution( defUpdate,
true );
1348 problem_->setLSIndex( currRHSIdx );
1351 defState.
curDim = curDim;
1354 block_gmres_iter->initialize(defState);
1361 else if ( maxIterTest_->getStatus() ==
Passed ) {
1363 isConverged =
false;
1371 else if ( block_gmres_iter->getCurSubspaceDim() == block_gmres_iter->getMaxSubspaceDim() ) {
1373 if ( numRestarts >= maxRestarts_ ) {
1374 isConverged =
false;
1379 printer_->stream(
Debug) <<
" Performing restart number " << numRestarts <<
" of " << maxRestarts_ << std::endl << std::endl;
1382 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1383 problem_->updateSolution( update,
true );
1390 newstate.
V.resize(currRHSIdx.size());
1391 newstate.
Z.resize(currRHSIdx.size());
1395 R_0 =
MVT::Clone( *(problem_->getInitPrecResVec()), currRHSIdx.size() );
1396 problem_->computeCurrPrecResVec( &*R_0 );
1397 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
1403 Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > tmpZ
1404 = Teuchos::rcp(
new Teuchos::SerialDenseVector<int,ScalarType>( 1 ));
1407 int rank = ortho_->normalize( *tmpV, tmpZ );
1409 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors after the restart.");
1411 newstate.
V[i] = tmpV;
1412 newstate.
Z[i] = tmpZ;
1417 block_gmres_iter->initialize(newstate);
1429 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
1430 "Belos::PseudoBlockGmresSolMgr::solve(): Invalid return from PseudoBlockGmresIter::iterate().");
1436 block_gmres_iter->updateLSQR( block_gmres_iter->getCurSubspaceDim() );
1439 sTest_->checkStatus( &*block_gmres_iter );
1440 if (convTest_->getStatus() !=
Passed)
1441 isConverged =
false;
1446 achievedTol_ = MT::one();
1447 Teuchos::RCP<MV> X = problem_->getLHS();
1449 printer_->stream(
Warnings) <<
"Belos::PseudoBlockGmresSolMgr::solve(): Warning! NaN has been detected!"
1453 catch (
const std::exception &e) {
1454 printer_->stream(
Errors) <<
"Error! Caught std::exception in PseudoBlockGmresIter::iterate() at iteration "
1455 << block_gmres_iter->getNumIters() << std::endl
1456 << e.what() << std::endl;
1463 if (nonnull(userConvStatusTest_)) {
1465 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1466 problem_->updateSolution( update,
true );
1468 else if (nonnull(expConvTest_->getSolution())) {
1470 Teuchos::RCP<MV> newX = expConvTest_->getSolution();
1471 Teuchos::RCP<MV> curX = problem_->getCurrLHSVec();
1476 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1477 problem_->updateSolution( update,
true );
1481 problem_->setCurrLS();
1484 startPtr += numCurrRHS;
1485 numRHS2Solve -= numCurrRHS;
1486 if ( numRHS2Solve > 0 ) {
1487 numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1489 blockSize_ = numCurrRHS;
1490 currIdx.resize( numCurrRHS );
1491 for (
int i=0; i<numCurrRHS; ++i)
1492 { currIdx[i] = startPtr+i; }
1495 if (defQuorum_ > blockSize_) {
1496 if (impConvTest_ != Teuchos::null)
1497 impConvTest_->setQuorum( blockSize_ );
1498 if (expConvTest_ != Teuchos::null)
1499 expConvTest_->setQuorum( blockSize_ );
1503 problem_->setLSIndex( currIdx );
1506 currIdx.resize( numRHS2Solve );
1517#ifdef BELOS_TEUCHOS_TIME_MONITOR
1522 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1526 numIters_ = maxIterTest_->getNumIters();
1539 const std::vector<MagnitudeType>* pTestValues = NULL;
1541 pTestValues = expConvTest_->getTestValue();
1542 if (pTestValues == NULL || pTestValues->size() < 1) {
1543 pTestValues = impConvTest_->getTestValue();
1548 pTestValues = impConvTest_->getTestValue();
1550 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1551 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1552 "getTestValue() method returned NULL. Please report this bug to the "
1553 "Belos developers.");
1554 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1555 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1556 "getTestValue() method returned a vector of length zero. Please report "
1557 "this bug to the Belos developers.");
1562 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1565 if (!isConverged || loaDetected_) {
1572template<
class ScalarType,
class MV,
class OP>
1575 std::ostringstream out;
1577 out <<
"\"Belos::PseudoBlockGmresSolMgr\": {";
1578 if (this->getObjectLabel () !=
"") {
1579 out <<
"Label: " << this->getObjectLabel () <<
", ";
1581 out <<
"Num Blocks: " << numBlocks_
1582 <<
", Maximum Iterations: " << maxIters_
1583 <<
", Maximum Restarts: " << maxRestarts_
1584 <<
", Convergence Tolerance: " << convtol_
1590template<
class ScalarType,
class MV,
class OP>
1593describe (Teuchos::FancyOStream &out,
1594 const Teuchos::EVerbosityLevel verbLevel)
const
1596 using Teuchos::TypeNameTraits;
1597 using Teuchos::VERB_DEFAULT;
1598 using Teuchos::VERB_NONE;
1599 using Teuchos::VERB_LOW;
1606 const Teuchos::EVerbosityLevel vl =
1607 (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
1609 if (vl != VERB_NONE) {
1610 Teuchos::OSTab tab0 (out);
1612 out <<
"\"Belos::PseudoBlockGmresSolMgr\":" << endl;
1613 Teuchos::OSTab tab1 (out);
1614 out <<
"Template parameters:" << endl;
1616 Teuchos::OSTab tab2 (out);
1617 out <<
"ScalarType: " << TypeNameTraits<ScalarType>::name () << endl
1618 <<
"MV: " << TypeNameTraits<MV>::name () << endl
1619 <<
"OP: " << TypeNameTraits<OP>::name () << endl;
1621 if (this->getObjectLabel () !=
"") {
1622 out <<
"Label: " << this->getObjectLabel () << endl;
1624 out <<
"Num Blocks: " << numBlocks_ << endl
1625 <<
"Maximum Iterations: " << maxIters_ << endl
1626 <<
"Maximum Restarts: " << maxRestarts_ << endl
1627 <<
"Convergence Tolerance: " << convtol_ << endl;
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.
Traits class which defines basic operations on multivectors.
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
Creates a new MV and copies contents of mv into the new vector (deep copy).
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
static Teuchos::RCP< MV > CloneViewNonConst(MV &mv, const std::vector< int > &index)
Creates a new MV that shares the selected contents of mv (shallow copy).
static void MvAddMv(const ScalarType alpha, const MV &A, const ScalarType beta, const MV &B, MV &mv)
Replace mv with .
static void MvInit(MV &mv, const ScalarType alpha=Teuchos::ScalarTraits< ScalarType >::zero())
Replace each element of the vectors in mv with alpha.
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in 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 > > 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...
PseudoBlockGmresIterOrthoFailure is thrown when the orthogonalization manager is unable to generate o...
This class implements the pseudo-block GMRES iteration, where a block Krylov subspace is constructed ...
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)
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
bool isLOADetected() const override
Whether a "loss of accuracy" was detected during the last solve().
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.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
A list of valid default parameters for this solver.
PseudoBlockGmresSolMgr()
Empty constructor.
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > ¶ms) override
Set the parameters the solver manager should use to solve the linear problem.
ReturnType solve() override
This method performs possibly repeated calls to the underlying linear solver's iterate() routine unti...
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
const StatusTestResNorm< ScalarType, MV, OP > * getResidualStatusTest() const
Return the residual status test.
void setDebugStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &debugStatusTest) override
Set a debug status test that will be checked at the same time as the top-level status test.
std::string description() const override
Return a one-line description of this object.
virtual void setUserConvStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &userConvStatusTest, const typename StatusTestCombo< ScalarType, MV, OP >::ComboType &comboType=StatusTestCombo< ScalarType, MV, OP >::SEQ) override
Set a custom status test.
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
const LinearProblem< ScalarType, MV, OP > & getProblem() const override
Return a reference to the linear problem being solved by this solver manager.
virtual ~PseudoBlockGmresSolMgr()
Destructor.
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
The current parameters for this solver.
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) override
Set the linear problem to solve.
int getNumIters() const override
Iteration count for the most recent call to solve().
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.
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.
A pure virtual class for defining the status tests for the Belos iterative solvers.
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.
std::vector< Teuchos::RCP< const Teuchos::SerialDenseVector< int, ScalarType > > > sn
The current Given's rotation coefficients.
std::vector< Teuchos::RCP< const MV > > V
The current Krylov basis.
std::vector< Teuchos::RCP< const Teuchos::SerialDenseVector< int, ScalarType > > > Z
The current right-hand side of the least squares system RY = Z.
std::vector< Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > > H
The current Hessenberg matrix.
std::vector< Teuchos::RCP< const Teuchos::SerialDenseVector< int, MagnitudeType > > > cs
int curDim
The current dimension of the reduction.