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"
34#ifdef BELOS_TEUCHOS_TIME_MONITOR
35# include "Teuchos_TimeMonitor.hpp"
38#if defined(HAVE_TEUCHOSCORE_CXX11)
39# include <type_traits>
40# if defined(HAVE_TEUCHOS_COMPLEX)
41#include "Kokkos_Complex.hpp"
130 template<
class ScalarType,
class MV,
class OP,
131 const bool lapackSupportsScalarType =
136 static const bool requiresLapack =
139 requiresLapack> base_type;
146 const Teuchos::RCP<Teuchos::ParameterList>& pl) :
155 template<
class ScalarType,
class MV,
class OP>
160#if defined(HAVE_TEUCHOSCORE_CXX11)
161# if defined(HAVE_TEUCHOS_COMPLEX)
162 #if defined(HAVE_TEUCHOS_LONG_DOUBLE)
163 static_assert (std::is_same<ScalarType, std::complex<float> >::value ||
164 std::is_same<ScalarType, std::complex<double> >::value ||
165 std::is_same<ScalarType, Kokkos::complex<double> >::value ||
166 std::is_same<ScalarType, float>::value ||
167 std::is_same<ScalarType, double>::value ||
168 std::is_same<ScalarType, long double>::value,
169 "Belos::GCRODRSolMgr: ScalarType must be one of the four "
170 "types (S,D,C,Z) supported by LAPACK or long double (largely not impl'd).");
172 static_assert (std::is_same<ScalarType, std::complex<float> >::value ||
173 std::is_same<ScalarType, std::complex<double> >::value ||
174 std::is_same<ScalarType, Kokkos::complex<double> >::value ||
175 std::is_same<ScalarType, float>::value ||
176 std::is_same<ScalarType, double>::value,
177 "Belos::GCRODRSolMgr: ScalarType must be one of the four "
178 "types (S,D,C,Z) supported by LAPACK.");
181 #if defined(HAVE_TEUCHOS_LONG_DOUBLE)
182 static_assert (std::is_same<ScalarType, float>::value ||
183 std::is_same<ScalarType, double>::value ||
184 std::is_same<ScalarType, long double>::value,
185 "Belos::GCRODRSolMgr: ScalarType must be float, double or long double. "
186 "Complex arithmetic support is currently disabled. To "
187 "enable it, set Teuchos_ENABLE_COMPLEX=ON.");
189 static_assert (std::is_same<ScalarType, float>::value ||
190 std::is_same<ScalarType, double>::value,
191 "Belos::GCRODRSolMgr: ScalarType must be float or double. "
192 "Complex arithmetic support is currently disabled. To "
193 "enable it, set Teuchos_ENABLE_COMPLEX=ON.");
201 typedef Teuchos::ScalarTraits<ScalarType> SCT;
202 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
203 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
270 const Teuchos::RCP<Teuchos::ParameterList> &pl);
276 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
292 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const override;
305 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
306 return Teuchos::tuple(timerSolve_);
338 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
override;
350 bool set = problem_->setProblem();
352 throw "Could not set problem.";
396 std::string description()
const override;
406 void initializeStateStorage();
415 int getHarmonicVecs1(
int m,
416 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
417 Teuchos::SerialDenseMatrix<int,ScalarType>& PP);
424 int getHarmonicVecs2(
int keff,
int m,
425 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
426 const Teuchos::RCP<const MV>& VV,
427 Teuchos::SerialDenseMatrix<int,ScalarType>& PP);
430 void sort(std::vector<MagnitudeType>& dlist,
int n, std::vector<int>& iperm);
433 Teuchos::LAPACK<int,ScalarType> lapack;
436 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
439 Teuchos::RCP<OutputManager<ScalarType> > printer_;
440 Teuchos::RCP<std::ostream> outputStream_;
443 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
444 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
445 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
446 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > expConvTest_, impConvTest_;
447 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
452 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
455 Teuchos::RCP<Teuchos::ParameterList> params_;
458 static constexpr double orthoKappa_default_ = 0.0;
459 static constexpr int maxRestarts_default_ = 100;
460 static constexpr int maxIters_default_ = 1000;
461 static constexpr int numBlocks_default_ = 50;
462 static constexpr int blockSize_default_ = 1;
463 static constexpr int recycledBlocks_default_ = 5;
466 static constexpr int outputFreq_default_ = -1;
467 static constexpr const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
468 static constexpr const char * expResScale_default_ =
"Norm of Initial Residual";
469 static constexpr const char * label_default_ =
"Belos";
470 static constexpr const char * orthoType_default_ =
"ICGS";
473 MagnitudeType convTol_, orthoKappa_, achievedTol_;
474 int maxRestarts_, maxIters_, numIters_;
475 int verbosity_, outputStyle_, outputFreq_;
476 std::string orthoType_;
477 std::string impResScale_, expResScale_;
484 int numBlocks_, recycledBlocks_;
495 Teuchos::RCP<MV> U_, C_;
498 Teuchos::RCP<MV> U1_, C1_;
501 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H2_;
502 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H_;
503 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B_;
504 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PP_;
505 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > HP_;
506 std::vector<ScalarType> tau_;
507 std::vector<ScalarType> work_;
508 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > R_;
509 std::vector<int> ipiv_;
514 Teuchos::RCP<Teuchos::Time> timerSolve_;
520 bool builtRecycleSpace_;
525template<
class ScalarType,
class MV,
class OP>
535template<
class ScalarType,
class MV,
class OP>
538 const Teuchos::RCP<Teuchos::ParameterList>& pl):
546 TEUCHOS_TEST_FOR_EXCEPTION(
547 problem == Teuchos::null, std::invalid_argument,
548 "Belos::GCRODRSolMgr constructor: The solver manager's "
549 "constructor needs the linear problem argument 'problem' "
558 if (! pl.is_null ()) {
564template<
class ScalarType,
class MV,
class OP>
566 outputStream_ = Teuchos::rcpFromRef(std::cout);
568 orthoKappa_ = orthoKappa_default_;
569 maxRestarts_ = maxRestarts_default_;
570 maxIters_ = maxIters_default_;
571 numBlocks_ = numBlocks_default_;
572 recycledBlocks_ = recycledBlocks_default_;
573 verbosity_ = verbosity_default_;
574 outputStyle_ = outputStyle_default_;
575 outputFreq_ = outputFreq_default_;
576 orthoType_ = orthoType_default_;
577 impResScale_ = impResScale_default_;
578 expResScale_ = expResScale_default_;
579 label_ = label_default_;
581 builtRecycleSpace_ =
false;
597template<
class ScalarType,
class MV,
class OP>
600setParameters (
const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
602 using Teuchos::isParameterType;
603 using Teuchos::getParameter;
605 using Teuchos::ParameterList;
606 using Teuchos::parameterList;
609 using Teuchos::rcp_dynamic_cast;
610 using Teuchos::rcpFromRef;
611 using Teuchos::Exceptions::InvalidParameter;
612 using Teuchos::Exceptions::InvalidParameterName;
613 using Teuchos::Exceptions::InvalidParameterType;
635 if (params_.is_null()) {
636 params_ = parameterList (*defaultParams);
644 if (params_ != params) {
650 params_ = parameterList (*params);
685 params_->validateParametersAndSetDefaults (*defaultParams);
689 if (params->isParameter (
"Maximum Restarts")) {
690 maxRestarts_ = params->get(
"Maximum Restarts", maxRestarts_default_);
693 params_->set (
"Maximum Restarts", maxRestarts_);
697 if (params->isParameter (
"Maximum Iterations")) {
698 maxIters_ = params->get (
"Maximum Iterations", maxIters_default_);
701 params_->set (
"Maximum Iterations", maxIters_);
702 if (! maxIterTest_.is_null())
703 maxIterTest_->setMaxIters (maxIters_);
707 if (params->isParameter (
"Num Blocks")) {
708 numBlocks_ = params->get (
"Num Blocks", numBlocks_default_);
709 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks_ <= 0, std::invalid_argument,
710 "Belos::GCRODRSolMgr: The \"Num Blocks\" parameter must "
711 "be strictly positive, but you specified a value of "
712 << numBlocks_ <<
".");
714 params_->set (
"Num Blocks", numBlocks_);
718 if (params->isParameter (
"Num Recycled Blocks")) {
719 recycledBlocks_ = params->get (
"Num Recycled Blocks",
720 recycledBlocks_default_);
721 TEUCHOS_TEST_FOR_EXCEPTION(recycledBlocks_ <= 0, std::invalid_argument,
722 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
723 "parameter must be strictly positive, but you specified "
724 "a value of " << recycledBlocks_ <<
".");
725 TEUCHOS_TEST_FOR_EXCEPTION(recycledBlocks_ >= numBlocks_, std::invalid_argument,
726 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
727 "parameter must be less than the \"Num Blocks\" "
728 "parameter, but you specified \"Num Recycled Blocks\" "
729 "= " << recycledBlocks_ <<
" and \"Num Blocks\" = "
730 << numBlocks_ <<
".");
732 params_->set(
"Num Recycled Blocks", recycledBlocks_);
738 if (params->isParameter (
"Timer Label")) {
739 std::string tempLabel = params->get (
"Timer Label", label_default_);
742 if (tempLabel != label_) {
744 params_->set (
"Timer Label", label_);
745 std::string solveLabel = label_ +
": GCRODRSolMgr total solve time";
746#ifdef BELOS_TEUCHOS_TIME_MONITOR
747 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
749 if (ortho_ != Teuchos::null) {
750 ortho_->setLabel( label_ );
756 if (params->isParameter (
"Verbosity")) {
757 if (isParameterType<int> (*params,
"Verbosity")) {
758 verbosity_ = params->get (
"Verbosity", verbosity_default_);
760 verbosity_ = (int) getParameter<Belos::MsgType> (*params,
"Verbosity");
763 params_->set (
"Verbosity", verbosity_);
766 if (! printer_.is_null())
767 printer_->setVerbosity (verbosity_);
771 if (params->isParameter (
"Output Style")) {
772 if (isParameterType<int> (*params,
"Output Style")) {
773 outputStyle_ = params->get (
"Output Style", outputStyle_default_);
775 outputStyle_ = (int) getParameter<OutputType> (*params,
"Output Style");
779 params_->set (
"Output Style", outputStyle_);
797 if (params->isParameter (
"Output Stream")) {
799 outputStream_ = getParameter<RCP<std::ostream> > (*params,
"Output Stream");
800 }
catch (InvalidParameter&) {
801 outputStream_ = rcpFromRef (std::cout);
808 if (outputStream_.is_null()) {
809 outputStream_ = rcp (
new Teuchos::oblackholestream);
812 params_->set (
"Output Stream", outputStream_);
815 if (! printer_.is_null()) {
816 printer_->setOStream (outputStream_);
822 if (params->isParameter (
"Output Frequency")) {
823 outputFreq_ = params->get (
"Output Frequency", outputFreq_default_);
827 params_->set(
"Output Frequency", outputFreq_);
828 if (! outputTest_.is_null())
829 outputTest_->setOutputFrequency (outputFreq_);
836 if (printer_.is_null()) {
847 bool changedOrthoType =
false;
848 if (params->isParameter (
"Orthogonalization")) {
849 const std::string& tempOrthoType =
850 params->get (
"Orthogonalization", orthoType_default_);
853 std::ostringstream os;
854 os <<
"Belos::GCRODRSolMgr: Invalid orthogonalization name \""
855 << tempOrthoType <<
"\". The following are valid options "
856 <<
"for the \"Orthogonalization\" name parameter: ";
858 throw std::invalid_argument (os.str());
860 if (tempOrthoType != orthoType_) {
861 changedOrthoType =
true;
862 orthoType_ = tempOrthoType;
864 params_->set (
"Orthogonalization", orthoType_);
880 RCP<ParameterList> orthoParams;
883 using Teuchos::sublist;
885 const std::string paramName (
"Orthogonalization Parameters");
888 orthoParams = sublist (params_, paramName,
true);
889 }
catch (InvalidParameter&) {
896 orthoParams = sublist (params_, paramName,
true);
899 TEUCHOS_TEST_FOR_EXCEPTION(orthoParams.is_null(), std::logic_error,
900 "Failed to get orthogonalization parameters. "
901 "Please report this bug to the Belos developers.");
906 if (ortho_.is_null() || changedOrthoType) {
912 label_, orthoParams);
920 typedef Teuchos::ParameterListAcceptor PLA;
921 RCP<PLA> pla = rcp_dynamic_cast<PLA> (ortho_);
927 label_, orthoParams);
929 pla->setParameterList (orthoParams);
941 if (params->isParameter (
"Orthogonalization Constant")) {
942 MagnitudeType orthoKappa = orthoKappa_default_;
943 if (params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
944 orthoKappa = params->get (
"Orthogonalization Constant", orthoKappa);
947 orthoKappa = params->get (
"Orthogonalization Constant", orthoKappa_default_);
950 if (orthoKappa > 0) {
951 orthoKappa_ = orthoKappa;
953 params_->set(
"Orthogonalization Constant", orthoKappa_);
955 if (orthoType_ ==
"DGKS" && ! ortho_.is_null()) {
962 rcp_dynamic_cast<ortho_man_type>(ortho_)->
setDepTol (orthoKappa_);
972 if (params->isParameter(
"Convergence Tolerance")) {
973 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
974 convTol_ = params->get (
"Convergence Tolerance",
982 params_->set (
"Convergence Tolerance", convTol_);
983 if (! impConvTest_.is_null())
984 impConvTest_->setTolerance (convTol_);
985 if (! expConvTest_.is_null())
986 expConvTest_->setTolerance (convTol_);
990 if (params->isParameter (
"Implicit Residual Scaling")) {
991 std::string tempImpResScale =
992 getParameter<std::string> (*params,
"Implicit Residual Scaling");
995 if (impResScale_ != tempImpResScale) {
997 impResScale_ = tempImpResScale;
1000 params_->set(
"Implicit Residual Scaling", impResScale_);
1010 if (! impConvTest_.is_null()) {
1016 impConvTest_ = null;
1023 if (params->isParameter(
"Explicit Residual Scaling")) {
1024 std::string tempExpResScale =
1025 getParameter<std::string> (*params,
"Explicit Residual Scaling");
1028 if (expResScale_ != tempExpResScale) {
1030 expResScale_ = tempExpResScale;
1033 params_->set(
"Explicit Residual Scaling", expResScale_);
1036 if (! expConvTest_.is_null()) {
1042 expConvTest_ = null;
1053 if (maxIterTest_.is_null())
1058 if (impConvTest_.is_null()) {
1059 impConvTest_ = rcp (
new StatusTestResNorm_t (convTol_));
1065 if (expConvTest_.is_null()) {
1066 expConvTest_ = rcp (
new StatusTestResNorm_t (convTol_));
1067 expConvTest_->defineResForm (StatusTestResNorm_t::Explicit,
Belos::TwoNorm);
1073 if (convTest_.is_null()) {
1074 convTest_ = rcp (
new StatusTestCombo_t (StatusTestCombo_t::SEQ,
1082 sTest_ = rcp (
new StatusTestCombo_t (StatusTestCombo_t::OR,
1088 outputTest_ = stoFactory.
create (printer_, sTest_, outputFreq_,
1092 std::string solverDesc =
" GCRODR ";
1093 outputTest_->setSolverDesc( solverDesc );
1096 if (timerSolve_.is_null()) {
1097 std::string solveLabel = label_ +
": GCRODRSolMgr total solve time";
1098#ifdef BELOS_TEUCHOS_TIME_MONITOR
1099 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
1108template<
class ScalarType,
class MV,
class OP>
1109Teuchos::RCP<const Teuchos::ParameterList>
1112 using Teuchos::ParameterList;
1113 using Teuchos::parameterList;
1116 static RCP<const ParameterList> validPL;
1117 if (is_null(validPL)) {
1118 RCP<ParameterList> pl = parameterList ();
1122 "The relative residual tolerance that needs to be achieved by the\n"
1123 "iterative solver in order for the linear system to be declared converged.");
1124 pl->set(
"Maximum Restarts",
static_cast<int>(maxRestarts_default_),
1125 "The maximum number of cycles allowed for each\n"
1126 "set of RHS solved.");
1127 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
1128 "The maximum number of iterations allowed for each\n"
1129 "set of RHS solved.");
1133 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
1134 "Block Size Parameter -- currently must be 1 for GCRODR");
1135 pl->set(
"Num Blocks",
static_cast<int>(numBlocks_default_),
1136 "The maximum number of vectors allowed in the Krylov subspace\n"
1137 "for each set of RHS solved.");
1138 pl->set(
"Num Recycled Blocks",
static_cast<int>(recycledBlocks_default_),
1139 "The maximum number of vectors in the recycled subspace." );
1140 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
1141 "What type(s) of solver information should be outputted\n"
1142 "to the output stream.");
1143 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
1144 "What style is used for the solver information outputted\n"
1145 "to the output stream.");
1146 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
1147 "How often convergence information should be outputted\n"
1148 "to the output stream.");
1149 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
1150 "A reference-counted pointer to the output stream where all\n"
1151 "solver output is sent.");
1152 pl->set(
"Implicit Residual Scaling",
static_cast<const char *
>(impResScale_default_),
1153 "The type of scaling used in the implicit residual convergence test.");
1154 pl->set(
"Explicit Residual Scaling",
static_cast<const char *
>(expResScale_default_),
1155 "The type of scaling used in the explicit residual convergence test.");
1156 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
1157 "The string to use as a prefix for the timer labels.");
1160 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
1161 "The type of orthogonalization to use. Valid options: " +
1163 RCP<const ParameterList> orthoParams =
1165 pl->set (
"Orthogonalization Parameters", *orthoParams,
1166 "Parameters specific to the type of orthogonalization used.");
1168 pl->set(
"Orthogonalization Constant",
static_cast<MagnitudeType
>(orthoKappa_default_),
1169 "When using DGKS orthogonalization: the \"depTol\" constant, used "
1170 "to determine whether another step of classical Gram-Schmidt is "
1171 "necessary. Otherwise ignored.");
1178template<
class ScalarType,
class MV,
class OP>
1181 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1184 Teuchos::RCP<const MV> rhsMV = problem_->getRHS();
1185 if (rhsMV == Teuchos::null) {
1192 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<ptrdiff_t
>(numBlocks_) > MVT::GetGlobalLength(*rhsMV),std::invalid_argument,
1193 "Belos::GCRODRSolMgr::initializeStateStorage(): Cannot generate a Krylov basis with dimension larger the operator!");
1196 if (U_ == Teuchos::null) {
1197 U_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1201 if (MVT::GetNumberVecs(*U_) < recycledBlocks_+1) {
1202 Teuchos::RCP<const MV> tmp = U_;
1203 U_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1208 if (C_ == Teuchos::null) {
1209 C_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1213 if (MVT::GetNumberVecs(*C_) < recycledBlocks_+1) {
1214 Teuchos::RCP<const MV> tmp = C_;
1215 C_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1220 if (V_ == Teuchos::null) {
1221 V_ = MVT::Clone( *rhsMV, numBlocks_+1 );
1225 if (MVT::GetNumberVecs(*V_) < numBlocks_+1) {
1226 Teuchos::RCP<const MV> tmp = V_;
1227 V_ = MVT::Clone( *tmp, numBlocks_+1 );
1232 if (U1_ == Teuchos::null) {
1233 U1_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1237 if (MVT::GetNumberVecs(*U1_) < recycledBlocks_+1) {
1238 Teuchos::RCP<const MV> tmp = U1_;
1239 U1_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1244 if (C1_ == Teuchos::null) {
1245 C1_ = MVT::Clone( *rhsMV, recycledBlocks_+1 );
1249 if (MVT::GetNumberVecs(*C1_) < recycledBlocks_+1) {
1250 Teuchos::RCP<const MV> tmp = C1_;
1251 C1_ = MVT::Clone( *tmp, recycledBlocks_+1 );
1256 if (r_ == Teuchos::null)
1257 r_ = MVT::Clone( *rhsMV, 1 );
1260 tau_.resize(recycledBlocks_+1);
1263 work_.resize(recycledBlocks_+1);
1266 ipiv_.resize(recycledBlocks_+1);
1269 if (H2_ == Teuchos::null)
1270 H2_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 ) );
1272 if ( (H2_->numRows() != numBlocks_+recycledBlocks_+2) || (H2_->numCols() != numBlocks_+recycledBlocks_+1) )
1273 H2_->reshape( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1275 H2_->putScalar(zero);
1278 if (R_ == Teuchos::null)
1279 R_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( recycledBlocks_+1, recycledBlocks_+1 ) );
1281 if ( (R_->numRows() != recycledBlocks_+1) || (R_->numCols() != recycledBlocks_+1) )
1282 R_->reshape( recycledBlocks_+1, recycledBlocks_+1 );
1284 R_->putScalar(zero);
1287 if (PP_ == Teuchos::null)
1288 PP_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 ) );
1290 if ( (PP_->numRows() != numBlocks_+recycledBlocks_+2) || (PP_->numCols() != recycledBlocks_+1) )
1291 PP_->reshape( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 );
1295 if (HP_ == Teuchos::null)
1296 HP_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 ) );
1298 if ( (HP_->numRows() != numBlocks_+recycledBlocks_+2) || (HP_->numCols() != numBlocks_+recycledBlocks_+1) )
1299 HP_->reshape( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1307template<
class ScalarType,
class MV,
class OP>
1317 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
1318 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1319 std::vector<int> index(numBlocks_+1);
1321 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,
GCRODRSolMgrLinearProblemFailure,
"Belos::GCRODRSolMgr::solve(): Linear problem is not a valid object.");
1323 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(),
GCRODRSolMgrLinearProblemFailure,
"Belos::GCRODRSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1327 std::vector<int> currIdx(1);
1331 problem_->setLSIndex( currIdx );
1335 if (
static_cast<ptrdiff_t
>(numBlocks_) > dim) {
1336 numBlocks_ = Teuchos::as<int>(dim);
1338 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1339 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1340 params_->set(
"Num Blocks", numBlocks_);
1344 bool isConverged =
true;
1347 initializeStateStorage();
1351 Teuchos::ParameterList plist;
1353 plist.set(
"Num Blocks",numBlocks_);
1354 plist.set(
"Recycled Blocks",recycledBlocks_);
1359 RCP<GCRODRIter<ScalarType,MV,OP> > gcrodr_iter;
1362 int prime_iterations = 0;
1366#ifdef BELOS_TEUCHOS_TIME_MONITOR
1367 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1370 while ( numRHS2Solve > 0 ) {
1373 builtRecycleSpace_ =
false;
1376 outputTest_->reset();
1384 "Belos::GCRODRSolMgr::solve(): Requested size of recycled subspace is not consistent with the current recycle subspace.");
1386 printer_->stream(
Debug) <<
" Now solving RHS index " << currIdx[0] <<
" using recycled subspace of dimension " << keff << std::endl << std::endl;
1389 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1392 problem_->apply( *Utmp, *Ctmp );
1398 Teuchos::SerialDenseMatrix<int,ScalarType> Rtmp( Teuchos::View, *R_, keff, keff );
1399 int rank = ortho_->normalize(*Ctmp, rcp(&Rtmp,
false));
1401 TEUCHOS_TEST_FOR_EXCEPTION(rank != keff,
GCRODRSolMgrOrthoFailure,
"Belos::GCRODRSolMgr::solve(): Failed to compute orthonormal basis for initial recycled subspace.");
1406 ipiv_.resize(Rtmp.numRows());
1407 lapack.GETRF(Rtmp.numRows(),Rtmp.numCols(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&info);
1408 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
1411 int lwork = Rtmp.numRows();
1412 work_.resize(lwork);
1413 lapack.GETRI(Rtmp.numRows(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&work_[0],lwork,&info);
1414 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to invert triangular matrix.");
1422 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1427 Teuchos::SerialDenseMatrix<int,ScalarType> Ctr(keff,1);
1428 problem_->computeCurrPrecResVec( &*r_ );
1432 RCP<MV> update =
MVT::Clone( *problem_->getCurrLHSVec(), 1 );
1435 problem_->updateSolution( update,
true );
1441 prime_iterations = 0;
1447 printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " << currIdx[0] << std::endl << std::endl;
1449 Teuchos::ParameterList primeList;
1452 primeList.set(
"Num Blocks",numBlocks_);
1453 primeList.set(
"Recycled Blocks",0);
1456 RCP<GCRODRIter<ScalarType,MV,OP> > gcrodr_prime_iter;
1460 problem_->computeCurrPrecResVec( &*r_ );
1461 index.resize( 1 ); index[0] = 0;
1467 index.resize( numBlocks_+1 );
1468 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1470 newstate.
U = Teuchos::null;
1471 newstate.
C = Teuchos::null;
1472 newstate.
H = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, recycledBlocks_+1, recycledBlocks_+1 ) );
1473 newstate.
B = Teuchos::null;
1475 gcrodr_prime_iter->initialize(newstate);
1478 bool primeConverged =
false;
1480 gcrodr_prime_iter->iterate();
1483 if ( convTest_->getStatus() ==
Passed ) {
1485 primeConverged =
true;
1490 gcrodr_prime_iter->updateLSQR( gcrodr_prime_iter->getCurSubspaceDim() );
1493 sTest_->checkStatus( &*gcrodr_prime_iter );
1494 if (convTest_->getStatus() ==
Passed)
1495 primeConverged =
true;
1499 achievedTol_ = MT::one();
1500 Teuchos::RCP<MV> X = problem_->getLHS();
1502 printer_->stream(
Warnings) <<
"Belos::GCRODRSolMgr::solve(): Warning! NaN has been detected!"
1506 catch (
const std::exception &e) {
1507 printer_->stream(
Errors) <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1508 << gcrodr_prime_iter->getNumIters() << std::endl
1509 << e.what() << std::endl;
1513 prime_iterations = gcrodr_prime_iter->getNumIters();
1516 RCP<MV> update = gcrodr_prime_iter->getCurrentUpdate();
1517 problem_->updateSolution( update,
true );
1520 newstate = gcrodr_prime_iter->getState();
1528 if (recycledBlocks_ < p+1) {
1530 RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PPtmp = rcp (
new Teuchos::SerialDenseMatrix<int,ScalarType> ( Teuchos::View, *PP_, p, recycledBlocks_+1 ) );
1532 keff = getHarmonicVecs1( p, *newstate.
H, *PPtmp );
1534 PPtmp = rcp (
new Teuchos::SerialDenseMatrix<int,ScalarType> ( Teuchos::View, *PP_, p, keff ) );
1537 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1542 for (
int ii=0; ii < p; ++ii) { index[ii] = ii; }
1554 Teuchos::SerialDenseMatrix<int,ScalarType> Htmp( Teuchos::View, *H2_, p+1, p, recycledBlocks_+1,recycledBlocks_+1);
1555 Teuchos::SerialDenseMatrix<int,ScalarType> HPtmp( Teuchos::View, *HP_, p+1, keff );
1556 HPtmp.multiply( Teuchos::NO_TRANS, Teuchos::NO_TRANS, one, Htmp, *PPtmp, zero );
1563 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1564 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1565 TEUCHOS_TEST_FOR_EXCEPTION(
1567 " LAPACK's _GEQRF failed to compute a workspace size.");
1575 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1576 work_.resize (lwork);
1577 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1578 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1579 TEUCHOS_TEST_FOR_EXCEPTION(
1581 " LAPACK's _GEQRF failed to compute a QR factorization.");
1585 Teuchos::SerialDenseMatrix<int,ScalarType> Rtmp( Teuchos::View, *R_, keff, keff );
1586 for (
int ii = 0; ii < keff; ++ii) {
1587 for (
int jj = ii; jj < keff; ++jj) {
1588 Rtmp(ii,jj) = HPtmp(ii,jj);
1595 lapack.UNGQR (HPtmp.numRows (), HPtmp.numCols (), HPtmp.numCols (),
1596 HPtmp.values (), HPtmp.stride (), &tau_[0], &work_[0],
1598 TEUCHOS_TEST_FOR_EXCEPTION(
1600 "LAPACK's _UNGQR failed to construct the Q factor.");
1605 index.resize (p + 1);
1606 for (
int ii = 0; ii < (p+1); ++ii) {
1617 ipiv_.resize(Rtmp.numRows());
1618 lapack.GETRF(Rtmp.numRows(),Rtmp.numCols(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&info);
1619 TEUCHOS_TEST_FOR_EXCEPTION(
1621 "LAPACK's _GETRF failed to compute an LU factorization.");
1630 lwork = Rtmp.numRows();
1631 work_.resize(lwork);
1632 lapack.GETRI(Rtmp.numRows(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&work_[0],lwork,&info);
1633 TEUCHOS_TEST_FOR_EXCEPTION(
1635 "LAPACK's _GETRI failed to invert triangular matrix.");
1640 printer_->stream(
Debug)
1641 <<
" Generated recycled subspace using RHS index " << currIdx[0]
1642 <<
" of dimension " << keff << std::endl << std::endl;
1647 if (primeConverged) {
1649 problem_->setCurrLS();
1653 if (numRHS2Solve > 0) {
1655 problem_->setLSIndex (currIdx);
1658 currIdx.resize (numRHS2Solve);
1668 gcrodr_iter->setSize( keff, numBlocks_ );
1671 gcrodr_iter->resetNumIters(prime_iterations);
1674 outputTest_->resetNumCalls();
1677 problem_->computeCurrPrecResVec( &*r_ );
1678 index.resize( 1 ); index[0] = 0;
1684 index.resize( numBlocks_+1 );
1685 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1687 index.resize( keff );
1688 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1691 newstate.
B = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1692 newstate.
H = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1694 gcrodr_iter->initialize(newstate);
1697 int numRestarts = 0;
1702 gcrodr_iter->iterate();
1709 if ( convTest_->getStatus() ==
Passed ) {
1718 else if ( maxIterTest_->getStatus() ==
Passed ) {
1720 isConverged =
false;
1728 else if ( gcrodr_iter->getCurSubspaceDim() == gcrodr_iter->getMaxSubspaceDim() ) {
1733 RCP<MV> update = gcrodr_iter->getCurrentUpdate();
1734 problem_->updateSolution( update,
true );
1736 buildRecycleSpace2(gcrodr_iter);
1738 printer_->stream(
Debug)
1739 <<
" Generated new recycled subspace using RHS index "
1740 << currIdx[0] <<
" of dimension " << keff << std::endl
1744 if (numRestarts >= maxRestarts_) {
1745 isConverged =
false;
1750 printer_->stream(
Debug)
1751 <<
" Performing restart number " << numRestarts <<
" of "
1752 << maxRestarts_ << std::endl << std::endl;
1755 problem_->computeCurrPrecResVec( &*r_ );
1756 index.resize( 1 ); index[0] = 0;
1762 index.resize( numBlocks_+1 );
1763 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1765 index.resize( keff );
1766 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1769 restartState.
B = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1770 restartState.
H = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1772 gcrodr_iter->initialize(restartState);
1785 TEUCHOS_TEST_FOR_EXCEPTION(
1786 true, std::logic_error,
"Belos::GCRODRSolMgr::solve: "
1787 "Invalid return from GCRODRIter::iterate().");
1792 gcrodr_iter->updateLSQR( gcrodr_iter->getCurSubspaceDim() );
1795 sTest_->checkStatus( &*gcrodr_iter );
1796 if (convTest_->getStatus() !=
Passed)
1797 isConverged =
false;
1800 catch (
const std::exception& e) {
1802 <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1803 << gcrodr_iter->getNumIters() << std::endl << e.what() << std::endl;
1810 RCP<MV> update = gcrodr_iter->getCurrentUpdate();
1811 problem_->updateSolution( update,
true );
1814 problem_->setCurrLS();
1819 if (!builtRecycleSpace_) {
1820 buildRecycleSpace2(gcrodr_iter);
1821 printer_->stream(
Debug)
1822 <<
" Generated new recycled subspace using RHS index " << currIdx[0]
1823 <<
" of dimension " << keff << std::endl << std::endl;
1828 if (numRHS2Solve > 0) {
1830 problem_->setLSIndex (currIdx);
1833 currIdx.resize (numRHS2Solve);
1841#ifdef BELOS_TEUCHOS_TIME_MONITOR
1846 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1850 numIters_ = maxIterTest_->getNumIters ();
1862 const std::vector<MagnitudeType>* pTestValues = expConvTest_->getTestValue();
1863 if (pTestValues == NULL || pTestValues->size() < 1) {
1864 pTestValues = impConvTest_->getTestValue();
1866 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1867 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1868 "method returned NULL. Please report this bug to the Belos developers.");
1869 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1870 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1871 "method returned a vector of length zero. Please report this bug to the "
1872 "Belos developers.");
1877 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1884template<
class ScalarType,
class MV,
class OP>
1887 MagnitudeType one = Teuchos::ScalarTraits<MagnitudeType>::one();
1888 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1890 std::vector<MagnitudeType> d(keff);
1891 std::vector<ScalarType> dscalar(keff);
1892 std::vector<int> index(numBlocks_+1);
1904 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1905 Teuchos::RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
1907 dscalar.resize(keff);
1908 MVT::MvNorm( *Utmp, d );
1909 for (
int i=0; i<keff; ++i) {
1911 dscalar[i] = (ScalarType)d[i];
1913 MVT::MvScale( *Utmp, dscalar );
1917 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H2tmp = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, p+keff+1, p+keff ) );
1920 for (
int i=0; i<keff; ++i) {
1921 (*H2tmp)(i,i) = d[i];
1928 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, p+keff, recycledBlocks_+1 );
1929 keff_new = getHarmonicVecs2( keff, p, *H2tmp, oldState.
V, PPtmp );
1936 Teuchos::RCP<MV> U1tmp;
1938 index.resize( keff );
1939 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1940 Teuchos::RCP<const MV> Utmp = MVT::CloneView( *U_, index );
1941 index.resize( keff_new );
1942 for (
int ii=0; ii<keff_new; ++ii) { index[ii] = ii; }
1943 U1tmp = MVT::CloneViewNonConst( *U1_, index );
1944 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, keff, keff_new );
1945 MVT::MvTimesMatAddMv( one, *Utmp, PPtmp, zero, *U1tmp );
1951 for (
int ii=0; ii < p; ii++) { index[ii] = ii; }
1952 Teuchos::RCP<const MV> Vtmp = MVT::CloneView( *V_, index );
1953 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, p, keff_new, keff );
1954 MVT::MvTimesMatAddMv( one, *Vtmp, PPtmp, one, *U1tmp );
1958 Teuchos::SerialDenseMatrix<int,ScalarType> HPtmp( Teuchos::View, *HP_, p+keff+1, keff_new );
1960 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *PP_, p+keff, keff_new );
1961 HPtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,*H2tmp,PPtmp,zero);
1965 int info = 0, lwork = -1;
1966 tau_.resize (keff_new);
1967 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1968 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1969 TEUCHOS_TEST_FOR_EXCEPTION(
1971 "LAPACK's _GEQRF failed to compute a workspace size.");
1977 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1978 work_.resize (lwork);
1979 lapack.GEQRF (HPtmp.numRows (), HPtmp.numCols (), HPtmp.values (),
1980 HPtmp.stride (), &tau_[0], &work_[0], lwork, &info);
1981 TEUCHOS_TEST_FOR_EXCEPTION(
1983 "LAPACK's _GEQRF failed to compute a QR factorization.");
1987 Teuchos::SerialDenseMatrix<int,ScalarType> Rtmp( Teuchos::View, *R_, keff_new, keff_new );
1988 for(
int i=0;i<keff_new;i++) {
for(
int j=i;j<keff_new;j++) Rtmp(i,j) = HPtmp(i,j); }
1994 lapack.UNGQR (HPtmp.numRows (), HPtmp.numCols (), HPtmp.numCols (),
1995 HPtmp.values (), HPtmp.stride (), &tau_[0], &work_[0],
1997 TEUCHOS_TEST_FOR_EXCEPTION(
1999 "LAPACK's _UNGQR failed to construct the Q factor.");
2006 Teuchos::RCP<MV> C1tmp;
2009 for (
int i=0; i < keff; i++) { index[i] = i; }
2010 Teuchos::RCP<const MV> Ctmp = MVT::CloneView( *C_, index );
2011 index.resize(keff_new);
2012 for (
int i=0; i < keff_new; i++) { index[i] = i; }
2013 C1tmp = MVT::CloneViewNonConst( *C1_, index );
2014 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *HP_, keff, keff_new );
2015 MVT::MvTimesMatAddMv( one, *Ctmp, PPtmp, zero, *C1tmp );
2019 index.resize( p+1 );
2020 for (
int i=0; i < p+1; ++i) { index[i] = i; }
2021 Teuchos::RCP<const MV> Vtmp = MVT::CloneView( *V_, index );
2022 Teuchos::SerialDenseMatrix<int,ScalarType> PPtmp( Teuchos::View, *HP_, p+1, keff_new, keff, 0 );
2023 MVT::MvTimesMatAddMv( one, *Vtmp, PPtmp, one, *C1tmp );
2032 ipiv_.resize(Rtmp.numRows());
2033 lapack.GETRF(Rtmp.numRows(),Rtmp.numCols(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&info);
2034 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
2037 lwork = Rtmp.numRows();
2038 work_.resize(lwork);
2039 lapack.GETRI(Rtmp.numRows(),Rtmp.values(),Rtmp.stride(),&ipiv_[0],&work_[0],lwork,&info);
2040 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to compute an LU factorization.");
2043 index.resize(keff_new);
2044 for (
int i=0; i < keff_new; i++) { index[i] = i; }
2045 Teuchos::RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
2046 MVT::MvTimesMatAddMv( one, *U1tmp, Rtmp, zero, *Utmp );
2050 if (keff != keff_new) {
2052 gcrodr_iter->setSize( keff, numBlocks_ );
2054 Teuchos::SerialDenseMatrix<int,ScalarType> b1( Teuchos::View, *H2_, recycledBlocks_+2, 1, 0, recycledBlocks_ );
2062template<
class ScalarType,
class MV,
class OP>
2064 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2065 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2067 bool xtraVec =
false;
2068 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
2071 std::vector<MagnitudeType> wr(m), wi(m);
2074 Teuchos::SerialDenseMatrix<int,ScalarType> vr(m,m,
false);
2077 std::vector<MagnitudeType> w(m);
2080 std::vector<int> iperm(m);
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, m, m );
2098 for( i=0; i<m; ++i )
2099 harmHH(i, m-1) += d * e_m[i];
2108 std::vector<ScalarType> work(1);
2109 std::vector<MagnitudeType> rwork(2*m);
2112 lapack.GEEV(
'N',
'V', m, harmHH.values(), harmHH.stride(), &wr[0], &wi[0],
2113 vl, ldvl, vr.values(), vr.stride(), &work[0], lwork, &rwork[0], &info);
2115 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work[0])));
2116 work.resize( lwork );
2118 lapack.GEEV(
'N',
'V', m, harmHH.values(), harmHH.stride(), &wr[0], &wi[0],
2119 vl, ldvl, vr.values(), vr.stride(), &work[0], lwork, &rwork[0], &info);
2120 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GEEV failed to compute eigensolutions.");
2123 for( i=0; i<m; ++i )
2124 w[i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot( wr[i]*wr[i] + wi[i]*wi[i] );
2127 this->sort(w, m, iperm);
2129 const bool scalarTypeIsComplex = Teuchos::ScalarTraits<ScalarType>::isComplex;
2132 for( i=0; i<recycledBlocks_; ++i ) {
2133 for( j=0; j<m; j++ ) {
2134 PP(j,i) = vr(j,iperm[i]);
2138 if(!scalarTypeIsComplex) {
2141 if (wi[iperm[recycledBlocks_-1]] != 0.0) {
2143 for ( i=0; i<recycledBlocks_; ++i ) {
2144 if (wi[iperm[i]] != 0.0)
2153 if (wi[iperm[recycledBlocks_-1]] > 0.0) {
2154 for( j=0; j<m; ++j ) {
2155 PP(j,recycledBlocks_) = vr(j,iperm[recycledBlocks_-1]+1);
2159 for( j=0; j<m; ++j ) {
2160 PP(j,recycledBlocks_) = vr(j,iperm[recycledBlocks_-1]-1);
2169 return recycledBlocks_+1;
2172 return recycledBlocks_;
2178template<
class ScalarType,
class MV,
class OP>
2180 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2181 const Teuchos::RCP<const MV>& VV,
2182 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2184 int m2 = HH.numCols();
2185 bool xtraVec =
false;
2186 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
2187 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
2188 std::vector<int> index;
2191 std::vector<MagnitudeType> wr(m2), wi(m2);
2194 std::vector<MagnitudeType> w(m2);
2197 Teuchos::SerialDenseMatrix<int,ScalarType> vr(m2,m2,
false);
2200 std::vector<int> iperm(m2);
2203 builtRecycleSpace_ =
true;
2208 Teuchos::SerialDenseMatrix<int,ScalarType> B(m2,m2,
false);
2209 B.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,HH,HH,zero);
2213 Teuchos::SerialDenseMatrix<int,ScalarType> A_tmp( keffloc+m+1, keffloc+m );
2216 index.resize(keffloc);
2217 for (i=0; i<keffloc; ++i) { index[i] = i; }
2218 Teuchos::RCP<const MV> Ctmp = MVT::CloneView( *C_, index );
2219 Teuchos::RCP<const MV> Utmp = MVT::CloneView( *U_, index );
2220 Teuchos::SerialDenseMatrix<int,ScalarType> A11( Teuchos::View, A_tmp, keffloc, keffloc );
2221 MVT::MvTransMv( one, *Ctmp, *Utmp, A11 );
2224 Teuchos::SerialDenseMatrix<int,ScalarType> A21( Teuchos::View, A_tmp, m+1, keffloc, keffloc );
2226 for (i=0; i < m+1; i++) { index[i] = i; }
2227 Teuchos::RCP<const MV> Vp = MVT::CloneView( *VV, index );
2228 MVT::MvTransMv( one, *Vp, *Utmp, A21 );
2231 for( i=keffloc; i<keffloc+m; i++ ) {
2236 Teuchos::SerialDenseMatrix<int,ScalarType> A( m2, A_tmp.numCols() );
2237 A.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, one, HH, A_tmp, zero );
2245 char balanc=
'P', jobvl=
'N', jobvr=
'V', sense=
'N';
2246 int ld = A.numRows();
2248 int ldvl = ld, ldvr = ld;
2249 int info = 0,ilo = 0,ihi = 0;
2250 MagnitudeType abnrm = 0.0, bbnrm = 0.0;
2252 std::vector<ScalarType> beta(ld);
2253 std::vector<ScalarType> work(lwork);
2254 std::vector<MagnitudeType> rwork(lwork);
2255 std::vector<MagnitudeType> lscale(ld), rscale(ld);
2256 std::vector<MagnitudeType> rconde(ld), rcondv(ld);
2257 std::vector<int> iwork(ld+6);
2262 lapack.GGEVX(balanc, jobvl, jobvr, sense, ld, A.values(), ld, B.values(), ld, &wr[0], &wi[0],
2263 &beta[0], vl, ldvl, vr.values(), ldvr, &ilo, &ihi, &lscale[0], &rscale[0],
2264 &abnrm, &bbnrm, &rconde[0], &rcondv[0], &work[0], lwork, &rwork[0],
2265 &iwork[0], bwork, &info);
2266 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GGEVX failed to compute eigensolutions.");
2270 for( i=0; i<ld; i++ ) {
2271 w[i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot (wr[i]*wr[i] + wi[i]*wi[i]) /
2272 Teuchos::ScalarTraits<ScalarType>::magnitude (beta[i]);
2276 this->sort(w,ld,iperm);
2278 const bool scalarTypeIsComplex = Teuchos::ScalarTraits<ScalarType>::isComplex;
2281 for( i=0; i<recycledBlocks_; i++ ) {
2282 for( j=0; j<ld; j++ ) {
2283 PP(j,i) = vr(j,iperm[ld-recycledBlocks_+i]);
2287 if(!scalarTypeIsComplex) {
2290 if (wi[iperm[ld-recycledBlocks_]] != 0.0) {
2292 for ( i=ld-recycledBlocks_; i<ld; i++ ) {
2293 if (wi[iperm[i]] != 0.0)
2302 if (wi[iperm[ld-recycledBlocks_]] > 0.0) {
2303 for( j=0; j<ld; j++ ) {
2304 PP(j,recycledBlocks_) = vr(j,iperm[ld-recycledBlocks_]+1);
2308 for( j=0; j<ld; j++ ) {
2309 PP(j,recycledBlocks_) = vr(j,iperm[ld-recycledBlocks_]-1);
2318 return recycledBlocks_+1;
2321 return recycledBlocks_;
2328template<
class ScalarType,
class MV,
class OP>
2330 int l, r, j, i, flag;
2332 MagnitudeType dRR, dK;
2359 if (dlist[j] > dlist[j - 1]) j = j + 1;
2361 if (dlist[j - 1] > dK) {
2362 dlist[i - 1] = dlist[j - 1];
2363 iperm[i - 1] = iperm[j - 1];
2377 dlist[r] = dlist[0];
2378 iperm[r] = iperm[0];
2393template<
class ScalarType,
class MV,
class OP>
2395 std::ostringstream out;
2396 out <<
"Belos::GCRODRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
2398 out <<
"Ortho Type: \"" << orthoType_ <<
"\"";
2399 out <<
", Num Blocks: " <<numBlocks_;
2400 out <<
", Num Recycle Blocks: " << recycledBlocks_;
2401 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 ...
This class implements the GCRODR iteration, where a single-stdvector Krylov subspace is constructed....
GCRODRIterOrthoFailure is thrown when the GCRODRIter object is unable to compute independent directio...
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)
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)
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.