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 =
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> &
params )
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):
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>
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()) {
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_);
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_);
722 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
723 "parameter must be strictly positive, but you specified "
724 "a value of " << recycledBlocks_ <<
".");
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")) {
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")) {
758 verbosity_ =
params->get (
"Verbosity", verbosity_default_);
763 params_->set (
"Verbosity", verbosity_);
766 if (! printer_.is_null())
767 printer_->setVerbosity (verbosity_);
771 if (
params->isParameter (
"Output Style")) {
773 outputStyle_ =
params->get (
"Output Style", outputStyle_default_);
779 params_->set (
"Output Style", outputStyle_);
797 if (
params->isParameter (
"Output Stream")) {
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()) {
848 if (
params->isParameter (
"Orthogonalization")) {
850 params->get (
"Orthogonalization", orthoType_default_);
853 std::ostringstream
os;
854 os <<
"Belos::GCRODRSolMgr: Invalid orthogonalization name \""
856 <<
"for the \"Orthogonalization\" name parameter: ";
858 throw std::invalid_argument (
os.str());
864 params_->set (
"Orthogonalization", orthoType_);
883 using Teuchos::sublist;
885 const std::string
paramName (
"Orthogonalization Parameters");
900 "Failed to get orthogonalization parameters. "
901 "Please report this bug to the Belos developers.");
911 ortho_ =
factory.makeMatOrthoManager (orthoType_,
null, printer_,
920 typedef Teuchos::ParameterListAcceptor
PLA;
926 ortho_ =
factory.makeMatOrthoManager (orthoType_,
null, printer_,
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()) {
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")) {
1000 params_->set(
"Implicit Residual Scaling", impResScale_);
1010 if (! impConvTest_.is_null()) {
1016 impConvTest_ =
null;
1023 if (
params->isParameter(
"Explicit Residual Scaling")) {
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_,
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;
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: " +
1164 factory.getDefaultParameters (orthoType_default_);
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>
1184 Teuchos::RCP<const MV>
rhsMV = problem_->getRHS();
1185 if (
rhsMV == Teuchos::null) {
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>
1315 if (!isSet_) { setParameters( params_ ); }
1319 std::vector<int> index(numBlocks_+1);
1326 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1331 problem_->setLSIndex(
currIdx );
1334 ptrdiff_t dim = MVT::GetGlobalLength( *(problem_->getRHS()) );
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_);
1347 initializeStateStorage();
1351 Teuchos::ParameterList
plist;
1353 plist.set(
"Num Blocks",numBlocks_);
1354 plist.set(
"Recycled Blocks",recycledBlocks_);
1366#ifdef BELOS_TEUCHOS_TIME_MONITOR
1367 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
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; }
1391 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1398 Teuchos::SerialDenseMatrix<int,ScalarType>
Rtmp( Teuchos::View, *R_, keff, keff );
1406 ipiv_.resize(
Rtmp.numRows());
1412 work_.resize(
lwork);
1422 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1423 Ctmp = MVT::CloneViewNonConst( *C_, index );
1424 Utmp = MVT::CloneView( *U_, index );
1427 Teuchos::SerialDenseMatrix<int,ScalarType>
Ctr(keff,1);
1428 problem_->computeCurrPrecResVec( &*r_ );
1432 RCP<MV> update = MVT::Clone( *problem_->getCurrLHSVec(), 1 );
1433 MVT::MvInit( *
update, 0.0 );
1435 problem_->updateSolution(
update,
true );
1447 printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " <<
currIdx[0] << std::endl << std::endl;
1460 problem_->computeCurrPrecResVec( &*r_ );
1461 index.resize( 1 ); index[0] = 0;
1462 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1463 MVT::SetBlock(*r_,index,*
v0);
1467 index.resize( numBlocks_+1 );
1468 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1469 newstate.V = MVT::CloneViewNonConst( *V_, index );
1472 newstate.H =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, recycledBlocks_+1, recycledBlocks_+1 ) );
1483 if ( convTest_->getStatus() ==
Passed ) {
1494 if (convTest_->getStatus() ==
Passed)
1499 achievedTol_ = MT::one();
1500 Teuchos::RCP<MV>
X = problem_->getLHS();
1501 MVT::MvInit( *
X, SCT::zero() );
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 "
1509 <<
e.what() << std::endl;
1517 problem_->updateSolution(
update,
true );
1528 if (recycledBlocks_ <
p+1) {
1534 PPtmp =
rcp (
new Teuchos::SerialDenseMatrix<int,ScalarType> ( Teuchos::View, *PP_,
p, keff ) );
1537 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1538 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1539 RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
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 );
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);
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) {
1596 HPtmp.values (),
HPtmp.stride (), &tau_[0], &work_[0],
1600 "LAPACK's _UNGQR failed to construct the Q factor.");
1605 index.resize (
p + 1);
1606 for (
int ii = 0;
ii < (
p+1); ++
ii) {
1609 Vtmp = MVT::CloneView( *V_, index );
1617 ipiv_.resize(
Rtmp.numRows());
1621 "LAPACK's _GETRF failed to compute an LU factorization.");
1631 work_.resize(
lwork);
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;
1649 problem_->setCurrLS();
1655 problem_->setLSIndex (
currIdx);
1674 outputTest_->resetNumCalls();
1677 problem_->computeCurrPrecResVec( &*r_ );
1678 index.resize( 1 ); index[0] = 0;
1679 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1680 MVT::SetBlock(*r_,index,*
v0);
1684 index.resize( numBlocks_+1 );
1685 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1686 newstate.V = MVT::CloneViewNonConst( *V_, index );
1687 index.resize( keff );
1688 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1689 newstate.C = MVT::CloneViewNonConst( *C_, index );
1690 newstate.U = MVT::CloneViewNonConst( *U_, index );
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 ) );
1709 if ( convTest_->getStatus() ==
Passed ) {
1718 else if ( maxIterTest_->getStatus() ==
Passed ) {
1734 problem_->updateSolution(
update,
true );
1738 printer_->stream(
Debug)
1739 <<
" Generated new recycled subspace using RHS index "
1740 <<
currIdx[0] <<
" of dimension " << keff << std::endl
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;
1757 RCP<MV> v00 = MVT::CloneViewNonConst( *V_, index );
1758 MVT::SetBlock(*r_,index,*
v00);
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 ) );
1786 true, std::logic_error,
"Belos::GCRODRSolMgr::solve: "
1787 "Invalid return from GCRODRIter::iterate().");
1796 if (convTest_->getStatus() !=
Passed)
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;
1811 problem_->updateSolution(
update,
true );
1814 problem_->setCurrLS();
1819 if (!builtRecycleSpace_) {
1821 printer_->stream(
Debug)
1822 <<
" Generated new recycled subspace using RHS index " <<
currIdx[0]
1823 <<
" of dimension " << keff << std::endl << std::endl;
1830 problem_->setLSIndex (
currIdx);
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();
1867 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1868 "method returned NULL. Please report this bug to the Belos developers.");
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.");
1884template<
class ScalarType,
class MV,
class OP>
1887 MagnitudeType
one = Teuchos::ScalarTraits<MagnitudeType>::one();
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 );
1908 MVT::MvNorm( *
Utmp,
d );
1909 for (
int i=0;
i<keff; ++
i) {
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 );
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 );
1943 U1tmp = MVT::CloneViewNonConst( *U1_, index );
1944 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_, keff,
keff_new );
1952 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView( *V_, index );
1953 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_,
p,
keff_new, keff );
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 );
1970 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
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);
1982 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
1983 "LAPACK's _GEQRF failed to compute a QR factorization.");
1995 HPtmp.values (),
HPtmp.stride (), &tau_[0], &work_[0],
1998 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
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 );
2013 C1tmp = MVT::CloneViewNonConst( *C1_, index );
2014 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *HP_, keff,
keff_new );
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 );
2032 ipiv_.resize(
Rtmp.numRows());
2034 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0,GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
2038 work_.resize(
lwork);
2040 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to compute an LU factorization.");
2045 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst( *U_, index );
2054 Teuchos::SerialDenseMatrix<int,ScalarType>
b1( Teuchos::View, *H2_, recycledBlocks_+2, 1, 0, recycledBlocks_ );
2062template<
class ScalarType,
class MV,
class OP>
2063int GCRODRSolMgr<ScalarType,MV,OP,true>::getHarmonicVecs1(
int m,
2064 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2065 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
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 );
2097 Teuchos::SerialDenseMatrix<int, ScalarType>
harmHH( Teuchos::Copy,
HH,
m,
m );
2098 for(
i=0;
i<
m; ++
i )
2108 std::vector<ScalarType>
work(1);
2109 std::vector<MagnitudeType>
rwork(2*
m);
2115 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (
work[0])));
2123 for(
i=0;
i<
m; ++
i )
2124 w[
i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot(
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i] );
2132 for(
i=0;
i<recycledBlocks_; ++
i ) {
2133 for(
j=0;
j<
m;
j++ ) {
2141 if (
wi[
iperm[recycledBlocks_-1]] != 0.0) {
2143 for (
i=0;
i<recycledBlocks_; ++
i ) {
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>
2179int GCRODRSolMgr<ScalarType,MV,OP,true>::getHarmonicVecs2(
int keffloc,
int m,
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();
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);
2203 builtRecycleSpace_ =
true;
2208 Teuchos::SerialDenseMatrix<int,ScalarType> B(
m2,
m2,
false);
2209 B.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,
one,
HH,
HH,
zero);
2218 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView( *C_, index );
2219 Teuchos::RCP<const MV>
Utmp = MVT::CloneView( *U_, index );
2226 for (
i=0;
i <
m+1;
i++) { index[
i] =
i; }
2227 Teuchos::RCP<const MV>
Vp = MVT::CloneView( *
VV, index );
2236 Teuchos::SerialDenseMatrix<int,ScalarType>
A(
m2,
A_tmp.numCols() );
2237 A.multiply( Teuchos::TRANS, Teuchos::NO_TRANS,
one,
HH,
A_tmp,
zero );
2246 int ld =
A.numRows();
2252 std::vector<ScalarType> beta(
ld);
2262 lapack.GGEVX(
balanc,
jobvl,
jobvr,
sense,
ld,
A.values(),
ld, B.values(),
ld, &
wr[0], &
wi[0],
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]);
2281 for(
i=0;
i<recycledBlocks_;
i++ ) {
2282 for(
j=0;
j<
ld;
j++ ) {
2290 if (
wi[
iperm[
ld-recycledBlocks_]] != 0.0) {
2292 for (
i=
ld-recycledBlocks_;
i<
ld;
i++ ) {
2302 if (
wi[
iperm[
ld-recycledBlocks_]] > 0.0) {
2303 for(
j=0;
j<
ld;
j++ ) {
2308 for(
j=0;
j<
ld;
j++ ) {
2318 return recycledBlocks_+1;
2321 return recycledBlocks_;
2328template<
class ScalarType,
class MV,
class OP>
2329void GCRODRSolMgr<ScalarType,MV,OP,true>::sort(std::vector<MagnitudeType>& dlist,
int n, std::vector<int>& iperm) {
2332 MagnitudeType
dRR,
dK;
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.
Parent class to all Belos exceptions.
Type traits class that says whether Teuchos::LAPACK has a valid implementation for the given ScalarTy...
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...
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().
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) override
Set the linear problem that needs to be solved.
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.
Implementation of the GCRODR (Recycling GMRES) iterative linear solver.
GCRODRSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< Teuchos::ParameterList > &pl)
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).
Exception thrown to signal error in a status test during Belos::StatusTest::checkStatus().
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.