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,
class DM = DefaultDenseMatrix<
int,ScalarType>,
131 const
bool lapackSupportsScalarType =
132 Belos::Details::LapackSupportsScalar<ScalarType>::value>
136 static const bool requiresLapack =
146 const Teuchos::RCP<Teuchos::ParameterList>&
pl) :
155 template<
class ScalarType,
class MV,
class OP,
class DM>
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.");
202 typedef Teuchos::ScalarTraits<ScalarType> SCT;
203 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
204 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
271 const Teuchos::RCP<Teuchos::ParameterList> &
pl);
277 Teuchos::RCP<SolverManager<ScalarType, MV, OP, DM> >
clone ()
const override {
293 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const override;
306 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
307 return Teuchos::tuple(timerSolve_);
342 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> &
params )
override;
362 bool set = problem_->setProblem();
364 throw "Could not set problem.";
408 std::string description()
const override;
418 void initializeStateStorage();
425 void computeGCRODRResidual();
427 void updateSolutionWithUpdate(
const Teuchos::RCP<MV>&
update);
433 int getHarmonicVecs1(
int m,
const DM&
HH, DM&
PP);
440 int getHarmonicVecs2(
int keff,
int m,
const DM&
HH,
441 const Teuchos::RCP<const MV>&
VV, DM&
PP);
443 int getFlexibleHarmonicVecs2(
int keff,
int m,
const DM&
HH,
444 const Teuchos::RCP<const MV>&
VV, DM&
PP);
447 void sort(std::vector<MagnitudeType>&
dlist,
int n, std::vector<int>&
iperm);
450 Teuchos::LAPACK<int,ScalarType> lapack;
453 Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > problem_;
456 Teuchos::RCP<OutputManager<ScalarType> > printer_;
457 Teuchos::RCP<std::ostream> outputStream_;
460 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > sTest_;
461 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP,DM> > maxIterTest_;
462 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > convTest_;
463 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP,DM> > expConvTest_, impConvTest_;
464 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP,DM> > outputTest_;
465 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > debugStatusTest_;
470 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > ortho_;
473 Teuchos::RCP<Teuchos::ParameterList> params_;
476 static constexpr double orthoKappa_default_ = 0.0;
477 static constexpr int maxRestarts_default_ = 100;
478 static constexpr int maxIters_default_ = 1000;
479 static constexpr int numBlocks_default_ = 50;
480 static constexpr int blockSize_default_ = 1;
481 static constexpr int recycledBlocks_default_ = 5;
482 static constexpr bool flexibleGCRODR_default_ =
false;
485 static constexpr int outputFreq_default_ = -1;
486 static constexpr const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
487 static constexpr const char * expResScale_default_ =
"Norm of Initial Residual";
488 static constexpr const char * label_default_ =
"Belos";
489 static constexpr const char * orthoType_default_ =
"ICGS";
492 MagnitudeType convTol_, orthoKappa_, achievedTol_;
493 int maxRestarts_, maxIters_, numIters_;
494 int verbosity_, outputStyle_, outputFreq_;
496 std::string orthoType_;
497 std::string impResScale_, expResScale_;
504 int numBlocks_, recycledBlocks_;
517 Teuchos::RCP<MV> U_, C_;
519 Teuchos::RCP<MV> W_, W1_;
522 Teuchos::RCP<MV> U1_, C1_;
525 Teuchos::RCP<DM> H2_;
527 Teuchos::RCP<DM> PP_;
528 Teuchos::RCP<DM> HP_;
529 std::vector<ScalarType> tau_;
530 std::vector<ScalarType> work_;
532 std::vector<int> ipiv_;
537 Teuchos::RCP<Teuchos::Time> timerSolve_;
543 bool builtRecycleSpace_;
548template<
class ScalarType,
class MV,
class OP,
class DM>
558template<
class ScalarType,
class MV,
class OP,
class DM>
561 const Teuchos::RCP<Teuchos::ParameterList>&
pl):
570 problem == Teuchos::null, std::invalid_argument,
571 "Belos::GCRODRSolMgr constructor: The solver manager's "
572 "constructor needs the linear problem argument 'problem' "
581 if (!
pl.is_null ()) {
587template<
class ScalarType,
class MV,
class OP,
class DM>
589 outputStream_ = Teuchos::rcpFromRef(std::cout);
591 orthoKappa_ = orthoKappa_default_;
592 maxRestarts_ = maxRestarts_default_;
593 maxIters_ = maxIters_default_;
594 numBlocks_ = numBlocks_default_;
595 recycledBlocks_ = recycledBlocks_default_;
596 verbosity_ = verbosity_default_;
597 outputStyle_ = outputStyle_default_;
598 outputFreq_ = outputFreq_default_;
599 isFlexible_ = flexibleGCRODR_default_;
600 orthoType_ = orthoType_default_;
601 impResScale_ = impResScale_default_;
602 expResScale_ = expResScale_default_;
603 label_ = label_default_;
605 builtRecycleSpace_ =
false;
623template<
class ScalarType,
class MV,
class OP,
class DM>
627 using Teuchos::isParameterType;
628 using Teuchos::getParameter;
630 using Teuchos::ParameterList;
631 using Teuchos::parameterList;
634 using Teuchos::rcp_dynamic_cast;
635 using Teuchos::rcpFromRef;
636 using Teuchos::Exceptions::InvalidParameter;
637 using Teuchos::Exceptions::InvalidParameterName;
638 using Teuchos::Exceptions::InvalidParameterType;
660 if (params_.is_null()) {
714 if (
params->isParameter (
"Maximum Restarts")) {
715 maxRestarts_ =
params->get(
"Maximum Restarts", maxRestarts_default_);
718 params_->set (
"Maximum Restarts", maxRestarts_);
722 if (
params->isParameter (
"Maximum Iterations")) {
723 maxIters_ =
params->get (
"Maximum Iterations", maxIters_default_);
726 params_->set (
"Maximum Iterations", maxIters_);
727 if (! maxIterTest_.is_null())
728 maxIterTest_->setMaxIters (maxIters_);
732 if (
params->isParameter (
"Num Blocks")) {
733 numBlocks_ =
params->get (
"Num Blocks", numBlocks_default_);
735 "Belos::GCRODRSolMgr: The \"Num Blocks\" parameter must "
736 "be strictly positive, but you specified a value of "
737 << numBlocks_ <<
".");
739 params_->set (
"Num Blocks", numBlocks_);
743 if (
params->isParameter (
"Num Recycled Blocks")) {
744 recycledBlocks_ =
params->get (
"Num Recycled Blocks",
745 recycledBlocks_default_);
747 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
748 "parameter must be strictly positive, but you specified "
749 "a value of " << recycledBlocks_ <<
".");
751 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
752 "parameter must be less than the \"Num Blocks\" "
753 "parameter, but you specified \"Num Recycled Blocks\" "
754 "= " << recycledBlocks_ <<
" and \"Num Blocks\" = "
755 << numBlocks_ <<
".");
757 params_->set(
"Num Recycled Blocks", recycledBlocks_);
760 if (
params->isParameter(
"Flexible GCRODR")) {
762 params->get(
"Flexible GCRODR", flexibleGCRODR_default_);
770 params_->set(
"Flexible GCRODR", isFlexible_);
776 if (
params->isParameter (
"Timer Label")) {
782 params_->set (
"Timer Label", label_);
783 std::string
solveLabel = label_ +
": GCRODRSolMgr total solve time";
784#ifdef BELOS_TEUCHOS_TIME_MONITOR
785 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (
solveLabel);
787 if (ortho_ != Teuchos::null) {
788 ortho_->setLabel( label_ );
794 if (
params->isParameter (
"Verbosity")) {
796 verbosity_ =
params->get (
"Verbosity", verbosity_default_);
801 params_->set (
"Verbosity", verbosity_);
804 if (! printer_.is_null())
805 printer_->setVerbosity (verbosity_);
809 if (
params->isParameter (
"Output Style")) {
811 outputStyle_ =
params->get (
"Output Style", outputStyle_default_);
817 params_->set (
"Output Style", outputStyle_);
835 if (
params->isParameter (
"Output Stream")) {
846 if (outputStream_.is_null()) {
847 outputStream_ =
rcp (
new Teuchos::oblackholestream);
850 params_->set (
"Output Stream", outputStream_);
853 if (! printer_.is_null()) {
854 printer_->setOStream (outputStream_);
860 if (
params->isParameter (
"Output Frequency")) {
861 outputFreq_ =
params->get (
"Output Frequency", outputFreq_default_);
865 params_->set(
"Output Frequency", outputFreq_);
866 if (! outputTest_.is_null())
867 outputTest_->setOutputFrequency (outputFreq_);
874 if (printer_.is_null()) {
886 if (
params->isParameter (
"Orthogonalization")) {
888 params->get (
"Orthogonalization", orthoType_default_);
891 std::ostringstream
os;
892 os <<
"Belos::GCRODRSolMgr: Invalid orthogonalization name \""
894 <<
"for the \"Orthogonalization\" name parameter: ";
896 throw std::invalid_argument (
os.str());
902 params_->set (
"Orthogonalization", orthoType_);
921 using Teuchos::sublist;
923 const std::string
paramName (
"Orthogonalization Parameters");
938 "Failed to get orthogonalization parameters. "
939 "Please report this bug to the Belos developers.");
949 ortho_ =
factory.makeMatOrthoManager (orthoType_,
null, printer_,
958 typedef Teuchos::ParameterListAcceptor
PLA;
964 ortho_ =
factory.makeMatOrthoManager (orthoType_,
null, printer_,
979 if (
params->isParameter (
"Orthogonalization Constant")) {
980 MagnitudeType orthoKappa = orthoKappa_default_;
981 if (
params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
982 orthoKappa =
params->get (
"Orthogonalization Constant", orthoKappa);
985 orthoKappa =
params->get (
"Orthogonalization Constant", orthoKappa_default_);
988 if (orthoKappa > 0) {
989 orthoKappa_ = orthoKappa;
991 params_->set(
"Orthogonalization Constant", orthoKappa_);
993 if (orthoType_ ==
"DGKS" && ! ortho_.is_null()) {
1010 if (
params->isParameter(
"Convergence Tolerance")) {
1011 if (
params->isType<MagnitudeType> (
"Convergence Tolerance")) {
1012 convTol_ =
params->get (
"Convergence Tolerance",
1020 params_->set (
"Convergence Tolerance", convTol_);
1021 if (! impConvTest_.is_null())
1022 impConvTest_->setTolerance (convTol_);
1023 if (! expConvTest_.is_null())
1024 expConvTest_->setTolerance (convTol_);
1028 if (
params->isParameter (
"Implicit Residual Scaling")) {
1038 params_->set(
"Implicit Residual Scaling", impResScale_);
1048 if (! impConvTest_.is_null()) {
1054 impConvTest_ =
null;
1061 if (
params->isParameter(
"Explicit Residual Scaling")) {
1071 params_->set(
"Explicit Residual Scaling", expResScale_);
1074 if (! expConvTest_.is_null()) {
1080 expConvTest_ =
null;
1091 if (maxIterTest_.is_null())
1101 if (impConvTest_.is_null()) {
1102 impConvTest_ =
rcp (
new StatusTestResNorm_t (convTol_));
1107 expConvTest_ = impConvTest_;
1108 convTest_ = impConvTest_;
1113 if (impConvTest_.is_null()) {
1114 impConvTest_ =
rcp (
new StatusTestResNorm_t (convTol_));
1120 if (expConvTest_.is_null()) {
1121 expConvTest_ =
rcp (
new StatusTestResNorm_t (convTol_));
1122 expConvTest_->defineResForm (StatusTestResNorm_t::Explicit,
Belos::TwoNorm);
1129 if (convTest_.is_null()) {
1130 convTest_ =
rcp (
new StatusTestCombo_t (StatusTestCombo_t::SEQ,
1139 sTest_ =
rcp (
new StatusTestCombo_t (StatusTestCombo_t::OR,
1147 if (Teuchos::nonnull(debugStatusTest_)) {
1148 sTest_ =
rcp (
new StatusTestCombo_t (StatusTestCombo_t::OR,
1156 outputTest_ =
stoFactory.create (printer_, sTest_, outputFreq_,
1166 if (timerSolve_.is_null()) {
1167 std::string
solveLabel = label_ +
": GCRODRSolMgr total solve time";
1168#ifdef BELOS_TEUCHOS_TIME_MONITOR
1169 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
1178template<
class ScalarType,
class MV,
class OP,
class DM>
1179Teuchos::RCP<const Teuchos::ParameterList>
1182 using Teuchos::ParameterList;
1183 using Teuchos::parameterList;
1192 "The relative residual tolerance that needs to be achieved by the\n"
1193 "iterative solver in order for the linear system to be declared converged.");
1194 pl->set(
"Maximum Restarts",
static_cast<int>(maxRestarts_default_),
1195 "The maximum number of cycles allowed for each\n"
1196 "set of RHS solved.");
1197 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
1198 "The maximum number of iterations allowed for each\n"
1199 "set of RHS solved.");
1203 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
1204 "Block Size Parameter -- currently must be 1 for GCRODR");
1205 pl->set(
"Num Blocks",
static_cast<int>(numBlocks_default_),
1206 "The maximum number of vectors allowed in the Krylov subspace\n"
1207 "for each set of RHS solved.");
1208 pl->set(
"Num Recycled Blocks",
static_cast<int>(recycledBlocks_default_),
1209 "The maximum number of vectors in the recycled subspace." );
1210 pl->set(
"Flexible GCRODR",
static_cast<bool>(flexibleGCRODR_default_),
1211 "Whether to use the flexible variant of GCRODR. The flexible variant stores the right-preconditioned correction basis Z.");
1212 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
1213 "What type(s) of solver information should be outputted\n"
1214 "to the output stream.");
1215 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
1216 "What style is used for the solver information outputted\n"
1217 "to the output stream.");
1218 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
1219 "How often convergence information should be outputted\n"
1220 "to the output stream.");
1221 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
1222 "A reference-counted pointer to the output stream where all\n"
1223 "solver output is sent.");
1224 pl->set(
"Implicit Residual Scaling",
static_cast<const char *
>(impResScale_default_),
1225 "The type of scaling used in the implicit residual convergence test.");
1226 pl->set(
"Explicit Residual Scaling",
static_cast<const char *
>(expResScale_default_),
1227 "The type of scaling used in the explicit residual convergence test.");
1228 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
1229 "The string to use as a prefix for the timer labels.");
1232 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
1233 "The type of orthogonalization to use. Valid options: " +
1236 factory.getDefaultParameters (orthoType_default_);
1238 "Parameters specific to the type of orthogonalization used.");
1240 pl->set(
"Orthogonalization Constant",
static_cast<MagnitudeType
>(orthoKappa_default_),
1241 "When using DGKS orthogonalization: the \"depTol\" constant, used "
1242 "to determine whether another step of classical Gram-Schmidt is "
1243 "necessary. Otherwise ignored.");
1250template<
class ScalarType,
class MV,
class OP,
class DM>
1256 Teuchos::RCP<const MV>
rhsMV = problem_->getRHS();
1257 if (
rhsMV == Teuchos::null) {
1265 "Belos::GCRODRSolMgr::initializeStateStorage(): Cannot generate a Krylov basis with dimension larger the operator!");
1268 if (U_ == Teuchos::null) {
1269 U_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1273 if (MVT::GetNumberVecs(*U_) < recycledBlocks_+1) {
1274 Teuchos::RCP<const MV>
tmp = U_;
1275 U_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1280 if (C_ == Teuchos::null) {
1281 C_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1285 if (MVT::GetNumberVecs(*C_) < recycledBlocks_+1) {
1286 Teuchos::RCP<const MV>
tmp = C_;
1287 C_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1292 if (V_ == Teuchos::null) {
1293 V_ = MVT::Clone( *
rhsMV, numBlocks_+1 );
1297 if (MVT::GetNumberVecs(*V_) < numBlocks_+1) {
1298 Teuchos::RCP<const MV>
tmp = V_;
1299 V_ = MVT::Clone( *
tmp, numBlocks_+1 );
1304 if (U1_ == Teuchos::null) {
1305 U1_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1309 if (MVT::GetNumberVecs(*U1_) < recycledBlocks_+1) {
1310 Teuchos::RCP<const MV>
tmp = U1_;
1311 U1_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1316 if (C1_ == Teuchos::null) {
1317 C1_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1321 if (MVT::GetNumberVecs(*C1_) < recycledBlocks_+1) {
1322 Teuchos::RCP<const MV>
tmp = C1_;
1323 C1_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1329 if (Z_ == Teuchos::null) {
1330 Z_ = MVT::Clone(*
rhsMV, numBlocks_+1);
1333 if (MVT::GetNumberVecs(*Z_) < numBlocks_+1) {
1334 Teuchos::RCP<const MV>
tmp = Z_;
1335 Z_ = MVT::Clone(*
tmp, numBlocks_+1);
1339 if (W_ == Teuchos::null) {
1340 W_ = MVT::Clone(*
rhsMV, recycledBlocks_+1);
1343 if (MVT::GetNumberVecs(*W_) < recycledBlocks_+1) {
1344 Teuchos::RCP<const MV>
tmp = W_;
1345 W_ = MVT::Clone(*
tmp, recycledBlocks_+1);
1349 if (W1_ == Teuchos::null) {
1350 W1_ = MVT::Clone(*
rhsMV, recycledBlocks_+1);
1353 if (MVT::GetNumberVecs(*W1_) < recycledBlocks_+1) {
1354 Teuchos::RCP<const MV>
tmp = W1_;
1355 W1_ = MVT::Clone(*
tmp, recycledBlocks_+1);
1361 if (r_ == Teuchos::null)
1362 r_ = MVT::Clone( *
rhsMV, 1 );
1365 tau_.resize(recycledBlocks_+1);
1368 work_.resize(recycledBlocks_+1);
1371 ipiv_.resize(recycledBlocks_+1);
1374 if (H2_ == Teuchos::null)
1375 H2_ = DMT::Create( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1377 if ( (DMT::GetNumRows(*H2_) != numBlocks_+recycledBlocks_+2) || (DMT::GetNumCols(*H2_) != numBlocks_+recycledBlocks_+1) )
1378 DMT::Reshape( *H2_, numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1380 DMT::PutScalar(*H2_,
zero);
1383 if (R_ == Teuchos::null)
1384 R_ = DMT::Create( recycledBlocks_+1, recycledBlocks_+1 );
1386 if ( (DMT::GetNumRows(*R_) != recycledBlocks_+1) || (DMT::GetNumCols(*R_) != recycledBlocks_+1) )
1387 DMT::Reshape( *R_, recycledBlocks_+1, recycledBlocks_+1 );
1389 DMT::PutScalar(*R_,
zero);
1392 if (PP_ == Teuchos::null)
1393 PP_ = DMT::Create( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 );
1395 if ( (DMT::GetNumRows(*PP_) != numBlocks_+recycledBlocks_+2) || (DMT::GetNumCols(*PP_) != recycledBlocks_+1) )
1396 DMT::Reshape( *PP_, numBlocks_+recycledBlocks_+2, recycledBlocks_+1 );
1400 if (HP_ == Teuchos::null)
1401 HP_ = DMT::Create( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1403 if ( (DMT::GetNumRows(*HP_) != numBlocks_+recycledBlocks_+2) || (DMT::GetNumCols(*HP_) != numBlocks_+recycledBlocks_+1) )
1404 DMT::Reshape( *HP_, numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1412template<
class ScalarType,
class MV,
class OP,
class DM>
1414GCRODRSolMgr<ScalarType,MV,OP,DM,true>::computeGCRODRResidual()
1417 problem_->computeCurrResVec(&*r_);
1420 problem_->computeCurrPrecResVec(&*r_);
1424template<
class ScalarType,
class MV,
class OP,
class DM>
1426GCRODRSolMgr<ScalarType,MV,OP,DM,true>::
1427updateSolutionWithUpdate(
const Teuchos::RCP<MV>& update)
1429 if (
update == Teuchos::null) {
1436 Teuchos::RCP<MV>
curX = problem_->getCurrLHSVec();
1440 problem_->updateSolution(
update,
true);
1446template<
class ScalarType,
class MV,
class OP,
class DM>
1456 if (!isSet_) { setParameters( params_ ); }
1460 std::vector<int> index(numBlocks_+1);
1468 !Teuchos::is_null(problem_->getLeftPrec()),
1470 "Belos::GCRODRSolMgr::solve(): Flexible GCRODR does not support left preconditioning; use no preconditioner or a right preconditioner.");
1474 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1479 problem_->setLSIndex(
currIdx );
1482 ptrdiff_t dim = MVT::GetGlobalLength( *(problem_->getRHS()) );
1484 numBlocks_ = Teuchos::as<int>(
dim);
1486 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1487 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1488 params_->set(
"Num Blocks", numBlocks_);
1495 initializeStateStorage();
1499 Teuchos::ParameterList
plist;
1501 plist.set(
"Num Blocks",numBlocks_);
1502 plist.set(
"Recycled Blocks",recycledBlocks_);
1519#ifdef BELOS_TEUCHOS_TIME_MONITOR
1520 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
1526 builtRecycleSpace_ =
false;
1529 outputTest_->reset();
1537 "Belos::GCRODRSolMgr::solve(): Requested size of recycled subspace is not consistent with the current recycle subspace.");
1539 printer_->stream(
Debug) <<
" Now solving RHS index " <<
currIdx[0] <<
" using recycled subspace of dimension " << keff << std::endl << std::endl;
1542 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1544 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1556 Teuchos::RCP<DM>
Rtmp = DMT::Subview( *R_, keff, keff );
1562 DMT::SyncDeviceToHost(*R_);
1567 ipiv_.resize(DMT::GetNumRows(*
Rtmp));
1568 lapack.GETRF(DMT::GetNumRows(*
Rtmp), DMT::GetNumCols(*
Rtmp), DMT::GetRawHostPtr(*
Rtmp), DMT::GetStride(*
Rtmp), &ipiv_[0], &
info);
1573 work_.resize(
lwork);
1574 lapack.GETRI(DMT::GetNumRows(*
Rtmp), DMT::GetRawHostPtr(*
Rtmp), DMT::GetStride(*
Rtmp), &ipiv_[0], &work_[0],
lwork, &
info);
1577 DMT::SyncHostToDevice(*R_);
1582 Teuchos::RCP<const MV>
Wtmp = MVT::CloneView(*W_, index);
1583 Teuchos::RCP<MV>
W1tmp = MVT::CloneViewNonConst(*W1_, index);
1591 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1592 Ctmp = MVT::CloneViewNonConst( *C_, index );
1593 Utmp = MVT::CloneView( *U_, index );
1596 Teuchos::RCP<DM>
Ctr = DMT::Create(keff, 1);
1597 computeGCRODRResidual();
1601 RCP<MV> update = MVT::Clone( *problem_->getCurrLHSVec(), 1 );
1602 MVT::MvInit( *
update, 0.0 );
1604 updateSolutionWithUpdate(
update);
1616 printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " <<
currIdx[0] << std::endl << std::endl;
1620 primeList.set(
"Recycled Blocks",recycledBlocks_);
1632 computeGCRODRResidual();
1633 index.resize( 1 ); index[0] = 0;
1634 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1635 MVT::SetBlock(*r_,index,*
v0);
1639 index.resize( numBlocks_+1 );
1640 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1641 newstate.V = MVT::CloneViewNonConst( *V_, index );
1642 if (isFlexible_)
newstate.Z = MVT::CloneViewNonConst( *Z_, index );
1656 if ( convTest_->getStatus() ==
Passed ) {
1663 else if (Teuchos::nonnull(debugStatusTest_) &&
1664 debugStatusTest_->getStatus() ==
Passed) {
1676 if (convTest_->getStatus() ==
Passed)
1682 achievedTol_ = MT::one();
1683 Teuchos::RCP<MV>
X = problem_->getLHS();
1684 MVT::MvInit( *
X, SCT::zero() );
1685 printer_->stream(
Warnings) <<
"Belos::GCRODRSolMgr::solve(): Warning! NaN has been detected!"
1689 catch (
const std::exception &
e) {
1691 printer_->stream(
Errors) <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1693 <<
e.what() << std::endl;
1705 updateSolutionWithUpdate(
update);
1716 if (recycledBlocks_ <
p+1) {
1720 DMT::SyncDeviceToHost( *H2_ );
1721 DMT::SyncDeviceToHost( *PP_ );
1728 DMT::SyncHostToDevice( *PP_ );
1730 PPtmp = DMT::Subview( *PP_,
p, keff );
1734 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1735 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1736 RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
1748 std::vector<int>
wind(keff);
1762 DMT::SyncDeviceToHost( *HP_ );
1764 RCP<DM> Htmp = DMT::Subview( *H2_,
p+1,
p, recycledBlocks_+1,recycledBlocks_+1 );
1767 Teuchos::BLAS<int,ScalarType>
blas;
1768 blas.GEMM( Teuchos::NO_TRANS, Teuchos::NO_TRANS,
p+1, keff,
p,
one,
1769 DMT::GetConstRawHostPtr(*
Htmp), DMT::GetStride(*
Htmp),
1770 DMT::GetConstRawHostPtr(*
PPtmp), DMT::GetStride(*
PPtmp),
1778 lapack.GEQRF (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetRawHostPtr(*
HPtmp),
1782 " LAPACK's _GEQRF failed to compute a workspace size.");
1790 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1791 work_.resize (
lwork);
1792 lapack.GEQRF (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetRawHostPtr(*
HPtmp),
1796 " LAPACK's _GEQRF failed to compute a QR factorization.");
1801 DMT::SyncDeviceToHost( *R_ );
1803 for (
int ii = 0;
ii < keff; ++
ii) {
1804 for (
int jj =
ii;
jj < keff; ++
jj) {
1808 DMT::SyncHostToDevice( *R_ );
1813 lapack.UNGQR (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetNumCols(*
HPtmp),
1814 DMT::GetRawHostPtr(*
HPtmp), DMT::GetStride(*
HPtmp), &tau_[0], &work_[0],
1818 "LAPACK's _UNGQR failed to construct the Q factor.");
1822 DMT::SyncHostToDevice( *HP_ );
1825 index.resize (
p + 1);
1826 for (
int ii = 0;
ii < (
p+1); ++
ii) {
1829 Vtmp = MVT::CloneView( *V_, index );
1837 ipiv_.resize(DMT::GetNumRows(*
Rtmp));
1838 lapack.GETRF(DMT::GetNumRows(*
Rtmp), DMT::GetNumCols(*
Rtmp), DMT::GetRawHostPtr(*
Rtmp),
1839 DMT::GetStride(*
Rtmp), &ipiv_[0], &
info);
1842 "LAPACK's _GETRF failed to compute an LU factorization.");
1852 work_.resize(
lwork);
1853 lapack.GETRI(DMT::GetNumRows(*
Rtmp), DMT::GetRawHostPtr(*
Rtmp), DMT::GetStride(*
Rtmp),
1857 "LAPACK's _GETRI failed to invert triangular matrix.");
1859 DMT::SyncHostToDevice( *R_ );
1864 std::vector<int>
wind(keff);
1871 printer_->stream(
Debug)
1872 <<
" Generated recycled subspace using RHS index " <<
currIdx[0]
1873 <<
" of dimension " << keff << std::endl << std::endl;
1880 problem_->setCurrLS();
1886 problem_->setLSIndex (
currIdx);
1905 outputTest_->resetNumCalls();
1908 computeGCRODRResidual();
1909 index.resize( 1 ); index[0] = 0;
1910 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1911 MVT::SetBlock(*r_,index,*
v0);
1914 DMT::SyncDeviceToHost( *H2_ );
1916 index.resize( numBlocks_+1 );
1917 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1918 newstate.V = MVT::CloneViewNonConst( *V_, index );
1919 if (isFlexible_)
newstate.Z = MVT::CloneViewNonConst( *Z_, index );
1920 index.resize( keff );
1921 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1922 newstate.C = MVT::CloneViewNonConst( *C_, index );
1923 newstate.U = MVT::CloneViewNonConst( *U_, index );
1941 if ( convTest_->getStatus() ==
Passed ) {
1950 else if ( maxIterTest_->getStatus() ==
Passed ) {
1967 updateSolutionWithUpdate(
update);
1971 printer_->stream(
Debug)
1972 <<
" Generated new recycled subspace using RHS index "
1973 <<
currIdx[0] <<
" of dimension " << keff << std::endl
1984 printer_->stream(
Debug)
1985 <<
" Performing restart number " <<
numRestarts <<
" of "
1986 << maxRestarts_ << std::endl << std::endl;
1989 computeGCRODRResidual();
1990 index.resize( 1 ); index[0] = 0;
1991 RCP<MV> v00 = MVT::CloneViewNonConst( *V_, index );
1992 MVT::SetBlock(*r_,index,*
v00);
1995 DMT::SyncDeviceToHost( *H2_ );
1997 index.resize( numBlocks_+1 );
1998 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
2000 if (isFlexible_)
restartState.Z = MVT::CloneViewNonConst( *Z_, index );
2001 index.resize( keff );
2002 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
2017 else if (Teuchos::nonnull(debugStatusTest_) &&
2018 debugStatusTest_->getStatus() ==
Passed) {
2036 std::logic_error,
"Belos::GCRODRSolMgr::solve: "
2037 "Invalid return from GCRODRIter::iterate().");
2046 if (convTest_->getStatus() !=
Passed) {
2052 catch (
const std::exception&
e) {
2055 <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
2056 <<
gcrodr_iter->getNumIters() << std::endl <<
e.what() << std::endl;
2064 updateSolutionWithUpdate(
update);
2067 problem_->setCurrLS();
2072 if (!builtRecycleSpace_) {
2074 printer_->stream(
Debug)
2075 <<
" Generated new recycled subspace using RHS index " <<
currIdx[0]
2076 <<
" of dimension " << keff << std::endl << std::endl;
2083 problem_->setLSIndex (
currIdx);
2094#ifdef BELOS_TEUCHOS_TIME_MONITOR
2099 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
2103 numIters_ = maxIterTest_->getNumIters ();
2116 if (! expConvTest_.is_null()) {
2123 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
2124 "method returned NULL. Please report this bug to the Belos developers.");
2126 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
2127 "method returned a vector of length zero. Please report this bug to the "
2128 "Belos developers.");
2143template<
class ScalarType,
class MV,
class OP,
class DM>
2151 MagnitudeType
one = Teuchos::ScalarTraits<MagnitudeType>::one();
2154 std::vector<MagnitudeType>
d(keff);
2155 std::vector<ScalarType>
dscalar(keff);
2156 std::vector<int> index(numBlocks_+1);
2168 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
2169 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst( *U_, index );
2172 MVT::MvNorm( *
Utmp,
d );
2173 for (
int i=0;
i<keff; ++
i) {
2181 DMT::SyncDeviceToHost( *H2_ );
2182 Teuchos::RCP<DM>
H2tmp = DMT::Subview( *H2_,
p+keff+1,
p+keff );
2185 for (
int i=0;
i<keff; ++
i) {
2189 DMT::SyncHostToDevice( *H2_ );
2195 DMT::SyncDeviceToHost( *PP_ );
2196 Teuchos::RCP<DM>
PPtmp = DMT::Subview( *PP_,
p+keff, recycledBlocks_+1 );
2198 DMT::SyncHostToDevice( *PP_ );
2205 Teuchos::RCP<MV>
U1tmp;
2207 index.resize( keff );
2208 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
2209 Teuchos::RCP<const MV>
Utmp = MVT::CloneView( *U_, index );
2212 U1tmp = MVT::CloneViewNonConst( *U1_, index );
2213 Teuchos::RCP<const DM>
PPtmp = DMT::SubviewConst( *PP_, keff,
keff_new );
2221 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView( *V_, index );
2222 Teuchos::RCP<const DM>
PPtmp = DMT::SubviewConst( *PP_,
p,
keff_new, keff );
2227 DMT::SyncDeviceToHost( *HP_ );
2228 Teuchos::RCP<DM>
HPtmp = DMT::Subview( *HP_,
p+keff+1,
keff_new );
2230 DMT::SyncDeviceToHost( *PP_ );
2233 Teuchos::BLAS<int,ScalarType>
blas;
2234 blas.GEMM( Teuchos::NO_TRANS, Teuchos::NO_TRANS,
p+keff+1,
keff_new,
p+keff,
one,
2235 DMT::GetConstRawHostPtr(*
H2tmp), DMT::GetStride(*
H2tmp),
2236 DMT::GetConstRawHostPtr(*
PPtmp), DMT::GetStride(*
PPtmp),
2243 lapack.GEQRF (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetRawHostPtr(*
HPtmp),
2246 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
2247 "LAPACK's _GEQRF failed to compute a workspace size.");
2253 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
2254 work_.resize (
lwork);
2255 lapack.GEQRF (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetRawHostPtr(*
HPtmp),
2258 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
2259 "LAPACK's _GEQRF failed to compute a QR factorization.");
2263 DMT::SyncDeviceToHost( *R_ );
2271 lapack.UNGQR (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetNumCols(*
HPtmp),
2272 DMT::GetRawHostPtr(*
HPtmp), DMT::GetStride(*
HPtmp), &tau_[0], &work_[0],
2275 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
2276 "LAPACK's _UNGQR failed to construct the Q factor.");
2278 DMT::SyncHostToDevice( *HP_ );
2279 HPtmp = Teuchos::null;
2286 Teuchos::RCP<MV>
C1tmp;
2289 for (
int i=0;
i < keff;
i++) { index[
i] =
i; }
2290 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView( *C_, index );
2293 C1tmp = MVT::CloneViewNonConst( *C1_, index );
2294 Teuchos::RCP<const DM>
PPtmp = DMT::SubviewConst( *HP_, keff,
keff_new );
2299 index.resize(
p+1 );
2300 for (
int i=0;
i <
p+1; ++
i) { index[
i] =
i; }
2301 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView( *V_, index );
2302 Teuchos::RCP<const DM>
PPtmp = DMT::SubviewConst( *HP_,
p+1,
keff_new, keff, 0 );
2312 ipiv_.resize(DMT::GetNumRows(*
Rtmp));
2313 lapack.GETRF(DMT::GetNumRows(*
Rtmp),DMT::GetNumCols(*
Rtmp),DMT::GetRawHostPtr(*
Rtmp),DMT::GetStride(*
Rtmp),&ipiv_[0],&
info);
2314 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0,GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::buildRecycleSpace2(): LAPACK _GETRF failed to compute an LU factorization.");
2318 work_.resize(
lwork);
2319 lapack.GETRI(DMT::GetNumRows(*
Rtmp),DMT::GetRawHostPtr(*
Rtmp),DMT::GetStride(*
Rtmp),&ipiv_[0],&work_[0],
lwork,&
info);
2320 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::buildRecycleSpace2(): LAPACK _GETRI failed to compute an LU factorization.");
2322 DMT::SyncHostToDevice(*R_);
2327 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst( *U_, index );
2336 Teuchos::RCP<DM>
b1 = DMT::Subview( *H2_, recycledBlocks_+2, 1, 0, recycledBlocks_ );
2337 DMT::PutScalar( *
b1,
zero );
2347template<
class ScalarType,
class MV,
class OP,
class DM>
2349GCRODRSolMgr<ScalarType,MV,OP,DM,true>::
2350buildFlexibleRecycleSpace2(Teuchos::RCP<GCRODRIteration<ScalarType,MV,OP,DM> > gcrodr_iter)
2352 MagnitudeType
magOne = Teuchos::ScalarTraits<MagnitudeType>::one();
2356 std::vector<MagnitudeType>
d(keff);
2357 std::vector<ScalarType>
dscalar(keff);
2358 std::vector<int> index(numBlocks_+1);
2367 GCRODRSolMgrRecyclingFailure,
2368 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): oldState.Z is null.");
2371 W_ == Teuchos::null,
2372 GCRODRSolMgrRecyclingFailure,
2373 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): W_ is null.");
2378 for (
int ii=0;
ii<keff; ++
ii) index[
ii] =
ii;
2380 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst(*U_, index);
2381 Teuchos::RCP<MV>
Wtmp = MVT::CloneViewNonConst(*W_, index);
2386 MVT::MvNorm(*
Utmp,
d);
2387 for (
int i=0;
i<keff; ++
i) {
2397 DMT::SyncDeviceToHost(*H2_);
2398 Teuchos::RCP<DM>
H2tmp = DMT::Subview(*H2_,
p+keff+1,
p+keff);
2401 for (
int i=0;
i<keff; ++
i) {
2405 DMT::SyncHostToDevice(*H2_);
2410 DMT::SyncDeviceToHost(*PP_);
2411 Teuchos::RCP<DM>
PPtmp = DMT::Subview(*PP_,
p+keff, recycledBlocks_+1);
2413 DMT::SyncHostToDevice(*PP_);
2417 Teuchos::RCP<MV>
U1tmp;
2420 for (
int ii=0;
ii<keff; ++
ii) index[
ii] =
ii;
2422 Teuchos::RCP<const MV>
Utmp = MVT::CloneView(*U_, index);
2427 U1tmp = MVT::CloneViewNonConst(*U1_, index);
2429 Teuchos::RCP<const DM>
PPtop = DMT::SubviewConst(*PP_, keff,
keff_new);
2437 Teuchos::RCP<const MV>
Ztmp = MVT::CloneView(*
oldState.Z, index);
2444 Teuchos::RCP<MV>
W1tmp;
2447 for (
int ii=0;
ii<keff; ++
ii) index[
ii] =
ii;
2449 Teuchos::RCP<const MV>
Wtmp = MVT::CloneView(*W_, index);
2454 W1tmp = MVT::CloneViewNonConst(*W1_, index);
2456 Teuchos::RCP<const DM>
PPtop = DMT::SubviewConst(*PP_, keff,
keff_new);
2464 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView(*
oldState.V, index);
2471 DMT::SyncDeviceToHost(*HP_);
2475 DMT::SyncDeviceToHost(*PP_);
2476 DMT::SyncDeviceToHost(*H2_);
2479 Teuchos::BLAS<int,ScalarType>
blas;
2480 blas.GEMM(Teuchos::NO_TRANS, Teuchos::NO_TRANS,
2483 DMT::GetConstRawHostPtr(*
H2tmp), DMT::GetStride(*
H2tmp),
2484 DMT::GetConstRawHostPtr(*
PPtmp), DMT::GetStride(*
PPtmp),
2486 DMT::GetRawHostPtr(*
HPtmp), DMT::GetStride(*
HPtmp));
2494 if (work_.size() < 1) work_.resize(1);
2496 lapack.GEQRF(DMT::GetNumRows(*
HPtmp),
2497 DMT::GetNumCols(*
HPtmp),
2498 DMT::GetRawHostPtr(*
HPtmp),
2499 DMT::GetStride(*
HPtmp),
2504 GCRODRSolMgrLAPACKFailure,
2505 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GEQRF workspace query failed.");
2507 lwork = std::abs(
static_cast<int>(Teuchos::ScalarTraits<ScalarType>::real(work_[0])));
2508 work_.resize(
lwork);
2510 lapack.GEQRF(DMT::GetNumRows(*
HPtmp),
2511 DMT::GetNumCols(*
HPtmp),
2512 DMT::GetRawHostPtr(*
HPtmp),
2513 DMT::GetStride(*
HPtmp),
2518 GCRODRSolMgrLAPACKFailure,
2519 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GEQRF failed.");
2522 DMT::SyncDeviceToHost(*R_);
2532 lapack.UNGQR(DMT::GetNumRows(*
HPtmp),
2533 DMT::GetNumCols(*
HPtmp),
2534 DMT::GetNumCols(*
HPtmp),
2535 DMT::GetRawHostPtr(*
HPtmp),
2536 DMT::GetStride(*
HPtmp),
2541 GCRODRSolMgrLAPACKFailure,
2542 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK UNGQR failed.");
2544 DMT::SyncHostToDevice(*HP_);
2548 Teuchos::RCP<MV>
C1tmp;
2552 for (
int i=0;
i<keff; ++
i) index[
i] =
i;
2554 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView(*C_, index);
2559 C1tmp = MVT::CloneViewNonConst(*C1_, index);
2561 Teuchos::RCP<const DM>
Qtop = DMT::SubviewConst(*HP_, keff,
keff_new);
2567 for (
int i=0;
i<
p+1; ++
i) index[
i] =
i;
2569 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView(*
oldState.V, index);
2570 Teuchos::RCP<const DM>
Qbottom = DMT::SubviewConst(*HP_,
p+1,
keff_new, keff, 0);
2579 ipiv_.resize(DMT::GetNumRows(*
Rtmp));
2581 lapack.GETRF(DMT::GetNumRows(*
Rtmp),
2582 DMT::GetNumCols(*
Rtmp),
2583 DMT::GetRawHostPtr(*
Rtmp),
2584 DMT::GetStride(*
Rtmp),
2589 GCRODRSolMgrLAPACKFailure,
2590 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GETRF failed.");
2593 work_.resize(
lwork);
2595 lapack.GETRI(DMT::GetNumRows(*
Rtmp),
2596 DMT::GetRawHostPtr(*
Rtmp),
2597 DMT::GetStride(*
Rtmp),
2602 GCRODRSolMgrLAPACKFailure,
2603 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GETRI failed.");
2605 DMT::SyncHostToDevice(*R_);
2611 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst(*U_, index);
2612 Teuchos::RCP<const MV>
U1tmpConst = MVT::CloneView(*U1_, index);
2615 Teuchos::RCP<MV>
Wtmp = MVT::CloneViewNonConst(*W_, index);
2616 Teuchos::RCP<const MV>
W1tmpConst = MVT::CloneView(*W1_, index);
2624 Teuchos::RCP<DM>
b1 = DMT::Subview(*H2_, recycledBlocks_+2, 1, 0, recycledBlocks_);
2625 DMT::PutScalar(*
b1,
zero);
2631template<
class ScalarType,
class MV,
class OP,
class DM>
2632int GCRODRSolMgr<ScalarType,MV,OP,DM,true>::getHarmonicVecs1(
int m,
const DM& HH, DM& PP) {
2639 std::vector<MagnitudeType>
wr(
m),
wi(
m);
2642 Teuchos::RCP<DM>
vr = DMT::Create(
m,
m,
false);
2645 std::vector<MagnitudeType>
w(
m);
2648 std::vector<int>
iperm(
m);
2654 builtRecycleSpace_ =
true;
2657 Teuchos::RCP<DM>
HHt = DMT::CreateCopy(
HH,
true );
2658 Teuchos::RCP<DM>
e_m = DMT::Create(
m, 1 );
2659 DMT::SyncDeviceToHost( *
HHt );
2661 DMT::Value( *
e_m,
m-1, 0 ) =
one;
2662 lapack.GESV(
m, 1, DMT::GetRawHostPtr(*
HHt), DMT::GetStride(*
HHt), &
iperm[0], DMT::GetRawHostPtr(*
e_m), DMT::GetStride(*
e_m), &
info);
2666 Teuchos::RCP<DM>
tmpHH = DMT::CreateCopy(
HH );
2667 DMT::SyncDeviceToHost( *
tmpHH );
2671 for(
i=0;
i<
m; ++
i )
2672 DMT::Value(*
harmHH,
i,
m-1) +=
d * DMT::ValueConst(*
e_m,
i, 0);
2681 std::vector<ScalarType>
work(1);
2682 std::vector<MagnitudeType>
rwork(2*
m);
2685 lapack.GEEV(
'N',
'V',
m, DMT::GetRawHostPtr(*
harmHH), DMT::GetStride(*
harmHH), &
wr[0], &
wi[0],
2688 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (
work[0])));
2691 lapack.GEEV(
'N',
'V',
m, DMT::GetRawHostPtr(*
harmHH), DMT::GetStride(*
harmHH), &
wr[0], &
wi[0],
2696 for(
i=0;
i<
m; ++
i )
2697 w[
i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot(
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i] );
2705 for(
i=0;
i<recycledBlocks_; ++
i ) {
2706 for(
j=0;
j<
m;
j++ ) {
2714 if (
wi[
iperm[recycledBlocks_-1]] != 0.0) {
2716 for (
i=0;
i<recycledBlocks_; ++
i ) {
2726 if (
wi[
iperm[recycledBlocks_-1]] > 0.0) {
2727 for(
j=0;
j<
m; ++
j ) {
2728 DMT::Value(
PP,
j,recycledBlocks_) = DMT::ValueConst(*
vr,
j,
iperm[recycledBlocks_-1]+1);
2732 for(
j=0;
j<
m; ++
j ) {
2733 DMT::Value(
PP,
j,recycledBlocks_) = DMT::ValueConst(*
vr,
j,
iperm[recycledBlocks_-1]-1);
2742 return recycledBlocks_+1;
2745 return recycledBlocks_;
2751template<
class ScalarType,
class MV,
class OP,
class DM>
2752int GCRODRSolMgr<ScalarType,MV,OP,DM,true>::getHarmonicVecs2(
int keffloc,
int m,
2754 const Teuchos::RCP<const MV>& VV,
2757 int m2 = DMT::GetNumCols(
HH);
2761 std::vector<int> index;
2764 std::vector<MagnitudeType>
wr(
m2),
wi(
m2);
2767 std::vector<MagnitudeType>
w(
m2);
2770 Teuchos::RCP<DM>
vr = DMT::Create(
m2,
m2,
false);
2776 builtRecycleSpace_ =
true;
2781 Teuchos::RCP<DM> B = DMT::Create(
m2,
m2,
false);
2783 Teuchos::BLAS<int,ScalarType>
blas;
2784 blas.GEMM( Teuchos::TRANS, Teuchos::NO_TRANS,
m2,
m2, DMT::GetNumRows(
HH),
one,
2785 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2786 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2787 zero, DMT::GetRawHostPtr(*B), DMT::GetStride(*B));
2796 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView( *C_, index );
2797 Teuchos::RCP<const MV>
Utmp = MVT::CloneView( *U_, index );
2804 for (
i=0;
i <
m+1;
i++) { index[
i] =
i; }
2805 Teuchos::RCP<const MV>
Vp = MVT::CloneView( *
VV, index );
2808 A11 = Teuchos::null;
2809 A21 = Teuchos::null;
2810 DMT::SyncDeviceToHost(*
A_tmp);
2818 Teuchos::RCP<DM>
A = DMT::Create(
m2, DMT::GetNumCols(*
A_tmp) );
2819 blas.GEMM( Teuchos::TRANS, Teuchos::NO_TRANS,
m2, DMT::GetNumCols(*
A_tmp), DMT::GetNumRows(*
A_tmp),
2820 one, DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2821 DMT::GetConstRawHostPtr(*
A_tmp), DMT::GetStride(*
A_tmp),
2822 zero, DMT::GetRawHostPtr(*
A), DMT::GetStride(*
A) );
2831 int ld = DMT::GetNumRows(*
A);
2837 std::vector<ScalarType> beta(
ld);
2848 ld, &
wr[0], &
wi[0], &beta[0],
vl,
ldvl, DMT::GetRawHostPtr(*
vr),
ldvr, &
ilo, &
ihi,
2851 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GGEVX failed to compute eigensolutions.");
2855 for(
i=0;
i<
ld;
i++ ) {
2856 w[
i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot (
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i]) /
2857 Teuchos::ScalarTraits<ScalarType>::magnitude (beta[
i]);
2866 for(
i=0;
i<recycledBlocks_;
i++ ) {
2867 for(
j=0;
j<
ld;
j++ ) {
2868 DMT::Value(
PP,
j,
i) = DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_+
i]);
2875 if (
wi[
iperm[
ld-recycledBlocks_]] != 0.0) {
2877 for (
i=
ld-recycledBlocks_;
i<
ld;
i++ ) {
2887 if (
wi[
iperm[
ld-recycledBlocks_]] > 0.0) {
2888 for(
j=0;
j<
ld;
j++ ) {
2889 DMT::Value(
PP,
j,recycledBlocks_) = DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_]+1);
2893 for(
j=0;
j<
ld;
j++ ) {
2894 DMT::Value(
PP,
j,recycledBlocks_) = DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_]-1);
2903 return recycledBlocks_+1;
2906 return recycledBlocks_;
2920template<
class ScalarType,
class MV,
class OP,
class DM>
2922GCRODRSolMgr<ScalarType,MV,OP,DM,true>::
2923getFlexibleHarmonicVecs2(
int keffloc,
int m,
2925 const Teuchos::RCP<const MV>& VV,
2929 int m2 = DMT::GetNumCols(
HH);
2935 std::vector<int> index;
2937 std::vector<MagnitudeType>
wr(
m2),
wi(
m2);
2938 std::vector<MagnitudeType>
w(
m2);
2940 Teuchos::RCP<DM>
vr = DMT::Create(
m2,
m2,
false);
2944 builtRecycleSpace_ =
true;
2947 Teuchos::RCP<DM> B = DMT::Create(
m2,
m2,
false);
2949 Teuchos::BLAS<int,ScalarType>
blas;
2950 blas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
2951 m2,
m2, DMT::GetNumRows(
HH),
2953 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2954 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2956 DMT::GetRawHostPtr(*B), DMT::GetStride(*B));
2966 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView(*C_, index);
2967 Teuchos::RCP<const MV>
Wtmp = MVT::CloneView(*W_, index);
2976 for (
i=0;
i<
m+1; ++
i) index[
i] =
i;
2978 Teuchos::RCP<const MV>
Vp = MVT::CloneView(*
VV, index);
2983 Wtmp = MVT::CloneView(*W_, index);
2987 A11 = Teuchos::null;
2988 A21 = Teuchos::null;
2990 DMT::SyncDeviceToHost(*
A_tmp);
2993 for (
i=0;
i<
m; ++
i) {
2998 Teuchos::RCP<DM>
A = DMT::Create(
m2, DMT::GetNumCols(*
A_tmp));
3000 blas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
3003 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
3004 DMT::GetConstRawHostPtr(*
A_tmp), DMT::GetStride(*
A_tmp),
3006 DMT::GetRawHostPtr(*
A), DMT::GetStride(*
A));
3010 int ld = DMT::GetNumRows(*
A);
3018 std::vector<ScalarType> beta(
ld);
3027 DMT::GetRawHostPtr(*
A),
ld,
3028 DMT::GetRawHostPtr(*B),
ld,
3029 &
wr[0], &
wi[0], &beta[0],
3031 DMT::GetRawHostPtr(*
vr),
ldvr,
3041 GCRODRSolMgrLAPACKFailure,
3042 "Belos::GCRODRSolMgr::getFlexibleHarmonicVecs2(): LAPACK GGEVX failed to compute eigensolutions.");
3044 for (
i=0;
i<
ld; ++
i) {
3046 Teuchos::ScalarTraits<MagnitudeType>::squareroot(
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i]) /
3047 Teuchos::ScalarTraits<ScalarType>::magnitude(beta[
i]);
3054 for (
i=0;
i<recycledBlocks_; ++
i) {
3055 for (
j=0;
j<
ld; ++
j) {
3056 DMT::Value(
PP,
j,
i) =
3057 DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_+
i]);
3062 if (
wi[
iperm[
ld-recycledBlocks_]] != 0.0) {
3064 for (
i=
ld-recycledBlocks_;
i<
ld; ++
i) {
3076 if (
wi[
iperm[
ld-recycledBlocks_]] > 0.0) {
3077 for (
j=0;
j<
ld; ++
j) {
3078 DMT::Value(
PP,
j, recycledBlocks_) =
3079 DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_]+1);
3083 for (
j=0;
j<
ld; ++
j) {
3084 DMT::Value(
PP,
j, recycledBlocks_) =
3085 DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_]-1);
3092 return recycledBlocks_ + 1;
3095 return recycledBlocks_;
3101template<
class ScalarType,
class MV,
class OP,
class DM>
3102void GCRODRSolMgr<ScalarType,MV,OP,DM,true>::sort(std::vector<MagnitudeType>& dlist,
int n, std::vector<int>& iperm) {
3105 MagnitudeType
dRR,
dK;
3166template<
class ScalarType,
class MV,
class OP,
class DM>
3168 std::ostringstream
out;
3169 out <<
"Belos::GCRODRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
3171 out <<
"Ortho Type: \"" << orthoType_ <<
"\"";
3172 out <<
", Flexible: " << (isFlexible_ ?
"true" :
"false");
3173 out <<
", Num Blocks: " <<numBlocks_;
3174 out <<
", Num Recycle Blocks: " << recycledBlocks_;
3175 out <<
", Max Restarts: " << maxRestarts_;
3182#ifdef HAVE_BELOS_TPETRA
3185#define BELOS_TPETRA_GCRODRSOLMGR_NOEXTERN_CALL(SC, LO, GO, NT) \
3186 BELOS_TPETRA_CALL(Belos::GCRODRSolMgr, SC, LO, GO, NT)
3188#define BELOS_TPETRA_GCRODRSOLMGR_EXTERN_CALL(SC, LO, GO, NT) \
3189 BELOS_TPETRA_EXTERN_CALL(Belos::GCRODRSolMgr, SC, LO, GO, NT)
3191TPETRA_INSTANTIATE_SLGN_NO_ORDINAL_SCALAR(BELOS_TPETRA_GCRODRSOLMGR_EXTERN_CALL)
Belos header file which uses auto-configuration information to include necessary C++ headers.
Belos concrete class for performing the flexible GCRO-DR iteration.
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...
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
virtual ~GCRODRSolMgr()
Destructor.
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const override
Get current linear problem being solved for in this object.
void setDebugStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &debugStatusTest) override
Set a debug status test, OR-combined into the top-level status test.
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
Get a parameter list containing the current parameters for this object.
bool isLOADetected() const override
Return whether a loss of accuracy was detected by this solver during the most current solve.
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
Teuchos::RCP< SolverManager< ScalarType, MV, OP, DM > > clone() const override
clone for Inverted Injection (DII)
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &problem) override
Set the linear problem that needs to be solved.
int getNumIters() const override
Get the iteration count for the most recent call to solve().
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
Implementation of the GCRODR (Recycling GMRES) iterative linear solver.
GCRODRSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &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.