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 =
139 requiresLapack> base_type;
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> ¶ms )
override;
346 debugStatusTest_ = debugStatusTest;
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):
569 TEUCHOS_TEST_FOR_EXCEPTION(
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>
625setParameters (
const Teuchos::RCP<Teuchos::ParameterList> ¶ms)
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()) {
661 params_ = parameterList (*defaultParams);
669 if (params_ != params) {
675 params_ = parameterList (*params);
710 params_->validateParametersAndSetDefaults (*defaultParams);
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_);
734 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks_ <= 0, std::invalid_argument,
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_);
746 TEUCHOS_TEST_FOR_EXCEPTION(recycledBlocks_ <= 0, std::invalid_argument,
747 "Belos::GCRODRSolMgr: The \"Num Recycled Blocks\" "
748 "parameter must be strictly positive, but you specified "
749 "a value of " << recycledBlocks_ <<
".");
750 TEUCHOS_TEST_FOR_EXCEPTION(recycledBlocks_ >= numBlocks_, std::invalid_argument,
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")) {
761 const bool newFlexible =
762 params->get(
"Flexible GCRODR", flexibleGCRODR_default_);
763 if (newFlexible != isFlexible_) {
769 isFlexible_ = newFlexible;
770 params_->set(
"Flexible GCRODR", isFlexible_);
776 if (params->isParameter (
"Timer Label")) {
777 std::string tempLabel = params->get (
"Timer Label", label_default_);
780 if (tempLabel != 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")) {
795 if (isParameterType<int> (*params,
"Verbosity")) {
796 verbosity_ = params->get (
"Verbosity", verbosity_default_);
798 verbosity_ = (int) getParameter<Belos::MsgType> (*params,
"Verbosity");
801 params_->set (
"Verbosity", verbosity_);
804 if (! printer_.is_null())
805 printer_->setVerbosity (verbosity_);
809 if (params->isParameter (
"Output Style")) {
810 if (isParameterType<int> (*params,
"Output Style")) {
811 outputStyle_ = params->get (
"Output Style", outputStyle_default_);
813 outputStyle_ = (int) getParameter<OutputType> (*params,
"Output Style");
817 params_->set (
"Output Style", outputStyle_);
835 if (params->isParameter (
"Output Stream")) {
837 outputStream_ = getParameter<RCP<std::ostream> > (*params,
"Output Stream");
838 }
catch (InvalidParameter&) {
839 outputStream_ = rcpFromRef (std::cout);
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()) {
885 bool changedOrthoType =
false;
886 if (params->isParameter (
"Orthogonalization")) {
887 const std::string& tempOrthoType =
888 params->get (
"Orthogonalization", orthoType_default_);
891 std::ostringstream os;
892 os <<
"Belos::GCRODRSolMgr: Invalid orthogonalization name \""
893 << tempOrthoType <<
"\". The following are valid options "
894 <<
"for the \"Orthogonalization\" name parameter: ";
896 throw std::invalid_argument (os.str());
898 if (tempOrthoType != orthoType_) {
899 changedOrthoType =
true;
900 orthoType_ = tempOrthoType;
902 params_->set (
"Orthogonalization", orthoType_);
918 RCP<ParameterList> orthoParams;
921 using Teuchos::sublist;
923 const std::string paramName (
"Orthogonalization Parameters");
926 orthoParams = sublist (params_, paramName,
true);
927 }
catch (InvalidParameter&) {
934 orthoParams = sublist (params_, paramName,
true);
937 TEUCHOS_TEST_FOR_EXCEPTION(orthoParams.is_null(), std::logic_error,
938 "Failed to get orthogonalization parameters. "
939 "Please report this bug to the Belos developers.");
944 if (ortho_.is_null() || changedOrthoType) {
950 label_, orthoParams);
958 typedef Teuchos::ParameterListAcceptor PLA;
959 RCP<PLA> pla = rcp_dynamic_cast<PLA> (ortho_);
965 label_, orthoParams);
967 pla->setParameterList (orthoParams);
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()) {
1000 rcp_dynamic_cast<ortho_man_type>(ortho_)->
setDepTol (orthoKappa_);
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")) {
1029 std::string tempImpResScale =
1030 getParameter<std::string> (*params,
"Implicit Residual Scaling");
1033 if (impResScale_ != tempImpResScale) {
1035 impResScale_ = tempImpResScale;
1038 params_->set(
"Implicit Residual Scaling", impResScale_);
1048 if (! impConvTest_.is_null()) {
1054 impConvTest_ = null;
1061 if (params->isParameter(
"Explicit Residual Scaling")) {
1062 std::string tempExpResScale =
1063 getParameter<std::string> (*params,
"Explicit Residual Scaling");
1066 if (expResScale_ != tempExpResScale) {
1068 expResScale_ = tempExpResScale;
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_,
1160 std::string solverDesc =
" GCRODR ";
1162 solverDesc =
"Flexible" + solverDesc;
1163 outputTest_->setSolverDesc( solverDesc );
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;
1186 static RCP<const ParameterList> validPL;
1187 if (is_null(validPL)) {
1188 RCP<ParameterList> pl = 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: " +
1235 RCP<const ParameterList> orthoParams =
1237 pl->set (
"Orthogonalization Parameters", *orthoParams,
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>
1253 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1256 Teuchos::RCP<const MV> rhsMV = problem_->getRHS();
1257 if (rhsMV == Teuchos::null) {
1264 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<ptrdiff_t
>(numBlocks_) > MVT::GetGlobalLength(*rhsMV),std::invalid_argument,
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>
1417 problem_->computeCurrResVec(&*r_);
1420 problem_->computeCurrPrecResVec(&*r_);
1424template<
class ScalarType,
class MV,
class OP,
class DM>
1429 if (update == Teuchos::null) {
1433 const ScalarType one = SCT::one();
1436 Teuchos::RCP<MV> curX = problem_->getCurrLHSVec();
1437 MVT::MvAddMv(one, *curX, one, *update, *curX);
1440 problem_->updateSolution(update,
true);
1446template<
class ScalarType,
class MV,
class OP,
class DM>
1458 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
1459 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1460 std::vector<int> index(numBlocks_+1);
1462 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,
GCRODRSolMgrLinearProblemFailure,
"Belos::GCRODRSolMgr::solve(): Linear problem is not a valid object.");
1464 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(),
GCRODRSolMgrLinearProblemFailure,
"Belos::GCRODRSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1467 TEUCHOS_TEST_FOR_EXCEPTION(
1468 !Teuchos::is_null(problem_->getLeftPrec()),
1470 "Belos::GCRODRSolMgr::solve(): Flexible GCRODR does not support left preconditioning; use no preconditioner or a right preconditioner.");
1475 std::vector<int> currIdx(1);
1479 problem_->setLSIndex( currIdx );
1483 if (
static_cast<ptrdiff_t
>(numBlocks_) > dim) {
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_);
1492 bool isConverged =
true;
1495 initializeStateStorage();
1499 Teuchos::ParameterList plist;
1501 plist.set(
"Num Blocks",numBlocks_);
1502 plist.set(
"Recycled Blocks",recycledBlocks_);
1507 RCP<GCRODRIteration<ScalarType,MV,OP,DM> > gcrodr_iter;
1515 int prime_iterations = 0;
1519#ifdef BELOS_TEUCHOS_TIME_MONITOR
1520 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1523 while ( numRHS2Solve > 0 ) {
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; }
1546 problem_->applyOp(*Utmp, *Ctmp);
1549 problem_->apply(*Utmp, *Ctmp);
1556 Teuchos::RCP<DM> Rtmp =
DMT::Subview( *R_, keff, keff );
1557 int rank = ortho_->normalize(*Ctmp, Rtmp);
1559 TEUCHOS_TEST_FOR_EXCEPTION(rank != keff,
GCRODRSolMgrOrthoFailure,
"Belos::GCRODRSolMgr::solve(): Failed to compute orthonormal basis for initial recycled subspace.");
1569 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRF failed to compute an LU factorization.");
1573 work_.resize(lwork);
1575 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK _GETRI failed to invert triangular matrix.");
1591 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1597 computeGCRODRResidual();
1601 RCP<MV> update =
MVT::Clone( *problem_->getCurrLHSVec(), 1 );
1604 updateSolutionWithUpdate(update);
1610 prime_iterations = 0;
1616 printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " << currIdx[0] << std::endl << std::endl;
1618 Teuchos::ParameterList primeList;
1619 primeList.set(
"Num Blocks",numBlocks_);
1620 primeList.set(
"Recycled Blocks",recycledBlocks_);
1623 RCP<GCRODRIteration<ScalarType,MV,OP,DM> > gcrodr_prime_iter;
1632 computeGCRODRResidual();
1633 index.resize( 1 ); index[0] = 0;
1639 index.resize( numBlocks_+1 );
1640 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1643 newstate.
U = Teuchos::null;
1644 newstate.
C = Teuchos::null;
1647 gcrodr_prime_iter->initialize(newstate);
1650 bool primeConverged =
false;
1651 bool debugTestPassed =
false;
1653 gcrodr_prime_iter->iterate();
1656 if ( convTest_->getStatus() ==
Passed ) {
1658 primeConverged =
true;
1663 else if (Teuchos::nonnull(debugStatusTest_) &&
1664 debugStatusTest_->getStatus() ==
Passed) {
1666 isConverged =
false;
1667 debugTestPassed =
true;
1672 gcrodr_prime_iter->updateLSQR( gcrodr_prime_iter->getCurSubspaceDim() );
1675 sTest_->checkStatus( &*gcrodr_prime_iter );
1676 if (convTest_->getStatus() ==
Passed)
1677 primeConverged =
true;
1682 achievedTol_ = MT::one();
1683 Teuchos::RCP<MV> X = problem_->getLHS();
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 "
1692 << gcrodr_prime_iter->getNumIters() << std::endl
1693 << e.what() << std::endl;
1697 prime_iterations = gcrodr_prime_iter->getNumIters();
1699 if (debugTestPassed) {
1704 RCP<MV> update = gcrodr_prime_iter->getCurrentUpdate();
1705 updateSolutionWithUpdate(update);
1708 newstate = gcrodr_prime_iter->getState();
1716 if (recycledBlocks_ < p+1) {
1722 RCP<DM> PPtmp =
DMT::Subview( *PP_, p, recycledBlocks_+1 );
1725 keff = getHarmonicVecs1( p, *newstate.
H, *PPtmp );
1734 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1739 for (
int ii=0; ii < p; ++ii) { index[ii] = ii; }
1748 std::vector<int> wind(keff);
1749 for (
int wi = 0; wi < keff; ++wi) wind[wi] = wi;
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,
1780 TEUCHOS_TEST_FOR_EXCEPTION(
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);
1794 TEUCHOS_TEST_FOR_EXCEPTION(
1796 " LAPACK's _GEQRF failed to compute a QR factorization.");
1803 for (
int ii = 0; ii < keff; ++ii) {
1804 for (
int jj = ii; jj < keff; ++jj) {
1816 TEUCHOS_TEST_FOR_EXCEPTION(
1818 "LAPACK's _UNGQR failed to construct the Q factor.");
1825 index.resize (p + 1);
1826 for (
int ii = 0; ii < (p+1); ++ii) {
1840 TEUCHOS_TEST_FOR_EXCEPTION(
1842 "LAPACK's _GETRF failed to compute an LU factorization.");
1852 work_.resize(lwork);
1854 &ipiv_[0], &work_[0], lwork, &info);
1855 TEUCHOS_TEST_FOR_EXCEPTION(
1857 "LAPACK's _GETRI failed to invert triangular matrix.");
1864 std::vector<int> wind(keff);
1865 for (
int wi = 0; wi < keff; ++wi) wind[wi] = wi;
1871 printer_->stream(
Debug)
1872 <<
" Generated recycled subspace using RHS index " << currIdx[0]
1873 <<
" of dimension " << keff << std::endl << std::endl;
1878 if (primeConverged) {
1880 problem_->setCurrLS();
1884 if (numRHS2Solve > 0) {
1886 problem_->setLSIndex (currIdx);
1889 currIdx.resize (numRHS2Solve);
1899 gcrodr_iter->setSize( keff, numBlocks_ );
1902 gcrodr_iter->resetNumIters(prime_iterations);
1905 outputTest_->resetNumCalls();
1908 computeGCRODRResidual();
1909 index.resize( 1 ); index[0] = 0;
1916 index.resize( numBlocks_+1 );
1917 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1920 index.resize( keff );
1921 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
1926 gcrodr_iter->initialize(newstate);
1929 int numRestarts = 0;
1934 gcrodr_iter->iterate();
1941 if ( convTest_->getStatus() ==
Passed ) {
1950 else if ( maxIterTest_->getStatus() ==
Passed ) {
1953 isConverged =
false;
1961 else if ( gcrodr_iter->getCurSubspaceDim() == gcrodr_iter->getMaxSubspaceDim() ) {
1966 RCP<MV> update = gcrodr_iter->getCurrentUpdate();
1967 updateSolutionWithUpdate(update);
1969 buildRecycleSpace2(gcrodr_iter);
1971 printer_->stream(
Debug)
1972 <<
" Generated new recycled subspace using RHS index "
1973 << currIdx[0] <<
" of dimension " << keff << std::endl
1977 if (numRestarts >= maxRestarts_) {
1979 isConverged =
false;
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;
1997 index.resize( numBlocks_+1 );
1998 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
2001 index.resize( keff );
2002 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
2005 restartState.
H2 = H2_;
2007 gcrodr_iter->initialize(restartState);
2017 else if (Teuchos::nonnull(debugStatusTest_) &&
2018 debugStatusTest_->getStatus() ==
Passed) {
2023 isConverged =
false;
2035 TEUCHOS_TEST_FOR_EXCEPTION(
true,
2036 std::logic_error,
"Belos::GCRODRSolMgr::solve: "
2037 "Invalid return from GCRODRIter::iterate().");
2042 gcrodr_iter->updateLSQR( gcrodr_iter->getCurSubspaceDim() );
2045 sTest_->checkStatus( &*gcrodr_iter );
2046 if (convTest_->getStatus() !=
Passed) {
2048 isConverged =
false;
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;
2063 RCP<MV> update = gcrodr_iter->getCurrentUpdate();
2064 updateSolutionWithUpdate(update);
2067 problem_->setCurrLS();
2072 if (!builtRecycleSpace_) {
2073 buildRecycleSpace2(gcrodr_iter);
2074 printer_->stream(
Debug)
2075 <<
" Generated new recycled subspace using RHS index " << currIdx[0]
2076 <<
" of dimension " << keff << std::endl << std::endl;
2081 if (numRHS2Solve > 0) {
2083 problem_->setLSIndex (currIdx);
2086 currIdx.resize (numRHS2Solve);
2094#ifdef BELOS_TEUCHOS_TIME_MONITOR
2099 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
2103 numIters_ = maxIterTest_->getNumIters ();
2115 const std::vector<MagnitudeType>* pTestValues = NULL;
2116 if (! expConvTest_.is_null()) {
2117 pTestValues = expConvTest_->getTestValue();
2119 if (pTestValues == NULL || pTestValues->size() < 1) {
2120 pTestValues = impConvTest_->getTestValue();
2122 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
2123 "Belos::GCRODRSolMgr::solve(): The implicit convergence test's getTestValue() "
2124 "method returned NULL. Please report this bug to the Belos developers.");
2125 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
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.");
2133 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
2143template<
class ScalarType,
class MV,
class OP,
class DM>
2147 buildFlexibleRecycleSpace2(gcrodr_iter);
2151 MagnitudeType one = Teuchos::ScalarTraits<MagnitudeType>::one();
2152 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
2154 std::vector<MagnitudeType> d(keff);
2155 std::vector<ScalarType> dscalar(keff);
2156 std::vector<int> index(numBlocks_+1);
2159 GCRODRIterState<ScalarType,MV,DM> oldState = gcrodr_iter->getState();
2160 int p = oldState.curDim;
2168 for (
int ii=0; ii<keff; ++ii) { index[ii] = ii; }
2169 Teuchos::RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
2171 dscalar.resize(keff);
2172 MVT::MvNorm( *Utmp, d );
2173 for (
int i=0; i<keff; ++i) {
2175 dscalar[i] = (ScalarType)d[i];
2177 MVT::MvScale( *Utmp, dscalar );
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) {
2186 DMT::Value(*H2tmp,i,i) = d[i];
2189 DMT::SyncHostToDevice( *H2_ );
2195 DMT::SyncDeviceToHost( *PP_ );
2196 Teuchos::RCP<DM> PPtmp = DMT::Subview( *PP_, p+keff, recycledBlocks_+1 );
2197 keff_new = getHarmonicVecs2( keff, p, *H2tmp, oldState.V, *PPtmp );
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 );
2210 index.resize( keff_new );
2211 for (
int ii=0; ii<keff_new; ++ii) { index[ii] = ii; }
2212 U1tmp = MVT::CloneViewNonConst( *U1_, index );
2213 Teuchos::RCP<const DM> PPtmp = DMT::SubviewConst( *PP_, keff, keff_new );
2214 MVT::MvTimesMatAddMv( one, *Utmp, *PPtmp, zero, *U1tmp );
2220 for (
int ii=0; ii < p; ii++) { index[ii] = ii; }
2221 Teuchos::RCP<const MV> Vtmp = MVT::CloneView( *V_, index );
2222 Teuchos::RCP<const DM> PPtmp = DMT::SubviewConst( *PP_, p, keff_new, keff );
2223 MVT::MvTimesMatAddMv( one, *Vtmp, *PPtmp, one, *U1tmp );
2227 DMT::SyncDeviceToHost( *HP_ );
2228 Teuchos::RCP<DM> HPtmp = DMT::Subview( *HP_, p+keff+1, keff_new );
2230 DMT::SyncDeviceToHost( *PP_ );
2231 Teuchos::RCP<DM> PPtmp = DMT::Subview( *PP_, p+keff, keff_new );
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),
2237 zero, DMT::GetRawHostPtr(*HPtmp), DMT::GetStride(*HPtmp));
2241 int info = 0, lwork = -1;
2242 tau_.resize (keff_new);
2243 lapack.GEQRF (DMT::GetNumRows(*HPtmp), DMT::GetNumCols(*HPtmp), DMT::GetRawHostPtr(*HPtmp),
2244 DMT::GetStride(*HPtmp), &tau_[0], &work_[0], lwork, &info);
2245 TEUCHOS_TEST_FOR_EXCEPTION(
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),
2256 DMT::GetStride(*HPtmp), &tau_[0], &work_[0], lwork, &info);
2257 TEUCHOS_TEST_FOR_EXCEPTION(
2259 "LAPACK's _GEQRF failed to compute a QR factorization.");
2263 DMT::SyncDeviceToHost( *R_ );
2264 Teuchos::RCP<DM> Rtmp = DMT::Subview( *R_, keff_new, keff_new );
2265 for(
int i=0;i<keff_new;i++) {
for(
int j=i;j<keff_new;j++) DMT::Value(*Rtmp,i,j) = DMT::ValueConst(*HPtmp,i,j); }
2271 lapack.UNGQR (DMT::GetNumRows(*HPtmp), DMT::GetNumCols(*HPtmp), DMT::GetNumCols(*HPtmp),
2272 DMT::GetRawHostPtr(*HPtmp), DMT::GetStride(*HPtmp), &tau_[0], &work_[0],
2274 TEUCHOS_TEST_FOR_EXCEPTION(
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 );
2291 index.resize(keff_new);
2292 for (
int i=0; i < keff_new; i++) { index[i] = i; }
2293 C1tmp = MVT::CloneViewNonConst( *C1_, index );
2294 Teuchos::RCP<const DM> PPtmp = DMT::SubviewConst( *HP_, keff, keff_new );
2295 MVT::MvTimesMatAddMv( one, *Ctmp, *PPtmp, zero, *C1tmp );
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 );
2303 MVT::MvTimesMatAddMv( one, *Vtmp, *PPtmp, one, *C1tmp );
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.");
2317 lwork = DMT::GetNumRows(*Rtmp);
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_);
2325 index.resize(keff_new);
2326 for (
int i=0; i < keff_new; i++) { index[i] = i; }
2327 Teuchos::RCP<MV> Utmp = MVT::CloneViewNonConst( *U_, index );
2328 MVT::MvTimesMatAddMv( one, *U1tmp, *Rtmp, zero, *Utmp );
2332 if (keff != keff_new) {
2334 gcrodr_iter->setSize( keff, numBlocks_ );
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>
2352 MagnitudeType magOne = Teuchos::ScalarTraits<MagnitudeType>::one();
2353 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
2354 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
2356 std::vector<MagnitudeType> d(keff);
2357 std::vector<ScalarType> dscalar(keff);
2358 std::vector<int> index(numBlocks_+1);
2365 TEUCHOS_TEST_FOR_EXCEPTION(
2366 oldState.Z == Teuchos::null,
2368 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): oldState.Z is null.");
2370 TEUCHOS_TEST_FOR_EXCEPTION(
2371 W_ == Teuchos::null,
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);
2384 dscalar.resize(keff);
2386 MVT::MvNorm(*Utmp, d);
2387 for (
int i=0; i<keff; ++i) {
2388 d[i] = magOne / d[i];
2389 dscalar[i] =
static_cast<ScalarType
>(d[i]);
2392 MVT::MvScale(*Utmp, dscalar);
2393 MVT::MvScale(*Wtmp, dscalar);
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) {
2402 DMT::Value(*H2tmp, i, i) = d[i];
2405 DMT::SyncHostToDevice(*H2_);
2410 DMT::SyncDeviceToHost(*PP_);
2411 Teuchos::RCP<DM> PPtmp = DMT::Subview(*PP_, p+keff, recycledBlocks_+1);
2412 keff_new = getFlexibleHarmonicVecs2(keff, p, *H2tmp, oldState.V, *PPtmp);
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);
2424 index.resize(keff_new);
2425 for (
int ii=0; ii<keff_new; ++ii) index[ii] = ii;
2427 U1tmp = MVT::CloneViewNonConst(*U1_, index);
2429 Teuchos::RCP<const DM> PPtop = DMT::SubviewConst(*PP_, keff, keff_new);
2430 MVT::MvTimesMatAddMv(one, *Utmp, *PPtop, zero, *U1tmp);
2435 for (
int ii=0; ii<p; ++ii) index[ii] = ii;
2437 Teuchos::RCP<const MV> Ztmp = MVT::CloneView(*oldState.Z, index);
2438 Teuchos::RCP<const DM> PPbottom = DMT::SubviewConst(*PP_, p, keff_new, keff);
2440 MVT::MvTimesMatAddMv(one, *Ztmp, *PPbottom, one, *U1tmp);
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);
2451 index.resize(keff_new);
2452 for (
int ii=0; ii<keff_new; ++ii) index[ii] = ii;
2454 W1tmp = MVT::CloneViewNonConst(*W1_, index);
2456 Teuchos::RCP<const DM> PPtop = DMT::SubviewConst(*PP_, keff, keff_new);
2457 MVT::MvTimesMatAddMv(one, *Wtmp, *PPtop, zero, *W1tmp);
2462 for (
int ii=0; ii<p; ++ii) index[ii] = ii;
2464 Teuchos::RCP<const MV> Vtmp = MVT::CloneView(*oldState.V, index);
2465 Teuchos::RCP<const DM> PPbottom = DMT::SubviewConst(*PP_, p, keff_new, keff);
2467 MVT::MvTimesMatAddMv(one, *Vtmp, *PPbottom, one, *W1tmp);
2471 DMT::SyncDeviceToHost(*HP_);
2472 Teuchos::RCP<DM> HPtmp = DMT::Subview(*HP_, p+keff+1, keff_new);
2475 DMT::SyncDeviceToHost(*PP_);
2476 DMT::SyncDeviceToHost(*H2_);
2477 Teuchos::RCP<DM> PPtmp = DMT::Subview(*PP_, p+keff, keff_new);
2479 Teuchos::BLAS<int,ScalarType> blas;
2480 blas.GEMM(Teuchos::NO_TRANS, Teuchos::NO_TRANS,
2481 p+keff+1, keff_new, p+keff,
2483 DMT::GetConstRawHostPtr(*H2tmp), DMT::GetStride(*H2tmp),
2484 DMT::GetConstRawHostPtr(*PPtmp), DMT::GetStride(*PPtmp),
2486 DMT::GetRawHostPtr(*HPtmp), DMT::GetStride(*HPtmp));
2493 tau_.resize(keff_new);
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),
2500 &tau_[0], &work_[0], lwork, &info);
2502 TEUCHOS_TEST_FOR_EXCEPTION(
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),
2514 &tau_[0], &work_[0], lwork, &info);
2516 TEUCHOS_TEST_FOR_EXCEPTION(
2519 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GEQRF failed.");
2522 DMT::SyncDeviceToHost(*R_);
2523 Teuchos::RCP<DM> Rtmp = DMT::Subview(*R_, keff_new, keff_new);
2525 for (
int i=0; i<keff_new; ++i) {
2526 for (
int j=i; j<keff_new; ++j) {
2527 DMT::Value(*Rtmp, i, j) = DMT::ValueConst(*HPtmp, i, j);
2532 lapack.UNGQR(DMT::GetNumRows(*HPtmp),
2533 DMT::GetNumCols(*HPtmp),
2534 DMT::GetNumCols(*HPtmp),
2535 DMT::GetRawHostPtr(*HPtmp),
2536 DMT::GetStride(*HPtmp),
2537 &tau_[0], &work_[0], lwork, &info);
2539 TEUCHOS_TEST_FOR_EXCEPTION(
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);
2556 index.resize(keff_new);
2557 for (
int i=0; i<keff_new; ++i) index[i] = i;
2559 C1tmp = MVT::CloneViewNonConst(*C1_, index);
2561 Teuchos::RCP<const DM> Qtop = DMT::SubviewConst(*HP_, keff, keff_new);
2562 MVT::MvTimesMatAddMv(one, *Ctmp, *Qtop, zero, *C1tmp);
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);
2572 MVT::MvTimesMatAddMv(one, *Vtmp, *Qbottom, one, *C1tmp);
2579 ipiv_.resize(DMT::GetNumRows(*Rtmp));
2581 lapack.GETRF(DMT::GetNumRows(*Rtmp),
2582 DMT::GetNumCols(*Rtmp),
2583 DMT::GetRawHostPtr(*Rtmp),
2584 DMT::GetStride(*Rtmp),
2587 TEUCHOS_TEST_FOR_EXCEPTION(
2590 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GETRF failed.");
2592 lwork = DMT::GetNumRows(*Rtmp);
2593 work_.resize(lwork);
2595 lapack.GETRI(DMT::GetNumRows(*Rtmp),
2596 DMT::GetRawHostPtr(*Rtmp),
2597 DMT::GetStride(*Rtmp),
2598 &ipiv_[0], &work_[0], lwork, &info);
2600 TEUCHOS_TEST_FOR_EXCEPTION(
2603 "Belos::GCRODRSolMgr::buildFlexibleRecycleSpace2(): LAPACK GETRI failed.");
2605 DMT::SyncHostToDevice(*R_);
2608 index.resize(keff_new);
2609 for (
int i=0; i<keff_new; ++i) index[i] = i;
2611 Teuchos::RCP<MV> Utmp = MVT::CloneViewNonConst(*U_, index);
2612 Teuchos::RCP<const MV> U1tmpConst = MVT::CloneView(*U1_, index);
2613 MVT::MvTimesMatAddMv(one, *U1tmpConst, *Rtmp, zero, *Utmp);
2615 Teuchos::RCP<MV> Wtmp = MVT::CloneViewNonConst(*W_, index);
2616 Teuchos::RCP<const MV> W1tmpConst = MVT::CloneView(*W1_, index);
2617 MVT::MvTimesMatAddMv(one, *W1tmpConst, *Rtmp, zero, *Wtmp);
2620 if (keff != keff_new) {
2622 gcrodr_iter->setSize(keff, numBlocks_);
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>
2635 bool xtraVec =
false;
2636 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
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);
2663 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GESV failed to compute a solution.");
2666 Teuchos::RCP<DM> tmpHH = DMT::CreateCopy( HH );
2667 DMT::SyncDeviceToHost( *tmpHH );
2669 ScalarType d = DMT::ValueConst(*tmpHH, m, m-1) * DMT::ValueConst(*tmpHH, m, m-1);
2670 Teuchos::RCP<DM> harmHH = DMT::Subview( *tmpHH, m, m );
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],
2686 vl, ldvl, DMT::GetRawHostPtr(*vr), DMT::GetStride(*vr), &work[0], lwork, &rwork[0], &info);
2688 lwork = std::abs (
static_cast<int> (Teuchos::ScalarTraits<ScalarType>::real (work[0])));
2689 work.resize( lwork );
2691 lapack.GEEV(
'N',
'V', m, DMT::GetRawHostPtr(*harmHH), DMT::GetStride(*harmHH), &wr[0], &wi[0],
2692 vl, ldvl, DMT::GetRawHostPtr(*vr), DMT::GetStride(*vr), &work[0], lwork, &rwork[0], &info);
2693 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,
GCRODRSolMgrLAPACKFailure,
"Belos::GCRODRSolMgr::solve(): LAPACK GEEV failed to compute eigensolutions.");
2696 for( i=0; i<m; ++i )
2697 w[i] = Teuchos::ScalarTraits<MagnitudeType>::squareroot( wr[i]*wr[i] + wi[i]*wi[i] );
2700 this->sort(w, m, iperm);
2702 const bool scalarTypeIsComplex = Teuchos::ScalarTraits<ScalarType>::isComplex;
2705 for( i=0; i<recycledBlocks_; ++i ) {
2706 for( j=0; j<m; j++ ) {
2707 DMT::Value(PP,j,i) = DMT::ValueConst(*vr,j,iperm[i]);
2711 if(!scalarTypeIsComplex) {
2714 if (wi[iperm[recycledBlocks_-1]] != 0.0) {
2716 for ( i=0; i<recycledBlocks_; ++i ) {
2717 if (wi[iperm[i]] != 0.0)
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>
2754 const Teuchos::RCP<const MV>& VV,
2757 int m2 = DMT::GetNumCols(HH);
2758 bool xtraVec =
false;
2759 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
2760 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
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);
2773 std::vector<int> iperm(m2);
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));
2791 Teuchos::RCP<DM> A_tmp = DMT::Create( keffloc+m+1, keffloc+m );
2794 index.resize(keffloc);
2795 for (i=0; i<keffloc; ++i) { index[i] = i; }
2796 Teuchos::RCP<const MV> Ctmp = MVT::CloneView( *C_, index );
2797 Teuchos::RCP<const MV> Utmp = MVT::CloneView( *U_, index );
2798 Teuchos::RCP<DM> A11 = DMT::Subview( *A_tmp, keffloc, keffloc );
2799 MVT::MvTransMv( one, *Ctmp, *Utmp, *A11 );
2802 Teuchos::RCP<DM> A21 = DMT::Subview( *A_tmp, m+1, keffloc, keffloc );
2804 for (i=0; i < m+1; i++) { index[i] = i; }
2805 Teuchos::RCP<const MV> Vp = MVT::CloneView( *VV, index );
2806 MVT::MvTransMv( one, *Vp, *Utmp, *A21 );
2808 A11 = Teuchos::null;
2809 A21 = Teuchos::null;
2810 DMT::SyncDeviceToHost(*A_tmp);
2813 for( i=keffloc; i<keffloc+m; i++ ) {
2814 DMT::Value(*A_tmp,i,i) = one;
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) );
2830 char balanc=
'P', jobvl=
'N', jobvr=
'V', sense=
'N';
2831 int ld = DMT::GetNumRows(*A);
2833 int ldvl = ld, ldvr = ld;
2834 int info = 0,ilo = 0,ihi = 0;
2835 MagnitudeType abnrm = 0.0, bbnrm = 0.0;
2837 std::vector<ScalarType> beta(ld);
2838 std::vector<ScalarType> work(lwork);
2839 std::vector<MagnitudeType> rwork(lwork);
2840 std::vector<MagnitudeType> lscale(ld), rscale(ld);
2841 std::vector<MagnitudeType> rconde(ld), rcondv(ld);
2842 std::vector<int> iwork(ld+6);
2847 lapack.GGEVX(balanc, jobvl, jobvr, sense, ld, DMT::GetRawHostPtr(*A), ld, DMT::GetRawHostPtr(*B),
2848 ld, &wr[0], &wi[0], &beta[0], vl, ldvl, DMT::GetRawHostPtr(*vr), ldvr, &ilo, &ihi,
2849 &lscale[0], &rscale[0], &abnrm, &bbnrm, &rconde[0], &rcondv[0], &work[0], lwork, &rwork[0],
2850 &iwork[0], bwork, &info);
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]);
2861 this->sort(w,ld,iperm);
2863 const bool scalarTypeIsComplex = Teuchos::ScalarTraits<ScalarType>::isComplex;
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]);
2872 if(!scalarTypeIsComplex) {
2875 if (wi[iperm[ld-recycledBlocks_]] != 0.0) {
2877 for ( i=ld-recycledBlocks_; i<ld; i++ ) {
2878 if (wi[iperm[i]] != 0.0)
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>
2925 const Teuchos::RCP<const MV>& VV,
2929 int m2 = DMT::GetNumCols(HH);
2930 bool xtraVec =
false;
2932 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
2933 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
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);
2942 std::vector<int> iperm(m2);
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));
2959 Teuchos::RCP<DM> A_tmp = DMT::Create(keffloc + m + 1, keffloc + m);
2960 DMT::PutScalar(*A_tmp, zero);
2963 index.resize(keffloc);
2964 for (i=0; i<keffloc; ++i) index[i] = i;
2966 Teuchos::RCP<const MV> Ctmp = MVT::CloneView(*C_, index);
2967 Teuchos::RCP<const MV> Wtmp = MVT::CloneView(*W_, index);
2968 Teuchos::RCP<DM> A11 = DMT::Subview(*A_tmp, keffloc, keffloc);
2970 MVT::MvTransMv(one, *Ctmp, *Wtmp, *A11);
2973 Teuchos::RCP<DM> A21 = DMT::Subview(*A_tmp, m+1, keffloc, keffloc);
2976 for (i=0; i<m+1; ++i) index[i] = i;
2978 Teuchos::RCP<const MV> Vp = MVT::CloneView(*VV, index);
2980 index.resize(keffloc);
2981 for (i=0; i<keffloc; ++i) index[i] = i;
2983 Wtmp = MVT::CloneView(*W_, index);
2985 MVT::MvTransMv(one, *Vp, *Wtmp, *A21);
2987 A11 = Teuchos::null;
2988 A21 = Teuchos::null;
2990 DMT::SyncDeviceToHost(*A_tmp);
2993 for (i=0; i<m; ++i) {
2994 DMT::Value(*A_tmp, keffloc+i, keffloc+i) = one;
2998 Teuchos::RCP<DM> A = DMT::Create(m2, DMT::GetNumCols(*A_tmp));
3000 blas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
3001 m2, DMT::GetNumCols(*A_tmp), DMT::GetNumRows(*A_tmp),
3003 DMT::GetConstRawHostPtr(HH), DMT::GetStride(HH),
3004 DMT::GetConstRawHostPtr(*A_tmp), DMT::GetStride(*A_tmp),
3006 DMT::GetRawHostPtr(*A), DMT::GetStride(*A));
3008 char balanc =
'P', jobvl =
'N', jobvr =
'V', sense =
'N';
3010 int ld = DMT::GetNumRows(*A);
3012 int ldvl = ld, ldvr = ld;
3013 int info = 0, ilo = 0, ihi = 0;
3015 MagnitudeType abnrm = 0.0, bbnrm = 0.0;
3018 std::vector<ScalarType> beta(ld);
3019 std::vector<ScalarType> work(lwork);
3020 std::vector<MagnitudeType> rwork(lwork);
3021 std::vector<MagnitudeType> lscale(ld), rscale(ld);
3022 std::vector<MagnitudeType> rconde(ld), rcondv(ld);
3023 std::vector<int> iwork(ld+6);
3026 lapack.GGEVX(balanc, jobvl, jobvr, sense, ld,
3027 DMT::GetRawHostPtr(*A), ld,
3028 DMT::GetRawHostPtr(*B), ld,
3029 &wr[0], &wi[0], &beta[0],
3031 DMT::GetRawHostPtr(*vr), ldvr,
3033 &lscale[0], &rscale[0],
3035 &rconde[0], &rcondv[0],
3036 &work[0], lwork, &rwork[0],
3037 &iwork[0], bwork, &info);
3039 TEUCHOS_TEST_FOR_EXCEPTION(
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]);
3050 this->sort(w, ld, iperm);
3052 const bool scalarTypeIsComplex = Teuchos::ScalarTraits<ScalarType>::isComplex;
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]);
3061 if (!scalarTypeIsComplex) {
3062 if (wi[iperm[ld-recycledBlocks_]] != 0.0) {
3064 for (i=ld-recycledBlocks_; i<ld; ++i) {
3065 if (wi[iperm[i]] != 0.0) {
3070 if (countImag % 2) {
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>
3103 int l, r, j, i, flag;
3105 MagnitudeType dRR, dK;
3132 if (dlist[j] > dlist[j - 1]) j = j + 1;
3134 if (dlist[j - 1] > dK) {
3135 dlist[i - 1] = dlist[j - 1];
3136 iperm[i - 1] = iperm[j - 1];
3150 dlist[r] = dlist[0];
3151 iperm[r] = iperm[0];
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.
BelosError(const std::string &what_arg)
An implementation of the Belos::MatOrthoManager that performs orthogonalization using (potentially) m...
void setDepTol(const MagnitudeType dep_tol)
Set parameter for re-orthogonalization threshhold.
Virtual base class which defines basic traits for the multi-vector type.
static Teuchos::RCP< DM > Subview(DM &source, int numRows, int numCols, int startRow=0, int startCol=0)
Marks host data modified to avoid device sync errors.
static void SyncHostToDevice(DM &dm)
static int GetNumRows(const DM &dm)
Obtain the number of rows of dm.
static ScalarType * GetRawHostPtr(DM &dm)
Returns a raw pointer to the (non-const) data on the host.
static const ScalarType & ValueConst(const DM &dm, const int i, const int j)
Access a const reference to the (i,j) entry of dm, e_i^T dm e_j.
static void SyncDeviceToHost(DM &dm)
static ScalarType const * GetConstRawHostPtr(const DM &dm)
Returns a raw pointer to const data on the host.
static ScalarType & Value(DM &dm, const int i, const int j)
Access a reference to the (i,j) entry of dm, e_i^T dm e_j.
static int GetStride(const DM &dm)
Obtain the stride between the columns of dm.
static Teuchos::RCP< DM > Create()
Creates a new empty DM with no dimension.
static int GetNumCols(const DM &dm)
Obtain the number of columns of dm.
Base class for Belos::SolverManager subclasses which normally can only compile with ScalarType types ...
This class implements the GCRODR iteration, where a single-vector Krylov subspace is constructed....
GCRODRIterOrthoFailure is thrown when the GCRODRIter object is unable to compute independent directio...
Common base interface for GCRODRIter and FGCRODRIter.
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 setParameters(const Teuchos::RCP< Teuchos::ParameterList > ¶ms) override
Set the parameters the solver manager should use to solve the linear problem.
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...
GCRODRSolMgr()
Empty constructor for GCRODRSolMgr. This constructor takes no arguments and sets the default values f...
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().
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
Get a parameter list containing the valid parameters for this object.
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)
Traits class which defines basic operations on multivectors.
static void MvInit(MV &mv, const ScalarType alpha=Teuchos::ScalarTraits< ScalarType >::zero())
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
static void MvTimesMatAddMv(const ScalarType alpha, const MV &A, const DM &B, const ScalarType beta, MV &mv)
static Teuchos::RCP< const MV > CloneView(const MV &mv, const std::vector< int > &index)
static void MvTransMv(const ScalarType alpha, const MV &A, const MV &mv, DM &B)
static ptrdiff_t GetGlobalLength(const MV &mv)
static void SetBlock(const MV &A, const std::vector< int > &index, MV &mv)
static Teuchos::RCP< MV > CloneViewNonConst(MV &mv, const std::vector< int > &index)
static int GetNumberVecs(const MV &mv)
Class which defines basic traits for the operator type.
Enumeration of all valid Belos (Mat)OrthoManager classes.
Teuchos::RCP< const Teuchos::ParameterList > getDefaultParameters(const std::string &name) const
Default parameters for the given MatOrthoManager subclass.
std::ostream & printValidNames(std::ostream &out) const
Print all recognized MatOrthoManager names to the given ostream.
Teuchos::RCP< Belos::MatOrthoManager< Scalar, MV, OP, DM > > makeMatOrthoManager(const std::string &ortho, const Teuchos::RCP< const OP > &M, const Teuchos::RCP< OutputManager< Scalar > > &, const std::string &label, const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Return an instance of the specified MatOrthoManager subclass.
bool isValidName(const std::string &name) const
Whether this factory recognizes the MatOrthoManager with the given name.
std::string validNamesString() const
List (as a string) of recognized MatOrthoManager names.
Belos's basic output manager for sending information of select verbosity levels to the appropriate ou...
A class for extending the status testing capabilities of Belos via logical combinations.
Exception thrown to signal error in a status test during Belos::StatusTest::checkStatus().
An implementation of StatusTestResNorm using a family of residual norms.
A pure virtual class for defining the status tests for the Belos iterative solvers.
A Belos::StatusTest class for specifying a maximum number of iterations.
A factory class for generating StatusTestOutput objects.
Teuchos::RCP< StatusTestOutput< ScalarType, MV, OP, DM > > create(const Teuchos::RCP< OutputManager< ScalarType > > &printer, Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > test, int mod, int printStates)
Create the StatusTestOutput object specified by the outputStyle.
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.
Structure to contain pointers to GCRODRIter state variables.
Teuchos::RCP< DM > H
The current Hessenberg matrix.
Teuchos::RCP< DM > H2
The global projection matrix including Krylov subpace and recycled subspace.
int curDim
The current dimension of the reduction.
Teuchos::RCP< MV > V
The current Krylov basis.
Teuchos::RCP< MV > U
The recycled subspace and its projection.
Teuchos::RCP< MV > Z
Optional flexible correction basis. Used by FGCRODRIter.