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>
700 if (!isSet_) { setParameters( params_ ); }
702 Teuchos::LAPACK<int,ScalarType> lapack;
707 "Belos::PCPGSolMgr::solve(): Linear problem is not a valid object.");
710 "Belos::PCPGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
713 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
720 problem_->setLSIndex(
currIdx );
727 Teuchos::ParameterList
plist;
728 plist.set(
"Saved Blocks", savedBlocks_);
729 plist.set(
"Block Size", 1);
730 plist.set(
"Keep Diagonal",
true);
731 plist.set(
"Initialize Diagonal",
true);
736 Teuchos::RCP<PCPGIter<ScalarType,MV,OP> >
pcpg_iter;
742#ifdef BELOS_TEUCHOS_TIME_MONITOR
743 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
748 outputTest_->reset();
751 if (R_ == Teuchos::null)
752 R_ = MVT::Clone( *(problem_->getRHS()), 1 );
754 problem_->computeCurrResVec( &*R_ );
760 if( U_ != Teuchos::null ){
765 Teuchos::RCP<MV>
cur_soln_vec = problem_->getCurrLHSVec();
766 std::vector<MagnitudeType>
rnorm0(1);
767 MVT::MvNorm( *R_,
rnorm0 );
770 std::cout <<
"Solver Manager: dimU_ = " << dimU_ << std::endl;
771 Teuchos::SerialDenseMatrix<int,ScalarType> Z( dimU_, 1 );
780 std::cout <<
" Solver Manager : check duality of seed basis " << std::endl;
781 Teuchos::SerialDenseMatrix<int,ScalarType> H( dimU_, dimU_ );
783 H.print( std::cout );
787 Teuchos::RCP<MV>
tempU = MVT::Clone( *R_, 1 );
792 std::vector<MagnitudeType>
rnorm(1);
793 MVT::MvNorm( *R_,
rnorm );
803 tempU = Teuchos::null;
814 if( U_ != Teuchos::null )
pcpgState.U = U_;
815 if( C_ != Teuchos::null )
pcpgState.C = C_;
816 if( dimU_ > 0 )
pcpgState.curDim = dimU_;
823 if( !dimU_ ) printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " <<
currIdx[0] << std::endl << std::endl;
826 if( dimU_ > savedBlocks_ )
827 std::cout <<
"Error: dimU_ = " << dimU_ <<
" > savedBlocks_ = " << savedBlocks_ << std::endl;
833 if(
debug )
printf(
"********** Calling iterate...\n");
841 if ( convTest_->getStatus() ==
Passed ) {
850 else if ( maxIterTest_->getStatus() ==
Passed ) {
866 "Belos::PCPGSolMgr::solve(): Invalid return from PCPGIter::iterate().");
872 achievedTol_ = MT::one();
873 Teuchos::RCP<MV>
X = problem_->getLHS();
874 MVT::MvInit( *
X, SCT::zero() );
875 printer_->stream(
Warnings) <<
"Belos::PCPG::solve(): Warning! NaN has been detected!"
879 catch (
const std::exception &
e) {
881 printer_->stream(
Errors) <<
"Error! Caught exception in PCPGIter::iterate() at iteration "
883 <<
e.what() << std::endl;
890 problem_->updateSolution(
update,
true );
893 problem_->setCurrLS();
901 std::cout <<
"SolverManager: dimU_ " << dimU_ <<
" prevUdim= " <<
q << std::endl;
903 if(
q > deflatedBlocks_ )
904 std::cout <<
"SolverManager: Error deflatedBlocks = " << deflatedBlocks_ << std::endl;
917 std::cout <<
" rank decreased in ARRQR, something to do? " << std::endl;
923 if( dimU_ > deflatedBlocks_ ){
925 if( !deflatedBlocks_ ){
928 dimU_ = deflatedBlocks_;
934 Teuchos::RCP<MV>
Uorth;
947 Teuchos::SerialDenseMatrix<int,ScalarType> R(dimU_,dimU_);
948 rank = ortho_->normalize(*
Uorth, Teuchos::rcp(&R,
false));
949 Uorth = Teuchos::null;
955 "Belos::PCPGSolMgr::solve(): Failed to compute orthonormal basis for initial recycled subspace.");
959 Teuchos::SerialDenseMatrix<int,ScalarType>
VT;
960 Teuchos::SerialDenseMatrix<int,ScalarType>
Ur;
964 if( problem_->isHermitian() )
lrwork = dimU_;
966 std::vector<ScalarType>
Svec(dimU_);
968 lapack.GESVD(
'N',
'O',
969 R.numRows(),R.numCols(),R.values(), R.numRows(),
977 "Belos::PCPGSolMgr::solve(): LAPACK _GESVD failed to compute singular values.");
979 if(
work[0] != 67. * dimU_ )
980 std::cout <<
" SVD " << dimU_ <<
" lwork " <<
work[0] << std::endl;
981 for(
int i=0;
i< dimU_;
i++)
982 std::cout <<
i <<
" " <<
Svec[
i] << std::endl;
984 Teuchos::SerialDenseMatrix<int,ScalarType>
wholeV( R, Teuchos::TRANS);
990 Teuchos::SerialDenseMatrix<int,ScalarType> V(Teuchos::Copy,
997 std::vector<int>
def_cols( deflatedBlocks_ );
1004 Ucopy = Teuchos::null;
1009 Ccopy = Teuchos::null;
1011 dimU_ = deflatedBlocks_;
1013 printer_->stream(
Debug) <<
" Generated recycled subspace using RHS index " <<
currIdx[0] <<
" of dimension " << dimU_ << std::endl << std::endl;
1016 problem_->setCurrLS();
1024 problem_->setLSIndex(
currIdx );
1036#ifdef BELOS_TEUCHOS_TIME_MONITOR
1041 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1046 using Teuchos::rcp_dynamic_cast;
1053 "Belos::PCPGSolMgr::solve(): The convergence test's getTestValue() "
1054 "method returned NULL. Please report this bug to the Belos developers.");
1057 "Belos::PCPGSolMgr::solve(): The convergence test's getTestValue() "
1058 "method returned a vector of length zero. Please report this bug to the "
1059 "Belos developers.");
1068 numIters_ = maxIterTest_->getNumIters();
1079template<
class ScalarType,
class MV,
class OP>
1087 Teuchos::SerialDenseMatrix<int,ScalarType> alpha( 1, 1 );
1088 Teuchos::SerialDenseMatrix<int,ScalarType>
gamma( 1, 1 );
1089 Teuchos::SerialDenseMatrix<int,ScalarType>
anorm( 1, 1 );
1090 std::vector<int>
curind(1);
1091 std::vector<int> ipiv(
p -
q);
1092 std::vector<ScalarType>
Pivots(
p);
1097 for(
i =
q ;
i <
p ;
i++ ){
1102 anorm(0,0) =
one / Teuchos::ScalarTraits<ScalarType>::squareroot( D(
i-
q,
i-
q) ) ;
1103 MVT::MvAddMv(
anorm(0,0), *P,
zero, *AP, *P );
1104 MVT::MvAddMv(
zero, *P,
anorm(0,0), *AP, *AP );
1108 for(
i =
q ;
i <
p ;
i++ ){
1109 if(
q <
i &&
i <
p-1 ){
1112 for(
j =
i+1 ;
j <
p ;
j++ ){
1113 const int k = ipiv[
j-
q];
1134 MVT::MvTransMv(
one, *P, *AP,
anorm );
1135 anorm(0,0) = Teuchos::ScalarTraits<ScalarType>::squareroot(
anorm(0,0) ) ;
1145 std::cout <<
"ARRQR: Bad case not implemented" << std::endl;
1148 std::cout <<
"ARRQR : deficient case not implemented " << std::endl;
1158 MVT::MvAddMv(
anorm(0,0), *P,
zero, *AP, *P );
1159 MVT::MvAddMv(
zero, *P,
anorm(0,0), *AP, *AP );
1163 P = MVT::CloneViewNonConst(*U_,
curind);
1164 AP = MVT::CloneViewNonConst(*C_,
curind);
1165 for(
j =
i+1 ;
j <
p ;
j++ ){
1169 MVT::MvTransMv(
one, *
Q, *AP, alpha);
1170 MVT::MvAddMv( -alpha(0,0), *P,
one, *
Q, *
Q );
1173 MVT::MvAddMv( -alpha(0,0), *AP,
one, *
AQ, *
AQ );
1176 if(
gamma(0,0) > 0){
1177 Pivots[
l] = Teuchos::ScalarTraits<ScalarType>::squareroot(
gamma(0,0) );
1188template<
class ScalarType,
class MV,
class OP>
1191 std::ostringstream
oss;
1192 oss <<
"Belos::PCPGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
1194 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).
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)
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)
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.