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>
1317 if (!isSet_) { setParameters( params_ ); }
1321 std::vector<int> index(numBlocks_+1);
1328 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1333 problem_->setLSIndex(
currIdx );
1336 ptrdiff_t dim = MVT::GetGlobalLength( *(problem_->getRHS()) );
1338 numBlocks_ = Teuchos::as<int>(
dim);
1340 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1341 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1342 params_->set(
"Num Blocks", numBlocks_);
1349 initializeStateStorage();
1353 Teuchos::ParameterList
plist;
1355 plist.set(
"Num Blocks",numBlocks_);
1356 plist.set(
"Recycled Blocks",recycledBlocks_);
1368#ifdef BELOS_TEUCHOS_TIME_MONITOR
1369 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
1375 builtRecycleSpace_ =
false;
1378 outputTest_->reset();
1386 "Belos::GCRODRSolMgr::solve(): Requested size of recycled subspace is not consistent with the current recycle subspace.");
1388 printer_->stream(
Debug) <<
" Now solving RHS index " <<
currIdx[0] <<
" using recycled subspace of dimension " << keff << std::endl << std::endl;
1391 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1393 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1400 Teuchos::SerialDenseMatrix<int,ScalarType>
Rtmp( Teuchos::View, *R_, keff, keff );
1408 ipiv_.resize(
Rtmp.numRows());
1414 work_.resize(
lwork);
1424 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1425 Ctmp = MVT::CloneViewNonConst( *C_, index );
1426 Utmp = MVT::CloneView( *U_, index );
1429 Teuchos::SerialDenseMatrix<int,ScalarType>
Ctr(keff,1);
1430 problem_->computeCurrPrecResVec( &*r_ );
1434 RCP<MV> update = MVT::Clone( *problem_->getCurrLHSVec(), 1 );
1435 MVT::MvInit( *
update, 0.0 );
1437 problem_->updateSolution(
update,
true );
1449 printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " <<
currIdx[0] << std::endl << std::endl;
1462 problem_->computeCurrPrecResVec( &*r_ );
1463 index.resize( 1 ); index[0] = 0;
1464 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1465 MVT::SetBlock(*r_,index,*
v0);
1469 index.resize( numBlocks_+1 );
1470 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1471 newstate.V = MVT::CloneViewNonConst( *V_, index );
1474 newstate.H =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, recycledBlocks_+1, recycledBlocks_+1 ) );
1485 if ( convTest_->getStatus() ==
Passed ) {
1496 if (convTest_->getStatus() ==
Passed)
1502 achievedTol_ = MT::one();
1503 Teuchos::RCP<MV>
X = problem_->getLHS();
1504 MVT::MvInit( *
X, SCT::zero() );
1505 printer_->stream(
Warnings) <<
"Belos::GCRODRSolMgr::solve(): Warning! NaN has been detected!"
1509 catch (
const std::exception &
e) {
1511 printer_->stream(
Errors) <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1513 <<
e.what() << std::endl;
1521 problem_->updateSolution(
update,
true );
1532 if (recycledBlocks_ <
p+1) {
1538 PPtmp =
rcp (
new Teuchos::SerialDenseMatrix<int,ScalarType> ( Teuchos::View, *PP_,
p, keff ) );
1541 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1542 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1543 RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
1558 Teuchos::SerialDenseMatrix<int,ScalarType>
Htmp( Teuchos::View, *H2_,
p+1,
p, recycledBlocks_+1,recycledBlocks_+1);
1559 Teuchos::SerialDenseMatrix<int,ScalarType>
HPtmp( Teuchos::View, *HP_,
p+1, keff );
1571 " LAPACK's _GEQRF failed to compute a workspace size.");
1579 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1580 work_.resize (
lwork);
1585 " LAPACK's _GEQRF failed to compute a QR factorization.");
1589 Teuchos::SerialDenseMatrix<int,ScalarType>
Rtmp( Teuchos::View, *R_, keff, keff );
1590 for (
int ii = 0;
ii < keff; ++
ii) {
1591 for (
int jj =
ii;
jj < keff; ++
jj) {
1600 HPtmp.values (),
HPtmp.stride (), &tau_[0], &work_[0],
1604 "LAPACK's _UNGQR failed to construct the Q factor.");
1609 index.resize (
p + 1);
1610 for (
int ii = 0;
ii < (
p+1); ++
ii) {
1613 Vtmp = MVT::CloneView( *V_, index );
1621 ipiv_.resize(
Rtmp.numRows());
1625 "LAPACK's _GETRF failed to compute an LU factorization.");
1635 work_.resize(
lwork);
1639 "LAPACK's _GETRI failed to invert triangular matrix.");
1644 printer_->stream(
Debug)
1645 <<
" Generated recycled subspace using RHS index " <<
currIdx[0]
1646 <<
" of dimension " << keff << std::endl << std::endl;
1653 problem_->setCurrLS();
1659 problem_->setLSIndex (
currIdx);
1678 outputTest_->resetNumCalls();
1681 problem_->computeCurrPrecResVec( &*r_ );
1682 index.resize( 1 ); index[0] = 0;
1683 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1684 MVT::SetBlock(*r_,index,*
v0);
1688 index.resize( numBlocks_+1 );
1689 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1690 newstate.V = MVT::CloneViewNonConst( *V_, index );
1691 index.resize( keff );
1692 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1693 newstate.C = MVT::CloneViewNonConst( *C_, index );
1694 newstate.U = MVT::CloneViewNonConst( *U_, index );
1695 newstate.B =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1696 newstate.H =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1713 if ( convTest_->getStatus() ==
Passed ) {
1722 else if ( maxIterTest_->getStatus() ==
Passed ) {
1739 problem_->updateSolution(
update,
true );
1743 printer_->stream(
Debug)
1744 <<
" Generated new recycled subspace using RHS index "
1745 <<
currIdx[0] <<
" of dimension " << keff << std::endl
1756 printer_->stream(
Debug)
1757 <<
" Performing restart number " <<
numRestarts <<
" of "
1758 << maxRestarts_ << std::endl << std::endl;
1761 problem_->computeCurrPrecResVec( &*r_ );
1762 index.resize( 1 ); index[0] = 0;
1763 RCP<MV> v00 = MVT::CloneViewNonConst( *V_, index );
1764 MVT::SetBlock(*r_,index,*
v00);
1768 index.resize( numBlocks_+1 );
1769 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1771 index.resize( keff );
1772 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1775 restartState.B =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1776 restartState.H =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1793 std::logic_error,
"Belos::GCRODRSolMgr::solve: "
1794 "Invalid return from GCRODRIter::iterate().");
1803 if (convTest_->getStatus() !=
Passed) {
1809 catch (
const std::exception&
e) {
1812 <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1813 <<
gcrodr_iter->getNumIters() << std::endl <<
e.what() << std::endl;
1821 problem_->updateSolution(
update,
true );
1824 problem_->setCurrLS();
1829 if (!builtRecycleSpace_) {
1831 printer_->stream(
Debug)
1832 <<
" Generated new recycled subspace using RHS index " <<
currIdx[0]
1833 <<
" of dimension " << keff << std::endl << std::endl;
1840 problem_->setLSIndex (
currIdx);
1851#ifdef BELOS_TEUCHOS_TIME_MONITOR
1856 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1860 numIters_ = maxIterTest_->getNumIters ();
1872 const std::vector<MagnitudeType>*
pTestValues = expConvTest_->getTestValue();
1877 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1878 "method returned NULL. Please report this bug to the Belos developers.");
1880 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1881 "method returned a vector of length zero. Please report this bug to the "
1882 "Belos developers.");
1897template<
class ScalarType,
class MV,
class OP>
1900 MagnitudeType
one = Teuchos::ScalarTraits<MagnitudeType>::one();
1903 std::vector<MagnitudeType>
d(keff);
1904 std::vector<ScalarType>
dscalar(keff);
1905 std::vector<int> index(numBlocks_+1);
1917 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1918 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst( *U_, index );
1921 MVT::MvNorm( *
Utmp,
d );
1922 for (
int i=0;
i<keff; ++
i) {
1930 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
H2tmp = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_,
p+keff+1,
p+keff ) );
1933 for (
int i=0;
i<keff; ++
i) {
1934 (*H2tmp)(
i,
i) =
d[
i];
1941 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_,
p+keff, recycledBlocks_+1 );
1949 Teuchos::RCP<MV>
U1tmp;
1951 index.resize( keff );
1952 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1953 Teuchos::RCP<const MV>
Utmp = MVT::CloneView( *U_, index );
1956 U1tmp = MVT::CloneViewNonConst( *U1_, index );
1957 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_, keff,
keff_new );
1965 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView( *V_, index );
1966 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_,
p,
keff_new, keff );
1971 Teuchos::SerialDenseMatrix<int,ScalarType>
HPtmp( Teuchos::View, *HP_,
p+keff+1,
keff_new );
1973 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_,
p+keff,
keff_new );
1983 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
1984 "LAPACK's _GEQRF failed to compute a workspace size.");
1990 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1991 work_.resize (
lwork);
1995 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
1996 "LAPACK's _GEQRF failed to compute a QR factorization.");
2008 HPtmp.values (),
HPtmp.stride (), &tau_[0], &work_[0],
2011 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
2012 "LAPACK's _UNGQR failed to construct the Q factor.");
2019 Teuchos::RCP<MV>
C1tmp;
2022 for (
int i=0;
i < keff;
i++) { index[
i] =
i; }
2023 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView( *C_, index );
2026 C1tmp = MVT::CloneViewNonConst( *C1_, index );
2027 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *HP_, keff,
keff_new );
2032 index.resize(
p+1 );
2033 for (
int i=0;
i <
p+1; ++
i) { index[
i] =
i; }
2034 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView( *V_, index );
2035 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *HP_,
p+1,
keff_new, keff, 0 );
2045 ipiv_.resize(
Rtmp.numRows());
2047 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0,GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
2051 work_.resize(
lwork);
2053 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to compute an LU factorization.");
2058 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst( *U_, index );
2067 Teuchos::SerialDenseMatrix<int,ScalarType>
b1( Teuchos::View, *H2_, recycledBlocks_+2, 1, 0, recycledBlocks_ );
2075template<
class ScalarType,
class MV,
class OP>
2076int GCRODRSolMgr<ScalarType,MV,OP,true>::getHarmonicVecs1(
int m,
2077 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2078 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2084 std::vector<MagnitudeType>
wr(
m),
wi(
m);
2087 Teuchos::SerialDenseMatrix<int,ScalarType>
vr(
m,
m,
false);
2090 std::vector<MagnitudeType>
w(
m);
2093 std::vector<int>
iperm(
m);
2099 builtRecycleSpace_ =
true;
2102 Teuchos::SerialDenseMatrix<int, ScalarType>
HHt(
HH, Teuchos::TRANS );
2103 Teuchos::SerialDenseVector<int, ScalarType>
e_m(
m );
2110 Teuchos::SerialDenseMatrix<int, ScalarType>
harmHH( Teuchos::Copy,
HH,
m,
m );
2111 for(
i=0;
i<
m; ++
i )
2121 std::vector<ScalarType>
work(1);
2122 std::vector<MagnitudeType>
rwork(2*
m);
2128 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (
work[0])));
2136 for(
i=0;
i<
m; ++
i )
2137 w[
i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot(
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i] );
2145 for(
i=0;
i<recycledBlocks_; ++
i ) {
2146 for(
j=0;
j<
m;
j++ ) {
2154 if (
wi[
iperm[recycledBlocks_-1]] != 0.0) {
2156 for (
i=0;
i<recycledBlocks_; ++
i ) {
2166 if (
wi[
iperm[recycledBlocks_-1]] > 0.0) {
2167 for(
j=0;
j<
m; ++
j ) {
2168 PP(
j,recycledBlocks_) =
vr(
j,
iperm[recycledBlocks_-1]+1);
2172 for(
j=0;
j<
m; ++
j ) {
2173 PP(
j,recycledBlocks_) =
vr(
j,
iperm[recycledBlocks_-1]-1);
2182 return recycledBlocks_+1;
2185 return recycledBlocks_;
2191template<
class ScalarType,
class MV,
class OP>
2192int GCRODRSolMgr<ScalarType,MV,OP,true>::getHarmonicVecs2(
int keffloc,
int m,
2193 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2194 const Teuchos::RCP<const MV>& VV,
2195 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2197 int m2 =
HH.numCols();
2201 std::vector<int> index;
2204 std::vector<MagnitudeType>
wr(
m2),
wi(
m2);
2207 std::vector<MagnitudeType>
w(
m2);
2210 Teuchos::SerialDenseMatrix<int,ScalarType>
vr(
m2,
m2,
false);
2216 builtRecycleSpace_ =
true;
2221 Teuchos::SerialDenseMatrix<int,ScalarType> B(
m2,
m2,
false);
2222 B.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,
one,
HH,
HH,
zero);
2231 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView( *C_, index );
2232 Teuchos::RCP<const MV>
Utmp = MVT::CloneView( *U_, index );
2239 for (
i=0;
i <
m+1;
i++) { index[
i] =
i; }
2240 Teuchos::RCP<const MV>
Vp = MVT::CloneView( *
VV, index );
2249 Teuchos::SerialDenseMatrix<int,ScalarType>
A(
m2,
A_tmp.numCols() );
2250 A.multiply( Teuchos::TRANS, Teuchos::NO_TRANS,
one,
HH,
A_tmp,
zero );
2259 int ld =
A.numRows();
2265 std::vector<ScalarType> beta(
ld);
2275 lapack.GGEVX(
balanc,
jobvl,
jobvr,
sense,
ld,
A.values(),
ld, B.values(),
ld, &
wr[0], &
wi[0],
2279 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GGEVX failed to compute eigensolutions.");
2283 for(
i=0;
i<
ld;
i++ ) {
2284 w[
i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot (
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i]) /
2285 Teuchos::ScalarTraits<ScalarType>::magnitude (beta[
i]);
2294 for(
i=0;
i<recycledBlocks_;
i++ ) {
2295 for(
j=0;
j<
ld;
j++ ) {
2303 if (
wi[
iperm[
ld-recycledBlocks_]] != 0.0) {
2305 for (
i=
ld-recycledBlocks_;
i<
ld;
i++ ) {
2315 if (
wi[
iperm[
ld-recycledBlocks_]] > 0.0) {
2316 for(
j=0;
j<
ld;
j++ ) {
2321 for(
j=0;
j<
ld;
j++ ) {
2331 return recycledBlocks_+1;
2334 return recycledBlocks_;
2341template<
class ScalarType,
class MV,
class OP>
2342void GCRODRSolMgr<ScalarType,MV,OP,true>::sort(std::vector<MagnitudeType>& dlist,
int n, std::vector<int>& iperm) {
2345 MagnitudeType
dRR,
dK;
2406template<
class ScalarType,
class MV,
class OP>
2408 std::ostringstream
out;
2409 out <<
"Belos::GCRODRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
2411 out <<
"Ortho Type: \"" << orthoType_ <<
"\"";
2412 out <<
", Num Blocks: " <<numBlocks_;
2413 out <<
", Num Recycle Blocks: " << recycledBlocks_;
2414 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...
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)
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)
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.