42 #ifndef BELOS_RCG_SOLMGR_HPP
43 #define BELOS_RCG_SOLMGR_HPP
64 #ifdef BELOS_TEUCHOS_TIME_MONITOR
147 template<
class ScalarType,
class MV,
class OP,
148 const bool supportsScalarType =
153 Belos::Details::LapackSupportsScalar<ScalarType>::value &&
154 ! Teuchos::ScalarTraits<ScalarType>::isComplex>
156 static const bool scalarTypeIsSupported =
181 template<
class ScalarType,
class MV,
class OP>
255 return Teuchos::tuple(timerSolve_);
329 std::string description()
const override;
345 void sort(std::vector<ScalarType>& dlist,
int n, std::vector<int>& iperm);
348 void initializeStateStorage();
367 static constexpr
int maxIters_default_ = 1000;
368 static constexpr
int blockSize_default_ = 1;
369 static constexpr
int numBlocks_default_ = 25;
370 static constexpr
int recycleBlocks_default_ = 3;
371 static constexpr
bool showMaxResNormOnly_default_ =
false;
374 static constexpr
int outputFreq_default_ = -1;
375 static constexpr
const char * label_default_ =
"Belos";
376 static constexpr std::ostream * outputStream_default_ = &std::cout;
383 MagnitudeType convtol_;
389 MagnitudeType achievedTol_;
397 int numBlocks_, recycleBlocks_;
398 bool showMaxResNormOnly_;
399 int verbosity_, outputStyle_, outputFreq_;
474 template<
class ScalarType,
class MV,
class OP>
483 template<
class ScalarType,
class MV,
class OP>
501 template<
class ScalarType,
class MV,
class OP>
504 outputStream_ =
Teuchos::rcp(outputStream_default_,
false);
506 maxIters_ = maxIters_default_;
507 numBlocks_ = numBlocks_default_;
508 recycleBlocks_ = recycleBlocks_default_;
509 verbosity_ = verbosity_default_;
510 outputStyle_= outputStyle_default_;
511 outputFreq_= outputFreq_default_;
512 showMaxResNormOnly_ = showMaxResNormOnly_default_;
513 label_ = label_default_;
524 Alpha_ = Teuchos::null;
525 Beta_ = Teuchos::null;
527 Delta_ = Teuchos::null;
528 UTAU_ = Teuchos::null;
529 LUUTAU_ = Teuchos::null;
530 ipiv_ = Teuchos::null;
531 AUTAU_ = Teuchos::null;
532 rTz_old_ = Teuchos::null;
537 DeltaL2_ = Teuchos::null;
538 AU1TUDeltaL2_ = Teuchos::null;
539 AU1TAU1_ = Teuchos::null;
540 AU1TU1_ = Teuchos::null;
541 AU1TAP_ = Teuchos::null;
544 APTAP_ = Teuchos::null;
545 U1Y1_ = Teuchos::null;
546 PY2_ = Teuchos::null;
547 AUTAP_ = Teuchos::null;
548 AU1TU_ = Teuchos::null;
552 template<
class ScalarType,
class MV,
class OP>
556 if (params_ == Teuchos::null) {
565 maxIters_ = params->
get(
"Maximum Iterations",maxIters_default_);
568 params_->set(
"Maximum Iterations", maxIters_);
569 if (maxIterTest_!=Teuchos::null)
570 maxIterTest_->setMaxIters( maxIters_ );
575 numBlocks_ = params->
get(
"Num Blocks",numBlocks_default_);
577 "Belos::RCGSolMgr: \"Num Blocks\" must be strictly positive.");
580 params_->set(
"Num Blocks", numBlocks_);
585 recycleBlocks_ = params->
get(
"Num Recycled Blocks",recycleBlocks_default_);
587 "Belos::RCGSolMgr: \"Num Recycled Blocks\" must be strictly positive.");
590 "Belos::RCGSolMgr: \"Num Recycled Blocks\" must be less than \"Num Blocks\".");
593 params_->set(
"Num Recycled Blocks", recycleBlocks_);
598 std::string tempLabel = params->
get(
"Timer Label", label_default_);
601 if (tempLabel != label_) {
603 params_->set(
"Timer Label", label_);
604 std::string solveLabel = label_ +
": RCGSolMgr total solve time";
605 #ifdef BELOS_TEUCHOS_TIME_MONITOR
613 if (Teuchos::isParameterType<int>(*params,
"Verbosity")) {
614 verbosity_ = params->
get(
"Verbosity", verbosity_default_);
616 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,
"Verbosity");
620 params_->set(
"Verbosity", verbosity_);
621 if (printer_ != Teuchos::null)
622 printer_->setVerbosity(verbosity_);
627 if (Teuchos::isParameterType<int>(*params,
"Output Style")) {
628 outputStyle_ = params->
get(
"Output Style", outputStyle_default_);
630 outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,
"Output Style");
634 params_->set(
"Output Style", outputStyle_);
635 outputTest_ = Teuchos::null;
640 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
643 params_->set(
"Output Stream", outputStream_);
644 if (printer_ != Teuchos::null)
645 printer_->setOStream( outputStream_ );
651 outputFreq_ = params->
get(
"Output Frequency", outputFreq_default_);
655 params_->set(
"Output Frequency", outputFreq_);
656 if (outputTest_ != Teuchos::null)
657 outputTest_->setOutputFrequency( outputFreq_ );
661 if (printer_ == Teuchos::null) {
670 if (params->
isParameter(
"Convergence Tolerance")) {
671 if (params->
isType<MagnitudeType> (
"Convergence Tolerance")) {
672 convtol_ = params->
get (
"Convergence Tolerance",
680 params_->set(
"Convergence Tolerance", convtol_);
681 if (convTest_ != Teuchos::null)
682 convTest_->setTolerance( convtol_ );
685 if (params->
isParameter(
"Show Maximum Residual Norm Only")) {
686 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,
"Show Maximum Residual Norm Only");
689 params_->set(
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
690 if (convTest_ != Teuchos::null)
691 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
697 if (maxIterTest_ == Teuchos::null)
701 if (convTest_ == Teuchos::null)
702 convTest_ =
Teuchos::rcp(
new StatusTestResNorm_t( convtol_, 1 ) );
704 if (sTest_ == Teuchos::null)
705 sTest_ =
Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
707 if (outputTest_ == Teuchos::null) {
715 std::string solverDesc =
" Recycling CG ";
716 outputTest_->setSolverDesc( solverDesc );
720 if (timerSolve_ == Teuchos::null) {
721 std::string solveLabel = label_ +
": RCGSolMgr total solve time";
722 #ifdef BELOS_TEUCHOS_TIME_MONITOR
732 template<
class ScalarType,
class MV,
class OP>
742 "The relative residual tolerance that needs to be achieved by the\n"
743 "iterative solver in order for the linear system to be declared converged.");
744 pl->
set(
"Maximum Iterations", static_cast<int>(maxIters_default_),
745 "The maximum number of block iterations allowed for each\n"
746 "set of RHS solved.");
747 pl->
set(
"Block Size", static_cast<int>(blockSize_default_),
748 "Block Size Parameter -- currently must be 1 for RCG");
749 pl->
set(
"Num Blocks", static_cast<int>(numBlocks_default_),
750 "The length of a cycle (and this max number of search vectors kept)\n");
751 pl->
set(
"Num Recycled Blocks", static_cast<int>(recycleBlocks_default_),
752 "The number of vectors in the recycle subspace.");
753 pl->
set(
"Verbosity", static_cast<int>(verbosity_default_),
754 "What type(s) of solver information should be outputted\n"
755 "to the output stream.");
756 pl->
set(
"Output Style", static_cast<int>(outputStyle_default_),
757 "What style is used for the solver information outputted\n"
758 "to the output stream.");
759 pl->
set(
"Output Frequency", static_cast<int>(outputFreq_default_),
760 "How often convergence information should be outputted\n"
761 "to the output stream.");
763 "A reference-counted pointer to the output stream where all\n"
764 "solver output is sent.");
765 pl->
set(
"Show Maximum Residual Norm Only", static_cast<bool>(showMaxResNormOnly_default_),
766 "When convergence information is printed, only show the maximum\n"
767 "relative residual norm when the block size is greater than one.");
768 pl->
set(
"Timer Label", static_cast<const char *>(label_default_),
769 "The string to use as a prefix for the timer labels.");
776 template<
class ScalarType,
class MV,
class OP>
781 if (rhsMV == Teuchos::null) {
789 "Belos::RCGSolMgr::initializeStateStorage(): Cannot generate a Krylov basis with dimension larger the operator!");
792 if (P_ == Teuchos::null) {
793 P_ = MVT::Clone( *rhsMV, numBlocks_+2 );
797 if (MVT::GetNumberVecs(*P_) < numBlocks_+2) {
799 P_ = MVT::Clone( *tmp, numBlocks_+2 );
804 if (Ap_ == Teuchos::null)
805 Ap_ = MVT::Clone( *rhsMV, 1 );
808 if (r_ == Teuchos::null)
809 r_ = MVT::Clone( *rhsMV, 1 );
812 if (z_ == Teuchos::null)
813 z_ = MVT::Clone( *rhsMV, 1 );
816 if (U_ == Teuchos::null) {
817 U_ = MVT::Clone( *rhsMV, recycleBlocks_ );
821 if (MVT::GetNumberVecs(*U_) < recycleBlocks_) {
823 U_ = MVT::Clone( *tmp, recycleBlocks_ );
828 if (AU_ == Teuchos::null) {
829 AU_ = MVT::Clone( *rhsMV, recycleBlocks_ );
833 if (MVT::GetNumberVecs(*AU_) < recycleBlocks_) {
835 AU_ = MVT::Clone( *tmp, recycleBlocks_ );
840 if (U1_ == Teuchos::null) {
841 U1_ = MVT::Clone( *rhsMV, recycleBlocks_ );
845 if (MVT::GetNumberVecs(*U1_) < recycleBlocks_) {
847 U1_ = MVT::Clone( *tmp, recycleBlocks_ );
852 if (Alpha_ == Teuchos::null)
855 if ( (Alpha_->numRows() != numBlocks_) || (Alpha_->numCols() != 1) )
856 Alpha_->reshape( numBlocks_, 1 );
860 if (Beta_ == Teuchos::null)
863 if ( (Beta_->numRows() != (numBlocks_+1)) || (Beta_->numCols() != 1) )
864 Beta_->reshape( numBlocks_ + 1, 1 );
868 if (D_ == Teuchos::null)
871 if ( (D_->numRows() != numBlocks_) || (D_->numCols() != 1) )
872 D_->reshape( numBlocks_, 1 );
876 if (Delta_ == Teuchos::null)
879 if ( (Delta_->numRows() != recycleBlocks_) || (Delta_->numCols() != (numBlocks_ + 1)) )
880 Delta_->reshape( recycleBlocks_, numBlocks_ + 1 );
884 if (UTAU_ == Teuchos::null)
887 if ( (UTAU_->numRows() != recycleBlocks_) || (UTAU_->numCols() != recycleBlocks_) )
888 UTAU_->reshape( recycleBlocks_, recycleBlocks_ );
892 if (LUUTAU_ == Teuchos::null)
895 if ( (LUUTAU_->numRows() != recycleBlocks_) || (LUUTAU_->numCols() != recycleBlocks_) )
896 LUUTAU_->reshape( recycleBlocks_, recycleBlocks_ );
900 if (ipiv_ == Teuchos::null)
901 ipiv_ =
Teuchos::rcp(
new std::vector<int>(recycleBlocks_) );
903 if ( (
int)ipiv_->size() != recycleBlocks_ )
904 ipiv_->resize(recycleBlocks_);
908 if (AUTAU_ == Teuchos::null)
911 if ( (AUTAU_->numRows() != recycleBlocks_) || (AUTAU_->numCols() != recycleBlocks_) )
912 AUTAU_->reshape( recycleBlocks_, recycleBlocks_ );
916 if (rTz_old_ == Teuchos::null)
919 if ( (rTz_old_->numRows() != 1) || (rTz_old_->numCols() != 1) )
920 rTz_old_->reshape( 1, 1 );
924 if (F_ == Teuchos::null)
927 if ( (F_->numRows() != (numBlocks_+recycleBlocks_)) || (F_->numCols() != numBlocks_+recycleBlocks_) )
928 F_->reshape( numBlocks_+recycleBlocks_, numBlocks_+recycleBlocks_ );
932 if (G_ == Teuchos::null)
935 if ( (G_->numRows() != (numBlocks_+recycleBlocks_)) || (G_->numCols() != numBlocks_+recycleBlocks_) )
936 G_->reshape( numBlocks_+recycleBlocks_, numBlocks_+recycleBlocks_ );
940 if (Y_ == Teuchos::null)
943 if ( (Y_->numRows() != (numBlocks_+recycleBlocks_)) || (Y_->numCols() != numBlocks_+recycleBlocks_) )
944 Y_->reshape( numBlocks_+recycleBlocks_, numBlocks_+recycleBlocks_ );
948 if (L2_ == Teuchos::null)
951 if ( (L2_->numRows() != (numBlocks_+1)) || (L2_->numCols() != numBlocks_) )
952 L2_->reshape( numBlocks_+1, numBlocks_ );
956 if (DeltaL2_ == Teuchos::null)
959 if ( (DeltaL2_->numRows() != (recycleBlocks_)) || (DeltaL2_->numCols() != (numBlocks_) ) )
960 DeltaL2_->reshape( recycleBlocks_, numBlocks_ );
964 if (AU1TUDeltaL2_ == Teuchos::null)
967 if ( (AU1TUDeltaL2_->numRows() != (recycleBlocks_)) || (AU1TUDeltaL2_->numCols() != (numBlocks_) ) )
968 AU1TUDeltaL2_->reshape( recycleBlocks_, numBlocks_ );
972 if (AU1TAU1_ == Teuchos::null)
975 if ( (AU1TAU1_->numRows() != (recycleBlocks_)) || (AU1TAU1_->numCols() != (recycleBlocks_) ) )
976 AU1TAU1_->reshape( recycleBlocks_, recycleBlocks_ );
980 if (GY_ == Teuchos::null)
983 if ( (GY_->numRows() != (numBlocks_ + recycleBlocks_)) || (GY_->numCols() != (recycleBlocks_) ) )
984 GY_->reshape( numBlocks_+recycleBlocks_, recycleBlocks_ );
988 if (AU1TU1_ == Teuchos::null)
991 if ( (AU1TU1_->numRows() != (recycleBlocks_)) || (AU1TU1_->numCols() != (recycleBlocks_) ) )
992 AU1TU1_->reshape( recycleBlocks_, recycleBlocks_ );
996 if (FY_ == Teuchos::null)
999 if ( (FY_->numRows() != (numBlocks_ + recycleBlocks_)) || (FY_->numCols() != (recycleBlocks_) ) )
1000 FY_->reshape( numBlocks_+recycleBlocks_, recycleBlocks_ );
1004 if (AU1TAP_ == Teuchos::null)
1007 if ( (AU1TAP_->numRows() != (recycleBlocks_)) || (AU1TAP_->numCols() != (numBlocks_) ) )
1008 AU1TAP_->reshape( recycleBlocks_, numBlocks_ );
1012 if (APTAP_ == Teuchos::null)
1015 if ( (APTAP_->numRows() != (numBlocks_)) || (APTAP_->numCols() != (numBlocks_) ) )
1016 APTAP_->reshape( numBlocks_, numBlocks_ );
1020 if (U1Y1_ == Teuchos::null) {
1021 U1Y1_ = MVT::Clone( *rhsMV, recycleBlocks_ );
1025 if (MVT::GetNumberVecs(*U1Y1_) < recycleBlocks_) {
1027 U1Y1_ = MVT::Clone( *tmp, recycleBlocks_ );
1032 if (PY2_ == Teuchos::null) {
1033 PY2_ = MVT::Clone( *rhsMV, recycleBlocks_ );
1037 if (MVT::GetNumberVecs(*PY2_) < recycleBlocks_) {
1039 PY2_ = MVT::Clone( *tmp, recycleBlocks_ );
1044 if (AUTAP_ == Teuchos::null)
1047 if ( (AUTAP_->numRows() != (recycleBlocks_)) || (AUTAP_->numCols() != (numBlocks_) ) )
1048 AUTAP_->reshape( recycleBlocks_, numBlocks_ );
1052 if (AU1TU_ == Teuchos::null)
1055 if ( (AU1TU_->numRows() != (recycleBlocks_)) || (AU1TU_->numCols() != (recycleBlocks_) ) )
1056 AU1TU_->reshape( recycleBlocks_, recycleBlocks_ );
1063 template<
class ScalarType,
class MV,
class OP>
1067 std::vector<int> index(recycleBlocks_);
1078 setParameters(Teuchos::parameterList(*getValidParameters()));
1082 "Belos::RCGSolMgr::solve(): Linear problem is not a valid object.");
1084 "Belos::RCGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1087 "Belos::RCGSolMgr::solve(): RCG does not support split preconditioning, only set left or right preconditioner.");
1091 if (problem_->getLeftPrec() != Teuchos::null) {
1092 precObj = Teuchos::rcp_const_cast<OP>(problem_->getLeftPrec());
1094 else if (problem_->getRightPrec() != Teuchos::null) {
1095 precObj = Teuchos::rcp_const_cast<OP>(problem_->getRightPrec());
1099 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1100 std::vector<int> currIdx(1);
1104 problem_->setLSIndex( currIdx );
1107 ptrdiff_t dim = MVT::GetGlobalLength( *(problem_->getRHS()) );
1108 if (numBlocks_ > dim) {
1109 numBlocks_ = Teuchos::asSafe<int>(dim);
1110 params_->set(
"Num Blocks", numBlocks_);
1112 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1113 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1117 initializeStateStorage();
1121 plist.
set(
"Num Blocks",numBlocks_);
1122 plist.
set(
"Recycled Blocks",recycleBlocks_);
1125 outputTest_->reset();
1128 bool isConverged =
true;
1132 index.resize(recycleBlocks_);
1133 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1135 index.resize(recycleBlocks_);
1136 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1139 problem_->applyOp( *Utmp, *AUtmp );
1142 MVT::MvTransMv( one, *Utmp, *AUtmp, UTAUtmp );
1145 if ( precObj != Teuchos::null ) {
1146 index.resize(recycleBlocks_);
1147 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1148 index.resize(recycleBlocks_);
1149 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1151 OPT::Apply( *precObj, *AUtmp, *PCAU );
1152 MVT::MvTransMv( one, *AUtmp, *PCAU, AUTAUtmp );
1154 MVT::MvTransMv( one, *AUtmp, *AUtmp, AUTAUtmp );
1166 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1170 while ( numRHS2Solve > 0 ) {
1173 if (printer_->isVerbosity(
Debug ) ) {
1174 if (existU_) printer_->print(
Debug,
"Using recycle space generated from previous call to solve()." );
1175 else printer_->print(
Debug,
"No recycle space exists." );
1179 rcg_iter->resetNumIters();
1182 rcg_iter->setSize( recycleBlocks_, numBlocks_ );
1185 outputTest_->resetNumCalls();
1194 problem_->computeCurrResVec( &*r_ );
1200 index.resize(recycleBlocks_);
1201 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1203 MVT::MvTransMv( one, *Utmp, *r_, Utr );
1206 LUUTAUtmp.
assign(UTAUtmp);
1210 "Belos::RCGSolMgr::solve(): LAPACK GESV failed to compute a solution.");
1213 MVT::MvTimesMatAddMv( one, *Utmp, Utr, one, *problem_->getCurrLHSVec() );
1216 index.resize(recycleBlocks_);
1217 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1219 MVT::MvTimesMatAddMv( -one, *AUtmp, Utr, one, *r_ );
1222 if ( precObj != Teuchos::null ) {
1223 OPT::Apply( *precObj, *r_, *z_ );
1229 MVT::MvTransMv( one, *r_, *z_, *rTz_old_ );
1234 index.resize(recycleBlocks_);
1235 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1237 MVT::MvTransMv( one, *AUtmp, *z_, mu );
1243 "Belos::RCGSolMgr::solve(): LAPACK GETRS failed to compute a solution.");
1248 MVT::MvAddMv(one,*z_,zero,*z_,*Ptmp);
1249 MVT::MvTimesMatAddMv( -one, *U_, mu, one, *Ptmp );
1255 MVT::MvAddMv(one,*z_,zero,*z_,*Ptmp);
1262 index.resize( numBlocks_+1 );
1263 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1264 newstate.
P = MVT::CloneViewNonConst( *P_, index );
1265 index.resize( recycleBlocks_ );
1266 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1267 newstate.
U = MVT::CloneViewNonConst( *U_, index );
1268 index.resize( recycleBlocks_ );
1269 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1270 newstate.
AU = MVT::CloneViewNonConst( *AU_, index );
1281 newstate.
existU = existU_;
1282 newstate.
ipiv = ipiv_;
1285 rcg_iter->initialize(newstate);
1291 rcg_iter->iterate();
1298 if ( convTest_->getStatus() ==
Passed ) {
1307 else if ( maxIterTest_->getStatus() ==
Passed ) {
1309 isConverged =
false;
1317 else if ( rcg_iter->getCurSubspaceDim() == rcg_iter->getMaxSubspaceDim() ) {
1322 if (recycleBlocks_ > 0) {
1333 for (
int ii=0;ii<numBlocks_;ii++) {
1334 Gtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii,0));
1336 Gtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1337 Gtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1339 Ftmp(ii,ii) = Dtmp(ii,0);
1344 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1347 index.resize( numBlocks_ );
1348 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii; }
1350 index.resize( recycleBlocks_ );
1351 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1353 MVT::MvTimesMatAddMv( one, *Ptmp, Ytmp, zero, *U1tmp );
1373 ScalarType alphatmp = -1.0 / Alphatmp(numBlocks_-1,0);
1374 for (
int ii=0; ii<recycleBlocks_; ++ii) {
1375 AU1TAPtmp(ii,0) = Ytmp(numBlocks_-1,ii) * alphatmp;
1383 lastBeta = numBlocks_-1;
1392 AU1TAPtmp.
scale(Dtmp(0,0));
1398 for (
int ii=0; ii<numBlocks_; ii++) {
1399 APTAPtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii+1,0));
1401 APTAPtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1402 APTAPtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1417 for(
int ii=0;ii<numBlocks_;ii++) {
1418 F22(ii,ii) = Dtmp(ii,0);
1431 for (
int ii=0;ii<recycleBlocks_;++ii)
1432 for (
int jj=0;jj<numBlocks_;++jj)
1433 G21(jj,ii) = G12(ii,jj);
1438 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1441 index.resize( numBlocks_ );
1442 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii+1; }
1444 index.resize( recycleBlocks_ );
1445 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1448 index.resize( recycleBlocks_ );
1449 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1451 index.resize( recycleBlocks_ );
1452 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1455 MVT::MvTimesMatAddMv( one, *Ptmp, Y2, zero, *PY2tmp );
1456 MVT::MvTimesMatAddMv( one, *U1tmp, Y1, zero, *U1Y1tmp );
1457 MVT::MvAddMv(one,*U1Y1tmp, one, *PY2tmp, *U1tmp);
1469 ScalarType alphatmp = -1.0 / Alphatmp(numBlocks_-1,0);
1470 for (
int ii=0; ii<recycleBlocks_; ++ii) {
1471 AU1TAPtmp(ii,0) = Ytmp(numBlocks_+recycleBlocks_-1,ii) * alphatmp;
1481 lastp = numBlocks_+1;
1482 lastBeta = numBlocks_;
1493 for (
int ii=0; ii<numBlocks_; ii++) {
1494 APTAPtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii,0));
1496 APTAPtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1497 APTAPtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1503 for(
int ii=0;ii<numBlocks_;ii++) {
1504 L2tmp(ii,ii) = 1./Alphatmp(ii,0);
1505 L2tmp(ii+1,ii) = -1./Alphatmp(ii,0);
1526 for(
int ii=0;ii<numBlocks_;ii++) {
1527 F22(ii,ii) = Dtmp(ii,0);
1540 for (
int ii=0;ii<recycleBlocks_;++ii)
1541 for (
int jj=0;jj<numBlocks_;++jj)
1542 G21(jj,ii) = G12(ii,jj);
1547 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1550 index.resize( recycleBlocks_ );
1551 for (
int ii=0; ii<(recycleBlocks_); ++ii) { index[ii] = ii; }
1553 index.resize( numBlocks_ );
1554 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii; }
1556 index.resize( recycleBlocks_ );
1557 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1560 index.resize( recycleBlocks_ );
1561 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1564 index.resize( recycleBlocks_ );
1565 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1567 MVT::MvTimesMatAddMv( one, *Ptmp, Y2, zero, *PY2tmp );
1568 MVT::MvTimesMatAddMv( one, *Utmp, Y1, zero, *UY1tmp );
1569 MVT::MvAddMv(one,*UY1tmp, one, *PY2tmp, *U1tmp);
1587 AU1TUtmp.
assign(UTAUtmp);
1590 dold = Dtmp(numBlocks_-1,0);
1597 lastBeta = numBlocks_-1;
1604 for (
int ii=0; ii<numBlocks_; ii++) {
1605 APTAPtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii+1,0));
1607 APTAPtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1608 APTAPtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1613 for(
int ii=0;ii<numBlocks_;ii++) {
1614 L2tmp(ii,ii) = 1./Alphatmp(ii,0);
1615 L2tmp(ii+1,ii) = -1./Alphatmp(ii,0);
1631 ScalarType val = dold * (-Betatmp(0,0)/Alphatmp(0,0));
1632 for(
int ii=0;ii<recycleBlocks_;ii++) {
1633 AU1TAPtmp(ii,0) += Y2(numBlocks_-1,ii)*val;
1639 AU1TUtmp.
assign(Y1TAU1TU);
1649 for(
int ii=0;ii<numBlocks_;ii++) {
1650 F22(ii,ii) = Dtmp(ii,0);
1663 for (
int ii=0;ii<recycleBlocks_;++ii)
1664 for (
int jj=0;jj<numBlocks_;++jj)
1665 G21(jj,ii) = G12(ii,jj);
1670 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1673 index.resize( numBlocks_ );
1674 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii+1; }
1676 index.resize( recycleBlocks_ );
1677 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1679 index.resize( recycleBlocks_ );
1680 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1682 index.resize( recycleBlocks_ );
1683 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1685 MVT::MvTimesMatAddMv( one, *Ptmp, Y2, zero, *PY2tmp );
1686 MVT::MvTimesMatAddMv( one, *U1tmp, Y1, zero, *U1Y1tmp );
1687 MVT::MvAddMv(one,*U1Y1tmp, one, *PY2tmp, *U1tmp);
1702 dold = Dtmp(numBlocks_-1,0);
1705 lastp = numBlocks_+1;
1706 lastBeta = numBlocks_;
1716 index[0] = lastp-1; index[1] = lastp;
1718 index[0] = 0; index[1] = 1;
1719 MVT::SetBlock(*Ptmp2,index,*P_);
1722 (*Beta_)(0,0) = (*Beta_)(lastBeta,0);
1732 newstate.
P = Teuchos::null;
1733 index.resize( numBlocks_+1 );
1734 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii+1; }
1735 newstate.
P = MVT::CloneViewNonConst( *P_, index );
1737 newstate.
Beta = Teuchos::null;
1740 newstate.
Delta = Teuchos::null;
1746 rcg_iter->initialize(newstate);
1759 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
1760 "Belos::RCGSolMgr::solve(): Invalid return from RCGIter::iterate().");
1763 catch (
const std::exception &e) {
1764 printer_->stream(
Errors) <<
"Error! Caught std::exception in RCGIter::iterate() at iteration "
1765 << rcg_iter->getNumIters() << std::endl
1766 << e.what() << std::endl;
1772 problem_->setCurrLS();
1776 if ( numRHS2Solve > 0 ) {
1779 problem_->setLSIndex( currIdx );
1782 currIdx.resize( numRHS2Solve );
1788 index.resize(recycleBlocks_);
1789 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1790 MVT::SetBlock(*U1_,index,*U_);
1793 if (numRHS2Solve > 0) {
1795 newstate.
P = Teuchos::null;
1796 newstate.
Ap = Teuchos::null;
1797 newstate.
r = Teuchos::null;
1798 newstate.
z = Teuchos::null;
1799 newstate.
U = Teuchos::null;
1800 newstate.
AU = Teuchos::null;
1801 newstate.
Alpha = Teuchos::null;
1802 newstate.
Beta = Teuchos::null;
1803 newstate.
D = Teuchos::null;
1804 newstate.
Delta = Teuchos::null;
1805 newstate.
LUUTAU = Teuchos::null;
1806 newstate.
ipiv = Teuchos::null;
1807 newstate.
rTz_old = Teuchos::null;
1810 index.resize(recycleBlocks_);
1811 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1813 index.resize(recycleBlocks_);
1814 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1817 problem_->applyOp( *Utmp, *AUtmp );
1820 MVT::MvTransMv( one, *Utmp, *AUtmp, UTAUtmp );
1823 if ( precObj != Teuchos::null ) {
1824 index.resize(recycleBlocks_);
1825 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1826 index.resize(recycleBlocks_);
1827 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1829 OPT::Apply( *precObj, *AUtmp, *LeftPCAU );
1830 MVT::MvTransMv( one, *AUtmp, *LeftPCAU, AUTAUtmp );
1832 MVT::MvTransMv( one, *AUtmp, *AUtmp, AUTAUtmp );
1845 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1854 numIters_ = maxIterTest_->getNumIters();
1858 using Teuchos::rcp_dynamic_cast;
1861 const std::vector<MagnitudeType>* pTestValues =
1862 rcp_dynamic_cast<conv_test_type>(convTest_)->getTestValue();
1864 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1865 "Belos::RCGSolMgr::solve(): The convergence test's getTestValue() "
1866 "method returned NULL. Please report this bug to the Belos developers.");
1868 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1869 "Belos::RCGSolMgr::solve(): The convergence test's getTestValue() "
1870 "method returned a vector of length zero. Please report this bug to the "
1871 "Belos developers.");
1876 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1886 template<
class ScalarType,
class MV,
class OP>
1897 std::vector<MagnitudeType> w(n);
1900 std::vector<int> iperm(n);
1907 std::vector<ScalarType> work(1);
1915 lapack.
SYGV(itype, jobz, uplo, n, G2.values(), G2.stride(), F2.values(), F2.stride(), &w[0], &work[0], lwork, &info);
1917 "Belos::RCGSolMgr::solve(): LAPACK SYGV failed to query optimal work size.");
1918 lwork = (int)work[0];
1920 lapack.
SYGV(itype, jobz, uplo, n, G2.values(), G2.stride(), F2.values(), F2.stride(), &w[0], &work[0], lwork, &info);
1922 "Belos::RCGSolMgr::solve(): LAPACK SYGV failed to compute eigensolutions.");
1926 this->sort(w,n,iperm);
1929 for(
int i=0; i<recycleBlocks_; i++ ) {
1930 for(
int j=0; j<n; j++ ) {
1931 Y(j,i) = G2(j,iperm[i]);
1938 template<
class ScalarType,
class MV,
class OP>
1939 void RCGSolMgr<ScalarType,MV,OP,true>::sort(std::vector<ScalarType>& dlist,
int n, std::vector<int>& iperm)
1941 int l, r, j, i, flag;
1970 if (dlist[j] > dlist[j - 1]) j = j + 1;
1972 if (dlist[j - 1] > dK) {
1973 dlist[i - 1] = dlist[j - 1];
1974 iperm[i - 1] = iperm[j - 1];
1987 dlist[r] = dlist[0];
1988 iperm[r] = iperm[0];
2003 template<
class ScalarType,
class MV,
class OP>
2006 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)
RCGSolMgrRecyclingFailure is thrown when any problem occurs in using/creating the recycling subspace...
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.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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)
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)
RCGSolMgrRecyclingFailure(const std::string &what_arg)
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...