42 #ifndef BELOS_GCRODR_SOLMGR_HPP
43 #define BELOS_GCRODR_SOLMGR_HPP
62 #include "Teuchos_BLAS.hpp"
63 #include "Teuchos_LAPACK.hpp"
64 #include "Teuchos_as.hpp"
65 #ifdef BELOS_TEUCHOS_TIME_MONITOR
66 # include "Teuchos_TimeMonitor.hpp"
67 #endif // BELOS_TEUCHOS_TIME_MONITOR
68 #if defined(HAVE_TEUCHOSCORE_CXX11)
69 # include <type_traits>
70 #endif // defined(HAVE_TEUCHOSCORE_CXX11)
154 template<
class ScalarType,
class MV,
class OP,
155 const bool lapackSupportsScalarType =
160 static const bool requiresLapack =
170 const Teuchos::RCP<Teuchos::ParameterList>& pl) :
179 template<
class ScalarType,
class MV,
class OP>
183 #if defined(HAVE_TEUCHOSCORE_CXX11)
184 # if defined(HAVE_TEUCHOS_COMPLEX)
185 static_assert (std::is_same<ScalarType, std::complex<float> >::value ||
186 std::is_same<ScalarType, std::complex<double> >::value ||
187 std::is_same<ScalarType, float>::value ||
188 std::is_same<ScalarType, double>::value,
189 "Belos::GCRODRSolMgr: ScalarType must be one of the four "
190 "types (S,D,C,Z) supported by LAPACK.");
192 static_assert (std::is_same<ScalarType, float>::value ||
193 std::is_same<ScalarType, double>::value,
194 "Belos::GCRODRSolMgr: ScalarType must be float or double. "
195 "Complex arithmetic support is currently disabled. To "
196 "enable it, set Teuchos_ENABLE_COMPLEX=ON.");
197 # endif // defined(HAVE_TEUCHOS_COMPLEX)
198 #endif // defined(HAVE_TEUCHOSCORE_CXX11)
203 typedef Teuchos::ScalarTraits<ScalarType> SCT;
204 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
205 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
272 const Teuchos::RCP<Teuchos::ParameterList> &pl);
278 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
294 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const override;
307 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
308 return Teuchos::tuple(timerSolve_);
340 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
override;
352 bool set = problem_->setProblem();
354 throw "Could not set problem.";
398 std::string description()
const override;
408 void initializeStateStorage();
417 int getHarmonicVecs1(
int m,
418 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
419 Teuchos::SerialDenseMatrix<int,ScalarType>& PP);
426 int getHarmonicVecs2(
int keff,
int m,
427 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
428 const Teuchos::RCP<const MV>& VV,
429 Teuchos::SerialDenseMatrix<int,ScalarType>& PP);
432 void sort(std::vector<MagnitudeType>& dlist,
int n, std::vector<int>& iperm);
435 Teuchos::LAPACK<int,ScalarType> lapack;
438 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
441 Teuchos::RCP<OutputManager<ScalarType> > printer_;
442 Teuchos::RCP<std::ostream> outputStream_;
445 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
446 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
447 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
448 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > expConvTest_, impConvTest_;
449 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
454 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
457 Teuchos::RCP<Teuchos::ParameterList> params_;
460 static constexpr
double orthoKappa_default_ = 0.0;
461 static constexpr
int maxRestarts_default_ = 100;
462 static constexpr
int maxIters_default_ = 1000;
463 static constexpr
int numBlocks_default_ = 50;
464 static constexpr
int blockSize_default_ = 1;
465 static constexpr
int recycledBlocks_default_ = 5;
468 static constexpr
int outputFreq_default_ = -1;
469 static constexpr
const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
470 static constexpr
const char * expResScale_default_ =
"Norm of Initial Residual";
471 static constexpr
const char * label_default_ =
"Belos";
472 static constexpr
const char * orthoType_default_ =
"DGKS";
473 static constexpr std::ostream * outputStream_default_ = &std::cout;
476 MagnitudeType convTol_, orthoKappa_, achievedTol_;
477 int maxRestarts_, maxIters_, numIters_;
478 int verbosity_, outputStyle_, outputFreq_;
479 std::string orthoType_;
480 std::string impResScale_, expResScale_;
487 int numBlocks_, recycledBlocks_;
498 Teuchos::RCP<MV> U_, C_;
501 Teuchos::RCP<MV> U1_, C1_;
504 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H2_;
505 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H_;
506 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B_;
507 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PP_;
508 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > HP_;
509 std::vector<ScalarType> tau_;
510 std::vector<ScalarType> work_;
511 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > R_;
512 std::vector<int> ipiv_;
517 Teuchos::RCP<Teuchos::Time> timerSolve_;
523 bool builtRecycleSpace_;
528 template<
class ScalarType,
class MV,
class OP>
538 template<
class ScalarType,
class MV,
class OP>
541 const Teuchos::RCP<Teuchos::ParameterList>& pl):
549 TEUCHOS_TEST_FOR_EXCEPTION(
550 problem == Teuchos::null, std::invalid_argument,
551 "Belos::GCRODRSolMgr constructor: The solver manager's "
552 "constructor needs the linear problem argument 'problem' "
561 if (! pl.is_null ()) {
567 template<
class ScalarType,
class MV,
class OP>
569 outputStream_ = Teuchos::rcp(outputStream_default_,
false);
571 orthoKappa_ = orthoKappa_default_;
572 maxRestarts_ = maxRestarts_default_;
573 maxIters_ = maxIters_default_;
574 numBlocks_ = numBlocks_default_;
575 recycledBlocks_ = recycledBlocks_default_;
576 verbosity_ = verbosity_default_;
577 outputStyle_ = outputStyle_default_;
578 outputFreq_ = outputFreq_default_;
579 orthoType_ = orthoType_default_;
580 impResScale_ = impResScale_default_;
581 expResScale_ = expResScale_default_;
582 label_ = label_default_;
584 builtRecycleSpace_ =
false;
600 template<
class ScalarType,
class MV,
class OP>
605 using Teuchos::isParameterType;
606 using Teuchos::getParameter;
608 using Teuchos::ParameterList;
609 using Teuchos::parameterList;
612 using Teuchos::rcp_dynamic_cast;
613 using Teuchos::rcpFromRef;
614 using Teuchos::Exceptions::InvalidParameter;
615 using Teuchos::Exceptions::InvalidParameterName;
616 using Teuchos::Exceptions::InvalidParameterType;
620 RCP<const ParameterList> defaultParams = getValidParameters();
638 if (params_.is_null()) {
639 params_ = parameterList (*defaultParams);
647 if (params_ != params) {
653 params_ = parameterList (*params);
688 params_->validateParametersAndSetDefaults (*defaultParams);
692 if (params->isParameter (
"Maximum Restarts")) {
693 maxRestarts_ = params->get(
"Maximum Restarts", maxRestarts_default_);
696 params_->set (
"Maximum Restarts", maxRestarts_);
700 if (params->isParameter (
"Maximum Iterations")) {
701 maxIters_ = params->get (
"Maximum Iterations", maxIters_default_);
704 params_->set (
"Maximum Iterations", maxIters_);
705 if (! maxIterTest_.is_null())
706 maxIterTest_->setMaxIters (maxIters_);
710 if (params->isParameter (
"Num Blocks")) {
711 numBlocks_ = params->get (
"Num Blocks", numBlocks_default_);
712 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks_ <= 0, std::invalid_argument,
713 "Belos::GCRODRSolMgr: The \"Num Blocks\" parameter must "
714 "be strictly positive, but you specified a value of "
715 << numBlocks_ <<
".");
717 params_->set (
"Num Blocks", numBlocks_);
721 if (params->isParameter (
"Num Recycled Blocks")) {
722 recycledBlocks_ = params->get (
"Num Recycled Blocks",
723 recycledBlocks_default_);
724 TEUCHOS_TEST_FOR_EXCEPTION(recycledBlocks_ <= 0, std::invalid_argument,
725 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
726 "parameter must be strictly positive, but you specified "
727 "a value of " << recycledBlocks_ <<
".");
728 TEUCHOS_TEST_FOR_EXCEPTION(recycledBlocks_ >= numBlocks_, std::invalid_argument,
729 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
730 "parameter must be less than the \"Num Blocks\" "
731 "parameter, but you specified \"Num Recycled Blocks\" "
732 "= " << recycledBlocks_ <<
" and \"Num Blocks\" = "
733 << numBlocks_ <<
".");
735 params_->set(
"Num Recycled Blocks", recycledBlocks_);
741 if (params->isParameter (
"Timer Label")) {
742 std::string tempLabel = params->get (
"Timer Label", label_default_);
745 if (tempLabel != label_) {
747 params_->set (
"Timer Label", label_);
748 std::string solveLabel = label_ +
": GCRODRSolMgr total solve time";
749 #ifdef BELOS_TEUCHOS_TIME_MONITOR
750 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
752 if (ortho_ != Teuchos::null) {
753 ortho_->setLabel( label_ );
759 if (params->isParameter (
"Verbosity")) {
760 if (isParameterType<int> (*params,
"Verbosity")) {
761 verbosity_ = params->get (
"Verbosity", verbosity_default_);
763 verbosity_ = (int) getParameter<Belos::MsgType> (*params,
"Verbosity");
766 params_->set (
"Verbosity", verbosity_);
769 if (! printer_.is_null())
770 printer_->setVerbosity (verbosity_);
774 if (params->isParameter (
"Output Style")) {
775 if (isParameterType<int> (*params,
"Output Style")) {
776 outputStyle_ = params->get (
"Output Style", outputStyle_default_);
778 outputStyle_ = (int) getParameter<OutputType> (*params,
"Output Style");
782 params_->set (
"Output Style", outputStyle_);
800 if (params->isParameter (
"Output Stream")) {
802 outputStream_ = getParameter<RCP<std::ostream> > (*params,
"Output Stream");
803 }
catch (InvalidParameter&) {
804 outputStream_ = rcpFromRef (std::cout);
811 if (outputStream_.is_null()) {
812 outputStream_ = rcp (
new Teuchos::oblackholestream);
815 params_->set (
"Output Stream", outputStream_);
818 if (! printer_.is_null()) {
819 printer_->setOStream (outputStream_);
825 if (params->isParameter (
"Output Frequency")) {
826 outputFreq_ = params->get (
"Output Frequency", outputFreq_default_);
830 params_->set(
"Output Frequency", outputFreq_);
831 if (! outputTest_.is_null())
832 outputTest_->setOutputFrequency (outputFreq_);
839 if (printer_.is_null()) {
850 bool changedOrthoType =
false;
851 if (params->isParameter (
"Orthogonalization")) {
852 const std::string& tempOrthoType =
853 params->get (
"Orthogonalization", orthoType_default_);
856 std::ostringstream os;
857 os <<
"Belos::GCRODRSolMgr: Invalid orthogonalization name \""
858 << tempOrthoType <<
"\". The following are valid options "
859 <<
"for the \"Orthogonalization\" name parameter: ";
861 throw std::invalid_argument (os.str());
863 if (tempOrthoType != orthoType_) {
864 changedOrthoType =
true;
865 orthoType_ = tempOrthoType;
867 params_->set (
"Orthogonalization", orthoType_);
883 RCP<ParameterList> orthoParams;
886 using Teuchos::sublist;
888 const std::string paramName (
"Orthogonalization Parameters");
891 orthoParams = sublist (params_, paramName,
true);
892 }
catch (InvalidParameter&) {
899 orthoParams = sublist (params_, paramName,
true);
902 TEUCHOS_TEST_FOR_EXCEPTION(orthoParams.is_null(), std::logic_error,
903 "Failed to get orthogonalization parameters. "
904 "Please report this bug to the Belos developers.");
909 if (ortho_.is_null() || changedOrthoType) {
915 label_, orthoParams);
923 typedef Teuchos::ParameterListAcceptor PLA;
924 RCP<PLA> pla = rcp_dynamic_cast<PLA> (ortho_);
930 label_, orthoParams);
932 pla->setParameterList (orthoParams);
944 if (params->isParameter (
"Orthogonalization Constant")) {
945 MagnitudeType orthoKappa = orthoKappa_default_;
946 if (params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
947 orthoKappa = params->get (
"Orthogonalization Constant", orthoKappa);
950 orthoKappa = params->get (
"Orthogonalization Constant", orthoKappa_default_);
953 if (orthoKappa > 0) {
954 orthoKappa_ = orthoKappa;
956 params_->set(
"Orthogonalization Constant", orthoKappa_);
958 if (orthoType_ ==
"DGKS" && ! ortho_.is_null()) {
965 rcp_dynamic_cast<ortho_man_type>(ortho_)->
setDepTol (orthoKappa_);
975 if (params->isParameter(
"Convergence Tolerance")) {
976 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
977 convTol_ = params->get (
"Convergence Tolerance",
985 params_->set (
"Convergence Tolerance", convTol_);
986 if (! impConvTest_.is_null())
988 if (! expConvTest_.is_null())
989 expConvTest_->setTolerance (convTol_);
993 if (params->isParameter (
"Implicit Residual Scaling")) {
994 std::string tempImpResScale =
995 getParameter<std::string> (*params,
"Implicit Residual Scaling");
998 if (impResScale_ != tempImpResScale) {
1000 impResScale_ = tempImpResScale;
1003 params_->set(
"Implicit Residual Scaling", impResScale_);
1013 if (! impConvTest_.is_null()) {
1019 impConvTest_ =
null;
1026 if (params->isParameter(
"Explicit Residual Scaling")) {
1027 std::string tempExpResScale =
1028 getParameter<std::string> (*params,
"Explicit Residual Scaling");
1031 if (expResScale_ != tempExpResScale) {
1033 expResScale_ = tempExpResScale;
1036 params_->set(
"Explicit Residual Scaling", expResScale_);
1039 if (! expConvTest_.is_null()) {
1045 expConvTest_ =
null;
1056 if (maxIterTest_.is_null())
1061 if (impConvTest_.is_null()) {
1062 impConvTest_ = rcp (
new StatusTestResNorm_t (convTol_));
1068 if (expConvTest_.is_null()) {
1069 expConvTest_ = rcp (
new StatusTestResNorm_t (convTol_));
1070 expConvTest_->defineResForm (StatusTestResNorm_t::Explicit,
Belos::TwoNorm);
1076 if (convTest_.is_null()) {
1077 convTest_ = rcp (
new StatusTestCombo_t (StatusTestCombo_t::SEQ,
1085 sTest_ = rcp (
new StatusTestCombo_t (StatusTestCombo_t::OR,
1091 outputTest_ = stoFactory.
create (printer_, sTest_, outputFreq_,
1095 std::string solverDesc =
" GCRODR ";
1096 outputTest_->setSolverDesc( solverDesc );
1099 if (timerSolve_.is_null()) {
1100 std::string solveLabel = label_ +
": GCRODRSolMgr total solve time";
1101 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1102 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
1111 template<
class ScalarType,
class MV,
class OP>
1112 Teuchos::RCP<const Teuchos::ParameterList>
1115 using Teuchos::ParameterList;
1116 using Teuchos::parameterList;
1119 static RCP<const ParameterList> validPL;
1120 if (is_null(validPL)) {
1121 RCP<ParameterList> pl = parameterList ();
1125 "The relative residual tolerance that needs to be achieved by the\n"
1126 "iterative solver in order for the linear system to be declared converged.");
1127 pl->set(
"Maximum Restarts", static_cast<int>(maxRestarts_default_),
1128 "The maximum number of cycles allowed for each\n"
1129 "set of RHS solved.");
1130 pl->set(
"Maximum Iterations", static_cast<int>(maxIters_default_),
1131 "The maximum number of iterations allowed for each\n"
1132 "set of RHS solved.");
1136 pl->set(
"Block Size", static_cast<int>(blockSize_default_),
1137 "Block Size Parameter -- currently must be 1 for GCRODR");
1138 pl->set(
"Num Blocks", static_cast<int>(numBlocks_default_),
1139 "The maximum number of vectors allowed in the Krylov subspace\n"
1140 "for each set of RHS solved.");
1141 pl->set(
"Num Recycled Blocks", static_cast<int>(recycledBlocks_default_),
1142 "The maximum number of vectors in the recycled subspace." );
1143 pl->set(
"Verbosity", static_cast<int>(verbosity_default_),
1144 "What type(s) of solver information should be outputted\n"
1145 "to the output stream.");
1146 pl->set(
"Output Style", static_cast<int>(outputStyle_default_),
1147 "What style is used for the solver information outputted\n"
1148 "to the output stream.");
1149 pl->set(
"Output Frequency", static_cast<int>(outputFreq_default_),
1150 "How often convergence information should be outputted\n"
1151 "to the output stream.");
1152 pl->set(
"Output Stream", Teuchos::rcp(outputStream_default_,
false),
1153 "A reference-counted pointer to the output stream where all\n"
1154 "solver output is sent.");
1155 pl->set(
"Implicit Residual Scaling", static_cast<const char *>(impResScale_default_),
1156 "The type of scaling used in the implicit residual convergence test.");
1157 pl->set(
"Explicit Residual Scaling", static_cast<const char *>(expResScale_default_),
1158 "The type of scaling used in the explicit residual convergence test.");
1159 pl->set(
"Timer Label", static_cast<const char *>(label_default_),
1160 "The string to use as a prefix for the timer labels.");
1163 pl->set(
"Orthogonalization", static_cast<const char *>(orthoType_default_),
1164 "The type of orthogonalization to use. Valid options: " +
1166 RCP<const ParameterList> orthoParams =
1168 pl->set (
"Orthogonalization Parameters", *orthoParams,
1169 "Parameters specific to the type of orthogonalization used.");
1171 pl->set(
"Orthogonalization Constant",static_cast<MagnitudeType>(orthoKappa_default_),
1172 "When using DGKS orthogonalization: the \"depTol\" constant, used "
1173 "to determine whether another step of classical Gram-Schmidt is "
1174 "necessary. Otherwise ignored.");
1181 template<
class ScalarType,
class MV,
class OP>
1184 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1187 Teuchos::RCP<const MV> rhsMV = problem_->getRHS();
1188 if (rhsMV == Teuchos::null) {
1195 TEUCHOS_TEST_FOR_EXCEPTION(static_cast<ptrdiff_t>(numBlocks_) > MVT::GetGlobalLength(*rhsMV),std::invalid_argument,
1196 "Belos::GCRODRSolMgr::initializeStateStorage(): Cannot generate a Krylov basis with dimension larger the operator!");
1199 if (U_ == Teuchos::null) {
1200 U_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1204 if (MVT::GetNumberVecs(*U_) < recycledBlocks_+1) {
1205 Teuchos::RCP<const MV> tmp = U_;
1206 U_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1211 if (C_ == Teuchos::null) {
1212 C_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1216 if (MVT::GetNumberVecs(*C_) < recycledBlocks_+1) {
1217 Teuchos::RCP<const MV> tmp = C_;
1218 C_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1223 if (V_ == Teuchos::null) {
1224 V_ = MVT::Clone( *rhsMV, numBlocks_+1 );
1228 if (MVT::GetNumberVecs(*V_) < numBlocks_+1) {
1229 Teuchos::RCP<const MV> tmp = V_;
1230 V_ = MVT::Clone( *tmp, numBlocks_+1 );
1235 if (U1_ == Teuchos::null) {
1236 U1_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1240 if (MVT::GetNumberVecs(*U1_) < recycledBlocks_+1) {
1241 Teuchos::RCP<const MV> tmp = U1_;
1242 U1_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1247 if (C1_ == Teuchos::null) {
1248 C1_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1252 if (MVT::GetNumberVecs(*C1_) < recycledBlocks_+1) {
1253 Teuchos::RCP<const MV> tmp = C1_;
1254 C1_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1259 if (r_ == Teuchos::null)
1260 r_ = MVT::Clone( *rhsMV, 1 );
1263 tau_.resize(recycledBlocks_+1);
1266 work_.resize(recycledBlocks_+1);
1269 ipiv_.resize(recycledBlocks_+1);
1272 if (H2_ == Teuchos::null)
1273 H2_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 ) );
1275 if ( (H2_->numRows() != numBlocks_+recycledBlocks_+2) || (H2_->numCols() != numBlocks_+recycledBlocks_+1) )
1276 H2_->reshape( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1278 H2_->putScalar(zero);
1281 if (R_ == Teuchos::null)
1282 R_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( recycledBlocks_+1, recycledBlocks_+1 ) );
1284 if ( (R_->numRows() != recycledBlocks_+1) || (R_->numCols() != recycledBlocks_+1) )
1285 R_->reshape( recycledBlocks_+1, recycledBlocks_+1 );
1287 R_->putScalar(zero);
1290 if (PP_ == Teuchos::null)
1291 PP_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 ) );
1293 if ( (PP_->numRows() != numBlocks_+recycledBlocks_+2) || (PP_->numCols() != recycledBlocks_+1) )
1294 PP_->reshape( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 );
1298 if (HP_ == Teuchos::null)
1299 HP_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 ) );
1301 if ( (HP_->numRows() != numBlocks_+recycledBlocks_+2) || (HP_->numCols() != numBlocks_+recycledBlocks_+1) )
1302 HP_->reshape( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1310 template<
class ScalarType,
class MV,
class OP>
1318 if (!isSet_) { setParameters( params_ ); }
1320 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
1321 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1322 std::vector<int> index(numBlocks_+1);
1324 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,
GCRODRSolMgrLinearProblemFailure,
"Belos::GCRODRSolMgr::solve(): Linear problem is not a valid object.");
1326 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(),
GCRODRSolMgrLinearProblemFailure,
"Belos::GCRODRSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1329 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1330 std::vector<int> currIdx(1);
1334 problem_->setLSIndex( currIdx );
1337 ptrdiff_t dim = MVT::GetGlobalLength( *(problem_->getRHS()) );
1338 if (static_cast<ptrdiff_t>(numBlocks_) > dim) {
1339 numBlocks_ = Teuchos::as<int>(dim);
1341 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1342 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1343 params_->set(
"Num Blocks", numBlocks_);
1347 bool isConverged =
true;
1350 initializeStateStorage();
1354 Teuchos::ParameterList plist;
1356 plist.set(
"Num Blocks",numBlocks_);
1357 plist.set(
"Recycled Blocks",recycledBlocks_);
1362 RCP<GCRODRIter<ScalarType,MV,OP> > gcrodr_iter;
1365 int prime_iterations = 0;
1369 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1370 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1373 while ( numRHS2Solve > 0 ) {
1376 builtRecycleSpace_ =
false;
1379 outputTest_->reset();
1387 "Belos::GCRODRSolMgr::solve(): Requested size of recycled subspace is not consistent with the current recycle subspace.");
1389 printer_->stream(
Debug) <<
" Now solving RHS index " << currIdx[0] <<
" using recycled subspace of dimension " << keff << std::endl << std::endl;
1392 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1393 RCP<const MV> Utmp = MVT::CloneView( *U_, index );
1394 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1395 problem_->apply( *Utmp, *Ctmp );
1397 RCP<MV> U1tmp = MVT::CloneViewNonConst( *U1_, index );
1401 Teuchos::SerialDenseMatrix<int,ScalarType> Rtmp( Teuchos::View, *R_, keff, keff );
1402 int rank = ortho_->normalize(*Ctmp, rcp(&Rtmp,
false));
1404 TEUCHOS_TEST_FOR_EXCEPTION(rank != keff,
GCRODRSolMgrOrthoFailure,
"Belos::GCRODRSolMgr::solve(): Failed to compute orthonormal basis for initial recycled subspace.");
1409 ipiv_.resize(Rtmp.numRows());
1410 lapack.GETRF(Rtmp.numRows(),Rtmp.numCols(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&info);
1411 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
1414 int lwork = Rtmp.numRows();
1415 work_.resize(lwork);
1416 lapack.GETRI(Rtmp.numRows(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&work_[0],lwork,&info);
1417 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to invert triangular matrix.");
1420 MVT::MvTimesMatAddMv( one, *Utmp, Rtmp, zero, *U1tmp );
1425 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1426 Ctmp = MVT::CloneViewNonConst( *C_, index );
1427 Utmp = MVT::CloneView( *U_, index );
1430 Teuchos::SerialDenseMatrix<int,ScalarType> Ctr(keff,1);
1431 problem_->computeCurrPrecResVec( &*r_ );
1432 MVT::MvTransMv( one, *Ctmp, *r_, Ctr );
1435 RCP<MV> update = MVT::Clone( *problem_->getCurrLHSVec(), 1 );
1436 MVT::MvInit( *update, 0.0 );
1437 MVT::MvTimesMatAddMv( one, *Utmp, Ctr, one, *update );
1438 problem_->updateSolution( update,
true );
1441 MVT::MvTimesMatAddMv( -one, *Ctmp, Ctr, one, *r_ );
1444 prime_iterations = 0;
1450 printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " << currIdx[0] << std::endl << std::endl;
1452 Teuchos::ParameterList primeList;
1455 primeList.set(
"Num Blocks",numBlocks_);
1456 primeList.set(
"Recycled Blocks",0);
1459 RCP<GCRODRIter<ScalarType,MV,OP> > gcrodr_prime_iter;
1463 problem_->computeCurrPrecResVec( &*r_ );
1464 index.resize( 1 ); index[0] = 0;
1465 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1466 MVT::SetBlock(*r_,index,*v0);
1470 index.resize( numBlocks_+1 );
1471 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1472 newstate.
V = MVT::CloneViewNonConst( *V_, index );
1473 newstate.
U = Teuchos::null;
1474 newstate.
C = Teuchos::null;
1475 newstate.
H = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, recycledBlocks_+1, recycledBlocks_+1 ) );
1476 newstate.
B = Teuchos::null;
1478 gcrodr_prime_iter->initialize(newstate);
1481 bool primeConverged =
false;
1483 gcrodr_prime_iter->iterate();
1486 if ( convTest_->getStatus() ==
Passed ) {
1488 primeConverged =
true;
1493 gcrodr_prime_iter->updateLSQR( gcrodr_prime_iter->getCurSubspaceDim() );
1496 sTest_->checkStatus( &*gcrodr_prime_iter );
1497 if (convTest_->getStatus() ==
Passed)
1498 primeConverged =
true;
1500 catch (
const std::exception &e) {
1501 printer_->stream(
Errors) <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1502 << gcrodr_prime_iter->getNumIters() << std::endl
1503 << e.what() << std::endl;
1507 prime_iterations = gcrodr_prime_iter->getNumIters();
1510 RCP<MV> update = gcrodr_prime_iter->getCurrentUpdate();
1511 problem_->updateSolution( update,
true );
1514 newstate = gcrodr_prime_iter->getState();
1522 if (recycledBlocks_ < p+1) {
1524 RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PPtmp = rcp (
new Teuchos::SerialDenseMatrix<int,ScalarType> ( Teuchos::View, *PP_, p, recycledBlocks_+1 ) );
1526 keff = getHarmonicVecs1( p, *newstate.
H, *PPtmp );
1528 PPtmp = rcp (
new Teuchos::SerialDenseMatrix<int,ScalarType> ( Teuchos::View, *PP_, p, keff ) );
1531 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1532 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1533 RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
1534 RCP<MV> U1tmp = MVT::CloneViewNonConst( *U1_, index );
1536 for (
int ii=0; ii < p; ++ii) { index[ii] = ii; }
1537 RCP<const MV> Vtmp = MVT::CloneView( *V_, index );
1541 MVT::MvTimesMatAddMv( one, *Vtmp, *PPtmp, zero, *U1tmp );
1548 Teuchos::SerialDenseMatrix<int,ScalarType> Htmp( Teuchos::View, *H2_, p+1, p, recycledBlocks_+1,recycledBlocks_+1);
1549 Teuchos::SerialDenseMatrix<int,ScalarType> HPtmp( Teuchos::View, *HP_, p+1, keff );
1550 HPtmp.multiply( Teuchos::NO_TRANS, Teuchos::NO_TRANS, one, Htmp, *PPtmp, zero );
1557 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1558 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1559 TEUCHOS_TEST_FOR_EXCEPTION(
1561 " LAPACK's _GEQRF failed to compute a workspace size.");
1569 lwork = std::abs (static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1570 work_.resize (lwork);
1571 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1572 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1573 TEUCHOS_TEST_FOR_EXCEPTION(
1575 " LAPACK's _GEQRF failed to compute a QR factorization.");
1579 Teuchos::SerialDenseMatrix<int,ScalarType> Rtmp( Teuchos::View, *R_, keff, keff );
1580 for (
int ii = 0; ii < keff; ++ii) {
1581 for (
int jj = ii; jj < keff; ++jj) {
1582 Rtmp(ii,jj) = HPtmp(ii,jj);
1589 lapack.UNGQR (HPtmp.numRows (), HPtmp.numCols (), HPtmp.numCols (),
1590 HPtmp.values (), HPtmp.stride (), &tau_[0], &work_[0],
1592 TEUCHOS_TEST_FOR_EXCEPTION(
1594 "LAPACK's _UNGQR failed to construct the Q factor.");
1599 index.resize (p + 1);
1600 for (
int ii = 0; ii < (p+1); ++ii) {
1603 Vtmp = MVT::CloneView( *V_, index );
1604 MVT::MvTimesMatAddMv( one, *Vtmp, HPtmp, zero, *Ctmp );
1611 ipiv_.resize(Rtmp.numRows());
1612 lapack.GETRF(Rtmp.numRows(),Rtmp.numCols(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&info);
1613 TEUCHOS_TEST_FOR_EXCEPTION(
1615 "LAPACK's _GETRF failed to compute an LU factorization.");
1624 lwork = Rtmp.numRows();
1625 work_.resize(lwork);
1626 lapack.GETRI(Rtmp.numRows(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&work_[0],lwork,&info);
1627 TEUCHOS_TEST_FOR_EXCEPTION(
1629 "LAPACK's _GETRI failed to invert triangular matrix.");
1632 MVT::MvTimesMatAddMv( one, *U1tmp, Rtmp, zero, *Utmp );
1634 printer_->stream(
Debug)
1635 <<
" Generated recycled subspace using RHS index " << currIdx[0]
1636 <<
" of dimension " << keff << std::endl << std::endl;
1641 if (primeConverged) {
1643 problem_->setCurrLS();
1647 if (numRHS2Solve > 0) {
1649 problem_->setLSIndex (currIdx);
1652 currIdx.resize (numRHS2Solve);
1662 gcrodr_iter->setSize( keff, numBlocks_ );
1665 gcrodr_iter->resetNumIters(prime_iterations);
1668 outputTest_->resetNumCalls();
1671 problem_->computeCurrPrecResVec( &*r_ );
1672 index.resize( 1 ); index[0] = 0;
1673 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1674 MVT::SetBlock(*r_,index,*v0);
1678 index.resize( numBlocks_+1 );
1679 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1680 newstate.
V = MVT::CloneViewNonConst( *V_, index );
1681 index.resize( keff );
1682 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1683 newstate.
C = MVT::CloneViewNonConst( *C_, index );
1684 newstate.
U = MVT::CloneViewNonConst( *U_, index );
1685 newstate.
B = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1686 newstate.
H = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1688 gcrodr_iter->initialize(newstate);
1691 int numRestarts = 0;
1696 gcrodr_iter->iterate();
1703 if ( convTest_->getStatus() ==
Passed ) {
1712 else if ( maxIterTest_->getStatus() ==
Passed ) {
1714 isConverged =
false;
1722 else if ( gcrodr_iter->getCurSubspaceDim() == gcrodr_iter->getMaxSubspaceDim() ) {
1727 RCP<MV> update = gcrodr_iter->getCurrentUpdate();
1728 problem_->updateSolution( update,
true );
1730 buildRecycleSpace2(gcrodr_iter);
1732 printer_->stream(
Debug)
1733 <<
" Generated new recycled subspace using RHS index "
1734 << currIdx[0] <<
" of dimension " << keff << std::endl
1738 if (numRestarts >= maxRestarts_) {
1739 isConverged =
false;
1744 printer_->stream(
Debug)
1745 <<
" Performing restart number " << numRestarts <<
" of "
1746 << maxRestarts_ << std::endl << std::endl;
1749 problem_->computeCurrPrecResVec( &*r_ );
1750 index.resize( 1 ); index[0] = 0;
1751 RCP<MV> v00 = MVT::CloneViewNonConst( *V_, index );
1752 MVT::SetBlock(*r_,index,*v00);
1756 index.resize( numBlocks_+1 );
1757 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1758 restartState.
V = MVT::CloneViewNonConst( *V_, index );
1759 index.resize( keff );
1760 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1761 restartState.
U = MVT::CloneViewNonConst( *U_, index );
1762 restartState.
C = MVT::CloneViewNonConst( *C_, index );
1763 restartState.
B = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1764 restartState.
H = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1766 gcrodr_iter->initialize(restartState);
1779 TEUCHOS_TEST_FOR_EXCEPTION(
1780 true, std::logic_error,
"Belos::GCRODRSolMgr::solve: "
1781 "Invalid return from GCRODRIter::iterate().");
1786 gcrodr_iter->updateLSQR( gcrodr_iter->getCurSubspaceDim() );
1789 sTest_->checkStatus( &*gcrodr_iter );
1790 if (convTest_->getStatus() !=
Passed)
1791 isConverged =
false;
1794 catch (
const std::exception& e) {
1796 <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1797 << gcrodr_iter->getNumIters() << std::endl << e.what() << std::endl;
1804 RCP<MV> update = gcrodr_iter->getCurrentUpdate();
1805 problem_->updateSolution( update,
true );
1808 problem_->setCurrLS();
1813 if (!builtRecycleSpace_) {
1814 buildRecycleSpace2(gcrodr_iter);
1815 printer_->stream(
Debug)
1816 <<
" Generated new recycled subspace using RHS index " << currIdx[0]
1817 <<
" of dimension " << keff << std::endl << std::endl;
1822 if (numRHS2Solve > 0) {
1824 problem_->setLSIndex (currIdx);
1827 currIdx.resize (numRHS2Solve);
1835 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1840 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1841 #endif // BELOS_TEUCHOS_TIME_MONITOR
1844 numIters_ = maxIterTest_->getNumIters ();
1856 const std::vector<MagnitudeType>* pTestValues = expConvTest_->getTestValue();
1857 if (pTestValues == NULL || pTestValues->size() < 1) {
1858 pTestValues = impConvTest_->getTestValue();
1860 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1861 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1862 "method returned NULL. Please report this bug to the Belos developers.");
1863 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1864 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1865 "method returned a vector of length zero. Please report this bug to the "
1866 "Belos developers.");
1871 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1878 template<
class ScalarType,
class MV,
class OP>
1881 MagnitudeType one = Teuchos::ScalarTraits<MagnitudeType>::one();
1882 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1884 std::vector<MagnitudeType> d(keff);
1885 std::vector<ScalarType> dscalar(keff);
1886 std::vector<int> index(numBlocks_+1);
1898 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1899 Teuchos::RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
1901 dscalar.resize(keff);
1902 MVT::MvNorm( *Utmp, d );
1903 for (
int i=0; i<keff; ++i) {
1905 dscalar[i] = (ScalarType)d[i];
1907 MVT::MvScale( *Utmp, dscalar );
1911 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H2tmp = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, p+keff+1, p+keff ) );
1914 for (
int i=0; i<keff; ++i) {
1915 (*H2tmp)(i,i) = d[i];
1922 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, p+keff, recycledBlocks_+1 );
1923 keff_new = getHarmonicVecs2( keff, p, *H2tmp, oldState.
V, PPtmp );
1930 Teuchos::RCP<MV> U1tmp;
1932 index.resize( keff );
1933 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1934 Teuchos::RCP<const MV> Utmp = MVT::CloneView( *U_, index );
1935 index.resize( keff_new );
1936 for (
int ii=0; ii<keff_new; ++ii) { index[ii] = ii; }
1937 U1tmp = MVT::CloneViewNonConst( *U1_, index );
1938 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, keff, keff_new );
1939 MVT::MvTimesMatAddMv( one, *Utmp, PPtmp, zero, *U1tmp );
1945 for (
int ii=0; ii < p; ii++) { index[ii] = ii; }
1946 Teuchos::RCP<const MV> Vtmp = MVT::CloneView( *V_, index );
1947 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, p, keff_new, keff );
1948 MVT::MvTimesMatAddMv( one, *Vtmp, PPtmp, one, *U1tmp );
1952 Teuchos::SerialDenseMatrix<int,ScalarType> HPtmp( Teuchos::View, *HP_, p+keff+1, keff_new );
1954 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, p+keff, keff_new );
1955 HPtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,*H2tmp,PPtmp,zero);
1959 int info = 0, lwork = -1;
1960 tau_.resize (keff_new);
1961 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1962 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1963 TEUCHOS_TEST_FOR_EXCEPTION(
1964 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
1965 "LAPACK's _GEQRF failed to compute a workspace size.");
1971 lwork = std::abs (static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1972 work_.resize (lwork);
1973 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1974 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1975 TEUCHOS_TEST_FOR_EXCEPTION(
1976 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
1977 "LAPACK's _GEQRF failed to compute a QR factorization.");
1981 Teuchos::SerialDenseMatrix<int,ScalarType> Rtmp( Teuchos::View, *R_, keff_new, keff_new );
1982 for(
int i=0;i<keff_new;i++) {
for(
int j=i;j<keff_new;j++) Rtmp(i,j) = HPtmp(i,j); }
1988 lapack.UNGQR (HPtmp.numRows (), HPtmp.numCols (), HPtmp.numCols (),
1989 HPtmp.values (), HPtmp.stride (), &tau_[0], &work_[0],
1991 TEUCHOS_TEST_FOR_EXCEPTION(
1992 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
1993 "LAPACK's _UNGQR failed to construct the Q factor.");
2000 Teuchos::RCP<MV> C1tmp;
2003 for (
int i=0; i < keff; i++) { index[i] = i; }
2004 Teuchos::RCP<const MV> Ctmp = MVT::CloneView( *C_, index );
2005 index.resize(keff_new);
2006 for (
int i=0; i < keff_new; i++) { index[i] = i; }
2007 C1tmp = MVT::CloneViewNonConst( *C1_, index );
2008 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *HP_, keff, keff_new );
2009 MVT::MvTimesMatAddMv( one, *Ctmp, PPtmp, zero, *C1tmp );
2013 index.resize( p+1 );
2014 for (
int i=0; i < p+1; ++i) { index[i] = i; }
2015 Teuchos::RCP<const MV> Vtmp = MVT::CloneView( *V_, index );
2016 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *HP_, p+1, keff_new, keff, 0 );
2017 MVT::MvTimesMatAddMv( one, *Vtmp, PPtmp, one, *C1tmp );
2026 ipiv_.resize(Rtmp.numRows());
2027 lapack.GETRF(Rtmp.numRows(),Rtmp.numCols(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&info);
2028 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
2031 lwork = Rtmp.numRows();
2032 work_.resize(lwork);
2033 lapack.GETRI(Rtmp.numRows(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&work_[0],lwork,&info);
2034 TEUCHOS_TEST_FOR_EXCEPTION(info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to compute an LU factorization.");
2037 index.resize(keff_new);
2038 for (
int i=0; i < keff_new; i++) { index[i] = i; }
2039 Teuchos::RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
2040 MVT::MvTimesMatAddMv( one, *U1tmp, Rtmp, zero, *Utmp );
2044 if (keff != keff_new) {
2046 gcrodr_iter->setSize( keff, numBlocks_ );
2048 Teuchos::SerialDenseMatrix<int,ScalarType> b1( Teuchos::View, *H2_, recycledBlocks_+2, 1, 0, recycledBlocks_ );
2056 template<
class ScalarType,
class MV,
class OP>
2057 int GCRODRSolMgr<ScalarType,MV,OP,true>::getHarmonicVecs1(
int m,
2058 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2059 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2061 bool xtraVec =
false;
2062 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
2066 std::vector<MagnitudeType> wr(m), wi(m);
2069 Teuchos::SerialDenseMatrix<int,ScalarType> vr(m,m,
false);
2072 std::vector<MagnitudeType> w(m);
2075 std::vector<int> iperm(m);
2079 std::vector<ScalarType> work(lwork);
2080 std::vector<MagnitudeType> rwork(lwork);
2086 builtRecycleSpace_ =
true;
2089 Teuchos::SerialDenseMatrix<int, ScalarType> HHt( HH,
Teuchos::TRANS );
2090 Teuchos::SerialDenseVector<int, ScalarType> e_m( m );
2092 lapack.GESV(m, 1, HHt.values(), HHt.stride(), &iperm[0], e_m.values(), e_m.stride(), &info);
2093 TEUCHOS_TEST_FOR_EXCEPTION(info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GESV failed to compute a solution.");
2096 ScalarType d = HH(m, m-1) * HH(m, m-1);
2097 Teuchos::SerialDenseMatrix<int, ScalarType> harmHH( Teuchos::Copy, HH, HH.numRows(), HH.numCols() );
2098 for( i=0; i<m; ++i )
2099 harmHH(i, m-1) += d * e_m[i];
2107 lapack.GEEV(
'N',
'V', m, harmHH.values(), harmHH.stride(), &wr[0], &wi[0],
2108 vl, ldvl, vr.values(), vr.stride(), &work[0], lwork, &rwork[0], &info);
2109 TEUCHOS_TEST_FOR_EXCEPTION(info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GEEV failed to compute eigensolutions.");
2112 for( i=0; i<m; ++i )
2113 w[i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot( wr[i]*wr[i] + wi[i]*wi[i] );
2116 this->sort(w, m, iperm);
2118 const bool scalarTypeIsComplex = Teuchos::ScalarTraits<ScalarType>::isComplex;
2121 for( i=0; i<recycledBlocks_; ++i ) {
2122 for( j=0; j<m; j++ ) {
2123 PP(j,i) = vr(j,iperm[i]);
2127 if(!scalarTypeIsComplex) {
2130 if (wi[iperm[recycledBlocks_-1]] != 0.0) {
2132 for ( i=0; i<recycledBlocks_; ++i ) {
2133 if (wi[iperm[i]] != 0.0)
2142 if (wi[iperm[recycledBlocks_-1]] > 0.0) {
2143 for( j=0; j<m; ++j ) {
2144 PP(j,recycledBlocks_) = vr(j,iperm[recycledBlocks_-1]+1);
2148 for( j=0; j<m; ++j ) {
2149 PP(j,recycledBlocks_) = vr(j,iperm[recycledBlocks_-1]-1);
2158 return recycledBlocks_+1;
2161 return recycledBlocks_;
2167 template<
class ScalarType,
class MV,
class OP>
2168 int GCRODRSolMgr<ScalarType,MV,OP,true>::getHarmonicVecs2(
int keffloc,
int m,
2169 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2170 const Teuchos::RCP<const MV>& VV,
2171 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2173 int m2 = HH.numCols();
2174 bool xtraVec =
false;
2175 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
2176 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
2177 std::vector<int> index;
2180 std::vector<MagnitudeType> wr(m2), wi(m2);
2183 std::vector<MagnitudeType> w(m2);
2186 Teuchos::SerialDenseMatrix<int,ScalarType> vr(m2,m2,
false);
2189 std::vector<int> iperm(m2);
2192 builtRecycleSpace_ =
true;
2197 Teuchos::SerialDenseMatrix<int,ScalarType> B(m2,m2,
false);
2202 Teuchos::SerialDenseMatrix<int,ScalarType> A_tmp( keffloc+m+1, keffloc+m );
2205 index.resize(keffloc);
2206 for (i=0; i<keffloc; ++i) { index[i] = i; }
2207 Teuchos::RCP<const MV> Ctmp = MVT::CloneView( *C_, index );
2208 Teuchos::RCP<const MV> Utmp = MVT::CloneView( *U_, index );
2209 Teuchos::SerialDenseMatrix<int,ScalarType> A11( Teuchos::View, A_tmp, keffloc, keffloc );
2210 MVT::MvTransMv( one, *Ctmp, *Utmp, A11 );
2213 Teuchos::SerialDenseMatrix<int,ScalarType> A21( Teuchos::View, A_tmp, m+1, keffloc, keffloc );
2215 for (i=0; i < m+1; i++) { index[i] = i; }
2216 Teuchos::RCP<const MV> Vp = MVT::CloneView( *VV, index );
2217 MVT::MvTransMv( one, *Vp, *Utmp, A21 );
2220 for( i=keffloc; i<keffloc+m; i++ ) {
2225 Teuchos::SerialDenseMatrix<int,ScalarType> A( m2, A_tmp.numCols() );
2226 A.multiply(
Teuchos::TRANS, Teuchos::NO_TRANS, one, HH, A_tmp, zero );
2234 char balanc=
'P', jobvl=
'N', jobvr=
'V', sense=
'N';
2235 int ld = A.numRows();
2237 int ldvl = ld, ldvr = ld;
2238 int info = 0,ilo = 0,ihi = 0;
2239 MagnitudeType abnrm = 0.0, bbnrm = 0.0;
2241 std::vector<ScalarType> beta(ld);
2242 std::vector<ScalarType> work(lwork);
2243 std::vector<MagnitudeType> rwork(lwork);
2244 std::vector<MagnitudeType> lscale(ld), rscale(ld);
2245 std::vector<MagnitudeType> rconde(ld), rcondv(ld);
2246 std::vector<int> iwork(ld+6);
2251 lapack.GGEVX(balanc, jobvl, jobvr, sense, ld, A.values(), ld, B.values(), ld, &wr[0], &wi[0],
2252 &beta[0], vl, ldvl, vr.values(), ldvr, &ilo, &ihi, &lscale[0], &rscale[0],
2253 &abnrm, &bbnrm, &rconde[0], &rcondv[0], &work[0], lwork, &rwork[0],
2254 &iwork[0], bwork, &info);
2255 TEUCHOS_TEST_FOR_EXCEPTION(info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GGEVX failed to compute eigensolutions.");
2259 for( i=0; i<ld; i++ ) {
2260 w[i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot (wr[i]*wr[i] + wi[i]*wi[i]) /
2261 Teuchos::ScalarTraits<ScalarType>::magnitude (beta[i]);
2265 this->sort(w,ld,iperm);
2267 const bool scalarTypeIsComplex = Teuchos::ScalarTraits<ScalarType>::isComplex;
2270 for( i=0; i<recycledBlocks_; i++ ) {
2271 for( j=0; j<ld; j++ ) {
2272 PP(j,i) = vr(j,iperm[ld-recycledBlocks_+i]);
2276 if(!scalarTypeIsComplex) {
2279 if (wi[iperm[ld-recycledBlocks_]] != 0.0) {
2281 for ( i=ld-recycledBlocks_; i<ld; i++ ) {
2282 if (wi[iperm[i]] != 0.0)
2291 if (wi[iperm[ld-recycledBlocks_]] > 0.0) {
2292 for( j=0; j<ld; j++ ) {
2293 PP(j,recycledBlocks_) = vr(j,iperm[ld-recycledBlocks_]+1);
2297 for( j=0; j<ld; j++ ) {
2298 PP(j,recycledBlocks_) = vr(j,iperm[ld-recycledBlocks_]-1);
2307 return recycledBlocks_+1;
2310 return recycledBlocks_;
2317 template<
class ScalarType,
class MV,
class OP>
2318 void GCRODRSolMgr<ScalarType,MV,OP,true>::sort(std::vector<MagnitudeType>& dlist,
int n, std::vector<int>& iperm) {
2319 int l, r, j, i, flag;
2321 MagnitudeType dRR, dK;
2348 if (dlist[j] > dlist[j - 1]) j = j + 1;
2350 if (dlist[j - 1] > dK) {
2351 dlist[i - 1] = dlist[j - 1];
2352 iperm[i - 1] = iperm[j - 1];
2366 dlist[r] = dlist[0];
2367 iperm[r] = iperm[0];
2382 template<
class ScalarType,
class MV,
class OP>
2384 std::ostringstream out;
2385 out <<
"Belos::GCRODRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
2387 out <<
"Ortho Type: \"" << orthoType_ <<
"\"";
2388 out <<
", Num Blocks: " <<numBlocks_;
2389 out <<
", Num Recycle Blocks: " << recycledBlocks_;
2390 out <<
", Max Restarts: " << maxRestarts_;