10#ifndef BELOS_PCPG_SOLMGR_HPP
11#define BELOS_PCPG_SOLMGR_HPP
30#include "Teuchos_LAPACK.hpp"
31#ifdef BELOS_TEUCHOS_TIME_MONITOR
32# include "Teuchos_TimeMonitor.hpp"
34#if defined(HAVE_TEUCHOSCORE_CXX11)
35# include <type_traits>
109 template<
class ScalarType,
class MV,
class OP,
110 const bool supportsScalarType =
112 ! Teuchos::ScalarTraits<ScalarType>::isComplex>
115 Belos::Details::LapackSupportsScalar<ScalarType>::value &&
116 ! Teuchos::ScalarTraits<ScalarType>::isComplex>
118 static const bool scalarTypeIsSupported =
120 ! Teuchos::ScalarTraits<ScalarType>::isComplex;
129 const Teuchos::RCP<Teuchos::ParameterList> &
pl) :
135 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
140 template<
class ScalarType,
class MV,
class OP>
146 typedef Teuchos::ScalarTraits<ScalarType> SCT;
147 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
148 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
198 const Teuchos::RCP<Teuchos::ParameterList> &
pl );
204 virtual Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const {
220 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const;
231 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
232 return Teuchos::tuple(timerSolve_);
262 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> &
params );
303 std::string description()
const;
311 int ARRQR(
int numVecs,
int numOrthVecs,
const Teuchos::SerialDenseMatrix<int,ScalarType>& D);
314 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
317 Teuchos::RCP<OutputManager<ScalarType> > printer_;
318 Teuchos::RCP<std::ostream> outputStream_;
321 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
322 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
323 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
324 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
327 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
330 Teuchos::RCP<Teuchos::ParameterList> params_;
333 static constexpr int maxIters_default_ = 1000;
334 static constexpr int deflatedBlocks_default_ = 2;
335 static constexpr int savedBlocks_default_ = 16;
338 static constexpr int outputFreq_default_ = -1;
339 static constexpr const char * label_default_ =
"Belos";
340 static constexpr const char * orthoType_default_ =
"ICGS";
347 MagnitudeType convtol_;
350 MagnitudeType orthoKappa_;
353 MagnitudeType achievedTol_;
361 int deflatedBlocks_, savedBlocks_, verbosity_, outputStyle_, outputFreq_;
362 std::string orthoType_;
365 Teuchos::RCP<MV> U_, C_, R_;
372 Teuchos::RCP<Teuchos::Time> timerSolve_;
380template<
class ScalarType,
class MV,
class OP>
387 maxIters_(maxIters_default_),
388 deflatedBlocks_(deflatedBlocks_default_),
389 savedBlocks_(savedBlocks_default_),
390 verbosity_(verbosity_default_),
391 outputStyle_(outputStyle_default_),
392 outputFreq_(outputFreq_default_),
393 orthoType_(orthoType_default_),
395 label_(label_default_),
401template<
class ScalarType,
class MV,
class OP>
404 const Teuchos::RCP<Teuchos::ParameterList> &
pl ) :
412 maxIters_(maxIters_default_),
413 deflatedBlocks_(deflatedBlocks_default_),
414 savedBlocks_(savedBlocks_default_),
415 verbosity_(verbosity_default_),
416 outputStyle_(outputStyle_default_),
417 outputFreq_(outputFreq_default_),
418 orthoType_(orthoType_default_),
420 label_(label_default_),
424 problem_.is_null (), std::invalid_argument,
425 "Belos::PCPGSolMgr two-argument constructor: "
426 "'problem' is null. You must supply a non-null Belos::LinearProblem "
427 "instance when calling this constructor.");
429 if (!
pl.is_null ()) {
436template<
class ScalarType,
class MV,
class OP>
440 if (params_ == Teuchos::null) {
441 params_ = Teuchos::rcp(
new Teuchos::ParameterList(*getValidParameters()) );
444 params->validateParameters(*getValidParameters());
448 if (
params->isParameter(
"Maximum Iterations")) {
449 maxIters_ =
params->get(
"Maximum Iterations",maxIters_default_);
452 params_->set(
"Maximum Iterations", maxIters_);
453 if (maxIterTest_!=Teuchos::null)
454 maxIterTest_->setMaxIters( maxIters_ );
458 if (
params->isParameter(
"Num Saved Blocks")) {
459 savedBlocks_ =
params->get(
"Num Saved Blocks",savedBlocks_default_);
461 "Belos::PCPGSolMgr: \"Num Saved Blocks\" must be strictly positive.");
468 params_->set(
"Num Saved Blocks", savedBlocks_);
470 if (
params->isParameter(
"Num Deflated Blocks")) {
471 deflatedBlocks_ =
params->get(
"Num Deflated Blocks",deflatedBlocks_default_);
473 "Belos::PCPGSolMgr: \"Num Deflated Blocks\" must be positive.");
476 "Belos::PCPGSolMgr: \"Num Deflated Blocks\" must be <= \"Num Saved Blocks\".");
480 params_->set(
"Num Deflated Blocks",
static_cast<int>(deflatedBlocks_));
484 if (
params->isParameter(
"Timer Label")) {
490 params_->set(
"Timer Label", label_);
491 std::string
solveLabel = label_ +
": PCPGSolMgr total solve time";
492#ifdef BELOS_TEUCHOS_TIME_MONITOR
493 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
495 if (ortho_ != Teuchos::null) {
496 ortho_->setLabel( label_ );
502 if (
params->isParameter(
"Verbosity")) {
503 if (Teuchos::isParameterType<int>(*
params,
"Verbosity")) {
504 verbosity_ =
params->get(
"Verbosity", verbosity_default_);
506 verbosity_ = (
int)Teuchos::getParameter<Belos::MsgType>(*
params,
"Verbosity");
510 params_->set(
"Verbosity", verbosity_);
511 if (printer_ != Teuchos::null)
512 printer_->setVerbosity(verbosity_);
516 if (
params->isParameter(
"Output Style")) {
517 if (Teuchos::isParameterType<int>(*
params,
"Output Style")) {
518 outputStyle_ =
params->get(
"Output Style", outputStyle_default_);
520 outputStyle_ = (
int)Teuchos::getParameter<Belos::OutputType>(*
params,
"Output Style");
524 params_->set(
"Output Style", outputStyle_);
525 outputTest_ = Teuchos::null;
529 if (
params->isParameter(
"Output Stream")) {
530 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*
params,
"Output Stream");
533 params_->set(
"Output Stream", outputStream_);
534 if (printer_ != Teuchos::null)
535 printer_->setOStream( outputStream_ );
540 if (
params->isParameter(
"Output Frequency")) {
541 outputFreq_ =
params->get(
"Output Frequency", outputFreq_default_);
545 params_->set(
"Output Frequency", outputFreq_);
546 if (outputTest_ != Teuchos::null)
547 outputTest_->setOutputFrequency( outputFreq_ );
551 if (printer_ == Teuchos::null) {
557 if (
params->isParameter(
"Orthogonalization")) {
564 params_->set(
"Orthogonalization", orthoType_);
567 if (
params->isParameter(
"Orthogonalization Constant")) {
568 if (
params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
569 orthoKappa_ =
params->get (
"Orthogonalization Constant",
573 orthoKappa_ =
params->get (
"Orthogonalization Constant",
578 params_->set(
"Orthogonalization Constant",orthoKappa_);
579 if (orthoType_==
"DGKS") {
581 Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
590 if (orthoType_==
"DGKS" && orthoKappa_ > 0) {
591 paramsOrtho = Teuchos::rcp(
new Teuchos::ParameterList());
595 ortho_ =
factory.makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_,
paramsOrtho);
603 if (
params->isParameter(
"Convergence Tolerance")) {
604 if (
params->isType<MagnitudeType> (
"Convergence Tolerance")) {
605 convtol_ =
params->get (
"Convergence Tolerance",
613 params_->set(
"Convergence Tolerance", convtol_);
614 if (convTest_ != Teuchos::null)
615 convTest_->setTolerance( convtol_ );
621 if (maxIterTest_ == Teuchos::null)
624 if (convTest_ == Teuchos::null)
625 convTest_ = Teuchos::rcp(
new StatusTestResNorm_t( convtol_, 1 ) );
627 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
639 if (timerSolve_ == Teuchos::null) {
640 std::string
solveLabel = label_ +
": PCPGSolMgr total solve time";
641#ifdef BELOS_TEUCHOS_TIME_MONITOR
642 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
651template<
class ScalarType,
class MV,
class OP>
652Teuchos::RCP<const Teuchos::ParameterList>
655 static Teuchos::RCP<const Teuchos::ParameterList>
validPL;
657 Teuchos::RCP<Teuchos::ParameterList>
pl = Teuchos::parameterList();
660 "The relative residual tolerance that needs to be achieved by the\n"
661 "iterative solver in order for the linear system to be declared converged.");
662 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
663 "The maximum number of iterations allowed for each\n"
664 "set of RHS solved.");
665 pl->set(
"Num Deflated Blocks",
static_cast<int>(deflatedBlocks_default_),
666 "The maximum number of vectors in the seed subspace." );
667 pl->set(
"Num Saved Blocks",
static_cast<int>(savedBlocks_default_),
668 "The maximum number of vectors saved from old Krylov subspaces." );
669 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
670 "What type(s) of solver information should be outputted\n"
671 "to the output stream.");
672 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
673 "What style is used for the solver information outputted\n"
674 "to the output stream.");
675 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
676 "How often convergence information should be outputted\n"
677 "to the output stream.");
678 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
679 "A reference-counted pointer to the output stream where all\n"
680 "solver output is sent.");
681 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
682 "The string to use as a prefix for the timer labels.");
683 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
684 "The type of orthogonalization to use: DGKS, ICGS, IMGS");
686 "The constant used by DGKS orthogonalization to determine\n"
687 "whether another step of classical Gram-Schmidt is necessary.");
695template<
class ScalarType,
class MV,
class OP>
699 if (!isSet_) { setParameters( params_ ); }
701 Teuchos::LAPACK<int,ScalarType> lapack;
706 "Belos::PCPGSolMgr::solve(): Linear problem is not a valid object.");
709 "Belos::PCPGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
712 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
719 problem_->setLSIndex(
currIdx );
726 Teuchos::ParameterList
plist;
727 plist.set(
"Saved Blocks", savedBlocks_);
728 plist.set(
"Block Size", 1);
729 plist.set(
"Keep Diagonal",
true);
730 plist.set(
"Initialize Diagonal",
true);
735 Teuchos::RCP<PCPGIter<ScalarType,MV,OP> >
pcpg_iter;
741#ifdef BELOS_TEUCHOS_TIME_MONITOR
742 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
747 outputTest_->reset();
750 if (R_ == Teuchos::null)
751 R_ = MVT::Clone( *(problem_->getRHS()), 1 );
753 problem_->computeCurrResVec( &*R_ );
759 if( U_ != Teuchos::null ){
764 Teuchos::RCP<MV>
cur_soln_vec = problem_->getCurrLHSVec();
765 std::vector<MagnitudeType>
rnorm0(1);
766 MVT::MvNorm( *R_,
rnorm0 );
769 std::cout <<
"Solver Manager: dimU_ = " << dimU_ << std::endl;
770 Teuchos::SerialDenseMatrix<int,ScalarType> Z( dimU_, 1 );
779 std::cout <<
" Solver Manager : check duality of seed basis " << std::endl;
780 Teuchos::SerialDenseMatrix<int,ScalarType> H( dimU_, dimU_ );
782 H.print( std::cout );
786 Teuchos::RCP<MV>
tempU = MVT::Clone( *R_, 1 );
791 std::vector<MagnitudeType>
rnorm(1);
792 MVT::MvNorm( *R_,
rnorm );
802 tempU = Teuchos::null;
813 if( U_ != Teuchos::null )
pcpgState.U = U_;
814 if( C_ != Teuchos::null )
pcpgState.C = C_;
815 if( dimU_ > 0 )
pcpgState.curDim = dimU_;
822 if( !dimU_ ) printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " <<
currIdx[0] << std::endl << std::endl;
825 if( dimU_ > savedBlocks_ )
826 std::cout <<
"Error: dimU_ = " << dimU_ <<
" > savedBlocks_ = " << savedBlocks_ << std::endl;
832 if(
debug )
printf(
"********** Calling iterate...\n");
840 if ( convTest_->getStatus() ==
Passed ) {
849 else if ( maxIterTest_->getStatus() ==
Passed ) {
864 "Belos::PCPGSolMgr::solve(): Invalid return from PCPGIter::iterate().");
869 achievedTol_ = MT::one();
870 Teuchos::RCP<MV>
X = problem_->getLHS();
871 MVT::MvInit( *
X, SCT::zero() );
872 printer_->stream(
Warnings) <<
"Belos::PCPG::solve(): Warning! NaN has been detected!"
876 catch (
const std::exception &
e) {
877 printer_->stream(
Errors) <<
"Error! Caught exception in PCPGIter::iterate() at iteration "
879 <<
e.what() << std::endl;
886 problem_->updateSolution(
update,
true );
889 problem_->setCurrLS();
897 std::cout <<
"SolverManager: dimU_ " << dimU_ <<
" prevUdim= " <<
q << std::endl;
899 if(
q > deflatedBlocks_ )
900 std::cout <<
"SolverManager: Error deflatedBlocks = " << deflatedBlocks_ << std::endl;
913 std::cout <<
" rank decreased in ARRQR, something to do? " << std::endl;
919 if( dimU_ > deflatedBlocks_ ){
921 if( !deflatedBlocks_ ){
924 dimU_ = deflatedBlocks_;
930 Teuchos::RCP<MV>
Uorth;
943 Teuchos::SerialDenseMatrix<int,ScalarType> R(dimU_,dimU_);
944 rank = ortho_->normalize(*
Uorth, Teuchos::rcp(&R,
false));
945 Uorth = Teuchos::null;
951 "Belos::PCPGSolMgr::solve(): Failed to compute orthonormal basis for initial recycled subspace.");
955 Teuchos::SerialDenseMatrix<int,ScalarType>
VT;
956 Teuchos::SerialDenseMatrix<int,ScalarType>
Ur;
960 if( problem_->isHermitian() )
lrwork = dimU_;
962 std::vector<ScalarType>
Svec(dimU_);
964 lapack.GESVD(
'N',
'O',
965 R.numRows(),R.numCols(),R.values(), R.numRows(),
973 "Belos::PCPGSolMgr::solve(): LAPACK _GESVD failed to compute singular values.");
975 if(
work[0] != 67. * dimU_ )
976 std::cout <<
" SVD " << dimU_ <<
" lwork " <<
work[0] << std::endl;
977 for(
int i=0;
i< dimU_;
i++)
978 std::cout <<
i <<
" " <<
Svec[
i] << std::endl;
980 Teuchos::SerialDenseMatrix<int,ScalarType>
wholeV( R, Teuchos::TRANS);
986 Teuchos::SerialDenseMatrix<int,ScalarType> V(Teuchos::Copy,
993 std::vector<int>
def_cols( deflatedBlocks_ );
1000 Ucopy = Teuchos::null;
1005 Ccopy = Teuchos::null;
1007 dimU_ = deflatedBlocks_;
1009 printer_->stream(
Debug) <<
" Generated recycled subspace using RHS index " <<
currIdx[0] <<
" of dimension " << dimU_ << std::endl << std::endl;
1012 problem_->setCurrLS();
1020 problem_->setLSIndex(
currIdx );
1032#ifdef BELOS_TEUCHOS_TIME_MONITOR
1037 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1042 using Teuchos::rcp_dynamic_cast;
1049 "Belos::PCPGSolMgr::solve(): The convergence test's getTestValue() "
1050 "method returned NULL. Please report this bug to the Belos developers.");
1053 "Belos::PCPGSolMgr::solve(): The convergence test's getTestValue() "
1054 "method returned a vector of length zero. Please report this bug to the "
1055 "Belos developers.");
1064 numIters_ = maxIterTest_->getNumIters();
1075template<
class ScalarType,
class MV,
class OP>
1083 Teuchos::SerialDenseMatrix<int,ScalarType> alpha( 1, 1 );
1084 Teuchos::SerialDenseMatrix<int,ScalarType>
gamma( 1, 1 );
1085 Teuchos::SerialDenseMatrix<int,ScalarType>
anorm( 1, 1 );
1086 std::vector<int>
curind(1);
1087 std::vector<int> ipiv(
p -
q);
1088 std::vector<ScalarType>
Pivots(
p);
1093 for(
i =
q ;
i <
p ;
i++ ){
1098 anorm(0,0) =
one / Teuchos::ScalarTraits<ScalarType>::squareroot( D(
i-
q,
i-
q) ) ;
1099 MVT::MvAddMv(
anorm(0,0), *P,
zero, *AP, *P );
1100 MVT::MvAddMv(
zero, *P,
anorm(0,0), *AP, *AP );
1104 for(
i =
q ;
i <
p ;
i++ ){
1105 if(
q <
i &&
i <
p-1 ){
1108 for(
j =
i+1 ;
j <
p ;
j++ ){
1109 const int k = ipiv[
j-
q];
1130 MVT::MvTransMv(
one, *P, *AP,
anorm );
1131 anorm(0,0) = Teuchos::ScalarTraits<ScalarType>::squareroot(
anorm(0,0) ) ;
1141 std::cout <<
"ARRQR: Bad case not implemented" << std::endl;
1144 std::cout <<
"ARRQR : deficient case not implemented " << std::endl;
1154 MVT::MvAddMv(
anorm(0,0), *P,
zero, *AP, *P );
1155 MVT::MvAddMv(
zero, *P,
anorm(0,0), *AP, *AP );
1159 P = MVT::CloneViewNonConst(*U_,
curind);
1160 AP = MVT::CloneViewNonConst(*C_,
curind);
1161 for(
j =
i+1 ;
j <
p ;
j++ ){
1165 MVT::MvTransMv(
one, *
Q, *AP, alpha);
1166 MVT::MvAddMv( -alpha(0,0), *P,
one, *
Q, *
Q );
1169 MVT::MvAddMv( -alpha(0,0), *AP,
one, *
AQ, *
AQ );
1172 if(
gamma(0,0) > 0){
1173 Pivots[
l] = Teuchos::ScalarTraits<ScalarType>::squareroot(
gamma(0,0) );
1184template<
class ScalarType,
class MV,
class OP>
1187 std::ostringstream
oss;
1188 oss <<
"Belos::PCPGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
1190 oss <<
"Ortho Type='"<<orthoType_;
Belos header file which uses auto-configuration information to include necessary C++ headers.
Class which describes the linear problem to be solved by the iterative solver.
Class which manages the output and verbosity of the Belos solvers.
Belos concrete class to iterate Preconditioned Conjugate Projected Gradients.
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 real ScalarType t...
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).
PCPGSolMgrLAPACKFailure is thrown when a nonzero value is retuned from an LAPACK call.
PCPGSolMgrLAPACKFailure(const std::string &what_arg)
PCPGSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i.e.
PCPGSolMgrLinearProblemFailure(const std::string &what_arg)
PCPGSolMgrOrthoFailure is thrown when the orthogonalization manager is unable to generate orthonormal...
PCPGSolMgrOrthoFailure(const std::string &what_arg)
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get current linear problem being solved for in this object.
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const
Get a parameter list containing the current parameters for this object.
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem)
Set the linear problem that needs to be solved.
bool isLOADetected() const
Return whether a loss of accuracy was detected by this solver during the most current solve.
int getNumIters() const
Get the iteration count for the most recent call to solve().
virtual ~PCPGSolMgr()
Destructor.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
virtual Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const
clone for Inverted Injection (DII)
MagnitudeType achievedTol() const
Tolerance achieved by the last solve() invocation.
void reset(const ResetType type)
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
PCPG iterative linear solver.
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
PCPGSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< Teuchos::ParameterList > &pl)
ReturnType
Whether the Belos solve converged for all linear systems.
ResetType
How to reset the solver.
Default parameters common to most Belos solvers.
static const double convTol
Default convergence tolerance.
static const double orthoKappa
DGKS orthogonalization constant.