10#ifndef BELOS_GCRODR_SOLMGR_HPP
11#define BELOS_GCRODR_SOLMGR_HPP
30#include "Teuchos_BLAS.hpp"
31#include "Teuchos_LAPACK.hpp"
32#include "Teuchos_as.hpp"
33#ifdef BELOS_TEUCHOS_TIME_MONITOR
34# include "Teuchos_TimeMonitor.hpp"
36#if defined(HAVE_TEUCHOSCORE_CXX11)
37# include <type_traits>
125 template<
class ScalarType,
class MV,
class OP,
126 const bool lapackSupportsScalarType =
131 static const bool requiresLapack =
141 const Teuchos::RCP<Teuchos::ParameterList>&
pl) :
150 template<
class ScalarType,
class MV,
class OP>
155#if defined(HAVE_TEUCHOSCORE_CXX11)
156# if defined(HAVE_TEUCHOS_COMPLEX)
157 #if defined(HAVE_TEUCHOS_LONG_DOUBLE)
158 static_assert (std::is_same<ScalarType, std::complex<float> >::value ||
159 std::is_same<ScalarType, std::complex<double> >::value ||
160 std::is_same<ScalarType, Kokkos::complex<double> >::value ||
161 std::is_same<ScalarType, float>::value ||
162 std::is_same<ScalarType, double>::value ||
163 std::is_same<ScalarType, long double>::value,
164 "Belos::GCRODRSolMgr: ScalarType must be one of the four "
165 "types (S,D,C,Z) supported by LAPACK or long double (largely not impl'd).");
167 static_assert (std::is_same<ScalarType, std::complex<float> >::value ||
168 std::is_same<ScalarType, std::complex<double> >::value ||
169 std::is_same<ScalarType, Kokkos::complex<double> >::value ||
170 std::is_same<ScalarType, float>::value ||
171 std::is_same<ScalarType, double>::value,
172 "Belos::GCRODRSolMgr: ScalarType must be one of the four "
173 "types (S,D,C,Z) supported by LAPACK.");
176 #if defined(HAVE_TEUCHOS_LONG_DOUBLE)
177 static_assert (std::is_same<ScalarType, float>::value ||
178 std::is_same<ScalarType, double>::value ||
179 std::is_same<ScalarType, long double>::value,
180 "Belos::GCRODRSolMgr: ScalarType must be float, double or long double. "
181 "Complex arithmetic support is currently disabled. To "
182 "enable it, set Teuchos_ENABLE_COMPLEX=ON.");
184 static_assert (std::is_same<ScalarType, float>::value ||
185 std::is_same<ScalarType, double>::value,
186 "Belos::GCRODRSolMgr: ScalarType must be float or double. "
187 "Complex arithmetic support is currently disabled. To "
188 "enable it, set Teuchos_ENABLE_COMPLEX=ON.");
196 typedef Teuchos::ScalarTraits<ScalarType> SCT;
197 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
198 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
265 const Teuchos::RCP<Teuchos::ParameterList> &
pl);
271 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
287 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const override;
300 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
301 return Teuchos::tuple(timerSolve_);
333 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> &
params )
override;
345 bool set = problem_->setProblem();
347 throw "Could not set problem.";
391 std::string description()
const override;
401 void initializeStateStorage();
410 int getHarmonicVecs1(
int m,
411 const Teuchos::SerialDenseMatrix<int,ScalarType>&
HH,
412 Teuchos::SerialDenseMatrix<int,ScalarType>&
PP);
419 int getHarmonicVecs2(
int keff,
int m,
420 const Teuchos::SerialDenseMatrix<int,ScalarType>&
HH,
421 const Teuchos::RCP<const MV>&
VV,
422 Teuchos::SerialDenseMatrix<int,ScalarType>&
PP);
425 void sort(std::vector<MagnitudeType>&
dlist,
int n, std::vector<int>&
iperm);
428 Teuchos::LAPACK<int,ScalarType> lapack;
431 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
434 Teuchos::RCP<OutputManager<ScalarType> > printer_;
435 Teuchos::RCP<std::ostream> outputStream_;
438 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
439 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
440 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
441 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > expConvTest_, impConvTest_;
442 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
447 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
450 Teuchos::RCP<Teuchos::ParameterList> params_;
453 static constexpr double orthoKappa_default_ = 0.0;
454 static constexpr int maxRestarts_default_ = 100;
455 static constexpr int maxIters_default_ = 1000;
456 static constexpr int numBlocks_default_ = 50;
457 static constexpr int blockSize_default_ = 1;
458 static constexpr int recycledBlocks_default_ = 5;
461 static constexpr int outputFreq_default_ = -1;
462 static constexpr const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
463 static constexpr const char * expResScale_default_ =
"Norm of Initial Residual";
464 static constexpr const char * label_default_ =
"Belos";
465 static constexpr const char * orthoType_default_ =
"ICGS";
468 MagnitudeType convTol_, orthoKappa_, achievedTol_;
469 int maxRestarts_, maxIters_, numIters_;
470 int verbosity_, outputStyle_, outputFreq_;
471 std::string orthoType_;
472 std::string impResScale_, expResScale_;
479 int numBlocks_, recycledBlocks_;
490 Teuchos::RCP<MV> U_, C_;
493 Teuchos::RCP<MV> U1_, C1_;
496 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H2_;
497 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H_;
498 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B_;
499 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > PP_;
500 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > HP_;
501 std::vector<ScalarType> tau_;
502 std::vector<ScalarType> work_;
503 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > R_;
504 std::vector<int> ipiv_;
509 Teuchos::RCP<Teuchos::Time> timerSolve_;
515 bool builtRecycleSpace_;
520template<
class ScalarType,
class MV,
class OP>
530template<
class ScalarType,
class MV,
class OP>
533 const Teuchos::RCP<Teuchos::ParameterList>&
pl):
542 problem == Teuchos::null, std::invalid_argument,
543 "Belos::GCRODRSolMgr constructor: The solver manager's "
544 "constructor needs the linear problem argument 'problem' "
553 if (!
pl.is_null ()) {
559template<
class ScalarType,
class MV,
class OP>
561 outputStream_ = Teuchos::rcpFromRef(std::cout);
563 orthoKappa_ = orthoKappa_default_;
564 maxRestarts_ = maxRestarts_default_;
565 maxIters_ = maxIters_default_;
566 numBlocks_ = numBlocks_default_;
567 recycledBlocks_ = recycledBlocks_default_;
568 verbosity_ = verbosity_default_;
569 outputStyle_ = outputStyle_default_;
570 outputFreq_ = outputFreq_default_;
571 orthoType_ = orthoType_default_;
572 impResScale_ = impResScale_default_;
573 expResScale_ = expResScale_default_;
574 label_ = label_default_;
576 builtRecycleSpace_ =
false;
592template<
class ScalarType,
class MV,
class OP>
597 using Teuchos::isParameterType;
598 using Teuchos::getParameter;
600 using Teuchos::ParameterList;
601 using Teuchos::parameterList;
604 using Teuchos::rcp_dynamic_cast;
605 using Teuchos::rcpFromRef;
606 using Teuchos::Exceptions::InvalidParameter;
607 using Teuchos::Exceptions::InvalidParameterName;
608 using Teuchos::Exceptions::InvalidParameterType;
630 if (params_.is_null()) {
684 if (
params->isParameter (
"Maximum Restarts")) {
685 maxRestarts_ =
params->get(
"Maximum Restarts", maxRestarts_default_);
688 params_->set (
"Maximum Restarts", maxRestarts_);
692 if (
params->isParameter (
"Maximum Iterations")) {
693 maxIters_ =
params->get (
"Maximum Iterations", maxIters_default_);
696 params_->set (
"Maximum Iterations", maxIters_);
697 if (! maxIterTest_.is_null())
698 maxIterTest_->setMaxIters (maxIters_);
702 if (
params->isParameter (
"Num Blocks")) {
703 numBlocks_ =
params->get (
"Num Blocks", numBlocks_default_);
705 "Belos::GCRODRSolMgr: The \"Num Blocks\" parameter must "
706 "be strictly positive, but you specified a value of "
707 << numBlocks_ <<
".");
709 params_->set (
"Num Blocks", numBlocks_);
713 if (
params->isParameter (
"Num Recycled Blocks")) {
714 recycledBlocks_ =
params->get (
"Num Recycled Blocks",
715 recycledBlocks_default_);
717 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
718 "parameter must be strictly positive, but you specified "
719 "a value of " << recycledBlocks_ <<
".");
721 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
722 "parameter must be less than the \"Num Blocks\" "
723 "parameter, but you specified \"Num Recycled Blocks\" "
724 "= " << recycledBlocks_ <<
" and \"Num Blocks\" = "
725 << numBlocks_ <<
".");
727 params_->set(
"Num Recycled Blocks", recycledBlocks_);
733 if (
params->isParameter (
"Timer Label")) {
739 params_->set (
"Timer Label", label_);
740 std::string
solveLabel = label_ +
": GCRODRSolMgr total solve time";
741#ifdef BELOS_TEUCHOS_TIME_MONITOR
742 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (
solveLabel);
744 if (ortho_ != Teuchos::null) {
745 ortho_->setLabel( label_ );
751 if (
params->isParameter (
"Verbosity")) {
753 verbosity_ =
params->get (
"Verbosity", verbosity_default_);
758 params_->set (
"Verbosity", verbosity_);
761 if (! printer_.is_null())
762 printer_->setVerbosity (verbosity_);
766 if (
params->isParameter (
"Output Style")) {
768 outputStyle_ =
params->get (
"Output Style", outputStyle_default_);
774 params_->set (
"Output Style", outputStyle_);
792 if (
params->isParameter (
"Output Stream")) {
803 if (outputStream_.is_null()) {
804 outputStream_ =
rcp (
new Teuchos::oblackholestream);
807 params_->set (
"Output Stream", outputStream_);
810 if (! printer_.is_null()) {
811 printer_->setOStream (outputStream_);
817 if (
params->isParameter (
"Output Frequency")) {
818 outputFreq_ =
params->get (
"Output Frequency", outputFreq_default_);
822 params_->set(
"Output Frequency", outputFreq_);
823 if (! outputTest_.is_null())
824 outputTest_->setOutputFrequency (outputFreq_);
831 if (printer_.is_null()) {
843 if (
params->isParameter (
"Orthogonalization")) {
845 params->get (
"Orthogonalization", orthoType_default_);
848 std::ostringstream
os;
849 os <<
"Belos::GCRODRSolMgr: Invalid orthogonalization name \""
851 <<
"for the \"Orthogonalization\" name parameter: ";
853 throw std::invalid_argument (
os.str());
859 params_->set (
"Orthogonalization", orthoType_);
878 using Teuchos::sublist;
880 const std::string
paramName (
"Orthogonalization Parameters");
895 "Failed to get orthogonalization parameters. "
896 "Please report this bug to the Belos developers.");
906 ortho_ =
factory.makeMatOrthoManager (orthoType_,
null, printer_,
915 typedef Teuchos::ParameterListAcceptor
PLA;
921 ortho_ =
factory.makeMatOrthoManager (orthoType_,
null, printer_,
936 if (
params->isParameter (
"Orthogonalization Constant")) {
937 MagnitudeType orthoKappa = orthoKappa_default_;
938 if (
params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
939 orthoKappa =
params->get (
"Orthogonalization Constant", orthoKappa);
942 orthoKappa =
params->get (
"Orthogonalization Constant", orthoKappa_default_);
945 if (orthoKappa > 0) {
946 orthoKappa_ = orthoKappa;
948 params_->set(
"Orthogonalization Constant", orthoKappa_);
950 if (orthoType_ ==
"DGKS" && ! ortho_.is_null()) {
967 if (
params->isParameter(
"Convergence Tolerance")) {
968 if (
params->isType<MagnitudeType> (
"Convergence Tolerance")) {
969 convTol_ =
params->get (
"Convergence Tolerance",
977 params_->set (
"Convergence Tolerance", convTol_);
978 if (! impConvTest_.is_null())
979 impConvTest_->setTolerance (convTol_);
980 if (! expConvTest_.is_null())
981 expConvTest_->setTolerance (convTol_);
985 if (
params->isParameter (
"Implicit Residual Scaling")) {
995 params_->set(
"Implicit Residual Scaling", impResScale_);
1005 if (! impConvTest_.is_null()) {
1011 impConvTest_ =
null;
1018 if (
params->isParameter(
"Explicit Residual Scaling")) {
1028 params_->set(
"Explicit Residual Scaling", expResScale_);
1031 if (! expConvTest_.is_null()) {
1037 expConvTest_ =
null;
1048 if (maxIterTest_.is_null())
1053 if (impConvTest_.is_null()) {
1054 impConvTest_ =
rcp (
new StatusTestResNorm_t (convTol_));
1060 if (expConvTest_.is_null()) {
1061 expConvTest_ =
rcp (
new StatusTestResNorm_t (convTol_));
1062 expConvTest_->defineResForm (StatusTestResNorm_t::Explicit,
Belos::TwoNorm);
1068 if (convTest_.is_null()) {
1069 convTest_ =
rcp (
new StatusTestCombo_t (StatusTestCombo_t::SEQ,
1077 sTest_ =
rcp (
new StatusTestCombo_t (StatusTestCombo_t::OR,
1083 outputTest_ =
stoFactory.create (printer_, sTest_, outputFreq_,
1091 if (timerSolve_.is_null()) {
1092 std::string
solveLabel = label_ +
": GCRODRSolMgr total solve time";
1093#ifdef BELOS_TEUCHOS_TIME_MONITOR
1094 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
1103template<
class ScalarType,
class MV,
class OP>
1104Teuchos::RCP<const Teuchos::ParameterList>
1107 using Teuchos::ParameterList;
1108 using Teuchos::parameterList;
1117 "The relative residual tolerance that needs to be achieved by the\n"
1118 "iterative solver in order for the linear system to be declared converged.");
1119 pl->set(
"Maximum Restarts",
static_cast<int>(maxRestarts_default_),
1120 "The maximum number of cycles allowed for each\n"
1121 "set of RHS solved.");
1122 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
1123 "The maximum number of iterations allowed for each\n"
1124 "set of RHS solved.");
1128 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
1129 "Block Size Parameter -- currently must be 1 for GCRODR");
1130 pl->set(
"Num Blocks",
static_cast<int>(numBlocks_default_),
1131 "The maximum number of vectors allowed in the Krylov subspace\n"
1132 "for each set of RHS solved.");
1133 pl->set(
"Num Recycled Blocks",
static_cast<int>(recycledBlocks_default_),
1134 "The maximum number of vectors in the recycled subspace." );
1135 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
1136 "What type(s) of solver information should be outputted\n"
1137 "to the output stream.");
1138 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
1139 "What style is used for the solver information outputted\n"
1140 "to the output stream.");
1141 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
1142 "How often convergence information should be outputted\n"
1143 "to the output stream.");
1144 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
1145 "A reference-counted pointer to the output stream where all\n"
1146 "solver output is sent.");
1147 pl->set(
"Implicit Residual Scaling",
static_cast<const char *
>(impResScale_default_),
1148 "The type of scaling used in the implicit residual convergence test.");
1149 pl->set(
"Explicit Residual Scaling",
static_cast<const char *
>(expResScale_default_),
1150 "The type of scaling used in the explicit residual convergence test.");
1151 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
1152 "The string to use as a prefix for the timer labels.");
1155 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
1156 "The type of orthogonalization to use. Valid options: " +
1159 factory.getDefaultParameters (orthoType_default_);
1161 "Parameters specific to the type of orthogonalization used.");
1163 pl->set(
"Orthogonalization Constant",
static_cast<MagnitudeType
>(orthoKappa_default_),
1164 "When using DGKS orthogonalization: the \"depTol\" constant, used "
1165 "to determine whether another step of classical Gram-Schmidt is "
1166 "necessary. Otherwise ignored.");
1173template<
class ScalarType,
class MV,
class OP>
1179 Teuchos::RCP<const MV>
rhsMV = problem_->getRHS();
1180 if (
rhsMV == Teuchos::null) {
1188 "Belos::GCRODRSolMgr::initializeStateStorage(): Cannot generate a Krylov basis with dimension larger the operator!");
1191 if (U_ == Teuchos::null) {
1192 U_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1196 if (MVT::GetNumberVecs(*U_) < recycledBlocks_+1) {
1197 Teuchos::RCP<const MV>
tmp = U_;
1198 U_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1203 if (C_ == Teuchos::null) {
1204 C_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1208 if (MVT::GetNumberVecs(*C_) < recycledBlocks_+1) {
1209 Teuchos::RCP<const MV>
tmp = C_;
1210 C_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1215 if (V_ == Teuchos::null) {
1216 V_ = MVT::Clone( *
rhsMV, numBlocks_+1 );
1220 if (MVT::GetNumberVecs(*V_) < numBlocks_+1) {
1221 Teuchos::RCP<const MV>
tmp = V_;
1222 V_ = MVT::Clone( *
tmp, numBlocks_+1 );
1227 if (U1_ == Teuchos::null) {
1228 U1_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1232 if (MVT::GetNumberVecs(*U1_) < recycledBlocks_+1) {
1233 Teuchos::RCP<const MV>
tmp = U1_;
1234 U1_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1239 if (C1_ == Teuchos::null) {
1240 C1_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1244 if (MVT::GetNumberVecs(*C1_) < recycledBlocks_+1) {
1245 Teuchos::RCP<const MV>
tmp = C1_;
1246 C1_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1251 if (r_ == Teuchos::null)
1252 r_ = MVT::Clone( *
rhsMV, 1 );
1255 tau_.resize(recycledBlocks_+1);
1258 work_.resize(recycledBlocks_+1);
1261 ipiv_.resize(recycledBlocks_+1);
1264 if (H2_ == Teuchos::null)
1265 H2_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 ) );
1267 if ( (H2_->numRows() != numBlocks_+recycledBlocks_+2) || (H2_->numCols() != numBlocks_+recycledBlocks_+1) )
1268 H2_->reshape( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1270 H2_->putScalar(
zero);
1273 if (R_ == Teuchos::null)
1274 R_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( recycledBlocks_+1, recycledBlocks_+1 ) );
1276 if ( (R_->numRows() != recycledBlocks_+1) || (R_->numCols() != recycledBlocks_+1) )
1277 R_->reshape( recycledBlocks_+1, recycledBlocks_+1 );
1279 R_->putScalar(
zero);
1282 if (PP_ == Teuchos::null)
1283 PP_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 ) );
1285 if ( (PP_->numRows() != numBlocks_+recycledBlocks_+2) || (PP_->numCols() != recycledBlocks_+1) )
1286 PP_->reshape( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 );
1290 if (HP_ == Teuchos::null)
1291 HP_ = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 ) );
1293 if ( (HP_->numRows() != numBlocks_+recycledBlocks_+2) || (HP_->numCols() != numBlocks_+recycledBlocks_+1) )
1294 HP_->reshape( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1302template<
class ScalarType,
class MV,
class OP>
1310 if (!isSet_) { setParameters( params_ ); }
1314 std::vector<int> index(numBlocks_+1);
1321 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1326 problem_->setLSIndex(
currIdx );
1329 ptrdiff_t dim = MVT::GetGlobalLength( *(problem_->getRHS()) );
1331 numBlocks_ = Teuchos::as<int>(
dim);
1333 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1334 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1335 params_->set(
"Num Blocks", numBlocks_);
1342 initializeStateStorage();
1346 Teuchos::ParameterList
plist;
1348 plist.set(
"Num Blocks",numBlocks_);
1349 plist.set(
"Recycled Blocks",recycledBlocks_);
1361#ifdef BELOS_TEUCHOS_TIME_MONITOR
1362 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
1368 builtRecycleSpace_ =
false;
1371 outputTest_->reset();
1379 "Belos::GCRODRSolMgr::solve(): Requested size of recycled subspace is not consistent with the current recycle subspace.");
1381 printer_->stream(
Debug) <<
" Now solving RHS index " <<
currIdx[0] <<
" using recycled subspace of dimension " << keff << std::endl << std::endl;
1384 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1386 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1393 Teuchos::SerialDenseMatrix<int,ScalarType>
Rtmp( Teuchos::View, *R_, keff, keff );
1401 ipiv_.resize(
Rtmp.numRows());
1407 work_.resize(
lwork);
1417 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1418 Ctmp = MVT::CloneViewNonConst( *C_, index );
1419 Utmp = MVT::CloneView( *U_, index );
1422 Teuchos::SerialDenseMatrix<int,ScalarType>
Ctr(keff,1);
1423 problem_->computeCurrPrecResVec( &*r_ );
1427 RCP<MV> update = MVT::Clone( *problem_->getCurrLHSVec(), 1 );
1428 MVT::MvInit( *
update, 0.0 );
1430 problem_->updateSolution(
update,
true );
1442 printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " <<
currIdx[0] << std::endl << std::endl;
1455 problem_->computeCurrPrecResVec( &*r_ );
1456 index.resize( 1 ); index[0] = 0;
1457 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1458 MVT::SetBlock(*r_,index,*
v0);
1462 index.resize( numBlocks_+1 );
1463 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1464 newstate.V = MVT::CloneViewNonConst( *V_, index );
1467 newstate.H =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, recycledBlocks_+1, recycledBlocks_+1 ) );
1478 if ( convTest_->getStatus() ==
Passed ) {
1489 if (convTest_->getStatus() ==
Passed)
1494 achievedTol_ = MT::one();
1495 Teuchos::RCP<MV>
X = problem_->getLHS();
1496 MVT::MvInit( *
X, SCT::zero() );
1497 printer_->stream(
Warnings) <<
"Belos::GCRODRSolMgr::solve(): Warning! NaN has been detected!"
1501 catch (
const std::exception &
e) {
1502 printer_->stream(
Errors) <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1504 <<
e.what() << std::endl;
1512 problem_->updateSolution(
update,
true );
1523 if (recycledBlocks_ <
p+1) {
1529 PPtmp =
rcp (
new Teuchos::SerialDenseMatrix<int,ScalarType> ( Teuchos::View, *PP_,
p, keff ) );
1532 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1533 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1534 RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
1549 Teuchos::SerialDenseMatrix<int,ScalarType>
Htmp( Teuchos::View, *H2_,
p+1,
p, recycledBlocks_+1,recycledBlocks_+1);
1550 Teuchos::SerialDenseMatrix<int,ScalarType>
HPtmp( Teuchos::View, *HP_,
p+1, keff );
1562 " LAPACK's _GEQRF failed to compute a workspace size.");
1570 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1571 work_.resize (
lwork);
1576 " LAPACK's _GEQRF failed to compute a QR factorization.");
1580 Teuchos::SerialDenseMatrix<int,ScalarType>
Rtmp( Teuchos::View, *R_, keff, keff );
1581 for (
int ii = 0;
ii < keff; ++
ii) {
1582 for (
int jj =
ii;
jj < keff; ++
jj) {
1591 HPtmp.values (),
HPtmp.stride (), &tau_[0], &work_[0],
1595 "LAPACK's _UNGQR failed to construct the Q factor.");
1600 index.resize (
p + 1);
1601 for (
int ii = 0;
ii < (
p+1); ++
ii) {
1604 Vtmp = MVT::CloneView( *V_, index );
1612 ipiv_.resize(
Rtmp.numRows());
1616 "LAPACK's _GETRF failed to compute an LU factorization.");
1626 work_.resize(
lwork);
1630 "LAPACK's _GETRI failed to invert triangular matrix.");
1635 printer_->stream(
Debug)
1636 <<
" Generated recycled subspace using RHS index " <<
currIdx[0]
1637 <<
" of dimension " << keff << std::endl << std::endl;
1644 problem_->setCurrLS();
1650 problem_->setLSIndex (
currIdx);
1669 outputTest_->resetNumCalls();
1672 problem_->computeCurrPrecResVec( &*r_ );
1673 index.resize( 1 ); index[0] = 0;
1674 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1675 MVT::SetBlock(*r_,index,*
v0);
1679 index.resize( numBlocks_+1 );
1680 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1681 newstate.V = MVT::CloneViewNonConst( *V_, index );
1682 index.resize( keff );
1683 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1684 newstate.C = MVT::CloneViewNonConst( *C_, index );
1685 newstate.U = MVT::CloneViewNonConst( *U_, index );
1686 newstate.B =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1687 newstate.H =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1704 if ( convTest_->getStatus() ==
Passed ) {
1713 else if ( maxIterTest_->getStatus() ==
Passed ) {
1729 problem_->updateSolution(
update,
true );
1733 printer_->stream(
Debug)
1734 <<
" Generated new recycled subspace using RHS index "
1735 <<
currIdx[0] <<
" of dimension " << keff << std::endl
1745 printer_->stream(
Debug)
1746 <<
" Performing restart number " <<
numRestarts <<
" of "
1747 << maxRestarts_ << std::endl << std::endl;
1750 problem_->computeCurrPrecResVec( &*r_ );
1751 index.resize( 1 ); index[0] = 0;
1752 RCP<MV> v00 = MVT::CloneViewNonConst( *V_, index );
1753 MVT::SetBlock(*r_,index,*
v00);
1757 index.resize( numBlocks_+1 );
1758 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1760 index.resize( keff );
1761 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1764 restartState.B =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, keff, numBlocks_, 0, keff ) );
1765 restartState.H =
rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_, numBlocks_+1, numBlocks_, keff, keff ) );
1781 true, std::logic_error,
"Belos::GCRODRSolMgr::solve: "
1782 "Invalid return from GCRODRIter::iterate().");
1791 if (convTest_->getStatus() !=
Passed)
1795 catch (
const std::exception&
e) {
1797 <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1798 <<
gcrodr_iter->getNumIters() << std::endl <<
e.what() << std::endl;
1806 problem_->updateSolution(
update,
true );
1809 problem_->setCurrLS();
1814 if (!builtRecycleSpace_) {
1816 printer_->stream(
Debug)
1817 <<
" Generated new recycled subspace using RHS index " <<
currIdx[0]
1818 <<
" of dimension " << keff << std::endl << std::endl;
1825 problem_->setLSIndex (
currIdx);
1836#ifdef BELOS_TEUCHOS_TIME_MONITOR
1841 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1845 numIters_ = maxIterTest_->getNumIters ();
1857 const std::vector<MagnitudeType>*
pTestValues = expConvTest_->getTestValue();
1862 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1863 "method returned NULL. Please report this bug to the Belos developers.");
1865 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
1866 "method returned a vector of length zero. Please report this bug to the "
1867 "Belos developers.");
1879template<
class ScalarType,
class MV,
class OP>
1882 MagnitudeType
one = Teuchos::ScalarTraits<MagnitudeType>::one();
1885 std::vector<MagnitudeType>
d(keff);
1886 std::vector<ScalarType>
dscalar(keff);
1887 std::vector<int> index(numBlocks_+1);
1899 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1900 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst( *U_, index );
1903 MVT::MvNorm( *
Utmp,
d );
1904 for (
int i=0;
i<keff; ++
i) {
1912 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
H2tmp = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *H2_,
p+keff+1,
p+keff ) );
1915 for (
int i=0;
i<keff; ++
i) {
1916 (*H2tmp)(
i,
i) =
d[
i];
1923 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_,
p+keff, recycledBlocks_+1 );
1931 Teuchos::RCP<MV>
U1tmp;
1933 index.resize( keff );
1934 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1935 Teuchos::RCP<const MV>
Utmp = MVT::CloneView( *U_, index );
1938 U1tmp = MVT::CloneViewNonConst( *U1_, index );
1939 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_, keff,
keff_new );
1947 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView( *V_, index );
1948 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_,
p,
keff_new, keff );
1953 Teuchos::SerialDenseMatrix<int,ScalarType>
HPtmp( Teuchos::View, *HP_,
p+keff+1,
keff_new );
1955 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *PP_,
p+keff,
keff_new );
1965 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
1966 "LAPACK's _GEQRF failed to compute a workspace size.");
1972 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1973 work_.resize (
lwork);
1977 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
1978 "LAPACK's _GEQRF failed to compute a QR factorization.");
1990 HPtmp.values (),
HPtmp.stride (), &tau_[0], &work_[0],
1993 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
1994 "LAPACK's _UNGQR failed to construct the Q factor.");
2001 Teuchos::RCP<MV>
C1tmp;
2004 for (
int i=0;
i < keff;
i++) { index[
i] =
i; }
2005 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView( *C_, index );
2008 C1tmp = MVT::CloneViewNonConst( *C1_, index );
2009 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *HP_, keff,
keff_new );
2014 index.resize(
p+1 );
2015 for (
int i=0;
i <
p+1; ++
i) { index[
i] =
i; }
2016 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView( *V_, index );
2017 Teuchos::SerialDenseMatrix<int,ScalarType>
PPtmp( Teuchos::View, *HP_,
p+1,
keff_new, keff, 0 );
2027 ipiv_.resize(
Rtmp.numRows());
2029 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0,GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
2033 work_.resize(
lwork);
2035 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to compute an LU factorization.");
2040 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst( *U_, index );
2049 Teuchos::SerialDenseMatrix<int,ScalarType>
b1( Teuchos::View, *H2_, recycledBlocks_+2, 1, 0, recycledBlocks_ );
2057template<
class ScalarType,
class MV,
class OP>
2058int GCRODRSolMgr<ScalarType,MV,OP,true>::getHarmonicVecs1(
int m,
2059 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2060 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2066 std::vector<MagnitudeType>
wr(
m),
wi(
m);
2069 Teuchos::SerialDenseMatrix<int,ScalarType>
vr(
m,
m,
false);
2072 std::vector<MagnitudeType>
w(
m);
2075 std::vector<int>
iperm(
m);
2081 builtRecycleSpace_ =
true;
2084 Teuchos::SerialDenseMatrix<int, ScalarType>
HHt(
HH, Teuchos::TRANS );
2085 Teuchos::SerialDenseVector<int, ScalarType>
e_m(
m );
2092 Teuchos::SerialDenseMatrix<int, ScalarType>
harmHH( Teuchos::Copy,
HH,
m,
m );
2093 for(
i=0;
i<
m; ++
i )
2103 std::vector<ScalarType>
work(1);
2104 std::vector<MagnitudeType>
rwork(2*
m);
2110 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (
work[0])));
2118 for(
i=0;
i<
m; ++
i )
2119 w[
i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot(
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i] );
2127 for(
i=0;
i<recycledBlocks_; ++
i ) {
2128 for(
j=0;
j<
m;
j++ ) {
2136 if (
wi[
iperm[recycledBlocks_-1]] != 0.0) {
2138 for (
i=0;
i<recycledBlocks_; ++
i ) {
2148 if (
wi[
iperm[recycledBlocks_-1]] > 0.0) {
2149 for(
j=0;
j<
m; ++
j ) {
2150 PP(
j,recycledBlocks_) =
vr(
j,
iperm[recycledBlocks_-1]+1);
2154 for(
j=0;
j<
m; ++
j ) {
2155 PP(
j,recycledBlocks_) =
vr(
j,
iperm[recycledBlocks_-1]-1);
2164 return recycledBlocks_+1;
2167 return recycledBlocks_;
2173template<
class ScalarType,
class MV,
class OP>
2174int GCRODRSolMgr<ScalarType,MV,OP,true>::getHarmonicVecs2(
int keffloc,
int m,
2175 const Teuchos::SerialDenseMatrix<int,ScalarType>& HH,
2176 const Teuchos::RCP<const MV>& VV,
2177 Teuchos::SerialDenseMatrix<int,ScalarType>& PP) {
2179 int m2 =
HH.numCols();
2183 std::vector<int> index;
2186 std::vector<MagnitudeType>
wr(
m2),
wi(
m2);
2189 std::vector<MagnitudeType>
w(
m2);
2192 Teuchos::SerialDenseMatrix<int,ScalarType>
vr(
m2,
m2,
false);
2198 builtRecycleSpace_ =
true;
2203 Teuchos::SerialDenseMatrix<int,ScalarType> B(
m2,
m2,
false);
2204 B.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,
one,
HH,
HH,
zero);
2213 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView( *C_, index );
2214 Teuchos::RCP<const MV>
Utmp = MVT::CloneView( *U_, index );
2221 for (
i=0;
i <
m+1;
i++) { index[
i] =
i; }
2222 Teuchos::RCP<const MV>
Vp = MVT::CloneView( *
VV, index );
2231 Teuchos::SerialDenseMatrix<int,ScalarType>
A(
m2,
A_tmp.numCols() );
2232 A.multiply( Teuchos::TRANS, Teuchos::NO_TRANS,
one,
HH,
A_tmp,
zero );
2241 int ld =
A.numRows();
2247 std::vector<ScalarType> beta(
ld);
2257 lapack.GGEVX(
balanc,
jobvl,
jobvr,
sense,
ld,
A.values(),
ld, B.values(),
ld, &
wr[0], &
wi[0],
2261 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GGEVX failed to compute eigensolutions.");
2265 for(
i=0;
i<
ld;
i++ ) {
2266 w[
i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot (
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i]) /
2267 Teuchos::ScalarTraits<ScalarType>::magnitude (beta[
i]);
2276 for(
i=0;
i<recycledBlocks_;
i++ ) {
2277 for(
j=0;
j<
ld;
j++ ) {
2285 if (
wi[
iperm[
ld-recycledBlocks_]] != 0.0) {
2287 for (
i=
ld-recycledBlocks_;
i<
ld;
i++ ) {
2297 if (
wi[
iperm[
ld-recycledBlocks_]] > 0.0) {
2298 for(
j=0;
j<
ld;
j++ ) {
2303 for(
j=0;
j<
ld;
j++ ) {
2313 return recycledBlocks_+1;
2316 return recycledBlocks_;
2323template<
class ScalarType,
class MV,
class OP>
2324void GCRODRSolMgr<ScalarType,MV,OP,true>::sort(std::vector<MagnitudeType>& dlist,
int n, std::vector<int>& iperm) {
2327 MagnitudeType
dRR,
dK;
2388template<
class ScalarType,
class MV,
class OP>
2390 std::ostringstream
out;
2391 out <<
"Belos::GCRODRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
2393 out <<
"Ortho Type: \"" << orthoType_ <<
"\"";
2394 out <<
", Num Blocks: " <<numBlocks_;
2395 out <<
", Num Recycle Blocks: " << recycledBlocks_;
2396 out <<
", Max Restarts: " << maxRestarts_;
Belos concrete class for performing the block, flexible GMRES iteration.
Belos header file which uses auto-configuration information to include necessary C++ headers.
Belos concrete class for performing the GCRO-DR iteration.
Class which describes the linear problem to be solved by the iterative solver.
Class which manages the output and verbosity of the Belos solvers.
Pure virtual base class which describes the basic interface for a solver manager.
Belos::StatusTest for logically combining several status tests.
Belos::StatusTestResNorm for specifying general residual norm stopping criteria.
Belos::StatusTest class for specifying a maximum number of iterations.
A factory class for generating StatusTestOutput objects.
Collection of types and exceptions used within the Belos solvers.
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.