10#ifndef BELOS_GCRODR_SOLMGR_HPP
11#define BELOS_GCRODR_SOLMGR_HPP
30#include "Teuchos_BLAS.hpp"
31#include "Teuchos_LAPACK.hpp"
32#include "Teuchos_as.hpp"
33#ifdef BELOS_TEUCHOS_TIME_MONITOR
34# include "Teuchos_TimeMonitor.hpp"
36#if defined(HAVE_TEUCHOSCORE_CXX11)
37# include <type_traits>
125 template<
class ScalarType,
class MV,
class OP,
126 const bool lapackSupportsScalarType =
131 static const bool requiresLapack =
134 requiresLapack> base_type;
141 const Teuchos::RCP<Teuchos::ParameterList>& pl) :
150 template<
class ScalarType,
class MV,
class OP>
155#if defined(HAVE_TEUCHOSCORE_CXX11)
156# if defined(HAVE_TEUCHOS_COMPLEX)
157 #if defined(HAVE_TEUCHOS_LONG_DOUBLE)
158 static_assert (std::is_same<ScalarType, std::complex<float> >::value ||
159 std::is_same<ScalarType, std::complex<double> >::value ||
160 std::is_same<ScalarType, Kokkos::complex<double> >::value ||
161 std::is_same<ScalarType, float>::value ||
162 std::is_same<ScalarType, double>::value ||
163 std::is_same<ScalarType, long double>::value,
164 "Belos::GCRODRSolMgr: ScalarType must be one of the four "
165 "types (S,D,C,Z) supported by LAPACK or long double (largely not impl'd).");
167 static_assert (std::is_same<ScalarType, std::complex<float> >::value ||
168 std::is_same<ScalarType, std::complex<double> >::value ||
169 std::is_same<ScalarType, Kokkos::complex<double> >::value ||
170 std::is_same<ScalarType, float>::value ||
171 std::is_same<ScalarType, double>::value,
172 "Belos::GCRODRSolMgr: ScalarType must be one of the four "
173 "types (S,D,C,Z) supported by LAPACK.");
176 #if defined(HAVE_TEUCHOS_LONG_DOUBLE)
177 static_assert (std::is_same<ScalarType, float>::value ||
178 std::is_same<ScalarType, double>::value ||
179 std::is_same<ScalarType, long double>::value,
180 "Belos::GCRODRSolMgr: ScalarType must be float, double or long double. "
181 "Complex arithmetic support is currently disabled. To "
182 "enable it, set Teuchos_ENABLE_COMPLEX=ON.");
184 static_assert (std::is_same<ScalarType, float>::value ||
185 std::is_same<ScalarType, double>::value,
186 "Belos::GCRODRSolMgr: ScalarType must be float or double. "
187 "Complex arithmetic support is currently disabled. To "
188 "enable it, set Teuchos_ENABLE_COMPLEX=ON.");
196 typedef Teuchos::ScalarTraits<ScalarType> SCT;
197 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
198 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
265 const Teuchos::RCP<Teuchos::ParameterList> &pl);
271 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
287 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const override;
300 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
301 return Teuchos::tuple(timerSolve_);
333 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
override;
345 bool set = problem_->setProblem();
347 throw "Could not set problem.";
391 std::string description()
const override;
401 void initializeStateStorage();
410 int getHarmonicVecs1(
int m,
411 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
412 Teuchos::SerialDenseMatrix<int,ScalarType>& PP);
419 int getHarmonicVecs2(
int keff,
int m,
420 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
421 const Teuchos::RCP<const MV>& VV,
422 Teuchos::SerialDenseMatrix<int,ScalarType>& PP);
425 void sort(std::vector<MagnitudeType>& dlist,
int n, std::vector<int>& iperm);
428 Teuchos::LAPACK<int,ScalarType> lapack;
431 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
434 Teuchos::RCP<OutputManager<ScalarType> > printer_;
435 Teuchos::RCP<std::ostream> outputStream_;
438 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
439 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
440 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
441 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > expConvTest_, impConvTest_;
442 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
447 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
450 Teuchos::RCP<Teuchos::ParameterList> params_;
453 static constexpr double orthoKappa_default_ = 0.0;
454 static constexpr int maxRestarts_default_ = 100;
455 static constexpr int maxIters_default_ = 1000;
456 static constexpr int numBlocks_default_ = 50;
457 static constexpr int blockSize_default_ = 1;
458 static constexpr int recycledBlocks_default_ = 5;
461 static constexpr int outputFreq_default_ = -1;
462 static constexpr const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
463 static constexpr const char * expResScale_default_ =
"Norm of Initial Residual";
464 static constexpr const char * label_default_ =
"Belos";
465 static constexpr const char * orthoType_default_ =
"ICGS";
468 MagnitudeType convTol_, orthoKappa_, achievedTol_;
469 int maxRestarts_, maxIters_, numIters_;
470 int verbosity_, outputStyle_, outputFreq_;
471 std::string orthoType_;
472 std::string impResScale_, expResScale_;
479 int numBlocks_, recycledBlocks_;
490 Teuchos::RCP<MV> U_, C_;
493 Teuchos::RCP<MV> U1_, C1_;
496 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H2_;
497 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H_;
498 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B_;
499 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PP_;
500 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > HP_;
501 std::vector<ScalarType> tau_;
502 std::vector<ScalarType> work_;
503 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > R_;
504 std::vector<int> ipiv_;
509 Teuchos::RCP<Teuchos::Time> timerSolve_;
515 bool builtRecycleSpace_;
520template<
class ScalarType,
class MV,
class OP>
530template<
class ScalarType,
class MV,
class OP>
533 const Teuchos::RCP<Teuchos::ParameterList>& pl):
541 TEUCHOS_TEST_FOR_EXCEPTION(
542 problem == Teuchos::null, std::invalid_argument,
543 "Belos::GCRODRSolMgr constructor: The solver manager's "
544 "constructor needs the linear problem argument 'problem' "
553 if (! pl.is_null ()) {
559template<
class ScalarType,
class MV,
class OP>
561 outputStream_ = Teuchos::rcpFromRef(std::cout);
563 orthoKappa_ = orthoKappa_default_;
564 maxRestarts_ = maxRestarts_default_;
565 maxIters_ = maxIters_default_;
566 numBlocks_ = numBlocks_default_;
567 recycledBlocks_ = recycledBlocks_default_;
568 verbosity_ = verbosity_default_;
569 outputStyle_ = outputStyle_default_;
570 outputFreq_ = outputFreq_default_;
571 orthoType_ = orthoType_default_;
572 impResScale_ = impResScale_default_;
573 expResScale_ = expResScale_default_;
574 label_ = label_default_;
576 builtRecycleSpace_ =
false;
592template<
class ScalarType,
class MV,
class OP>
595setParameters (
const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
597 using Teuchos::isParameterType;
598 using Teuchos::getParameter;
600 using Teuchos::ParameterList;
601 using Teuchos::parameterList;
604 using Teuchos::rcp_dynamic_cast;
605 using Teuchos::rcpFromRef;
606 using Teuchos::Exceptions::InvalidParameter;
607 using Teuchos::Exceptions::InvalidParameterName;
608 using Teuchos::Exceptions::InvalidParameterType;
630 if (params_.is_null()) {
631 params_ = parameterList (*defaultParams);
639 if (params_ != params) {
645 params_ = parameterList (*params);
680 params_->validateParametersAndSetDefaults (*defaultParams);
684 if (params->isParameter (
"Maximum Restarts")) {
685 maxRestarts_ = params->get(
"Maximum Restarts", maxRestarts_default_);
688 params_->set (
"Maximum Restarts", maxRestarts_);
692 if (params->isParameter (
"Maximum Iterations")) {
693 maxIters_ = params->get (
"Maximum Iterations", maxIters_default_);
696 params_->set (
"Maximum Iterations", maxIters_);
697 if (! maxIterTest_.is_null())
698 maxIterTest_->setMaxIters (maxIters_);
702 if (params->isParameter (
"Num Blocks")) {
703 numBlocks_ = params->get (
"Num Blocks", numBlocks_default_);
704 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks_ <= 0, std::invalid_argument,
705 "Belos::GCRODRSolMgr: The \"Num Blocks\" parameter must "
706 "be strictly positive, but you specified a value of "
707 << numBlocks_ <<
".");
709 params_->set (
"Num Blocks", numBlocks_);
713 if (params->isParameter (
"Num Recycled Blocks")) {
714 recycledBlocks_ = params->get (
"Num Recycled Blocks",
715 recycledBlocks_default_);
716 TEUCHOS_TEST_FOR_EXCEPTION(recycledBlocks_ <= 0, std::invalid_argument,
717 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
718 "parameter must be strictly positive, but you specified "
719 "a value of " << recycledBlocks_ <<
".");
720 TEUCHOS_TEST_FOR_EXCEPTION(recycledBlocks_ >= numBlocks_, std::invalid_argument,
721 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
722 "parameter must be less than the \"Num Blocks\" "
723 "parameter, but you specified \"Num Recycled Blocks\" "
724 "= " << recycledBlocks_ <<
" and \"Num Blocks\" = "
725 << numBlocks_ <<
".");
727 params_->set(
"Num Recycled Blocks", recycledBlocks_);
733 if (params->isParameter (
"Timer Label")) {
734 std::string tempLabel = params->get (
"Timer Label", label_default_);
737 if (tempLabel != label_) {
739 params_->set (
"Timer Label", label_);
740 std::string solveLabel = label_ +
": GCRODRSolMgr total solve time";
741#ifdef BELOS_TEUCHOS_TIME_MONITOR
742 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
744 if (ortho_ != Teuchos::null) {
745 ortho_->setLabel( label_ );
751 if (params->isParameter (
"Verbosity")) {
752 if (isParameterType<int> (*params,
"Verbosity")) {
753 verbosity_ = params->get (
"Verbosity", verbosity_default_);
755 verbosity_ = (int) getParameter<Belos::MsgType> (*params,
"Verbosity");
758 params_->set (
"Verbosity", verbosity_);
761 if (! printer_.is_null())
762 printer_->setVerbosity (verbosity_);
766 if (params->isParameter (
"Output Style")) {
767 if (isParameterType<int> (*params,
"Output Style")) {
768 outputStyle_ = params->get (
"Output Style", outputStyle_default_);
770 outputStyle_ = (int) getParameter<OutputType> (*params,
"Output Style");
774 params_->set (
"Output Style", outputStyle_);
792 if (params->isParameter (
"Output Stream")) {
794 outputStream_ = getParameter<RCP<std::ostream> > (*params,
"Output Stream");
795 }
catch (InvalidParameter&) {
796 outputStream_ = rcpFromRef (std::cout);
803 if (outputStream_.is_null()) {
804 outputStream_ = rcp (
new Teuchos::oblackholestream);
807 params_->set (
"Output Stream", outputStream_);
810 if (! printer_.is_null()) {
811 printer_->setOStream (outputStream_);
817 if (params->isParameter (
"Output Frequency")) {
818 outputFreq_ = params->get (
"Output Frequency", outputFreq_default_);
822 params_->set(
"Output Frequency", outputFreq_);
823 if (! outputTest_.is_null())
824 outputTest_->setOutputFrequency (outputFreq_);
831 if (printer_.is_null()) {
842 bool changedOrthoType =
false;
843 if (params->isParameter (
"Orthogonalization")) {
844 const std::string& tempOrthoType =
845 params->get (
"Orthogonalization", orthoType_default_);
848 std::ostringstream os;
849 os <<
"Belos::GCRODRSolMgr: Invalid orthogonalization name \""
850 << tempOrthoType <<
"\". The following are valid options "
851 <<
"for the \"Orthogonalization\" name parameter: ";
853 throw std::invalid_argument (os.str());
855 if (tempOrthoType != orthoType_) {
856 changedOrthoType =
true;
857 orthoType_ = tempOrthoType;
859 params_->set (
"Orthogonalization", orthoType_);
875 RCP<ParameterList> orthoParams;
878 using Teuchos::sublist;
880 const std::string paramName (
"Orthogonalization Parameters");
883 orthoParams = sublist (params_, paramName,
true);
884 }
catch (InvalidParameter&) {
891 orthoParams = sublist (params_, paramName,
true);
894 TEUCHOS_TEST_FOR_EXCEPTION(orthoParams.is_null(), std::logic_error,
895 "Failed to get orthogonalization parameters. "
896 "Please report this bug to the Belos developers.");
901 if (ortho_.is_null() || changedOrthoType) {
907 label_, orthoParams);
915 typedef Teuchos::ParameterListAcceptor PLA;
916 RCP<PLA> pla = rcp_dynamic_cast<PLA> (ortho_);
922 label_, orthoParams);
924 pla->setParameterList (orthoParams);
936 if (params->isParameter (
"Orthogonalization Constant")) {
937 MagnitudeType orthoKappa = orthoKappa_default_;
938 if (params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
939 orthoKappa = params->get (
"Orthogonalization Constant", orthoKappa);
942 orthoKappa = params->get (
"Orthogonalization Constant", orthoKappa_default_);
945 if (orthoKappa > 0) {
946 orthoKappa_ = orthoKappa;
948 params_->set(
"Orthogonalization Constant", orthoKappa_);
950 if (orthoType_ ==
"DGKS" && ! ortho_.is_null()) {
957 rcp_dynamic_cast<ortho_man_type>(ortho_)->
setDepTol (orthoKappa_);
967 if (params->isParameter(
"Convergence Tolerance")) {
968 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
969 convTol_ = params->get (
"Convergence Tolerance",
977 params_->set (
"Convergence Tolerance", convTol_);
978 if (! impConvTest_.is_null())
979 impConvTest_->setTolerance (convTol_);
980 if (! expConvTest_.is_null())
981 expConvTest_->setTolerance (convTol_);
985 if (params->isParameter (
"Implicit Residual Scaling")) {
986 std::string tempImpResScale =
987 getParameter<std::string> (*params,
"Implicit Residual Scaling");
990 if (impResScale_ != tempImpResScale) {
992 impResScale_ = tempImpResScale;
995 params_->set(
"Implicit Residual Scaling", impResScale_);
1005 if (! impConvTest_.is_null()) {
1011 impConvTest_ = null;
1018 if (params->isParameter(
"Explicit Residual Scaling")) {
1019 std::string tempExpResScale =
1020 getParameter<std::string> (*params,
"Explicit Residual Scaling");
1023 if (expResScale_ != tempExpResScale) {
1025 expResScale_ = tempExpResScale;
1028 params_->set(
"Explicit Residual Scaling", expResScale_);
1031 if (! expConvTest_.is_null()) {
1037 expConvTest_ = null;
1048 if (maxIterTest_.is_null())
1053 if (impConvTest_.is_null()) {
1054 impConvTest_ = rcp (
new StatusTestResNorm_t (convTol_));
1060 if (expConvTest_.is_null()) {
1061 expConvTest_ = rcp (
new StatusTestResNorm_t (convTol_));
1062 expConvTest_->defineResForm (StatusTestResNorm_t::Explicit,
Belos::TwoNorm);
1068 if (convTest_.is_null()) {
1069 convTest_ = rcp (
new StatusTestCombo_t (StatusTestCombo_t::SEQ,
1077 sTest_ = rcp (
new StatusTestCombo_t (StatusTestCombo_t::OR,
1083 outputTest_ = stoFactory.
create (printer_, sTest_, outputFreq_,
1087 std::string solverDesc =
" GCRODR ";
1088 outputTest_->setSolverDesc( solverDesc );
1091 if (timerSolve_.is_null()) {
1092 std::string solveLabel = label_ +
": GCRODRSolMgr total solve time";
1093#ifdef BELOS_TEUCHOS_TIME_MONITOR
1094 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
1103template<
class ScalarType,
class MV,
class OP>
1104Teuchos::RCP<const Teuchos::ParameterList>
1107 using Teuchos::ParameterList;
1108 using Teuchos::parameterList;
1111 static RCP<const ParameterList> validPL;
1112 if (is_null(validPL)) {
1113 RCP<ParameterList> pl = parameterList ();
1117 "The relative residual tolerance that needs to be achieved by the\n"
1118 "iterative solver in order for the linear system to be declared converged.");
1119 pl->set(
"Maximum Restarts",
static_cast<int>(maxRestarts_default_),
1120 "The maximum number of cycles allowed for each\n"
1121 "set of RHS solved.");
1122 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
1123 "The maximum number of iterations allowed for each\n"
1124 "set of RHS solved.");
1128 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
1129 "Block Size Parameter -- currently must be 1 for GCRODR");
1130 pl->set(
"Num Blocks",
static_cast<int>(numBlocks_default_),
1131 "The maximum number of vectors allowed in the Krylov subspace\n"
1132 "for each set of RHS solved.");
1133 pl->set(
"Num Recycled Blocks",
static_cast<int>(recycledBlocks_default_),
1134 "The maximum number of vectors in the recycled subspace." );
1135 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
1136 "What type(s) of solver information should be outputted\n"
1137 "to the output stream.");
1138 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
1139 "What style is used for the solver information outputted\n"
1140 "to the output stream.");
1141 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
1142 "How often convergence information should be outputted\n"
1143 "to the output stream.");
1144 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
1145 "A reference-counted pointer to the output stream where all\n"
1146 "solver output is sent.");
1147 pl->set(
"Implicit Residual Scaling",
static_cast<const char *
>(impResScale_default_),
1148 "The type of scaling used in the implicit residual convergence test.");
1149 pl->set(
"Explicit Residual Scaling",
static_cast<const char *
>(expResScale_default_),
1150 "The type of scaling used in the explicit residual convergence test.");
1151 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
1152 "The string to use as a prefix for the timer labels.");
1155 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
1156 "The type of orthogonalization to use. Valid options: " +
1158 RCP<const ParameterList> orthoParams =
1160 pl->set (
"Orthogonalization Parameters", *orthoParams,
1161 "Parameters specific to the type of orthogonalization used.");
1163 pl->set(
"Orthogonalization Constant",
static_cast<MagnitudeType
>(orthoKappa_default_),
1164 "When using DGKS orthogonalization: the \"depTol\" constant, used "
1165 "to determine whether another step of classical Gram-Schmidt is "
1166 "necessary. Otherwise ignored.");
1173template<
class ScalarType,
class MV,
class OP>
1176 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1179 Teuchos::RCP<const MV> rhsMV = problem_->getRHS();
1180 if (rhsMV == Teuchos::null) {
1187 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<ptrdiff_t
>(numBlocks_) > MVT::GetGlobalLength(*rhsMV),std::invalid_argument,
1188 "Belos::GCRODRSolMgr::initializeStateStorage(): Cannot generate a Krylov basis with dimension larger the operator!");
1191 if (U_ == Teuchos::null) {
1192 U_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1196 if (MVT::GetNumberVecs(*U_) < recycledBlocks_+1) {
1197 Teuchos::RCP<const MV> tmp = U_;
1198 U_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1203 if (C_ == Teuchos::null) {
1204 C_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1208 if (MVT::GetNumberVecs(*C_) < recycledBlocks_+1) {
1209 Teuchos::RCP<const MV> tmp = C_;
1210 C_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1215 if (V_ == Teuchos::null) {
1216 V_ = MVT::Clone( *rhsMV, numBlocks_+1 );
1220 if (MVT::GetNumberVecs(*V_) < numBlocks_+1) {
1221 Teuchos::RCP<const MV> tmp = V_;
1222 V_ = MVT::Clone( *tmp, numBlocks_+1 );
1227 if (U1_ == Teuchos::null) {
1228 U1_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1232 if (MVT::GetNumberVecs(*U1_) < recycledBlocks_+1) {
1233 Teuchos::RCP<const MV> tmp = U1_;
1234 U1_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1239 if (C1_ == Teuchos::null) {
1240 C1_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1244 if (MVT::GetNumberVecs(*C1_) < recycledBlocks_+1) {
1245 Teuchos::RCP<const MV> tmp = C1_;
1246 C1_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1251 if (r_ == Teuchos::null)
1252 r_ = MVT::Clone( *rhsMV, 1 );
1255 tau_.resize(recycledBlocks_+1);
1258 work_.resize(recycledBlocks_+1);
1261 ipiv_.resize(recycledBlocks_+1);
1264 if (H2_ == Teuchos::null)
1265 H2_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 ) );
1267 if ( (H2_->numRows() != numBlocks_+recycledBlocks_+2) || (H2_->numCols() != numBlocks_+recycledBlocks_+1) )
1268 H2_->reshape( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1270 H2_->putScalar(zero);
1273 if (R_ == Teuchos::null)
1274 R_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( recycledBlocks_+1, recycledBlocks_+1 ) );
1276 if ( (R_->numRows() != recycledBlocks_+1) || (R_->numCols() != recycledBlocks_+1) )
1277 R_->reshape( recycledBlocks_+1, recycledBlocks_+1 );
1279 R_->putScalar(zero);
1282 if (PP_ == Teuchos::null)
1283 PP_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 ) );
1285 if ( (PP_->numRows() != numBlocks_+recycledBlocks_+2) || (PP_->numCols() != recycledBlocks_+1) )
1286 PP_->reshape( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 );
1290 if (HP_ == Teuchos::null)
1291 HP_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 ) );
1293 if ( (HP_->numRows() != numBlocks_+recycledBlocks_+2) || (HP_->numCols() != numBlocks_+recycledBlocks_+1) )
1294 HP_->reshape( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1302template<
class ScalarType,
class MV,
class OP>
1312 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
1313 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1314 std::vector<int> index(numBlocks_+1);
1316 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,
GCRODRSolMgrLinearProblemFailure,
"Belos::GCRODRSolMgr::solve(): Linear problem is not a valid object.");
1318 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(),
GCRODRSolMgrLinearProblemFailure,
"Belos::GCRODRSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1322 std::vector<int> currIdx(1);
1326 problem_->setLSIndex( currIdx );
1330 if (
static_cast<ptrdiff_t
>(numBlocks_) > dim) {
1331 numBlocks_ = Teuchos::as<int>(dim);
1333 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1334 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1335 params_->set(
"Num Blocks", numBlocks_);
1339 bool isConverged =
true;
1342 initializeStateStorage();
1346 Teuchos::ParameterList plist;
1348 plist.set(
"Num Blocks",numBlocks_);
1349 plist.set(
"Recycled Blocks",recycledBlocks_);
1354 RCP<GCRODRIter<ScalarType,MV,OP> > gcrodr_iter;
1357 int prime_iterations = 0;
1361#ifdef BELOS_TEUCHOS_TIME_MONITOR
1362 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1365 while ( numRHS2Solve > 0 ) {
1368 builtRecycleSpace_ =
false;
1371 outputTest_->reset();
1379 "Belos::GCRODRSolMgr::solve(): Requested size of recycled subspace is not consistent with the current recycle subspace.");
1381 printer_->stream(
Debug) <<
" Now solving RHS index " << currIdx[0] <<
" using recycled subspace of dimension " << keff << std::endl << std::endl;
1384 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1387 problem_->apply( *Utmp, *Ctmp );
1393 Teuchos::SerialDenseMatrix<int,ScalarType> Rtmp( Teuchos::View, *R_, keff, keff );
1394 int rank = ortho_->normalize(*Ctmp, rcp(&Rtmp,
false));
1396 TEUCHOS_TEST_FOR_EXCEPTION(rank != keff,
GCRODRSolMgrOrthoFailure,
"Belos::GCRODRSolMgr::solve(): Failed to compute orthonormal basis for initial recycled subspace.");
1401 ipiv_.resize(Rtmp.numRows());
1402 lapack.GETRF(Rtmp.numRows(),Rtmp.numCols(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&info);
1403 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
1406 int lwork = Rtmp.numRows();
1407 work_.resize(lwork);
1408 lapack.GETRI(Rtmp.numRows(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&work_[0],lwork,&info);
1409 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to invert triangular matrix.");
1417 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1422 Teuchos::SerialDenseMatrix<int,ScalarType> Ctr(keff,1);
1423 problem_->computeCurrPrecResVec( &*r_ );
1427 RCP<MV> update =
MVT::Clone( *problem_->getCurrLHSVec(), 1 );
1430 problem_->updateSolution( update,
true );
1436 prime_iterations = 0;
1442 printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " << currIdx[0] << std::endl << std::endl;
1444 Teuchos::ParameterList primeList;
1447 primeList.set(
"Num Blocks",numBlocks_);
1448 primeList.set(
"Recycled Blocks",0);
1451 RCP<GCRODRIter<ScalarType,MV,OP> > gcrodr_prime_iter;
1455 problem_->computeCurrPrecResVec( &*r_ );
1456 index.resize( 1 ); index[0] = 0;
1462 index.resize( numBlocks_+1 );
1463 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1465 newstate.
U = Teuchos::null;
1466 newstate.
C = Teuchos::null;
1467 newstate.
H = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, recycledBlocks_+1, recycledBlocks_+1 ) );
1468 newstate.
B = Teuchos::null;
1470 gcrodr_prime_iter->initialize(newstate);
1473 bool primeConverged =
false;
1475 gcrodr_prime_iter->iterate();
1478 if ( convTest_->getStatus() ==
Passed ) {
1480 primeConverged =
true;
1485 gcrodr_prime_iter->updateLSQR( gcrodr_prime_iter->getCurSubspaceDim() );
1488 sTest_->checkStatus( &*gcrodr_prime_iter );
1489 if (convTest_->getStatus() ==
Passed)
1490 primeConverged =
true;
1494 achievedTol_ = MT::one();
1495 Teuchos::RCP<MV> X = problem_->getLHS();
1497 printer_->stream(
Warnings) <<
"Belos::GCRODRSolMgr::solve(): Warning! NaN has been detected!"
1501 catch (
const std::exception &e) {
1502 printer_->stream(
Errors) <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1503 << gcrodr_prime_iter->getNumIters() << std::endl
1504 << e.what() << std::endl;
1508 prime_iterations = gcrodr_prime_iter->getNumIters();
1511 RCP<MV> update = gcrodr_prime_iter->getCurrentUpdate();
1512 problem_->updateSolution( update,
true );
1515 newstate = gcrodr_prime_iter->getState();
1523 if (recycledBlocks_ < p+1) {
1525 RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PPtmp = rcp (
new Teuchos::SerialDenseMatrix<int,ScalarType> ( Teuchos::View, *PP_, p, recycledBlocks_+1 ) );
1527 keff = getHarmonicVecs1( p, *newstate.
H, *PPtmp );
1529 PPtmp = rcp (
new Teuchos::SerialDenseMatrix<int,ScalarType> ( Teuchos::View, *PP_, p, keff ) );
1532 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1537 for (
int ii=0; ii < p; ++ii) { index[ii] = ii; }
1549 Teuchos::SerialDenseMatrix<int,ScalarType> Htmp( Teuchos::View, *H2_, p+1, p, recycledBlocks_+1,recycledBlocks_+1);
1550 Teuchos::SerialDenseMatrix<int,ScalarType> HPtmp( Teuchos::View, *HP_, p+1, keff );
1551 HPtmp.multiply( Teuchos::NO_TRANS, Teuchos::NO_TRANS, one, Htmp, *PPtmp, zero );
1558 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1559 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1560 TEUCHOS_TEST_FOR_EXCEPTION(
1562 " LAPACK's _GEQRF failed to compute a workspace size.");
1570 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1571 work_.resize (lwork);
1572 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1573 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1574 TEUCHOS_TEST_FOR_EXCEPTION(
1576 " LAPACK's _GEQRF failed to compute a QR factorization.");
1580 Teuchos::SerialDenseMatrix<int,ScalarType> Rtmp( Teuchos::View, *R_, keff, keff );
1581 for (
int ii = 0; ii < keff; ++ii) {
1582 for (
int jj = ii; jj < keff; ++jj) {
1583 Rtmp(ii,jj) = HPtmp(ii,jj);
1590 lapack.UNGQR (HPtmp.numRows (), HPtmp.numCols (), HPtmp.numCols (),
1591 HPtmp.values (), HPtmp.stride (), &tau_[0], &work_[0],
1593 TEUCHOS_TEST_FOR_EXCEPTION(
1595 "LAPACK's _UNGQR failed to construct the Q factor.");
1600 index.resize (p + 1);
1601 for (
int ii = 0; ii < (p+1); ++ii) {
1612 ipiv_.resize(Rtmp.numRows());
1613 lapack.GETRF(Rtmp.numRows(),Rtmp.numCols(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&info);
1614 TEUCHOS_TEST_FOR_EXCEPTION(
1616 "LAPACK's _GETRF failed to compute an LU factorization.");
1625 lwork = Rtmp.numRows();
1626 work_.resize(lwork);
1627 lapack.GETRI(Rtmp.numRows(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&work_[0],lwork,&info);
1628 TEUCHOS_TEST_FOR_EXCEPTION(
1630 "LAPACK's _GETRI failed to invert triangular matrix.");
1635 printer_->stream(
Debug)
1636 <<
" Generated recycled subspace using RHS index " << currIdx[0]
1637 <<
" of dimension " << keff << std::endl << std::endl;
1642 if (primeConverged) {
1644 problem_->setCurrLS();
1648 if (numRHS2Solve > 0) {
1650 problem_->setLSIndex (currIdx);
1653 currIdx.resize (numRHS2Solve);
1663 gcrodr_iter->setSize( keff, numBlocks_ );
1666 gcrodr_iter->resetNumIters(prime_iterations);
1669 outputTest_->resetNumCalls();
1672 problem_->computeCurrPrecResVec( &*r_ );
1673 index.resize( 1 ); index[0] = 0;
1679 index.resize( numBlocks_+1 );
1680 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1682 index.resize( keff );
1683 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1686 newstate.
B = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1687 newstate.
H = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1689 gcrodr_iter->initialize(newstate);
1692 int numRestarts = 0;
1697 gcrodr_iter->iterate();
1704 if ( convTest_->getStatus() ==
Passed ) {
1713 else if ( maxIterTest_->getStatus() ==
Passed ) {
1715 isConverged =
false;
1723 else if ( gcrodr_iter->getCurSubspaceDim() == gcrodr_iter->getMaxSubspaceDim() ) {
1728 RCP<MV> update = gcrodr_iter->getCurrentUpdate();
1729 problem_->updateSolution( update,
true );
1731 buildRecycleSpace2(gcrodr_iter);
1733 printer_->stream(
Debug)
1734 <<
" Generated new recycled subspace using RHS index "
1735 << currIdx[0] <<
" of dimension " << keff << std::endl
1739 if (numRestarts >= maxRestarts_) {
1740 isConverged =
false;
1745 printer_->stream(
Debug)
1746 <<
" Performing restart number " << numRestarts <<
" of "
1747 << maxRestarts_ << std::endl << std::endl;
1750 problem_->computeCurrPrecResVec( &*r_ );
1751 index.resize( 1 ); index[0] = 0;
1757 index.resize( numBlocks_+1 );
1758 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1760 index.resize( keff );
1761 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1764 restartState.
B = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1765 restartState.
H = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1767 gcrodr_iter->initialize(restartState);
1780 TEUCHOS_TEST_FOR_EXCEPTION(
1781 true, std::logic_error,
"Belos::GCRODRSolMgr::solve: "
1782 "Invalid return from GCRODRIter::iterate().");
1787 gcrodr_iter->updateLSQR( gcrodr_iter->getCurSubspaceDim() );
1790 sTest_->checkStatus( &*gcrodr_iter );
1791 if (convTest_->getStatus() !=
Passed)
1792 isConverged =
false;
1795 catch (
const std::exception& e) {
1797 <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1798 << gcrodr_iter->getNumIters() << std::endl << e.what() << std::endl;
1805 RCP<MV> update = gcrodr_iter->getCurrentUpdate();
1806 problem_->updateSolution( update,
true );
1809 problem_->setCurrLS();
1814 if (!builtRecycleSpace_) {
1815 buildRecycleSpace2(gcrodr_iter);
1816 printer_->stream(
Debug)
1817 <<
" Generated new recycled subspace using RHS index " << currIdx[0]
1818 <<
" of dimension " << keff << std::endl << std::endl;
1823 if (numRHS2Solve > 0) {
1825 problem_->setLSIndex (currIdx);
1828 currIdx.resize (numRHS2Solve);
1836#ifdef BELOS_TEUCHOS_TIME_MONITOR
1841 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1845 numIters_ = maxIterTest_->getNumIters ();
1857 const std::vector<MagnitudeType>* pTestValues = expConvTest_->getTestValue();
1858 if (pTestValues == NULL || pTestValues->size() < 1) {
1859 pTestValues = impConvTest_->getTestValue();
1861 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1862 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1863 "method returned NULL. Please report this bug to the Belos developers.");
1864 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1865 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1866 "method returned a vector of length zero. Please report this bug to the "
1867 "Belos developers.");
1872 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1879template<
class ScalarType,
class MV,
class OP>
1882 MagnitudeType one = Teuchos::ScalarTraits<MagnitudeType>::one();
1883 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1885 std::vector<MagnitudeType> d(keff);
1886 std::vector<ScalarType> dscalar(keff);
1887 std::vector<int> index(numBlocks_+1);
1899 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1900 Teuchos::RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
1902 dscalar.resize(keff);
1903 MVT::MvNorm( *Utmp, d );
1904 for (
int i=0; i<keff; ++i) {
1906 dscalar[i] = (ScalarType)d[i];
1908 MVT::MvScale( *Utmp, dscalar );
1912 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H2tmp = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, p+keff+1, p+keff ) );
1915 for (
int i=0; i<keff; ++i) {
1916 (*H2tmp)(i,i) = d[i];
1923 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, p+keff, recycledBlocks_+1 );
1924 keff_new = getHarmonicVecs2( keff, p, *H2tmp, oldState.
V, PPtmp );
1931 Teuchos::RCP<MV> U1tmp;
1933 index.resize( keff );
1934 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1935 Teuchos::RCP<const MV> Utmp = MVT::CloneView( *U_, index );
1936 index.resize( keff_new );
1937 for (
int ii=0; ii<keff_new; ++ii) { index[ii] = ii; }
1938 U1tmp = MVT::CloneViewNonConst( *U1_, index );
1939 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, keff, keff_new );
1940 MVT::MvTimesMatAddMv( one, *Utmp, PPtmp, zero, *U1tmp );
1946 for (
int ii=0; ii < p; ii++) { index[ii] = ii; }
1947 Teuchos::RCP<const MV> Vtmp = MVT::CloneView( *V_, index );
1948 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, p, keff_new, keff );
1949 MVT::MvTimesMatAddMv( one, *Vtmp, PPtmp, one, *U1tmp );
1953 Teuchos::SerialDenseMatrix<int,ScalarType> HPtmp( Teuchos::View, *HP_, p+keff+1, keff_new );
1955 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, p+keff, keff_new );
1956 HPtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,*H2tmp,PPtmp,zero);
1960 int info = 0, lwork = -1;
1961 tau_.resize (keff_new);
1962 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1963 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1964 TEUCHOS_TEST_FOR_EXCEPTION(
1966 "LAPACK's _GEQRF failed to compute a workspace size.");
1972 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1973 work_.resize (lwork);
1974 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1975 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1976 TEUCHOS_TEST_FOR_EXCEPTION(
1978 "LAPACK's _GEQRF failed to compute a QR factorization.");
1982 Teuchos::SerialDenseMatrix<int,ScalarType> Rtmp( Teuchos::View, *R_, keff_new, keff_new );
1983 for(
int i=0;i<keff_new;i++) {
for(
int j=i;j<keff_new;j++) Rtmp(i,j) = HPtmp(i,j); }
1989 lapack.UNGQR (HPtmp.numRows (), HPtmp.numCols (), HPtmp.numCols (),
1990 HPtmp.values (), HPtmp.stride (), &tau_[0], &work_[0],
1992 TEUCHOS_TEST_FOR_EXCEPTION(
1994 "LAPACK's _UNGQR failed to construct the Q factor.");
2001 Teuchos::RCP<MV> C1tmp;
2004 for (
int i=0; i < keff; i++) { index[i] = i; }
2005 Teuchos::RCP<const MV> Ctmp = MVT::CloneView( *C_, index );
2006 index.resize(keff_new);
2007 for (
int i=0; i < keff_new; i++) { index[i] = i; }
2008 C1tmp = MVT::CloneViewNonConst( *C1_, index );
2009 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *HP_, keff, keff_new );
2010 MVT::MvTimesMatAddMv( one, *Ctmp, PPtmp, zero, *C1tmp );
2014 index.resize( p+1 );
2015 for (
int i=0; i < p+1; ++i) { index[i] = i; }
2016 Teuchos::RCP<const MV> Vtmp = MVT::CloneView( *V_, index );
2017 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *HP_, p+1, keff_new, keff, 0 );
2018 MVT::MvTimesMatAddMv( one, *Vtmp, PPtmp, one, *C1tmp );
2027 ipiv_.resize(Rtmp.numRows());
2028 lapack.GETRF(Rtmp.numRows(),Rtmp.numCols(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&info);
2029 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
2032 lwork = Rtmp.numRows();
2033 work_.resize(lwork);
2034 lapack.GETRI(Rtmp.numRows(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&work_[0],lwork,&info);
2035 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to compute an LU factorization.");
2038 index.resize(keff_new);
2039 for (
int i=0; i < keff_new; i++) { index[i] = i; }
2040 Teuchos::RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
2041 MVT::MvTimesMatAddMv( one, *U1tmp, Rtmp, zero, *Utmp );
2045 if (keff != keff_new) {
2047 gcrodr_iter->setSize( keff, numBlocks_ );
2049 Teuchos::SerialDenseMatrix<int,ScalarType> b1( Teuchos::View, *H2_, recycledBlocks_+2, 1, 0, recycledBlocks_ );
2057template<
class ScalarType,
class MV,
class OP>
2059 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2060 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2062 bool xtraVec =
false;
2063 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);
2081 builtRecycleSpace_ =
true;
2084 Teuchos::SerialDenseMatrix<int, ScalarType> HHt( HH, Teuchos::TRANS );
2085 Teuchos::SerialDenseVector<int, ScalarType> e_m( m );
2087 lapack.GESV(m, 1, HHt.values(), HHt.stride(), &iperm[0], e_m.values(), e_m.stride(), &info);
2088 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GESV failed to compute a solution.");
2091 ScalarType d = HH(m, m-1) * HH(m, m-1);
2092 Teuchos::SerialDenseMatrix<int, ScalarType> harmHH( Teuchos::Copy, HH, m, m );
2093 for( i=0; i<m; ++i )
2094 harmHH(i, m-1) += d * e_m[i];
2103 std::vector<ScalarType> work(1);
2104 std::vector<MagnitudeType> rwork(2*m);
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);
2110 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work[0])));
2111 work.resize( lwork );
2113 lapack.GEEV(
'N',
'V', m, harmHH.values(), harmHH.stride(), &wr[0], &wi[0],
2114 vl, ldvl, vr.values(), vr.stride(), &work[0], lwork, &rwork[0], &info);
2115 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GEEV failed to compute eigensolutions.");
2118 for( i=0; i<m; ++i )
2119 w[i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot( wr[i]*wr[i] + wi[i]*wi[i] );
2122 this->sort(w, m, iperm);
2124 const bool scalarTypeIsComplex = Teuchos::ScalarTraits<ScalarType>::isComplex;
2127 for( i=0; i<recycledBlocks_; ++i ) {
2128 for( j=0; j<m; j++ ) {
2129 PP(j,i) = vr(j,iperm[i]);
2133 if(!scalarTypeIsComplex) {
2136 if (wi[iperm[recycledBlocks_-1]] != 0.0) {
2138 for ( i=0; i<recycledBlocks_; ++i ) {
2139 if (wi[iperm[i]] != 0.0)
2148 if (wi[iperm[recycledBlocks_-1]] > 0.0) {
2149 for( j=0; j<m; ++j ) {
2150 PP(j,recycledBlocks_) = vr(j,iperm[recycledBlocks_-1]+1);
2154 for( j=0; j<m; ++j ) {
2155 PP(j,recycledBlocks_) = vr(j,iperm[recycledBlocks_-1]-1);
2164 return recycledBlocks_+1;
2167 return recycledBlocks_;
2173template<
class ScalarType,
class MV,
class OP>
2175 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2176 const Teuchos::RCP<const MV>& VV,
2177 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2179 int m2 = HH.numCols();
2180 bool xtraVec =
false;
2181 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
2182 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
2183 std::vector<int> index;
2186 std::vector<MagnitudeType> wr(m2), wi(m2);
2189 std::vector<MagnitudeType> w(m2);
2192 Teuchos::SerialDenseMatrix<int,ScalarType> vr(m2,m2,
false);
2195 std::vector<int> iperm(m2);
2198 builtRecycleSpace_ =
true;
2203 Teuchos::SerialDenseMatrix<int,ScalarType> B(m2,m2,
false);
2204 B.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,HH,HH,zero);
2208 Teuchos::SerialDenseMatrix<int,ScalarType> A_tmp( keffloc+m+1, keffloc+m );
2211 index.resize(keffloc);
2212 for (i=0; i<keffloc; ++i) { index[i] = i; }
2213 Teuchos::RCP<const MV> Ctmp = MVT::CloneView( *C_, index );
2214 Teuchos::RCP<const MV> Utmp = MVT::CloneView( *U_, index );
2215 Teuchos::SerialDenseMatrix<int,ScalarType> A11( Teuchos::View, A_tmp, keffloc, keffloc );
2216 MVT::MvTransMv( one, *Ctmp, *Utmp, A11 );
2219 Teuchos::SerialDenseMatrix<int,ScalarType> A21( Teuchos::View, A_tmp, m+1, keffloc, keffloc );
2221 for (i=0; i < m+1; i++) { index[i] = i; }
2222 Teuchos::RCP<const MV> Vp = MVT::CloneView( *VV, index );
2223 MVT::MvTransMv( one, *Vp, *Utmp, A21 );
2226 for( i=keffloc; i<keffloc+m; i++ ) {
2231 Teuchos::SerialDenseMatrix<int,ScalarType> A( m2, A_tmp.numCols() );
2232 A.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, one, HH, A_tmp, zero );
2240 char balanc=
'P', jobvl=
'N', jobvr=
'V', sense=
'N';
2241 int ld = A.numRows();
2243 int ldvl = ld, ldvr = ld;
2244 int info = 0,ilo = 0,ihi = 0;
2245 MagnitudeType abnrm = 0.0, bbnrm = 0.0;
2247 std::vector<ScalarType> beta(ld);
2248 std::vector<ScalarType> work(lwork);
2249 std::vector<MagnitudeType> rwork(lwork);
2250 std::vector<MagnitudeType> lscale(ld), rscale(ld);
2251 std::vector<MagnitudeType> rconde(ld), rcondv(ld);
2252 std::vector<int> iwork(ld+6);
2257 lapack.GGEVX(balanc, jobvl, jobvr, sense, ld, A.values(), ld, B.values(), ld, &wr[0], &wi[0],
2258 &beta[0], vl, ldvl, vr.values(), ldvr, &ilo, &ihi, &lscale[0], &rscale[0],
2259 &abnrm, &bbnrm, &rconde[0], &rcondv[0], &work[0], lwork, &rwork[0],
2260 &iwork[0], bwork, &info);
2261 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GGEVX failed to compute eigensolutions.");
2265 for( i=0; i<ld; i++ ) {
2266 w[i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot (wr[i]*wr[i] + wi[i]*wi[i]) /
2267 Teuchos::ScalarTraits<ScalarType>::magnitude (beta[i]);
2271 this->sort(w,ld,iperm);
2273 const bool scalarTypeIsComplex = Teuchos::ScalarTraits<ScalarType>::isComplex;
2276 for( i=0; i<recycledBlocks_; i++ ) {
2277 for( j=0; j<ld; j++ ) {
2278 PP(j,i) = vr(j,iperm[ld-recycledBlocks_+i]);
2282 if(!scalarTypeIsComplex) {
2285 if (wi[iperm[ld-recycledBlocks_]] != 0.0) {
2287 for ( i=ld-recycledBlocks_; i<ld; i++ ) {
2288 if (wi[iperm[i]] != 0.0)
2297 if (wi[iperm[ld-recycledBlocks_]] > 0.0) {
2298 for( j=0; j<ld; j++ ) {
2299 PP(j,recycledBlocks_) = vr(j,iperm[ld-recycledBlocks_]+1);
2303 for( j=0; j<ld; j++ ) {
2304 PP(j,recycledBlocks_) = vr(j,iperm[ld-recycledBlocks_]-1);
2313 return recycledBlocks_+1;
2316 return recycledBlocks_;
2323template<
class ScalarType,
class MV,
class OP>
2325 int l, r, j, i, flag;
2327 MagnitudeType dRR, dK;
2354 if (dlist[j] > dlist[j - 1]) j = j + 1;
2356 if (dlist[j - 1] > dK) {
2357 dlist[i - 1] = dlist[j - 1];
2358 iperm[i - 1] = iperm[j - 1];
2372 dlist[r] = dlist[0];
2373 iperm[r] = iperm[0];
2388template<
class ScalarType,
class MV,
class OP>
2390 std::ostringstream out;
2391 out <<
"Belos::GCRODRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
2393 out <<
"Ortho Type: \"" << orthoType_ <<
"\"";
2394 out <<
", Num Blocks: " <<numBlocks_;
2395 out <<
", Num Recycle Blocks: " << recycledBlocks_;
2396 out <<
", Max Restarts: " << maxRestarts_;
Belos concrete class for performing the block, flexible GMRES iteration.
Belos header file which uses auto-configuration information to include necessary C++ headers.
Belos concrete class for performing the GCRO-DR iteration.
Class which describes the linear problem to be solved by the iterative solver.
Class which manages the output and verbosity of the Belos solvers.
Pure virtual base class which describes the basic interface for a solver manager.
Belos::StatusTest for logically combining several status tests.
Belos::StatusTestResNorm for specifying general residual norm stopping criteria.
Belos::StatusTest class for specifying a maximum number of iterations.
A factory class for generating StatusTestOutput objects.
Collection of types and exceptions used within the Belos solvers.
BelosError(const std::string &what_arg)
An implementation of the Belos::MatOrthoManager that performs orthogonalization using (potentially) m...
void setDepTol(const MagnitudeType dep_tol)
Set parameter for re-orthogonalization threshhold.
Base class for Belos::SolverManager subclasses which normally can only compile with ScalarType types ...
GCRODRIterOrthoFailure is thrown when the GCRODRIter object is unable to compute independent directio...
This class implements the GCRODR iteration, where a single-stdvector Krylov subspace is constructed....
GCRODRSolMgrLAPACKFailure is thrown when a nonzero value is retuned from an LAPACK call.
GCRODRSolMgrLAPACKFailure(const std::string &what_arg)
GCRODRSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i....
GCRODRSolMgrLinearProblemFailure(const std::string &what_arg)
GCRODRSolMgrOrthoFailure is thrown when the orthogonalization manager is unable to generate orthonorm...
GCRODRSolMgrOrthoFailure(const std::string &what_arg)
GCRODRSolMgrRecyclingFailure is thrown when any problem occurs in using/creating the recycling subspa...
GCRODRSolMgrRecyclingFailure(const std::string &what_arg)
const LinearProblem< ScalarType, MV, OP > & getProblem() const override
Get current linear problem being solved for in this object.
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
virtual ~GCRODRSolMgr()
Destructor.
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
int getNumIters() const override
Get the iteration count for the most recent call to solve().
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
Get a parameter list containing the valid parameters for this object.
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) override
Set the linear problem that needs to be solved.
GCRODRSolMgr()
Empty constructor for GCRODRSolMgr. This constructor takes no arguments and sets the default values f...
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
Get a parameter list containing the current parameters for this object.
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
bool isLOADetected() const override
Return whether a loss of accuracy was detected by this solver during the most current solve.
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > ¶ms) override
Set the parameters the solver manager should use to solve the linear problem.
Implementation of the GCRODR (Recycling GMRES) iterative linear solver.
GCRODRSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< Teuchos::ParameterList > &pl)
Traits class which defines basic operations on multivectors.
static void MvTransMv(const ScalarType alpha, const MV &A, const MV &mv, Teuchos::SerialDenseMatrix< int, ScalarType > &B)
Compute a dense matrix B through the matrix-matrix multiply .
static void MvTimesMatAddMv(const ScalarType alpha, const MV &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta, MV &mv)
Update mv with .
static ptrdiff_t GetGlobalLength(const MV &mv)
Return the number of rows in the given multivector mv.
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
static Teuchos::RCP< const MV > CloneView(const MV &mv, const std::vector< int > &index)
Creates a new const MV that shares the selected contents of mv (shallow copy).
static Teuchos::RCP< MV > CloneViewNonConst(MV &mv, const std::vector< int > &index)
Creates a new MV that shares the selected contents of mv (shallow copy).
static void MvInit(MV &mv, const ScalarType alpha=Teuchos::ScalarTraits< ScalarType >::zero())
Replace each element of the vectors in mv with alpha.
static void SetBlock(const MV &A, const std::vector< int > &index, MV &mv)
Copy the vectors in A to a set of vectors in mv indicated by the indices given in index.
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
Class which defines basic traits for the operator type.
Enumeration of all valid Belos (Mat)OrthoManager classes.
std::ostream & printValidNames(std::ostream &out) const
Print all recognized MatOrthoManager names to the given ostream.
bool isValidName(const std::string &name) const
Whether this factory recognizes the MatOrthoManager with the given name.
std::string validNamesString() const
List (as a string) of recognized MatOrthoManager names.
Teuchos::RCP< Belos::MatOrthoManager< Scalar, MV, OP > > makeMatOrthoManager(const std::string &ortho, const Teuchos::RCP< const OP > &M, const Teuchos::RCP< OutputManager< Scalar > > &, const std::string &label, const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Return an instance of the specified MatOrthoManager subclass.
Teuchos::RCP< const Teuchos::ParameterList > getDefaultParameters(const std::string &name) const
Default parameters for the given MatOrthoManager subclass.
Belos's basic output manager for sending information of select verbosity levels to the appropriate ou...
A class for extending the status testing capabilities of Belos via logical combinations.
Exception thrown to signal error in a status test during Belos::StatusTest::checkStatus().
An implementation of StatusTestResNorm using a family of residual norms.
A Belos::StatusTest class for specifying a maximum number of iterations.
A factory class for generating StatusTestOutput objects.
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.
ScaleType convertStringToScaleType(const std::string &scaleType)
Convert the given string to its ScaleType enum value.
ReturnType
Whether the Belos solve converged for all linear systems.
ScaleType
The type of scaling to use on the residual norm value.
ResetType
How to reset the solver.
static const double convTol
Default convergence tolerance.
Structure to contain pointers to GCRODRIter state variables.
Teuchos::RCP< MV > U
The recycled subspace and its projection.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > B
The projection of the Krylov subspace against the recycled subspace.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > H
The current Hessenberg matrix.
Teuchos::RCP< MV > V
The current Krylov basis.
int curDim
The current dimension of the reduction.