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>
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";
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_;
515 template<
class ScalarType,
class MV,
class OP>
528 maxIters_ = params->
get(
"Maximum Iterations",maxIters_default_);
531 params_->set(
"Maximum Iterations", maxIters_);
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_);
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_);
603 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
606 params_->set(
"Output Stream", outputStream_);
608 printer_->setOStream( outputStream_ );
614 outputFreq_ = params->
get(
"Output Frequency", outputFreq_default_);
618 params_->set(
"Output Frequency", outputFreq_);
620 outputTest_->setOutputFrequency( outputFreq_ );
633 if (params->
isParameter(
"Convergence Tolerance")) {
635 convtol_ = params->
get (
"Convergence Tolerance",
643 params_->set(
"Convergence Tolerance", convtol_);
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_);
654 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
665 convTest_ =
Teuchos::rcp(
new StatusTestResNorm_t( convtol_, 1 ) );
668 sTest_ =
Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
678 std::string solverDesc =
" Recycling CG ";
679 outputTest_->setSolverDesc( solverDesc );
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>
752 "Belos::RCGSolMgr::initializeStateStorage(): Cannot generate a Krylov basis with dimension larger the operator!");
756 P_ = MVT::Clone( *rhsMV, numBlocks_+2 );
760 if (MVT::GetNumberVecs(*P_) < numBlocks_+2) {
762 P_ = MVT::Clone( *tmp, numBlocks_+2 );
768 Ap_ = MVT::Clone( *rhsMV, 1 );
772 r_ = MVT::Clone( *rhsMV, 1 );
776 z_ = MVT::Clone( *rhsMV, 1 );
780 U_ = MVT::Clone( *rhsMV, recycleBlocks_ );
784 if (MVT::GetNumberVecs(*U_) < recycleBlocks_) {
786 U_ = MVT::Clone( *tmp, recycleBlocks_ );
792 AU_ = MVT::Clone( *rhsMV, recycleBlocks_ );
796 if (MVT::GetNumberVecs(*AU_) < recycleBlocks_) {
798 AU_ = MVT::Clone( *tmp, recycleBlocks_ );
804 U1_ = MVT::Clone( *rhsMV, recycleBlocks_ );
808 if (MVT::GetNumberVecs(*U1_) < recycleBlocks_) {
810 U1_ = MVT::Clone( *tmp, recycleBlocks_ );
818 if ( (Alpha_->numRows() != numBlocks_) || (Alpha_->numCols() != 1) )
819 Alpha_->reshape( numBlocks_, 1 );
826 if ( (Beta_->numRows() != (numBlocks_+1)) || (Beta_->numCols() != 1) )
827 Beta_->reshape( numBlocks_ + 1, 1 );
834 if ( (D_->numRows() != numBlocks_) || (D_->numCols() != 1) )
835 D_->reshape( numBlocks_, 1 );
842 if ( (Delta_->numRows() != recycleBlocks_) || (Delta_->numCols() != (numBlocks_ + 1)) )
843 Delta_->reshape( recycleBlocks_, numBlocks_ + 1 );
850 if ( (UTAU_->numRows() != recycleBlocks_) || (UTAU_->numCols() != recycleBlocks_) )
851 UTAU_->reshape( recycleBlocks_, recycleBlocks_ );
858 if ( (LUUTAU_->numRows() != recycleBlocks_) || (LUUTAU_->numCols() != recycleBlocks_) )
859 LUUTAU_->reshape( recycleBlocks_, recycleBlocks_ );
864 ipiv_ =
Teuchos::rcp(
new std::vector<int>(recycleBlocks_) );
866 if ( (
int)ipiv_->size() != recycleBlocks_ )
867 ipiv_->resize(recycleBlocks_);
874 if ( (AUTAU_->numRows() != recycleBlocks_) || (AUTAU_->numCols() != recycleBlocks_) )
875 AUTAU_->reshape( recycleBlocks_, recycleBlocks_ );
882 if ( (rTz_old_->numRows() != 1) || (rTz_old_->numCols() != 1) )
883 rTz_old_->reshape( 1, 1 );
890 if ( (F_->numRows() != (numBlocks_+recycleBlocks_)) || (F_->numCols() != numBlocks_+recycleBlocks_) )
891 F_->reshape( numBlocks_+recycleBlocks_, numBlocks_+recycleBlocks_ );
898 if ( (G_->numRows() != (numBlocks_+recycleBlocks_)) || (G_->numCols() != numBlocks_+recycleBlocks_) )
899 G_->reshape( numBlocks_+recycleBlocks_, numBlocks_+recycleBlocks_ );
906 if ( (Y_->numRows() != (numBlocks_+recycleBlocks_)) || (Y_->numCols() != numBlocks_+recycleBlocks_) )
907 Y_->reshape( numBlocks_+recycleBlocks_, numBlocks_+recycleBlocks_ );
914 if ( (L2_->numRows() != (numBlocks_+1)) || (L2_->numCols() != numBlocks_) )
915 L2_->reshape( numBlocks_+1, numBlocks_ );
922 if ( (DeltaL2_->numRows() != (recycleBlocks_)) || (DeltaL2_->numCols() != (numBlocks_) ) )
923 DeltaL2_->reshape( recycleBlocks_, numBlocks_ );
930 if ( (AU1TUDeltaL2_->numRows() != (recycleBlocks_)) || (AU1TUDeltaL2_->numCols() != (numBlocks_) ) )
931 AU1TUDeltaL2_->reshape( recycleBlocks_, numBlocks_ );
938 if ( (AU1TAU1_->numRows() != (recycleBlocks_)) || (AU1TAU1_->numCols() != (recycleBlocks_) ) )
939 AU1TAU1_->reshape( recycleBlocks_, recycleBlocks_ );
946 if ( (GY_->numRows() != (numBlocks_ + recycleBlocks_)) || (GY_->numCols() != (recycleBlocks_) ) )
947 GY_->reshape( numBlocks_+recycleBlocks_, recycleBlocks_ );
954 if ( (AU1TU1_->numRows() != (recycleBlocks_)) || (AU1TU1_->numCols() != (recycleBlocks_) ) )
955 AU1TU1_->reshape( recycleBlocks_, recycleBlocks_ );
962 if ( (FY_->numRows() != (numBlocks_ + recycleBlocks_)) || (FY_->numCols() != (recycleBlocks_) ) )
963 FY_->reshape( numBlocks_+recycleBlocks_, recycleBlocks_ );
970 if ( (AU1TAP_->numRows() != (recycleBlocks_)) || (AU1TAP_->numCols() != (numBlocks_) ) )
971 AU1TAP_->reshape( recycleBlocks_, numBlocks_ );
978 if ( (APTAP_->numRows() != (numBlocks_)) || (APTAP_->numCols() != (numBlocks_) ) )
979 APTAP_->reshape( numBlocks_, numBlocks_ );
984 U1Y1_ = MVT::Clone( *rhsMV, recycleBlocks_ );
988 if (MVT::GetNumberVecs(*U1Y1_) < recycleBlocks_) {
990 U1Y1_ = MVT::Clone( *tmp, recycleBlocks_ );
996 PY2_ = MVT::Clone( *rhsMV, recycleBlocks_ );
1000 if (MVT::GetNumberVecs(*PY2_) < recycleBlocks_) {
1002 PY2_ = MVT::Clone( *tmp, recycleBlocks_ );
1010 if ( (AUTAP_->numRows() != (recycleBlocks_)) || (AUTAP_->numCols() != (numBlocks_) ) )
1011 AUTAP_->reshape( recycleBlocks_, numBlocks_ );
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.");
1055 precObj = Teuchos::rcp_const_cast<OP>(problem_->getLeftPrec());
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 );
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_ );
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);
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 );
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) {
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 );
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>
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< std::ostream > outputStream_
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::ScalarTraits< MagnitudeType > MT
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.
Teuchos::RCP< Teuchos::Time > timerSolve_
bool is_null(const boost::shared_ptr< T > &p)
static const bool scalarTypeIsSupported
Teuchos::RCP< StatusTest< ScalarType, MV, OP > > sTest_
MagnitudeType achievedTol_
Tolerance achieved by the last solve() invocation.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > D_
Teuchos::RCP< StatusTestOutput< ScalarType, MV, OP > > outputTest_
int getNumIters() const override
Get the iteration count for the most recent call to solve().
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > AUTAU_
T & get(ParameterList &l, const std::string &name)
virtual ~RCGSolMgr()
Destructor.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > GY_
bool is_null(const std::shared_ptr< T > &p)
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > L2_
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...
int numIters_
Number of iterations taken by the last solve() invocation.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > AUTAP_
Teuchos::ScalarTraits< ScalarType >::magnitudeType MagnitudeType
An implementation of StatusTestResNorm using a family of residual norms.
int scale(const ScalarType alpha)
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > UTAU_
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)
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > rTz_old_
static const double convTol
Default convergence tolerance.
Belos::StatusTest class for specifying a maximum number of iterations.
Teuchos::RCP< Teuchos::ParameterList > params_
static std::string name()
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > AU1TU1_
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.
MagnitudeType convtol_
Convergence tolerance (read from parameter list).
Traits class which defines basic operations on multivectors.
Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > problem_
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.
MultiVecTraits< ScalarType, MV > MVT
int maxIters_
Maximum iteration count (read from parameter list).
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)
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Alpha_
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...
OperatorTraits< ScalarType, MV, OP > OPT
ReturnType
Whether the Belos solve converged for all linear systems.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > APTAP_
Teuchos::RCP< std::vector< int > > ipiv_
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
Teuchos::RCP< StatusTestGenResNorm< ScalarType, MV, OP > > convTest_
Teuchos::RCP< OutputManager< ScalarType > > printer_
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
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Beta_
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
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Y_
Belos::StatusTestResNorm for specifying general residual norm stopping criteria.
Teuchos::RCP< StatusTestMaxIters< ScalarType, MV, OP > > maxIterTest_
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)
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > LUUTAU_
A class for extending the status testing capabilities of Belos via logical combinations.
Details::SolverManagerRequiresRealLapack< ScalarType, MV, OP, scalarTypeIsSupported > base_type
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
Teuchos::ScalarTraits< ScalarType > SCT
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
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Delta_
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...