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_);
339 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> &
params )
override;
351 bool set = problem_->setProblem();
353 throw "Could not set problem.";
397 std::string description()
const override;
407 void initializeStateStorage();
414 void computeGCRODRResidual();
416 void updateSolutionWithUpdate(
const Teuchos::RCP<MV>&
update);
422 int getHarmonicVecs1(
int m,
const DM&
HH, DM&
PP);
429 int getHarmonicVecs2(
int keff,
int m,
const DM&
HH,
430 const Teuchos::RCP<const MV>&
VV, DM&
PP);
432 int getFlexibleHarmonicVecs2(
int keff,
int m,
const DM&
HH,
433 const Teuchos::RCP<const MV>&
VV, DM&
PP);
436 void sort(std::vector<MagnitudeType>&
dlist,
int n, std::vector<int>&
iperm);
439 Teuchos::LAPACK<int,ScalarType> lapack;
442 Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > problem_;
445 Teuchos::RCP<OutputManager<ScalarType> > printer_;
446 Teuchos::RCP<std::ostream> outputStream_;
449 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > sTest_;
450 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP,DM> > maxIterTest_;
451 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > convTest_;
452 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP,DM> > expConvTest_, impConvTest_;
453 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP,DM> > outputTest_;
458 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > ortho_;
461 Teuchos::RCP<Teuchos::ParameterList> params_;
464 static constexpr double orthoKappa_default_ = 0.0;
465 static constexpr int maxRestarts_default_ = 100;
466 static constexpr int maxIters_default_ = 1000;
467 static constexpr int numBlocks_default_ = 50;
468 static constexpr int blockSize_default_ = 1;
469 static constexpr int recycledBlocks_default_ = 5;
470 static constexpr bool flexibleGCRODR_default_ =
false;
473 static constexpr int outputFreq_default_ = -1;
474 static constexpr const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
475 static constexpr const char * expResScale_default_ =
"Norm of Initial Residual";
476 static constexpr const char * label_default_ =
"Belos";
477 static constexpr const char * orthoType_default_ =
"ICGS";
480 MagnitudeType convTol_, orthoKappa_, achievedTol_;
481 int maxRestarts_, maxIters_, numIters_;
482 int verbosity_, outputStyle_, outputFreq_;
484 std::string orthoType_;
485 std::string impResScale_, expResScale_;
492 int numBlocks_, recycledBlocks_;
505 Teuchos::RCP<MV> U_, C_;
507 Teuchos::RCP<MV> W_, W1_;
510 Teuchos::RCP<MV> U1_, C1_;
513 Teuchos::RCP<DM> H2_;
515 Teuchos::RCP<DM> PP_;
516 Teuchos::RCP<DM> HP_;
517 std::vector<ScalarType> tau_;
518 std::vector<ScalarType> work_;
520 std::vector<int> ipiv_;
525 Teuchos::RCP<Teuchos::Time> timerSolve_;
531 bool builtRecycleSpace_;
536template<
class ScalarType,
class MV,
class OP,
class DM>
546template<
class ScalarType,
class MV,
class OP,
class DM>
549 const Teuchos::RCP<Teuchos::ParameterList>&
pl):
558 problem == Teuchos::null, std::invalid_argument,
559 "Belos::GCRODRSolMgr constructor: The solver manager's "
560 "constructor needs the linear problem argument 'problem' "
569 if (!
pl.is_null ()) {
575template<
class ScalarType,
class MV,
class OP,
class DM>
577 outputStream_ = Teuchos::rcpFromRef(std::cout);
579 orthoKappa_ = orthoKappa_default_;
580 maxRestarts_ = maxRestarts_default_;
581 maxIters_ = maxIters_default_;
582 numBlocks_ = numBlocks_default_;
583 recycledBlocks_ = recycledBlocks_default_;
584 verbosity_ = verbosity_default_;
585 outputStyle_ = outputStyle_default_;
586 outputFreq_ = outputFreq_default_;
587 isFlexible_ = flexibleGCRODR_default_;
588 orthoType_ = orthoType_default_;
589 impResScale_ = impResScale_default_;
590 expResScale_ = expResScale_default_;
591 label_ = label_default_;
593 builtRecycleSpace_ =
false;
611template<
class ScalarType,
class MV,
class OP,
class DM>
615 using Teuchos::isParameterType;
616 using Teuchos::getParameter;
618 using Teuchos::ParameterList;
619 using Teuchos::parameterList;
622 using Teuchos::rcp_dynamic_cast;
623 using Teuchos::rcpFromRef;
624 using Teuchos::Exceptions::InvalidParameter;
625 using Teuchos::Exceptions::InvalidParameterName;
626 using Teuchos::Exceptions::InvalidParameterType;
648 if (params_.is_null()) {
702 if (
params->isParameter (
"Maximum Restarts")) {
703 maxRestarts_ =
params->get(
"Maximum Restarts", maxRestarts_default_);
706 params_->set (
"Maximum Restarts", maxRestarts_);
710 if (
params->isParameter (
"Maximum Iterations")) {
711 maxIters_ =
params->get (
"Maximum Iterations", maxIters_default_);
714 params_->set (
"Maximum Iterations", maxIters_);
715 if (! maxIterTest_.is_null())
716 maxIterTest_->setMaxIters (maxIters_);
720 if (
params->isParameter (
"Num Blocks")) {
721 numBlocks_ =
params->get (
"Num Blocks", numBlocks_default_);
723 "Belos::GCRODRSolMgr: The \"Num Blocks\" parameter must "
724 "be strictly positive, but you specified a value of "
725 << numBlocks_ <<
".");
727 params_->set (
"Num Blocks", numBlocks_);
731 if (
params->isParameter (
"Num Recycled Blocks")) {
732 recycledBlocks_ =
params->get (
"Num Recycled Blocks",
733 recycledBlocks_default_);
735 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
736 "parameter must be strictly positive, but you specified "
737 "a value of " << recycledBlocks_ <<
".");
739 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
740 "parameter must be less than the \"Num Blocks\" "
741 "parameter, but you specified \"Num Recycled Blocks\" "
742 "= " << recycledBlocks_ <<
" and \"Num Blocks\" = "
743 << numBlocks_ <<
".");
745 params_->set(
"Num Recycled Blocks", recycledBlocks_);
748 if (
params->isParameter(
"Flexible GCRODR")) {
750 params->get(
"Flexible GCRODR", flexibleGCRODR_default_);
758 params_->set(
"Flexible GCRODR", isFlexible_);
764 if (
params->isParameter (
"Timer Label")) {
770 params_->set (
"Timer Label", label_);
771 std::string
solveLabel = label_ +
": GCRODRSolMgr total solve time";
772#ifdef BELOS_TEUCHOS_TIME_MONITOR
773 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (
solveLabel);
775 if (ortho_ != Teuchos::null) {
776 ortho_->setLabel( label_ );
782 if (
params->isParameter (
"Verbosity")) {
784 verbosity_ =
params->get (
"Verbosity", verbosity_default_);
789 params_->set (
"Verbosity", verbosity_);
792 if (! printer_.is_null())
793 printer_->setVerbosity (verbosity_);
797 if (
params->isParameter (
"Output Style")) {
799 outputStyle_ =
params->get (
"Output Style", outputStyle_default_);
805 params_->set (
"Output Style", outputStyle_);
823 if (
params->isParameter (
"Output Stream")) {
834 if (outputStream_.is_null()) {
835 outputStream_ =
rcp (
new Teuchos::oblackholestream);
838 params_->set (
"Output Stream", outputStream_);
841 if (! printer_.is_null()) {
842 printer_->setOStream (outputStream_);
848 if (
params->isParameter (
"Output Frequency")) {
849 outputFreq_ =
params->get (
"Output Frequency", outputFreq_default_);
853 params_->set(
"Output Frequency", outputFreq_);
854 if (! outputTest_.is_null())
855 outputTest_->setOutputFrequency (outputFreq_);
862 if (printer_.is_null()) {
874 if (
params->isParameter (
"Orthogonalization")) {
876 params->get (
"Orthogonalization", orthoType_default_);
879 std::ostringstream
os;
880 os <<
"Belos::GCRODRSolMgr: Invalid orthogonalization name \""
882 <<
"for the \"Orthogonalization\" name parameter: ";
884 throw std::invalid_argument (
os.str());
890 params_->set (
"Orthogonalization", orthoType_);
909 using Teuchos::sublist;
911 const std::string
paramName (
"Orthogonalization Parameters");
926 "Failed to get orthogonalization parameters. "
927 "Please report this bug to the Belos developers.");
937 ortho_ =
factory.makeMatOrthoManager (orthoType_,
null, printer_,
946 typedef Teuchos::ParameterListAcceptor
PLA;
952 ortho_ =
factory.makeMatOrthoManager (orthoType_,
null, printer_,
967 if (
params->isParameter (
"Orthogonalization Constant")) {
968 MagnitudeType orthoKappa = orthoKappa_default_;
969 if (
params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
970 orthoKappa =
params->get (
"Orthogonalization Constant", orthoKappa);
973 orthoKappa =
params->get (
"Orthogonalization Constant", orthoKappa_default_);
976 if (orthoKappa > 0) {
977 orthoKappa_ = orthoKappa;
979 params_->set(
"Orthogonalization Constant", orthoKappa_);
981 if (orthoType_ ==
"DGKS" && ! ortho_.is_null()) {
998 if (
params->isParameter(
"Convergence Tolerance")) {
999 if (
params->isType<MagnitudeType> (
"Convergence Tolerance")) {
1000 convTol_ =
params->get (
"Convergence Tolerance",
1008 params_->set (
"Convergence Tolerance", convTol_);
1009 if (! impConvTest_.is_null())
1010 impConvTest_->setTolerance (convTol_);
1011 if (! expConvTest_.is_null())
1012 expConvTest_->setTolerance (convTol_);
1016 if (
params->isParameter (
"Implicit Residual Scaling")) {
1026 params_->set(
"Implicit Residual Scaling", impResScale_);
1036 if (! impConvTest_.is_null()) {
1042 impConvTest_ =
null;
1049 if (
params->isParameter(
"Explicit Residual Scaling")) {
1059 params_->set(
"Explicit Residual Scaling", expResScale_);
1062 if (! expConvTest_.is_null()) {
1068 expConvTest_ =
null;
1079 if (maxIterTest_.is_null())
1089 if (impConvTest_.is_null()) {
1090 impConvTest_ =
rcp (
new StatusTestResNorm_t (convTol_));
1095 expConvTest_ = impConvTest_;
1096 convTest_ = impConvTest_;
1101 if (impConvTest_.is_null()) {
1102 impConvTest_ =
rcp (
new StatusTestResNorm_t (convTol_));
1108 if (expConvTest_.is_null()) {
1109 expConvTest_ =
rcp (
new StatusTestResNorm_t (convTol_));
1110 expConvTest_->defineResForm (StatusTestResNorm_t::Explicit,
Belos::TwoNorm);
1117 if (convTest_.is_null()) {
1118 convTest_ =
rcp (
new StatusTestCombo_t (StatusTestCombo_t::SEQ,
1127 sTest_ =
rcp (
new StatusTestCombo_t (StatusTestCombo_t::OR,
1133 outputTest_ =
stoFactory.create (printer_, sTest_, outputFreq_,
1143 if (timerSolve_.is_null()) {
1144 std::string
solveLabel = label_ +
": GCRODRSolMgr total solve time";
1145#ifdef BELOS_TEUCHOS_TIME_MONITOR
1146 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
1155template<
class ScalarType,
class MV,
class OP,
class DM>
1156Teuchos::RCP<const Teuchos::ParameterList>
1159 using Teuchos::ParameterList;
1160 using Teuchos::parameterList;
1169 "The relative residual tolerance that needs to be achieved by the\n"
1170 "iterative solver in order for the linear system to be declared converged.");
1171 pl->set(
"Maximum Restarts",
static_cast<int>(maxRestarts_default_),
1172 "The maximum number of cycles allowed for each\n"
1173 "set of RHS solved.");
1174 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
1175 "The maximum number of iterations allowed for each\n"
1176 "set of RHS solved.");
1180 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
1181 "Block Size Parameter -- currently must be 1 for GCRODR");
1182 pl->set(
"Num Blocks",
static_cast<int>(numBlocks_default_),
1183 "The maximum number of vectors allowed in the Krylov subspace\n"
1184 "for each set of RHS solved.");
1185 pl->set(
"Num Recycled Blocks",
static_cast<int>(recycledBlocks_default_),
1186 "The maximum number of vectors in the recycled subspace." );
1187 pl->set(
"Flexible GCRODR",
static_cast<bool>(flexibleGCRODR_default_),
1188 "Whether to use the flexible variant of GCRODR. The flexible variant stores the right-preconditioned correction basis Z.");
1189 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
1190 "What type(s) of solver information should be outputted\n"
1191 "to the output stream.");
1192 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
1193 "What style is used for the solver information outputted\n"
1194 "to the output stream.");
1195 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
1196 "How often convergence information should be outputted\n"
1197 "to the output stream.");
1198 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
1199 "A reference-counted pointer to the output stream where all\n"
1200 "solver output is sent.");
1201 pl->set(
"Implicit Residual Scaling",
static_cast<const char *
>(impResScale_default_),
1202 "The type of scaling used in the implicit residual convergence test.");
1203 pl->set(
"Explicit Residual Scaling",
static_cast<const char *
>(expResScale_default_),
1204 "The type of scaling used in the explicit residual convergence test.");
1205 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
1206 "The string to use as a prefix for the timer labels.");
1209 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
1210 "The type of orthogonalization to use. Valid options: " +
1213 factory.getDefaultParameters (orthoType_default_);
1215 "Parameters specific to the type of orthogonalization used.");
1217 pl->set(
"Orthogonalization Constant",
static_cast<MagnitudeType
>(orthoKappa_default_),
1218 "When using DGKS orthogonalization: the \"depTol\" constant, used "
1219 "to determine whether another step of classical Gram-Schmidt is "
1220 "necessary. Otherwise ignored.");
1227template<
class ScalarType,
class MV,
class OP,
class DM>
1233 Teuchos::RCP<const MV>
rhsMV = problem_->getRHS();
1234 if (
rhsMV == Teuchos::null) {
1242 "Belos::GCRODRSolMgr::initializeStateStorage(): Cannot generate a Krylov basis with dimension larger the operator!");
1245 if (U_ == Teuchos::null) {
1246 U_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1250 if (MVT::GetNumberVecs(*U_) < recycledBlocks_+1) {
1251 Teuchos::RCP<const MV>
tmp = U_;
1252 U_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1257 if (C_ == Teuchos::null) {
1258 C_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1262 if (MVT::GetNumberVecs(*C_) < recycledBlocks_+1) {
1263 Teuchos::RCP<const MV>
tmp = C_;
1264 C_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1269 if (V_ == Teuchos::null) {
1270 V_ = MVT::Clone( *
rhsMV, numBlocks_+1 );
1274 if (MVT::GetNumberVecs(*V_) < numBlocks_+1) {
1275 Teuchos::RCP<const MV>
tmp = V_;
1276 V_ = MVT::Clone( *
tmp, numBlocks_+1 );
1281 if (U1_ == Teuchos::null) {
1282 U1_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1286 if (MVT::GetNumberVecs(*U1_) < recycledBlocks_+1) {
1287 Teuchos::RCP<const MV>
tmp = U1_;
1288 U1_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1293 if (C1_ == Teuchos::null) {
1294 C1_ = MVT::Clone( *
rhsMV, recycledBlocks_+1 );
1298 if (MVT::GetNumberVecs(*C1_) < recycledBlocks_+1) {
1299 Teuchos::RCP<const MV>
tmp = C1_;
1300 C1_ = MVT::Clone( *
tmp, recycledBlocks_+1 );
1306 if (Z_ == Teuchos::null) {
1307 Z_ = MVT::Clone(*
rhsMV, numBlocks_+1);
1310 if (MVT::GetNumberVecs(*Z_) < numBlocks_+1) {
1311 Teuchos::RCP<const MV>
tmp = Z_;
1312 Z_ = MVT::Clone(*
tmp, numBlocks_+1);
1316 if (W_ == Teuchos::null) {
1317 W_ = MVT::Clone(*
rhsMV, recycledBlocks_+1);
1320 if (MVT::GetNumberVecs(*W_) < recycledBlocks_+1) {
1321 Teuchos::RCP<const MV>
tmp = W_;
1322 W_ = MVT::Clone(*
tmp, recycledBlocks_+1);
1326 if (W1_ == Teuchos::null) {
1327 W1_ = MVT::Clone(*
rhsMV, recycledBlocks_+1);
1330 if (MVT::GetNumberVecs(*W1_) < recycledBlocks_+1) {
1331 Teuchos::RCP<const MV>
tmp = W1_;
1332 W1_ = MVT::Clone(*
tmp, recycledBlocks_+1);
1338 if (r_ == Teuchos::null)
1339 r_ = MVT::Clone( *
rhsMV, 1 );
1342 tau_.resize(recycledBlocks_+1);
1345 work_.resize(recycledBlocks_+1);
1348 ipiv_.resize(recycledBlocks_+1);
1351 if (H2_ == Teuchos::null)
1352 H2_ = DMT::Create( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1354 if ( (DMT::GetNumRows(*H2_) != numBlocks_+recycledBlocks_+2) || (DMT::GetNumCols(*H2_) != numBlocks_+recycledBlocks_+1) )
1355 DMT::Reshape( *H2_, numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1357 DMT::PutScalar(*H2_,
zero);
1360 if (R_ == Teuchos::null)
1361 R_ = DMT::Create( recycledBlocks_+1, recycledBlocks_+1 );
1363 if ( (DMT::GetNumRows(*R_) != recycledBlocks_+1) || (DMT::GetNumCols(*R_) != recycledBlocks_+1) )
1364 DMT::Reshape( *R_, recycledBlocks_+1, recycledBlocks_+1 );
1366 DMT::PutScalar(*R_,
zero);
1369 if (PP_ == Teuchos::null)
1370 PP_ = DMT::Create( numBlocks_+recycledBlocks_+2, recycledBlocks_+1 );
1372 if ( (DMT::GetNumRows(*PP_) != numBlocks_+recycledBlocks_+2) || (DMT::GetNumCols(*PP_) != recycledBlocks_+1) )
1373 DMT::Reshape( *PP_, numBlocks_+recycledBlocks_+2, recycledBlocks_+1 );
1377 if (HP_ == Teuchos::null)
1378 HP_ = DMT::Create( numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1380 if ( (DMT::GetNumRows(*HP_) != numBlocks_+recycledBlocks_+2) || (DMT::GetNumCols(*HP_) != numBlocks_+recycledBlocks_+1) )
1381 DMT::Reshape( *HP_, numBlocks_+recycledBlocks_+2, numBlocks_+recycledBlocks_+1 );
1389template<
class ScalarType,
class MV,
class OP,
class DM>
1391GCRODRSolMgr<ScalarType,MV,OP,DM,true>::computeGCRODRResidual()
1394 problem_->computeCurrResVec(&*r_);
1397 problem_->computeCurrPrecResVec(&*r_);
1401template<
class ScalarType,
class MV,
class OP,
class DM>
1403GCRODRSolMgr<ScalarType,MV,OP,DM,true>::
1404updateSolutionWithUpdate(
const Teuchos::RCP<MV>& update)
1406 if (
update == Teuchos::null) {
1413 Teuchos::RCP<MV>
curX = problem_->getCurrLHSVec();
1417 problem_->updateSolution(
update,
true);
1423template<
class ScalarType,
class MV,
class OP,
class DM>
1433 if (!isSet_) { setParameters( params_ ); }
1437 std::vector<int> index(numBlocks_+1);
1445 !Teuchos::is_null(problem_->getLeftPrec()),
1447 "Belos::GCRODRSolMgr::solve(): Flexible GCRODR does not support left preconditioning; use no preconditioner or a right preconditioner.");
1451 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1456 problem_->setLSIndex(
currIdx );
1459 ptrdiff_t dim = MVT::GetGlobalLength( *(problem_->getRHS()) );
1461 numBlocks_ = Teuchos::as<int>(
dim);
1463 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1464 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1465 params_->set(
"Num Blocks", numBlocks_);
1472 initializeStateStorage();
1476 Teuchos::ParameterList
plist;
1478 plist.set(
"Num Blocks",numBlocks_);
1479 plist.set(
"Recycled Blocks",recycledBlocks_);
1496#ifdef BELOS_TEUCHOS_TIME_MONITOR
1497 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
1503 builtRecycleSpace_ =
false;
1506 outputTest_->reset();
1514 "Belos::GCRODRSolMgr::solve(): Requested size of recycled subspace is not consistent with the current recycle subspace.");
1516 printer_->stream(
Debug) <<
" Now solving RHS index " <<
currIdx[0] <<
" using recycled subspace of dimension " << keff << std::endl << std::endl;
1519 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1521 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1533 Teuchos::RCP<DM>
Rtmp = DMT::Subview( *R_, keff, keff );
1539 DMT::SyncDeviceToHost(*R_);
1544 ipiv_.resize(DMT::GetNumRows(*
Rtmp));
1545 lapack.GETRF(DMT::GetNumRows(*
Rtmp), DMT::GetNumCols(*
Rtmp), DMT::GetRawHostPtr(*
Rtmp), DMT::GetStride(*
Rtmp), &ipiv_[0], &
info);
1550 work_.resize(
lwork);
1551 lapack.GETRI(DMT::GetNumRows(*
Rtmp), DMT::GetRawHostPtr(*
Rtmp), DMT::GetStride(*
Rtmp), &ipiv_[0], &work_[0],
lwork, &
info);
1554 DMT::SyncHostToDevice(*R_);
1559 Teuchos::RCP<const MV>
Wtmp = MVT::CloneView(*W_, index);
1560 Teuchos::RCP<MV>
W1tmp = MVT::CloneViewNonConst(*W1_, index);
1568 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1569 Ctmp = MVT::CloneViewNonConst( *C_, index );
1570 Utmp = MVT::CloneView( *U_, index );
1573 Teuchos::RCP<DM>
Ctr = DMT::Create(keff, 1);
1574 computeGCRODRResidual();
1578 RCP<MV> update = MVT::Clone( *problem_->getCurrLHSVec(), 1 );
1579 MVT::MvInit( *
update, 0.0 );
1581 updateSolutionWithUpdate(
update);
1593 printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " <<
currIdx[0] << std::endl << std::endl;
1597 primeList.set(
"Recycled Blocks",recycledBlocks_);
1609 computeGCRODRResidual();
1610 index.resize( 1 ); index[0] = 0;
1611 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1612 MVT::SetBlock(*r_,index,*
v0);
1616 index.resize( numBlocks_+1 );
1617 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1618 newstate.V = MVT::CloneViewNonConst( *V_, index );
1619 if (isFlexible_)
newstate.Z = MVT::CloneViewNonConst( *Z_, index );
1632 if ( convTest_->getStatus() ==
Passed ) {
1643 if (convTest_->getStatus() ==
Passed)
1649 achievedTol_ = MT::one();
1650 Teuchos::RCP<MV>
X = problem_->getLHS();
1651 MVT::MvInit( *
X, SCT::zero() );
1652 printer_->stream(
Warnings) <<
"Belos::GCRODRSolMgr::solve(): Warning! NaN has been detected!"
1656 catch (
const std::exception &
e) {
1658 printer_->stream(
Errors) <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
1660 <<
e.what() << std::endl;
1668 updateSolutionWithUpdate(
update);
1679 if (recycledBlocks_ <
p+1) {
1683 DMT::SyncDeviceToHost( *H2_ );
1684 DMT::SyncDeviceToHost( *PP_ );
1691 DMT::SyncHostToDevice( *PP_ );
1693 PPtmp = DMT::Subview( *PP_,
p, keff );
1697 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1698 RCP<MV> Ctmp = MVT::CloneViewNonConst( *C_, index );
1699 RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
1711 std::vector<int>
wind(keff);
1725 DMT::SyncDeviceToHost( *HP_ );
1727 RCP<DM> Htmp = DMT::Subview( *H2_,
p+1,
p, recycledBlocks_+1,recycledBlocks_+1 );
1730 Teuchos::BLAS<int,ScalarType>
blas;
1731 blas.GEMM( Teuchos::NO_TRANS, Teuchos::NO_TRANS,
p+1, keff,
p,
one,
1732 DMT::GetConstRawHostPtr(*
Htmp), DMT::GetStride(*
Htmp),
1733 DMT::GetConstRawHostPtr(*
PPtmp), DMT::GetStride(*
PPtmp),
1741 lapack.GEQRF (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetRawHostPtr(*
HPtmp),
1745 " LAPACK's _GEQRF failed to compute a workspace size.");
1753 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
1754 work_.resize (
lwork);
1755 lapack.GEQRF (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetRawHostPtr(*
HPtmp),
1759 " LAPACK's _GEQRF failed to compute a QR factorization.");
1764 DMT::SyncDeviceToHost( *R_ );
1766 for (
int ii = 0;
ii < keff; ++
ii) {
1767 for (
int jj =
ii;
jj < keff; ++
jj) {
1771 DMT::SyncHostToDevice( *R_ );
1776 lapack.UNGQR (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetNumCols(*
HPtmp),
1777 DMT::GetRawHostPtr(*
HPtmp), DMT::GetStride(*
HPtmp), &tau_[0], &work_[0],
1781 "LAPACK's _UNGQR failed to construct the Q factor.");
1785 DMT::SyncHostToDevice( *HP_ );
1788 index.resize (
p + 1);
1789 for (
int ii = 0;
ii < (
p+1); ++
ii) {
1792 Vtmp = MVT::CloneView( *V_, index );
1800 ipiv_.resize(DMT::GetNumRows(*
Rtmp));
1801 lapack.GETRF(DMT::GetNumRows(*
Rtmp), DMT::GetNumCols(*
Rtmp), DMT::GetRawHostPtr(*
Rtmp),
1802 DMT::GetStride(*
Rtmp), &ipiv_[0], &
info);
1805 "LAPACK's _GETRF failed to compute an LU factorization.");
1815 work_.resize(
lwork);
1816 lapack.GETRI(DMT::GetNumRows(*
Rtmp), DMT::GetRawHostPtr(*
Rtmp), DMT::GetStride(*
Rtmp),
1820 "LAPACK's _GETRI failed to invert triangular matrix.");
1822 DMT::SyncHostToDevice( *R_ );
1827 std::vector<int>
wind(keff);
1834 printer_->stream(
Debug)
1835 <<
" Generated recycled subspace using RHS index " <<
currIdx[0]
1836 <<
" of dimension " << keff << std::endl << std::endl;
1843 problem_->setCurrLS();
1849 problem_->setLSIndex (
currIdx);
1868 outputTest_->resetNumCalls();
1871 computeGCRODRResidual();
1872 index.resize( 1 ); index[0] = 0;
1873 RCP<MV> v0 = MVT::CloneViewNonConst( *V_, index );
1874 MVT::SetBlock(*r_,index,*
v0);
1877 DMT::SyncDeviceToHost( *H2_ );
1879 index.resize( numBlocks_+1 );
1880 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1881 newstate.V = MVT::CloneViewNonConst( *V_, index );
1882 if (isFlexible_)
newstate.Z = MVT::CloneViewNonConst( *Z_, index );
1883 index.resize( keff );
1884 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1885 newstate.C = MVT::CloneViewNonConst( *C_, index );
1886 newstate.U = MVT::CloneViewNonConst( *U_, index );
1904 if ( convTest_->getStatus() ==
Passed ) {
1913 else if ( maxIterTest_->getStatus() ==
Passed ) {
1930 updateSolutionWithUpdate(
update);
1934 printer_->stream(
Debug)
1935 <<
" Generated new recycled subspace using RHS index "
1936 <<
currIdx[0] <<
" of dimension " << keff << std::endl
1947 printer_->stream(
Debug)
1948 <<
" Performing restart number " <<
numRestarts <<
" of "
1949 << maxRestarts_ << std::endl << std::endl;
1952 computeGCRODRResidual();
1953 index.resize( 1 ); index[0] = 0;
1954 RCP<MV> v00 = MVT::CloneViewNonConst( *V_, index );
1955 MVT::SetBlock(*r_,index,*
v00);
1958 DMT::SyncDeviceToHost( *H2_ );
1960 index.resize( numBlocks_+1 );
1961 for (
int ii=0;
ii<(numBlocks_+1); ++
ii) { index[
ii] =
ii; }
1963 if (isFlexible_)
restartState.Z = MVT::CloneViewNonConst( *Z_, index );
1964 index.resize( keff );
1965 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
1985 std::logic_error,
"Belos::GCRODRSolMgr::solve: "
1986 "Invalid return from GCRODRIter::iterate().");
1995 if (convTest_->getStatus() !=
Passed) {
2001 catch (
const std::exception&
e) {
2004 <<
"Error! Caught exception in GCRODRIter::iterate() at iteration "
2005 <<
gcrodr_iter->getNumIters() << std::endl <<
e.what() << std::endl;
2013 updateSolutionWithUpdate(
update);
2016 problem_->setCurrLS();
2021 if (!builtRecycleSpace_) {
2023 printer_->stream(
Debug)
2024 <<
" Generated new recycled subspace using RHS index " <<
currIdx[0]
2025 <<
" of dimension " << keff << std::endl << std::endl;
2032 problem_->setLSIndex (
currIdx);
2043#ifdef BELOS_TEUCHOS_TIME_MONITOR
2048 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
2052 numIters_ = maxIterTest_->getNumIters ();
2065 if (! expConvTest_.is_null()) {
2072 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
2073 "method returned NULL. Please report this bug to the Belos developers.");
2075 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
2076 "method returned a vector of length zero. Please report this bug to the "
2077 "Belos developers.");
2092template<
class ScalarType,
class MV,
class OP,
class DM>
2100 MagnitudeType
one = Teuchos::ScalarTraits<MagnitudeType>::one();
2103 std::vector<MagnitudeType>
d(keff);
2104 std::vector<ScalarType>
dscalar(keff);
2105 std::vector<int> index(numBlocks_+1);
2117 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
2118 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst( *U_, index );
2121 MVT::MvNorm( *
Utmp,
d );
2122 for (
int i=0;
i<keff; ++
i) {
2130 DMT::SyncDeviceToHost( *H2_ );
2131 Teuchos::RCP<DM>
H2tmp = DMT::Subview( *H2_,
p+keff+1,
p+keff );
2134 for (
int i=0;
i<keff; ++
i) {
2138 DMT::SyncHostToDevice( *H2_ );
2144 DMT::SyncDeviceToHost( *PP_ );
2145 Teuchos::RCP<DM>
PPtmp = DMT::Subview( *PP_,
p+keff, recycledBlocks_+1 );
2147 DMT::SyncHostToDevice( *PP_ );
2154 Teuchos::RCP<MV>
U1tmp;
2156 index.resize( keff );
2157 for (
int ii=0;
ii<keff; ++
ii) { index[
ii] =
ii; }
2158 Teuchos::RCP<const MV>
Utmp = MVT::CloneView( *U_, index );
2161 U1tmp = MVT::CloneViewNonConst( *U1_, index );
2162 Teuchos::RCP<const DM>
PPtmp = DMT::SubviewConst( *PP_, keff,
keff_new );
2170 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView( *V_, index );
2171 Teuchos::RCP<const DM>
PPtmp = DMT::SubviewConst( *PP_,
p,
keff_new, keff );
2176 DMT::SyncDeviceToHost( *HP_ );
2177 Teuchos::RCP<DM>
HPtmp = DMT::Subview( *HP_,
p+keff+1,
keff_new );
2179 DMT::SyncDeviceToHost( *PP_ );
2182 Teuchos::BLAS<int,ScalarType>
blas;
2183 blas.GEMM( Teuchos::NO_TRANS, Teuchos::NO_TRANS,
p+keff+1,
keff_new,
p+keff,
one,
2184 DMT::GetConstRawHostPtr(*
H2tmp), DMT::GetStride(*
H2tmp),
2185 DMT::GetConstRawHostPtr(*
PPtmp), DMT::GetStride(*
PPtmp),
2192 lapack.GEQRF (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetRawHostPtr(*
HPtmp),
2195 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
2196 "LAPACK's _GEQRF failed to compute a workspace size.");
2202 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work_[0])));
2203 work_.resize (
lwork);
2204 lapack.GEQRF (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetRawHostPtr(*
HPtmp),
2207 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
2208 "LAPACK's _GEQRF failed to compute a QR factorization.");
2212 DMT::SyncDeviceToHost( *R_ );
2220 lapack.UNGQR (DMT::GetNumRows(*
HPtmp), DMT::GetNumCols(*
HPtmp), DMT::GetNumCols(*
HPtmp),
2221 DMT::GetRawHostPtr(*
HPtmp), DMT::GetStride(*
HPtmp), &tau_[0], &work_[0],
2224 info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve: "
2225 "LAPACK's _UNGQR failed to construct the Q factor.");
2227 DMT::SyncHostToDevice( *HP_ );
2228 HPtmp = Teuchos::null;
2235 Teuchos::RCP<MV>
C1tmp;
2238 for (
int i=0;
i < keff;
i++) { index[
i] =
i; }
2239 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView( *C_, index );
2242 C1tmp = MVT::CloneViewNonConst( *C1_, index );
2243 Teuchos::RCP<const DM>
PPtmp = DMT::SubviewConst( *HP_, keff,
keff_new );
2248 index.resize(
p+1 );
2249 for (
int i=0;
i <
p+1; ++
i) { index[
i] =
i; }
2250 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView( *V_, index );
2251 Teuchos::RCP<const DM>
PPtmp = DMT::SubviewConst( *HP_,
p+1,
keff_new, keff, 0 );
2261 ipiv_.resize(DMT::GetNumRows(*
Rtmp));
2262 lapack.GETRF(DMT::GetNumRows(*
Rtmp),DMT::GetNumCols(*
Rtmp),DMT::GetRawHostPtr(*
Rtmp),DMT::GetStride(*
Rtmp),&ipiv_[0],&
info);
2263 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0,GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::buildRecycleSpace2(): LAPACK _GETRF failed to compute an LU factorization.");
2267 work_.resize(
lwork);
2268 lapack.GETRI(DMT::GetNumRows(*
Rtmp),DMT::GetRawHostPtr(*
Rtmp),DMT::GetStride(*
Rtmp),&ipiv_[0],&work_[0],
lwork,&
info);
2269 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::buildRecycleSpace2(): LAPACK _GETRI failed to compute an LU factorization.");
2271 DMT::SyncHostToDevice(*R_);
2276 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst( *U_, index );
2285 Teuchos::RCP<DM>
b1 = DMT::Subview( *H2_, recycledBlocks_+2, 1, 0, recycledBlocks_ );
2286 DMT::PutScalar( *
b1,
zero );
2296template<
class ScalarType,
class MV,
class OP,
class DM>
2298GCRODRSolMgr<ScalarType,MV,OP,DM,true>::
2299buildFlexibleRecycleSpace2(Teuchos::RCP<GCRODRIteration<ScalarType,MV,OP,DM> > gcrodr_iter)
2301 MagnitudeType
magOne = Teuchos::ScalarTraits<MagnitudeType>::one();
2305 std::vector<MagnitudeType>
d(keff);
2306 std::vector<ScalarType>
dscalar(keff);
2307 std::vector<int> index(numBlocks_+1);
2316 GCRODRSolMgrRecyclingFailure,
2317 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): oldState.Z is null.");
2320 W_ == Teuchos::null,
2321 GCRODRSolMgrRecyclingFailure,
2322 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): W_ is null.");
2327 for (
int ii=0;
ii<keff; ++
ii) index[
ii] =
ii;
2329 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst(*U_, index);
2330 Teuchos::RCP<MV>
Wtmp = MVT::CloneViewNonConst(*W_, index);
2335 MVT::MvNorm(*
Utmp,
d);
2336 for (
int i=0;
i<keff; ++
i) {
2346 DMT::SyncDeviceToHost(*H2_);
2347 Teuchos::RCP<DM>
H2tmp = DMT::Subview(*H2_,
p+keff+1,
p+keff);
2350 for (
int i=0;
i<keff; ++
i) {
2354 DMT::SyncHostToDevice(*H2_);
2359 DMT::SyncDeviceToHost(*PP_);
2360 Teuchos::RCP<DM>
PPtmp = DMT::Subview(*PP_,
p+keff, recycledBlocks_+1);
2362 DMT::SyncHostToDevice(*PP_);
2366 Teuchos::RCP<MV>
U1tmp;
2369 for (
int ii=0;
ii<keff; ++
ii) index[
ii] =
ii;
2371 Teuchos::RCP<const MV>
Utmp = MVT::CloneView(*U_, index);
2376 U1tmp = MVT::CloneViewNonConst(*U1_, index);
2378 Teuchos::RCP<const DM>
PPtop = DMT::SubviewConst(*PP_, keff,
keff_new);
2386 Teuchos::RCP<const MV>
Ztmp = MVT::CloneView(*
oldState.Z, index);
2393 Teuchos::RCP<MV>
W1tmp;
2396 for (
int ii=0;
ii<keff; ++
ii) index[
ii] =
ii;
2398 Teuchos::RCP<const MV>
Wtmp = MVT::CloneView(*W_, index);
2403 W1tmp = MVT::CloneViewNonConst(*W1_, index);
2405 Teuchos::RCP<const DM>
PPtop = DMT::SubviewConst(*PP_, keff,
keff_new);
2413 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView(*
oldState.V, index);
2420 DMT::SyncDeviceToHost(*HP_);
2424 DMT::SyncDeviceToHost(*PP_);
2425 DMT::SyncDeviceToHost(*H2_);
2428 Teuchos::BLAS<int,ScalarType>
blas;
2429 blas.GEMM(Teuchos::NO_TRANS, Teuchos::NO_TRANS,
2432 DMT::GetConstRawHostPtr(*
H2tmp), DMT::GetStride(*
H2tmp),
2433 DMT::GetConstRawHostPtr(*
PPtmp), DMT::GetStride(*
PPtmp),
2435 DMT::GetRawHostPtr(*
HPtmp), DMT::GetStride(*
HPtmp));
2443 if (work_.size() < 1) work_.resize(1);
2445 lapack.GEQRF(DMT::GetNumRows(*
HPtmp),
2446 DMT::GetNumCols(*
HPtmp),
2447 DMT::GetRawHostPtr(*
HPtmp),
2448 DMT::GetStride(*
HPtmp),
2453 GCRODRSolMgrLAPACKFailure,
2454 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GEQRF workspace query failed.");
2456 lwork = std::abs(
static_cast<int>(Teuchos::ScalarTraits<ScalarType>::real(work_[0])));
2457 work_.resize(
lwork);
2459 lapack.GEQRF(DMT::GetNumRows(*
HPtmp),
2460 DMT::GetNumCols(*
HPtmp),
2461 DMT::GetRawHostPtr(*
HPtmp),
2462 DMT::GetStride(*
HPtmp),
2467 GCRODRSolMgrLAPACKFailure,
2468 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GEQRF failed.");
2471 DMT::SyncDeviceToHost(*R_);
2481 lapack.UNGQR(DMT::GetNumRows(*
HPtmp),
2482 DMT::GetNumCols(*
HPtmp),
2483 DMT::GetNumCols(*
HPtmp),
2484 DMT::GetRawHostPtr(*
HPtmp),
2485 DMT::GetStride(*
HPtmp),
2490 GCRODRSolMgrLAPACKFailure,
2491 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK UNGQR failed.");
2493 DMT::SyncHostToDevice(*HP_);
2497 Teuchos::RCP<MV>
C1tmp;
2501 for (
int i=0;
i<keff; ++
i) index[
i] =
i;
2503 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView(*C_, index);
2508 C1tmp = MVT::CloneViewNonConst(*C1_, index);
2510 Teuchos::RCP<const DM>
Qtop = DMT::SubviewConst(*HP_, keff,
keff_new);
2516 for (
int i=0;
i<
p+1; ++
i) index[
i] =
i;
2518 Teuchos::RCP<const MV>
Vtmp = MVT::CloneView(*
oldState.V, index);
2519 Teuchos::RCP<const DM>
Qbottom = DMT::SubviewConst(*HP_,
p+1,
keff_new, keff, 0);
2528 ipiv_.resize(DMT::GetNumRows(*
Rtmp));
2530 lapack.GETRF(DMT::GetNumRows(*
Rtmp),
2531 DMT::GetNumCols(*
Rtmp),
2532 DMT::GetRawHostPtr(*
Rtmp),
2533 DMT::GetStride(*
Rtmp),
2538 GCRODRSolMgrLAPACKFailure,
2539 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GETRF failed.");
2542 work_.resize(
lwork);
2544 lapack.GETRI(DMT::GetNumRows(*
Rtmp),
2545 DMT::GetRawHostPtr(*
Rtmp),
2546 DMT::GetStride(*
Rtmp),
2551 GCRODRSolMgrLAPACKFailure,
2552 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GETRI failed.");
2554 DMT::SyncHostToDevice(*R_);
2560 Teuchos::RCP<MV>
Utmp = MVT::CloneViewNonConst(*U_, index);
2561 Teuchos::RCP<const MV>
U1tmpConst = MVT::CloneView(*U1_, index);
2564 Teuchos::RCP<MV>
Wtmp = MVT::CloneViewNonConst(*W_, index);
2565 Teuchos::RCP<const MV>
W1tmpConst = MVT::CloneView(*W1_, index);
2573 Teuchos::RCP<DM>
b1 = DMT::Subview(*H2_, recycledBlocks_+2, 1, 0, recycledBlocks_);
2574 DMT::PutScalar(*
b1,
zero);
2580template<
class ScalarType,
class MV,
class OP,
class DM>
2581int GCRODRSolMgr<ScalarType,MV,OP,DM,true>::getHarmonicVecs1(
int m,
const DM& HH, DM& PP) {
2588 std::vector<MagnitudeType>
wr(
m),
wi(
m);
2591 Teuchos::RCP<DM>
vr = DMT::Create(
m,
m,
false);
2594 std::vector<MagnitudeType>
w(
m);
2597 std::vector<int>
iperm(
m);
2603 builtRecycleSpace_ =
true;
2606 Teuchos::RCP<DM>
HHt = DMT::CreateCopy(
HH,
true );
2607 Teuchos::RCP<DM>
e_m = DMT::Create(
m, 1 );
2608 DMT::SyncDeviceToHost( *
HHt );
2610 DMT::Value( *
e_m,
m-1, 0 ) =
one;
2611 lapack.GESV(
m, 1, DMT::GetRawHostPtr(*
HHt), DMT::GetStride(*
HHt), &
iperm[0], DMT::GetRawHostPtr(*
e_m), DMT::GetStride(*
e_m), &
info);
2615 Teuchos::RCP<DM>
tmpHH = DMT::CreateCopy(
HH );
2616 DMT::SyncDeviceToHost( *
tmpHH );
2620 for(
i=0;
i<
m; ++
i )
2621 DMT::Value(*
harmHH,
i,
m-1) +=
d * DMT::ValueConst(*
e_m,
i, 0);
2630 std::vector<ScalarType>
work(1);
2631 std::vector<MagnitudeType>
rwork(2*
m);
2634 lapack.GEEV(
'N',
'V',
m, DMT::GetRawHostPtr(*
harmHH), DMT::GetStride(*
harmHH), &
wr[0], &
wi[0],
2637 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (
work[0])));
2640 lapack.GEEV(
'N',
'V',
m, DMT::GetRawHostPtr(*
harmHH), DMT::GetStride(*
harmHH), &
wr[0], &
wi[0],
2645 for(
i=0;
i<
m; ++
i )
2646 w[
i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot(
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i] );
2654 for(
i=0;
i<recycledBlocks_; ++
i ) {
2655 for(
j=0;
j<
m;
j++ ) {
2663 if (
wi[
iperm[recycledBlocks_-1]] != 0.0) {
2665 for (
i=0;
i<recycledBlocks_; ++
i ) {
2675 if (
wi[
iperm[recycledBlocks_-1]] > 0.0) {
2676 for(
j=0;
j<
m; ++
j ) {
2677 DMT::Value(
PP,
j,recycledBlocks_) = DMT::ValueConst(*
vr,
j,
iperm[recycledBlocks_-1]+1);
2681 for(
j=0;
j<
m; ++
j ) {
2682 DMT::Value(
PP,
j,recycledBlocks_) = DMT::ValueConst(*
vr,
j,
iperm[recycledBlocks_-1]-1);
2691 return recycledBlocks_+1;
2694 return recycledBlocks_;
2700template<
class ScalarType,
class MV,
class OP,
class DM>
2701int GCRODRSolMgr<ScalarType,MV,OP,DM,true>::getHarmonicVecs2(
int keffloc,
int m,
2703 const Teuchos::RCP<const MV>& VV,
2706 int m2 = DMT::GetNumCols(
HH);
2710 std::vector<int> index;
2713 std::vector<MagnitudeType>
wr(
m2),
wi(
m2);
2716 std::vector<MagnitudeType>
w(
m2);
2719 Teuchos::RCP<DM>
vr = DMT::Create(
m2,
m2,
false);
2725 builtRecycleSpace_ =
true;
2730 Teuchos::RCP<DM> B = DMT::Create(
m2,
m2,
false);
2732 Teuchos::BLAS<int,ScalarType>
blas;
2733 blas.GEMM( Teuchos::TRANS, Teuchos::NO_TRANS,
m2,
m2, DMT::GetNumRows(
HH),
one,
2734 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2735 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2736 zero, DMT::GetRawHostPtr(*B), DMT::GetStride(*B));
2745 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView( *C_, index );
2746 Teuchos::RCP<const MV>
Utmp = MVT::CloneView( *U_, index );
2753 for (
i=0;
i <
m+1;
i++) { index[
i] =
i; }
2754 Teuchos::RCP<const MV>
Vp = MVT::CloneView( *
VV, index );
2757 A11 = Teuchos::null;
2758 A21 = Teuchos::null;
2759 DMT::SyncDeviceToHost(*
A_tmp);
2767 Teuchos::RCP<DM>
A = DMT::Create(
m2, DMT::GetNumCols(*
A_tmp) );
2768 blas.GEMM( Teuchos::TRANS, Teuchos::NO_TRANS,
m2, DMT::GetNumCols(*
A_tmp), DMT::GetNumRows(*
A_tmp),
2769 one, DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2770 DMT::GetConstRawHostPtr(*
A_tmp), DMT::GetStride(*
A_tmp),
2771 zero, DMT::GetRawHostPtr(*
A), DMT::GetStride(*
A) );
2780 int ld = DMT::GetNumRows(*
A);
2786 std::vector<ScalarType> beta(
ld);
2797 ld, &
wr[0], &
wi[0], &beta[0],
vl,
ldvl, DMT::GetRawHostPtr(*
vr),
ldvr, &
ilo, &
ihi,
2800 TEUCHOS_TEST_FOR_EXCEPTION(
info != 0, GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GGEVX failed to compute eigensolutions.");
2804 for(
i=0;
i<
ld;
i++ ) {
2805 w[
i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot (
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i]) /
2806 Teuchos::ScalarTraits<ScalarType>::magnitude (beta[
i]);
2815 for(
i=0;
i<recycledBlocks_;
i++ ) {
2816 for(
j=0;
j<
ld;
j++ ) {
2817 DMT::Value(
PP,
j,
i) = DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_+
i]);
2824 if (
wi[
iperm[
ld-recycledBlocks_]] != 0.0) {
2826 for (
i=
ld-recycledBlocks_;
i<
ld;
i++ ) {
2836 if (
wi[
iperm[
ld-recycledBlocks_]] > 0.0) {
2837 for(
j=0;
j<
ld;
j++ ) {
2838 DMT::Value(
PP,
j,recycledBlocks_) = DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_]+1);
2842 for(
j=0;
j<
ld;
j++ ) {
2843 DMT::Value(
PP,
j,recycledBlocks_) = DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_]-1);
2852 return recycledBlocks_+1;
2855 return recycledBlocks_;
2869template<
class ScalarType,
class MV,
class OP,
class DM>
2871GCRODRSolMgr<ScalarType,MV,OP,DM,true>::
2872getFlexibleHarmonicVecs2(
int keffloc,
int m,
2874 const Teuchos::RCP<const MV>& VV,
2878 int m2 = DMT::GetNumCols(
HH);
2884 std::vector<int> index;
2886 std::vector<MagnitudeType>
wr(
m2),
wi(
m2);
2887 std::vector<MagnitudeType>
w(
m2);
2889 Teuchos::RCP<DM>
vr = DMT::Create(
m2,
m2,
false);
2893 builtRecycleSpace_ =
true;
2896 Teuchos::RCP<DM> B = DMT::Create(
m2,
m2,
false);
2898 Teuchos::BLAS<int,ScalarType>
blas;
2899 blas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
2900 m2,
m2, DMT::GetNumRows(
HH),
2902 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2903 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2905 DMT::GetRawHostPtr(*B), DMT::GetStride(*B));
2915 Teuchos::RCP<const MV>
Ctmp = MVT::CloneView(*C_, index);
2916 Teuchos::RCP<const MV>
Wtmp = MVT::CloneView(*W_, index);
2925 for (
i=0;
i<
m+1; ++
i) index[
i] =
i;
2927 Teuchos::RCP<const MV>
Vp = MVT::CloneView(*
VV, index);
2932 Wtmp = MVT::CloneView(*W_, index);
2936 A11 = Teuchos::null;
2937 A21 = Teuchos::null;
2939 DMT::SyncDeviceToHost(*
A_tmp);
2942 for (
i=0;
i<
m; ++
i) {
2947 Teuchos::RCP<DM>
A = DMT::Create(
m2, DMT::GetNumCols(*
A_tmp));
2949 blas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
2952 DMT::GetConstRawHostPtr(
HH), DMT::GetStride(
HH),
2953 DMT::GetConstRawHostPtr(*
A_tmp), DMT::GetStride(*
A_tmp),
2955 DMT::GetRawHostPtr(*
A), DMT::GetStride(*
A));
2959 int ld = DMT::GetNumRows(*
A);
2967 std::vector<ScalarType> beta(
ld);
2976 DMT::GetRawHostPtr(*
A),
ld,
2977 DMT::GetRawHostPtr(*B),
ld,
2978 &
wr[0], &
wi[0], &beta[0],
2980 DMT::GetRawHostPtr(*
vr),
ldvr,
2990 GCRODRSolMgrLAPACKFailure,
2991 "Belos::GCRODRSolMgr::getFlexibleHarmonicVecs2(): LAPACK GGEVX failed to compute eigensolutions.");
2993 for (
i=0;
i<
ld; ++
i) {
2995 Teuchos::ScalarTraits<MagnitudeType>::squareroot(
wr[
i]*
wr[
i] +
wi[
i]*
wi[
i]) /
2996 Teuchos::ScalarTraits<ScalarType>::magnitude(beta[
i]);
3003 for (
i=0;
i<recycledBlocks_; ++
i) {
3004 for (
j=0;
j<
ld; ++
j) {
3005 DMT::Value(
PP,
j,
i) =
3006 DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_+
i]);
3011 if (
wi[
iperm[
ld-recycledBlocks_]] != 0.0) {
3013 for (
i=
ld-recycledBlocks_;
i<
ld; ++
i) {
3025 if (
wi[
iperm[
ld-recycledBlocks_]] > 0.0) {
3026 for (
j=0;
j<
ld; ++
j) {
3027 DMT::Value(
PP,
j, recycledBlocks_) =
3028 DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_]+1);
3032 for (
j=0;
j<
ld; ++
j) {
3033 DMT::Value(
PP,
j, recycledBlocks_) =
3034 DMT::ValueConst(*
vr,
j,
iperm[
ld-recycledBlocks_]-1);
3041 return recycledBlocks_ + 1;
3044 return recycledBlocks_;
3050template<
class ScalarType,
class MV,
class OP,
class DM>
3051void GCRODRSolMgr<ScalarType,MV,OP,DM,true>::sort(std::vector<MagnitudeType>& dlist,
int n, std::vector<int>& iperm) {
3054 MagnitudeType
dRR,
dK;
3115template<
class ScalarType,
class MV,
class OP,
class DM>
3117 std::ostringstream
out;
3118 out <<
"Belos::GCRODRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
3120 out <<
"Ortho Type: \"" << orthoType_ <<
"\"";
3121 out <<
", Flexible: " << (isFlexible_ ?
"true" :
"false");
3122 out <<
", Num Blocks: " <<numBlocks_;
3123 out <<
", Num Recycle Blocks: " << recycledBlocks_;
3124 out <<
", Max Restarts: " << maxRestarts_;
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.
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.