10 #ifndef BELOS_RCG_SOLMGR_HPP
11 #define BELOS_RCG_SOLMGR_HPP
31 #ifdef BELOS_TEUCHOS_TIME_MONITOR
111 template<
class ScalarType,
class MV,
class OP,
112 const bool supportsScalarType =
117 Belos::Details::LapackSupportsScalar<ScalarType>::value &&
118 ! Teuchos::ScalarTraits<ScalarType>::isComplex>
120 static const bool scalarTypeIsSupported =
145 template<
class ScalarType,
class MV,
class OP>
219 return Teuchos::tuple(timerSolve_);
293 std::string description()
const override;
309 void sort(std::vector<ScalarType>& dlist,
int n, std::vector<int>& iperm);
312 void initializeStateStorage();
331 static constexpr
int maxIters_default_ = 1000;
332 static constexpr
int blockSize_default_ = 1;
333 static constexpr
int numBlocks_default_ = 25;
334 static constexpr
int recycleBlocks_default_ = 3;
335 static constexpr
bool showMaxResNormOnly_default_ =
false;
338 static constexpr
int outputFreq_default_ = -1;
339 static constexpr
const char * label_default_ =
"Belos";
346 MagnitudeType convtol_;
352 MagnitudeType achievedTol_;
360 int numBlocks_, recycleBlocks_;
361 bool showMaxResNormOnly_;
362 int verbosity_, outputStyle_, outputFreq_;
437 template<
class ScalarType,
class MV,
class OP>
446 template<
class ScalarType,
class MV,
class OP>
464 template<
class ScalarType,
class MV,
class OP>
467 outputStream_ = Teuchos::rcpFromRef(std::cout);
469 maxIters_ = maxIters_default_;
470 numBlocks_ = numBlocks_default_;
471 recycleBlocks_ = recycleBlocks_default_;
472 verbosity_ = verbosity_default_;
473 outputStyle_= outputStyle_default_;
474 outputFreq_= outputFreq_default_;
475 showMaxResNormOnly_ = showMaxResNormOnly_default_;
476 label_ = label_default_;
487 Alpha_ = Teuchos::null;
488 Beta_ = Teuchos::null;
490 Delta_ = Teuchos::null;
491 UTAU_ = Teuchos::null;
492 LUUTAU_ = Teuchos::null;
493 ipiv_ = Teuchos::null;
494 AUTAU_ = Teuchos::null;
495 rTz_old_ = Teuchos::null;
500 DeltaL2_ = Teuchos::null;
501 AU1TUDeltaL2_ = Teuchos::null;
502 AU1TAU1_ = Teuchos::null;
503 AU1TU1_ = Teuchos::null;
504 AU1TAP_ = Teuchos::null;
507 APTAP_ = Teuchos::null;
508 U1Y1_ = Teuchos::null;
509 PY2_ = Teuchos::null;
510 AUTAP_ = Teuchos::null;
511 AU1TU_ = Teuchos::null;
515 template<
class ScalarType,
class MV,
class OP>
519 if (params_ == Teuchos::null) {
528 maxIters_ = params->
get(
"Maximum Iterations",maxIters_default_);
531 params_->set(
"Maximum Iterations", maxIters_);
532 if (maxIterTest_!=Teuchos::null)
533 maxIterTest_->setMaxIters( maxIters_ );
538 numBlocks_ = params->
get(
"Num Blocks",numBlocks_default_);
540 "Belos::RCGSolMgr: \"Num Blocks\" must be strictly positive.");
543 params_->set(
"Num Blocks", numBlocks_);
548 recycleBlocks_ = params->
get(
"Num Recycled Blocks",recycleBlocks_default_);
550 "Belos::RCGSolMgr: \"Num Recycled Blocks\" must be strictly positive.");
553 "Belos::RCGSolMgr: \"Num Recycled Blocks\" must be less than \"Num Blocks\".");
556 params_->set(
"Num Recycled Blocks", recycleBlocks_);
561 std::string tempLabel = params->
get(
"Timer Label", label_default_);
564 if (tempLabel != label_) {
566 params_->set(
"Timer Label", label_);
567 std::string solveLabel = label_ +
": RCGSolMgr total solve time";
568 #ifdef BELOS_TEUCHOS_TIME_MONITOR
576 if (Teuchos::isParameterType<int>(*params,
"Verbosity")) {
577 verbosity_ = params->
get(
"Verbosity", verbosity_default_);
579 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,
"Verbosity");
583 params_->set(
"Verbosity", verbosity_);
584 if (printer_ != Teuchos::null)
585 printer_->setVerbosity(verbosity_);
590 if (Teuchos::isParameterType<int>(*params,
"Output Style")) {
591 outputStyle_ = params->
get(
"Output Style", outputStyle_default_);
593 outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,
"Output Style");
597 params_->set(
"Output Style", outputStyle_);
598 outputTest_ = Teuchos::null;
603 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
606 params_->set(
"Output Stream", outputStream_);
607 if (printer_ != Teuchos::null)
608 printer_->setOStream( outputStream_ );
614 outputFreq_ = params->
get(
"Output Frequency", outputFreq_default_);
618 params_->set(
"Output Frequency", outputFreq_);
619 if (outputTest_ != Teuchos::null)
620 outputTest_->setOutputFrequency( outputFreq_ );
624 if (printer_ == Teuchos::null) {
633 if (params->
isParameter(
"Convergence Tolerance")) {
634 if (params->
isType<MagnitudeType> (
"Convergence Tolerance")) {
635 convtol_ = params->
get (
"Convergence Tolerance",
643 params_->set(
"Convergence Tolerance", convtol_);
644 if (convTest_ != Teuchos::null)
645 convTest_->setTolerance( convtol_ );
648 if (params->
isParameter(
"Show Maximum Residual Norm Only")) {
649 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,
"Show Maximum Residual Norm Only");
652 params_->set(
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
653 if (convTest_ != Teuchos::null)
654 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
660 if (maxIterTest_ == Teuchos::null)
664 if (convTest_ == Teuchos::null)
665 convTest_ =
Teuchos::rcp(
new StatusTestResNorm_t( convtol_, 1 ) );
667 if (sTest_ == Teuchos::null)
668 sTest_ =
Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
670 if (outputTest_ == Teuchos::null) {
678 std::string solverDesc =
" Recycling CG ";
679 outputTest_->setSolverDesc( solverDesc );
683 if (timerSolve_ == Teuchos::null) {
684 std::string solveLabel = label_ +
": RCGSolMgr total solve time";
685 #ifdef BELOS_TEUCHOS_TIME_MONITOR
695 template<
class ScalarType,
class MV,
class OP>
705 "The relative residual tolerance that needs to be achieved by the\n"
706 "iterative solver in order for the linear system to be declared converged.");
707 pl->
set(
"Maximum Iterations", static_cast<int>(maxIters_default_),
708 "The maximum number of block iterations allowed for each\n"
709 "set of RHS solved.");
710 pl->
set(
"Block Size", static_cast<int>(blockSize_default_),
711 "Block Size Parameter -- currently must be 1 for RCG");
712 pl->
set(
"Num Blocks", static_cast<int>(numBlocks_default_),
713 "The length of a cycle (and this max number of search vectors kept)\n");
714 pl->
set(
"Num Recycled Blocks", static_cast<int>(recycleBlocks_default_),
715 "The number of vectors in the recycle subspace.");
716 pl->
set(
"Verbosity", static_cast<int>(verbosity_default_),
717 "What type(s) of solver information should be outputted\n"
718 "to the output stream.");
719 pl->
set(
"Output Style", static_cast<int>(outputStyle_default_),
720 "What style is used for the solver information outputted\n"
721 "to the output stream.");
722 pl->
set(
"Output Frequency", static_cast<int>(outputFreq_default_),
723 "How often convergence information should be outputted\n"
724 "to the output stream.");
725 pl->
set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
726 "A reference-counted pointer to the output stream where all\n"
727 "solver output is sent.");
728 pl->
set(
"Show Maximum Residual Norm Only", static_cast<bool>(showMaxResNormOnly_default_),
729 "When convergence information is printed, only show the maximum\n"
730 "relative residual norm when the block size is greater than one.");
731 pl->
set(
"Timer Label", static_cast<const char *>(label_default_),
732 "The string to use as a prefix for the timer labels.");
739 template<
class ScalarType,
class MV,
class OP>
744 if (rhsMV == Teuchos::null) {
752 "Belos::RCGSolMgr::initializeStateStorage(): Cannot generate a Krylov basis with dimension larger the operator!");
755 if (P_ == Teuchos::null) {
756 P_ = MVT::Clone( *rhsMV, numBlocks_+2 );
760 if (MVT::GetNumberVecs(*P_) < numBlocks_+2) {
762 P_ = MVT::Clone( *tmp, numBlocks_+2 );
767 if (Ap_ == Teuchos::null)
768 Ap_ = MVT::Clone( *rhsMV, 1 );
771 if (r_ == Teuchos::null)
772 r_ = MVT::Clone( *rhsMV, 1 );
775 if (z_ == Teuchos::null)
776 z_ = MVT::Clone( *rhsMV, 1 );
779 if (U_ == Teuchos::null) {
780 U_ = MVT::Clone( *rhsMV, recycleBlocks_ );
784 if (MVT::GetNumberVecs(*U_) < recycleBlocks_) {
786 U_ = MVT::Clone( *tmp, recycleBlocks_ );
791 if (AU_ == Teuchos::null) {
792 AU_ = MVT::Clone( *rhsMV, recycleBlocks_ );
796 if (MVT::GetNumberVecs(*AU_) < recycleBlocks_) {
798 AU_ = MVT::Clone( *tmp, recycleBlocks_ );
803 if (U1_ == Teuchos::null) {
804 U1_ = MVT::Clone( *rhsMV, recycleBlocks_ );
808 if (MVT::GetNumberVecs(*U1_) < recycleBlocks_) {
810 U1_ = MVT::Clone( *tmp, recycleBlocks_ );
815 if (Alpha_ == Teuchos::null)
818 if ( (Alpha_->numRows() != numBlocks_) || (Alpha_->numCols() != 1) )
819 Alpha_->reshape( numBlocks_, 1 );
823 if (Beta_ == Teuchos::null)
826 if ( (Beta_->numRows() != (numBlocks_+1)) || (Beta_->numCols() != 1) )
827 Beta_->reshape( numBlocks_ + 1, 1 );
831 if (D_ == Teuchos::null)
834 if ( (D_->numRows() != numBlocks_) || (D_->numCols() != 1) )
835 D_->reshape( numBlocks_, 1 );
839 if (Delta_ == Teuchos::null)
842 if ( (Delta_->numRows() != recycleBlocks_) || (Delta_->numCols() != (numBlocks_ + 1)) )
843 Delta_->reshape( recycleBlocks_, numBlocks_ + 1 );
847 if (UTAU_ == Teuchos::null)
850 if ( (UTAU_->numRows() != recycleBlocks_) || (UTAU_->numCols() != recycleBlocks_) )
851 UTAU_->reshape( recycleBlocks_, recycleBlocks_ );
855 if (LUUTAU_ == Teuchos::null)
858 if ( (LUUTAU_->numRows() != recycleBlocks_) || (LUUTAU_->numCols() != recycleBlocks_) )
859 LUUTAU_->reshape( recycleBlocks_, recycleBlocks_ );
863 if (ipiv_ == Teuchos::null)
864 ipiv_ =
Teuchos::rcp(
new std::vector<int>(recycleBlocks_) );
866 if ( (
int)ipiv_->size() != recycleBlocks_ )
867 ipiv_->resize(recycleBlocks_);
871 if (AUTAU_ == Teuchos::null)
874 if ( (AUTAU_->numRows() != recycleBlocks_) || (AUTAU_->numCols() != recycleBlocks_) )
875 AUTAU_->reshape( recycleBlocks_, recycleBlocks_ );
879 if (rTz_old_ == Teuchos::null)
882 if ( (rTz_old_->numRows() != 1) || (rTz_old_->numCols() != 1) )
883 rTz_old_->reshape( 1, 1 );
887 if (F_ == Teuchos::null)
890 if ( (F_->numRows() != (numBlocks_+recycleBlocks_)) || (F_->numCols() != numBlocks_+recycleBlocks_) )
891 F_->reshape( numBlocks_+recycleBlocks_, numBlocks_+recycleBlocks_ );
895 if (G_ == Teuchos::null)
898 if ( (G_->numRows() != (numBlocks_+recycleBlocks_)) || (G_->numCols() != numBlocks_+recycleBlocks_) )
899 G_->reshape( numBlocks_+recycleBlocks_, numBlocks_+recycleBlocks_ );
903 if (Y_ == Teuchos::null)
906 if ( (Y_->numRows() != (numBlocks_+recycleBlocks_)) || (Y_->numCols() != numBlocks_+recycleBlocks_) )
907 Y_->reshape( numBlocks_+recycleBlocks_, numBlocks_+recycleBlocks_ );
911 if (L2_ == Teuchos::null)
914 if ( (L2_->numRows() != (numBlocks_+1)) || (L2_->numCols() != numBlocks_) )
915 L2_->reshape( numBlocks_+1, numBlocks_ );
919 if (DeltaL2_ == Teuchos::null)
922 if ( (DeltaL2_->numRows() != (recycleBlocks_)) || (DeltaL2_->numCols() != (numBlocks_) ) )
923 DeltaL2_->reshape( recycleBlocks_, numBlocks_ );
927 if (AU1TUDeltaL2_ == Teuchos::null)
930 if ( (AU1TUDeltaL2_->numRows() != (recycleBlocks_)) || (AU1TUDeltaL2_->numCols() != (numBlocks_) ) )
931 AU1TUDeltaL2_->reshape( recycleBlocks_, numBlocks_ );
935 if (AU1TAU1_ == Teuchos::null)
938 if ( (AU1TAU1_->numRows() != (recycleBlocks_)) || (AU1TAU1_->numCols() != (recycleBlocks_) ) )
939 AU1TAU1_->reshape( recycleBlocks_, recycleBlocks_ );
943 if (GY_ == Teuchos::null)
946 if ( (GY_->numRows() != (numBlocks_ + recycleBlocks_)) || (GY_->numCols() != (recycleBlocks_) ) )
947 GY_->reshape( numBlocks_+recycleBlocks_, recycleBlocks_ );
951 if (AU1TU1_ == Teuchos::null)
954 if ( (AU1TU1_->numRows() != (recycleBlocks_)) || (AU1TU1_->numCols() != (recycleBlocks_) ) )
955 AU1TU1_->reshape( recycleBlocks_, recycleBlocks_ );
959 if (FY_ == Teuchos::null)
962 if ( (FY_->numRows() != (numBlocks_ + recycleBlocks_)) || (FY_->numCols() != (recycleBlocks_) ) )
963 FY_->reshape( numBlocks_+recycleBlocks_, recycleBlocks_ );
967 if (AU1TAP_ == Teuchos::null)
970 if ( (AU1TAP_->numRows() != (recycleBlocks_)) || (AU1TAP_->numCols() != (numBlocks_) ) )
971 AU1TAP_->reshape( recycleBlocks_, numBlocks_ );
975 if (APTAP_ == Teuchos::null)
978 if ( (APTAP_->numRows() != (numBlocks_)) || (APTAP_->numCols() != (numBlocks_) ) )
979 APTAP_->reshape( numBlocks_, numBlocks_ );
983 if (U1Y1_ == Teuchos::null) {
984 U1Y1_ = MVT::Clone( *rhsMV, recycleBlocks_ );
988 if (MVT::GetNumberVecs(*U1Y1_) < recycleBlocks_) {
990 U1Y1_ = MVT::Clone( *tmp, recycleBlocks_ );
995 if (PY2_ == Teuchos::null) {
996 PY2_ = MVT::Clone( *rhsMV, recycleBlocks_ );
1000 if (MVT::GetNumberVecs(*PY2_) < recycleBlocks_) {
1002 PY2_ = MVT::Clone( *tmp, recycleBlocks_ );
1007 if (AUTAP_ == Teuchos::null)
1010 if ( (AUTAP_->numRows() != (recycleBlocks_)) || (AUTAP_->numCols() != (numBlocks_) ) )
1011 AUTAP_->reshape( recycleBlocks_, numBlocks_ );
1015 if (AU1TU_ == Teuchos::null)
1018 if ( (AU1TU_->numRows() != (recycleBlocks_)) || (AU1TU_->numCols() != (recycleBlocks_) ) )
1019 AU1TU_->reshape( recycleBlocks_, recycleBlocks_ );
1026 template<
class ScalarType,
class MV,
class OP>
1030 std::vector<int> index(recycleBlocks_);
1041 setParameters(Teuchos::parameterList(*getValidParameters()));
1045 "Belos::RCGSolMgr::solve(): Linear problem is not a valid object.");
1047 "Belos::RCGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1050 "Belos::RCGSolMgr::solve(): RCG does not support split preconditioning, only set left or right preconditioner.");
1054 if (problem_->getLeftPrec() != Teuchos::null) {
1055 precObj = Teuchos::rcp_const_cast<OP>(problem_->getLeftPrec());
1057 else if (problem_->getRightPrec() != Teuchos::null) {
1058 precObj = Teuchos::rcp_const_cast<OP>(problem_->getRightPrec());
1062 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1063 std::vector<int> currIdx(1);
1067 problem_->setLSIndex( currIdx );
1070 ptrdiff_t dim = MVT::GetGlobalLength( *(problem_->getRHS()) );
1071 if (numBlocks_ > dim) {
1072 numBlocks_ = Teuchos::asSafe<int>(dim);
1073 params_->set(
"Num Blocks", numBlocks_);
1075 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1076 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1080 initializeStateStorage();
1084 plist.
set(
"Num Blocks",numBlocks_);
1085 plist.
set(
"Recycled Blocks",recycleBlocks_);
1088 outputTest_->reset();
1091 bool isConverged =
true;
1095 index.resize(recycleBlocks_);
1096 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1098 index.resize(recycleBlocks_);
1099 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1102 problem_->applyOp( *Utmp, *AUtmp );
1105 MVT::MvTransMv( one, *Utmp, *AUtmp, UTAUtmp );
1108 if ( precObj != Teuchos::null ) {
1109 index.resize(recycleBlocks_);
1110 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1111 index.resize(recycleBlocks_);
1112 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1114 OPT::Apply( *precObj, *AUtmp, *PCAU );
1115 MVT::MvTransMv( one, *AUtmp, *PCAU, AUTAUtmp );
1117 MVT::MvTransMv( one, *AUtmp, *AUtmp, AUTAUtmp );
1129 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1133 while ( numRHS2Solve > 0 ) {
1136 if (printer_->isVerbosity(
Debug ) ) {
1137 if (existU_) printer_->print(
Debug,
"Using recycle space generated from previous call to solve()." );
1138 else printer_->print(
Debug,
"No recycle space exists." );
1142 rcg_iter->resetNumIters();
1145 rcg_iter->setSize( recycleBlocks_, numBlocks_ );
1148 outputTest_->resetNumCalls();
1157 problem_->computeCurrResVec( &*r_ );
1163 index.resize(recycleBlocks_);
1164 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1166 MVT::MvTransMv( one, *Utmp, *r_, Utr );
1169 LUUTAUtmp.
assign(UTAUtmp);
1173 "Belos::RCGSolMgr::solve(): LAPACK GESV failed to compute a solution.");
1176 MVT::MvTimesMatAddMv( one, *Utmp, Utr, one, *problem_->getCurrLHSVec() );
1179 index.resize(recycleBlocks_);
1180 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1182 MVT::MvTimesMatAddMv( -one, *AUtmp, Utr, one, *r_ );
1185 if ( precObj != Teuchos::null ) {
1186 OPT::Apply( *precObj, *r_, *z_ );
1192 MVT::MvTransMv( one, *r_, *z_, *rTz_old_ );
1197 index.resize(recycleBlocks_);
1198 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1200 MVT::MvTransMv( one, *AUtmp, *z_, mu );
1206 "Belos::RCGSolMgr::solve(): LAPACK GETRS failed to compute a solution.");
1211 MVT::MvAddMv(one,*z_,zero,*z_,*Ptmp);
1212 MVT::MvTimesMatAddMv( -one, *U_, mu, one, *Ptmp );
1218 MVT::MvAddMv(one,*z_,zero,*z_,*Ptmp);
1225 index.resize( numBlocks_+1 );
1226 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1227 newstate.
P = MVT::CloneViewNonConst( *P_, index );
1228 index.resize( recycleBlocks_ );
1229 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1230 newstate.
U = MVT::CloneViewNonConst( *U_, index );
1231 index.resize( recycleBlocks_ );
1232 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1233 newstate.
AU = MVT::CloneViewNonConst( *AU_, index );
1244 newstate.
existU = existU_;
1245 newstate.
ipiv = ipiv_;
1248 rcg_iter->initialize(newstate);
1254 rcg_iter->iterate();
1261 if ( convTest_->getStatus() ==
Passed ) {
1270 else if ( maxIterTest_->getStatus() ==
Passed ) {
1272 isConverged =
false;
1280 else if ( rcg_iter->getCurSubspaceDim() == rcg_iter->getMaxSubspaceDim() ) {
1285 if (recycleBlocks_ > 0) {
1296 for (
int ii=0;ii<numBlocks_;ii++) {
1297 Gtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii,0));
1299 Gtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1300 Gtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1302 Ftmp(ii,ii) = Dtmp(ii,0);
1307 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1310 index.resize( numBlocks_ );
1311 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii; }
1313 index.resize( recycleBlocks_ );
1314 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1316 MVT::MvTimesMatAddMv( one, *Ptmp, Ytmp, zero, *U1tmp );
1336 ScalarType alphatmp = -1.0 / Alphatmp(numBlocks_-1,0);
1337 for (
int ii=0; ii<recycleBlocks_; ++ii) {
1338 AU1TAPtmp(ii,0) = Ytmp(numBlocks_-1,ii) * alphatmp;
1346 lastBeta = numBlocks_-1;
1355 AU1TAPtmp.
scale(Dtmp(0,0));
1361 for (
int ii=0; ii<numBlocks_; ii++) {
1362 APTAPtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii+1,0));
1364 APTAPtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1365 APTAPtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1380 for(
int ii=0;ii<numBlocks_;ii++) {
1381 F22(ii,ii) = Dtmp(ii,0);
1394 for (
int ii=0;ii<recycleBlocks_;++ii)
1395 for (
int jj=0;jj<numBlocks_;++jj)
1396 G21(jj,ii) = G12(ii,jj);
1401 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1404 index.resize( numBlocks_ );
1405 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii+1; }
1407 index.resize( recycleBlocks_ );
1408 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1411 index.resize( recycleBlocks_ );
1412 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1414 index.resize( recycleBlocks_ );
1415 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1418 MVT::MvTimesMatAddMv( one, *Ptmp, Y2, zero, *PY2tmp );
1419 MVT::MvTimesMatAddMv( one, *U1tmp, Y1, zero, *U1Y1tmp );
1420 MVT::MvAddMv(one,*U1Y1tmp, one, *PY2tmp, *U1tmp);
1432 ScalarType alphatmp = -1.0 / Alphatmp(numBlocks_-1,0);
1433 for (
int ii=0; ii<recycleBlocks_; ++ii) {
1434 AU1TAPtmp(ii,0) = Ytmp(numBlocks_+recycleBlocks_-1,ii) * alphatmp;
1444 lastp = numBlocks_+1;
1445 lastBeta = numBlocks_;
1456 for (
int ii=0; ii<numBlocks_; ii++) {
1457 APTAPtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii,0));
1459 APTAPtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1460 APTAPtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1466 for(
int ii=0;ii<numBlocks_;ii++) {
1467 L2tmp(ii,ii) = 1./Alphatmp(ii,0);
1468 L2tmp(ii+1,ii) = -1./Alphatmp(ii,0);
1489 for(
int ii=0;ii<numBlocks_;ii++) {
1490 F22(ii,ii) = Dtmp(ii,0);
1503 for (
int ii=0;ii<recycleBlocks_;++ii)
1504 for (
int jj=0;jj<numBlocks_;++jj)
1505 G21(jj,ii) = G12(ii,jj);
1510 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1513 index.resize( recycleBlocks_ );
1514 for (
int ii=0; ii<(recycleBlocks_); ++ii) { index[ii] = ii; }
1516 index.resize( numBlocks_ );
1517 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii; }
1519 index.resize( recycleBlocks_ );
1520 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1523 index.resize( recycleBlocks_ );
1524 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1527 index.resize( recycleBlocks_ );
1528 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1530 MVT::MvTimesMatAddMv( one, *Ptmp, Y2, zero, *PY2tmp );
1531 MVT::MvTimesMatAddMv( one, *Utmp, Y1, zero, *UY1tmp );
1532 MVT::MvAddMv(one,*UY1tmp, one, *PY2tmp, *U1tmp);
1550 AU1TUtmp.
assign(UTAUtmp);
1553 dold = Dtmp(numBlocks_-1,0);
1560 lastBeta = numBlocks_-1;
1567 for (
int ii=0; ii<numBlocks_; ii++) {
1568 APTAPtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii+1,0));
1570 APTAPtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1571 APTAPtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1576 for(
int ii=0;ii<numBlocks_;ii++) {
1577 L2tmp(ii,ii) = 1./Alphatmp(ii,0);
1578 L2tmp(ii+1,ii) = -1./Alphatmp(ii,0);
1594 ScalarType val = dold * (-Betatmp(0,0)/Alphatmp(0,0));
1595 for(
int ii=0;ii<recycleBlocks_;ii++) {
1596 AU1TAPtmp(ii,0) += Y2(numBlocks_-1,ii)*val;
1602 AU1TUtmp.
assign(Y1TAU1TU);
1612 for(
int ii=0;ii<numBlocks_;ii++) {
1613 F22(ii,ii) = Dtmp(ii,0);
1626 for (
int ii=0;ii<recycleBlocks_;++ii)
1627 for (
int jj=0;jj<numBlocks_;++jj)
1628 G21(jj,ii) = G12(ii,jj);
1633 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1636 index.resize( numBlocks_ );
1637 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii+1; }
1639 index.resize( recycleBlocks_ );
1640 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1642 index.resize( recycleBlocks_ );
1643 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1645 index.resize( recycleBlocks_ );
1646 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1648 MVT::MvTimesMatAddMv( one, *Ptmp, Y2, zero, *PY2tmp );
1649 MVT::MvTimesMatAddMv( one, *U1tmp, Y1, zero, *U1Y1tmp );
1650 MVT::MvAddMv(one,*U1Y1tmp, one, *PY2tmp, *U1tmp);
1665 dold = Dtmp(numBlocks_-1,0);
1668 lastp = numBlocks_+1;
1669 lastBeta = numBlocks_;
1679 index[0] = lastp-1; index[1] = lastp;
1681 index[0] = 0; index[1] = 1;
1682 MVT::SetBlock(*Ptmp2,index,*P_);
1685 (*Beta_)(0,0) = (*Beta_)(lastBeta,0);
1695 newstate.
P = Teuchos::null;
1696 index.resize( numBlocks_+1 );
1697 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii+1; }
1698 newstate.
P = MVT::CloneViewNonConst( *P_, index );
1700 newstate.
Beta = Teuchos::null;
1703 newstate.
Delta = Teuchos::null;
1709 rcg_iter->initialize(newstate);
1722 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
1723 "Belos::RCGSolMgr::solve(): Invalid return from RCGIter::iterate().");
1728 achievedTol_ = MT::one();
1730 MVT::MvInit( *X, SCT::zero() );
1731 printer_->stream(
Warnings) <<
"Belos::RCGSolMgr::solve(): Warning! NaN has been detected!"
1735 catch (
const std::exception &e) {
1736 printer_->stream(
Errors) <<
"Error! Caught std::exception in RCGIter::iterate() at iteration "
1737 << rcg_iter->getNumIters() << std::endl
1738 << e.what() << std::endl;
1744 problem_->setCurrLS();
1748 if ( numRHS2Solve > 0 ) {
1751 problem_->setLSIndex( currIdx );
1754 currIdx.resize( numRHS2Solve );
1760 index.resize(recycleBlocks_);
1761 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1762 MVT::SetBlock(*U1_,index,*U_);
1765 if (numRHS2Solve > 0) {
1767 newstate.
P = Teuchos::null;
1768 newstate.
Ap = Teuchos::null;
1769 newstate.
r = Teuchos::null;
1770 newstate.
z = Teuchos::null;
1771 newstate.
U = Teuchos::null;
1772 newstate.
AU = Teuchos::null;
1773 newstate.
Alpha = Teuchos::null;
1774 newstate.
Beta = Teuchos::null;
1775 newstate.
D = Teuchos::null;
1776 newstate.
Delta = Teuchos::null;
1777 newstate.
LUUTAU = Teuchos::null;
1778 newstate.
ipiv = Teuchos::null;
1779 newstate.
rTz_old = Teuchos::null;
1782 index.resize(recycleBlocks_);
1783 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1785 index.resize(recycleBlocks_);
1786 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1789 problem_->applyOp( *Utmp, *AUtmp );
1792 MVT::MvTransMv( one, *Utmp, *AUtmp, UTAUtmp );
1795 if ( precObj != Teuchos::null ) {
1796 index.resize(recycleBlocks_);
1797 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1798 index.resize(recycleBlocks_);
1799 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1801 OPT::Apply( *precObj, *AUtmp, *LeftPCAU );
1802 MVT::MvTransMv( one, *AUtmp, *LeftPCAU, AUTAUtmp );
1804 MVT::MvTransMv( one, *AUtmp, *AUtmp, AUTAUtmp );
1817 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1826 numIters_ = maxIterTest_->getNumIters();
1830 using Teuchos::rcp_dynamic_cast;
1833 const std::vector<MagnitudeType>* pTestValues =
1834 rcp_dynamic_cast<conv_test_type>(convTest_)->getTestValue();
1836 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1837 "Belos::RCGSolMgr::solve(): The convergence test's getTestValue() "
1838 "method returned NULL. Please report this bug to the Belos developers.");
1840 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1841 "Belos::RCGSolMgr::solve(): The convergence test's getTestValue() "
1842 "method returned a vector of length zero. Please report this bug to the "
1843 "Belos developers.");
1848 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1858 template<
class ScalarType,
class MV,
class OP>
1869 std::vector<MagnitudeType> w(n);
1872 std::vector<int> iperm(n);
1879 std::vector<ScalarType> work(1);
1887 lapack.
SYGV(itype, jobz, uplo, n, G2.values(), G2.stride(), F2.values(), F2.stride(), &w[0], &work[0], lwork, &info);
1889 "Belos::RCGSolMgr::solve(): LAPACK SYGV failed to query optimal work size.");
1890 lwork = (int)work[0];
1892 lapack.
SYGV(itype, jobz, uplo, n, G2.values(), G2.stride(), F2.values(), F2.stride(), &w[0], &work[0], lwork, &info);
1894 "Belos::RCGSolMgr::solve(): LAPACK SYGV failed to compute eigensolutions.");
1898 this->sort(w,n,iperm);
1901 for(
int i=0; i<recycleBlocks_; i++ ) {
1902 for(
int j=0; j<n; j++ ) {
1903 Y(j,i) = G2(j,iperm[i]);
1910 template<
class ScalarType,
class MV,
class OP>
1911 void RCGSolMgr<ScalarType,MV,OP,true>::sort(std::vector<ScalarType>& dlist,
int n, std::vector<int>& iperm)
1913 int l, r, j, i, flag;
1942 if (dlist[j] > dlist[j - 1]) j = j + 1;
1944 if (dlist[j - 1] > dK) {
1945 dlist[i - 1] = dlist[j - 1];
1946 iperm[i - 1] = iperm[j - 1];
1959 dlist[r] = dlist[0];
1960 iperm[r] = iperm[0];
1975 template<
class ScalarType,
class MV,
class OP>
1978 std::ostringstream oss;
ScalarType * values() const
Teuchos::RCP< MV > r
The current residual.
Collection of types and exceptions used within the Belos solvers.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > rTz_old
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
Get a parameter list containing the current parameters for this object.
Belos's basic output manager for sending information of select verbosity levels to the appropriate ou...
Teuchos::RCP< MV > P
The current Krylov basis.
Teuchos::RCP< std::vector< int > > ipiv
Data from LU factorization of U^T A U.
Class which manages the output and verbosity of the Belos solvers.
bool is_null(const boost::shared_ptr< T > &p)
int getNumIters() const override
Get the iteration count for the most recent call to solve().
T & get(const std::string &name, T def_value)
virtual ~RCGSolMgr()
Destructor.
bool is_null(const std::shared_ptr< T > &p)
int multiply(ETransp transa, ETransp transb, ScalarType alpha, const SerialDenseMatrix< OrdinalType, ScalarType > &A, const SerialDenseMatrix< OrdinalType, ScalarType > &B, ScalarType beta)
Teuchos::RCP< MV > U
The recycled subspace and its image.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > LUUTAU
The LU factorization of the matrix U^T A U.
Base class for Belos::SolverManager subclasses which normally can only compile with real ScalarType t...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
A factory class for generating StatusTestOutput objects.
Implementation of the RCG (Recycling Conjugate Gradient) iterative linear solver. ...
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Beta
This class implements the RCG iteration, where a single-std::vector Krylov subspace is constructed...
An implementation of StatusTestResNorm using a family of residual norms.
int scale(const ScalarType alpha)
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
static const double convTol
Default convergence tolerance.
Belos::StatusTest class for specifying a maximum number of iterations.
static std::string name()
bool isLOADetected() const override
Return whether a loss of accuracy was detected by this solver during the most current solve...
A factory class for generating StatusTestOutput objects.
RCGSolMgrLinearProblemFailure(const std::string &what_arg)
RCGSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i.e.
Traits class which defines basic operations on multivectors.
Belos::StatusTest for logically combining several status tests.
bool isParameter(const std::string &name) const
Structure to contain pointers to RCGIter state variables.
Belos concrete class for performing the RCG iteration.
A Belos::StatusTest class for specifying a maximum number of iterations.
ResetType
How to reset the solver.
bool existU
Flag to indicate the recycle space should be used.
const LinearProblem< ScalarType, MV, OP > & getProblem() const override
Return a reference to the linear problem being solved by this solver manager.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Pure virtual base class which describes the basic interface for a solver manager. ...
Teuchos::RCP< MV > z
The current preconditioned residual.
Teuchos::RCP< MV > Ap
A times current search vector.
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
int putScalar(const ScalarType value=Teuchos::ScalarTraits< ScalarType >::zero())
A linear system to solve, and its associated information.
Class which describes the linear problem to be solved by the iterative solver.
void SYGV(const OrdinalType &itype, const char &JOBZ, const char &UPLO, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb, ScalarType *W, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *info) const
Type traits class that says whether Teuchos::LAPACK has a valid implementation for the given ScalarTy...
ReturnType
Whether the Belos solve converged for all linear systems.
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Alpha
Coefficients arising in RCG iteration.
OrdinalType numCols() const
Teuchos::RCP< StatusTestOutput< ScalarType, MV, OP > > create(const Teuchos::RCP< OutputManager< ScalarType > > &printer, Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test, int mod, int printStates)
Create the StatusTestOutput object specified by the outputStyle.
void GESV(const OrdinalType &n, const OrdinalType &nrhs, ScalarType *A, const OrdinalType &lda, OrdinalType *IPIV, ScalarType *B, const OrdinalType &ldb, OrdinalType *info) const
void GETRS(const char &TRANS, const OrdinalType &n, const OrdinalType &nrhs, const ScalarType *A, const OrdinalType &lda, const OrdinalType *IPIV, ScalarType *B, const OrdinalType &ldb, OrdinalType *info) const
Belos::StatusTestResNorm for specifying general residual norm stopping criteria.
int curDim
The current dimension of the reduction.
RCGSolMgrLAPACKFailure(const std::string &what_arg)
bool isType(const std::string &name) const
RCGSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< Teuchos::ParameterList > &pl)
A class for extending the status testing capabilities of Belos via logical combinations.
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
Class which defines basic traits for the operator type.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > D
Parent class to all Belos exceptions.
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
Belos header file which uses auto-configuration information to include necessary C++ headers...
RCGSolMgrLAPACKFailure is thrown when a nonzero value is retuned from an LAPACK call.
SerialDenseMatrix< OrdinalType, ScalarType > & assign(const SerialDenseMatrix< OrdinalType, ScalarType > &Source)
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Delta
Solutions to local least-squares problems.
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) override
Set the linear problem that needs to be solved.
OrdinalType stride() const
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...