10#ifndef BELOS_PCPG_SOLMGR_HPP
11#define BELOS_PCPG_SOLMGR_HPP
33#include "Teuchos_LAPACK.hpp"
34#ifdef BELOS_TEUCHOS_TIME_MONITOR
35# include "Teuchos_TimeMonitor.hpp"
37#if defined(HAVE_TEUCHOSCORE_CXX11)
38# include <type_traits>
112 template<
class ScalarType,
class MV,
class OP,
class DM = DefaultDenseMatrix<
int,ScalarType>,
113 const
bool supportsScalarType =
114 Belos::Details::LapackSupportsScalar<ScalarType>::value &&
115 ! Teuchos::ScalarTraits<ScalarType>::isComplex>
118 Belos::Details::LapackSupportsScalar<ScalarType>::value &&
119 ! Teuchos::ScalarTraits<ScalarType>::isComplex>
121 static const bool scalarTypeIsSupported =
123 ! Teuchos::ScalarTraits<ScalarType>::isComplex;
132 const Teuchos::RCP<Teuchos::ParameterList> &
pl) :
138 Teuchos::RCP<SolverManager<ScalarType, MV, OP, DM> >
clone ()
const override {
143 template<
class ScalarType,
class MV,
class OP,
class DM>
150 typedef Teuchos::ScalarTraits<ScalarType> SCT;
151 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
152 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
202 const Teuchos::RCP<Teuchos::ParameterList> &
pl );
208 virtual Teuchos::RCP<SolverManager<ScalarType, MV, OP, DM> >
clone ()
const {
224 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const;
235 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
236 return Teuchos::tuple(timerSolve_);
266 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> &
params );
307 std::string description()
const;
318 Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > problem_;
321 Teuchos::RCP<OutputManager<ScalarType> > printer_;
322 Teuchos::RCP<std::ostream> outputStream_;
325 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > sTest_;
326 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP,DM> > maxIterTest_;
327 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP,DM> > convTest_;
328 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP,DM> > outputTest_;
331 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > ortho_;
334 Teuchos::RCP<Teuchos::ParameterList> params_;
337 static constexpr int maxIters_default_ = 1000;
338 static constexpr int deflatedBlocks_default_ = 2;
339 static constexpr int savedBlocks_default_ = 16;
342 static constexpr int outputFreq_default_ = -1;
343 static constexpr const char * label_default_ =
"Belos";
344 static constexpr const char * orthoType_default_ =
"ICGS";
351 MagnitudeType convtol_;
354 MagnitudeType orthoKappa_;
357 MagnitudeType achievedTol_;
365 int deflatedBlocks_, savedBlocks_, verbosity_, outputStyle_, outputFreq_;
366 std::string orthoType_;
369 Teuchos::RCP<MV> U_, C_, R_;
376 Teuchos::RCP<Teuchos::Time> timerSolve_;
384template<
class ScalarType,
class MV,
class OP,
class DM>
391 maxIters_(maxIters_default_),
392 deflatedBlocks_(deflatedBlocks_default_),
393 savedBlocks_(savedBlocks_default_),
394 verbosity_(verbosity_default_),
395 outputStyle_(outputStyle_default_),
396 outputFreq_(outputFreq_default_),
397 orthoType_(orthoType_default_),
399 label_(label_default_),
405template<
class ScalarType,
class MV,
class OP,
class DM>
408 const Teuchos::RCP<Teuchos::ParameterList> &
pl ) :
416 maxIters_(maxIters_default_),
417 deflatedBlocks_(deflatedBlocks_default_),
418 savedBlocks_(savedBlocks_default_),
419 verbosity_(verbosity_default_),
420 outputStyle_(outputStyle_default_),
421 outputFreq_(outputFreq_default_),
422 orthoType_(orthoType_default_),
424 label_(label_default_),
428 problem_.is_null (), std::invalid_argument,
429 "Belos::PCPGSolMgr two-argument constructor: "
430 "'problem' is null. You must supply a non-null Belos::LinearProblem "
431 "instance when calling this constructor.");
433 if (!
pl.is_null ()) {
440template<
class ScalarType,
class MV,
class OP,
class DM>
444 if (params_ == Teuchos::null) {
445 params_ = Teuchos::rcp(
new Teuchos::ParameterList(*getValidParameters()) );
448 params->validateParameters(*getValidParameters());
452 if (
params->isParameter(
"Maximum Iterations")) {
453 maxIters_ =
params->get(
"Maximum Iterations",maxIters_default_);
456 params_->set(
"Maximum Iterations", maxIters_);
457 if (maxIterTest_!=Teuchos::null)
458 maxIterTest_->setMaxIters( maxIters_ );
462 if (
params->isParameter(
"Num Saved Blocks")) {
463 savedBlocks_ =
params->get(
"Num Saved Blocks",savedBlocks_default_);
465 "Belos::PCPGSolMgr: \"Num Saved Blocks\" must be strictly positive.");
472 params_->set(
"Num Saved Blocks", savedBlocks_);
474 if (
params->isParameter(
"Num Deflated Blocks")) {
475 deflatedBlocks_ =
params->get(
"Num Deflated Blocks",deflatedBlocks_default_);
477 "Belos::PCPGSolMgr: \"Num Deflated Blocks\" must be positive.");
480 "Belos::PCPGSolMgr: \"Num Deflated Blocks\" must be <= \"Num Saved Blocks\".");
484 params_->set(
"Num Deflated Blocks",
static_cast<int>(deflatedBlocks_));
488 if (
params->isParameter(
"Timer Label")) {
494 params_->set(
"Timer Label", label_);
495 std::string
solveLabel = label_ +
": PCPGSolMgr total solve time";
496#ifdef BELOS_TEUCHOS_TIME_MONITOR
497 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
499 if (ortho_ != Teuchos::null) {
500 ortho_->setLabel( label_ );
506 if (
params->isParameter(
"Verbosity")) {
507 if (Teuchos::isParameterType<int>(*
params,
"Verbosity")) {
508 verbosity_ =
params->get(
"Verbosity", verbosity_default_);
510 verbosity_ = (
int)Teuchos::getParameter<Belos::MsgType>(*
params,
"Verbosity");
514 params_->set(
"Verbosity", verbosity_);
515 if (printer_ != Teuchos::null)
516 printer_->setVerbosity(verbosity_);
520 if (
params->isParameter(
"Output Style")) {
521 if (Teuchos::isParameterType<int>(*
params,
"Output Style")) {
522 outputStyle_ =
params->get(
"Output Style", outputStyle_default_);
524 outputStyle_ = (
int)Teuchos::getParameter<Belos::OutputType>(*
params,
"Output Style");
528 params_->set(
"Output Style", outputStyle_);
529 outputTest_ = Teuchos::null;
533 if (
params->isParameter(
"Output Stream")) {
534 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*
params,
"Output Stream");
537 params_->set(
"Output Stream", outputStream_);
538 if (printer_ != Teuchos::null)
539 printer_->setOStream( outputStream_ );
544 if (
params->isParameter(
"Output Frequency")) {
545 outputFreq_ =
params->get(
"Output Frequency", outputFreq_default_);
549 params_->set(
"Output Frequency", outputFreq_);
550 if (outputTest_ != Teuchos::null)
551 outputTest_->setOutputFrequency( outputFreq_ );
555 if (printer_ == Teuchos::null) {
561 if (
params->isParameter(
"Orthogonalization")) {
568 params_->set(
"Orthogonalization", orthoType_);
571 if (
params->isParameter(
"Orthogonalization Constant")) {
572 if (
params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
573 orthoKappa_ =
params->get (
"Orthogonalization Constant",
577 orthoKappa_ =
params->get (
"Orthogonalization Constant",
582 params_->set(
"Orthogonalization Constant",orthoKappa_);
583 if (orthoType_==
"DGKS") {
585 Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP,DM> >(ortho_)->setDepTol( orthoKappa_ );
594 if (orthoType_==
"DGKS" && orthoKappa_ > 0) {
595 paramsOrtho = Teuchos::rcp(
new Teuchos::ParameterList());
599 ortho_ =
factory.makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_,
paramsOrtho);
607 if (
params->isParameter(
"Convergence Tolerance")) {
608 if (
params->isType<MagnitudeType> (
"Convergence Tolerance")) {
609 convtol_ =
params->get (
"Convergence Tolerance",
617 params_->set(
"Convergence Tolerance", convtol_);
618 if (convTest_ != Teuchos::null)
619 convTest_->setTolerance( convtol_ );
625 if (maxIterTest_ == Teuchos::null)
628 if (convTest_ == Teuchos::null)
629 convTest_ = Teuchos::rcp(
new StatusTestResNorm_t( convtol_, 1 ) );
631 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
643 if (timerSolve_ == Teuchos::null) {
644 std::string
solveLabel = label_ +
": PCPGSolMgr total solve time";
645#ifdef BELOS_TEUCHOS_TIME_MONITOR
646 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
655template<
class ScalarType,
class MV,
class OP,
class DM>
656Teuchos::RCP<const Teuchos::ParameterList>
659 static Teuchos::RCP<const Teuchos::ParameterList>
validPL;
661 Teuchos::RCP<Teuchos::ParameterList>
pl = Teuchos::parameterList();
664 "The relative residual tolerance that needs to be achieved by the\n"
665 "iterative solver in order for the linear system to be declared converged.");
666 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
667 "The maximum number of iterations allowed for each\n"
668 "set of RHS solved.");
669 pl->set(
"Num Deflated Blocks",
static_cast<int>(deflatedBlocks_default_),
670 "The maximum number of vectors in the seed subspace." );
671 pl->set(
"Num Saved Blocks",
static_cast<int>(savedBlocks_default_),
672 "The maximum number of vectors saved from old Krylov subspaces." );
673 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
674 "What type(s) of solver information should be outputted\n"
675 "to the output stream.");
676 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
677 "What style is used for the solver information outputted\n"
678 "to the output stream.");
679 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
680 "How often convergence information should be outputted\n"
681 "to the output stream.");
682 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
683 "A reference-counted pointer to the output stream where all\n"
684 "solver output is sent.");
685 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
686 "The string to use as a prefix for the timer labels.");
687 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
688 "The type of orthogonalization to use: DGKS, ICGS, IMGS");
690 "The constant used by DGKS orthogonalization to determine\n"
691 "whether another step of classical Gram-Schmidt is necessary.");
699template<
class ScalarType,
class MV,
class OP,
class DM>
704 if (!isSet_) { setParameters( params_ ); }
706 Teuchos::LAPACK<int,ScalarType> lapack;
711 "Belos::PCPGSolMgr::solve(): Linear problem is not a valid object.");
714 "Belos::PCPGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
717 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
722 problem_->setLSIndex(
currIdx );
729 Teuchos::ParameterList
plist;
730 plist.set(
"Saved Blocks", savedBlocks_);
731 plist.set(
"Block Size", 1);
732 plist.set(
"Keep Diagonal",
true);
733 plist.set(
"Initialize Diagonal",
true);
738 Teuchos::RCP<PCPGIter<ScalarType,MV,OP,DM> >
pcpg_iter;
744#ifdef BELOS_TEUCHOS_TIME_MONITOR
745 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
750 outputTest_->reset();
753 if (R_ == Teuchos::null)
754 R_ = MVT::Clone( *(problem_->getRHS()), 1 );
756 problem_->computeCurrResVec( &*R_ );
762 if( U_ != Teuchos::null ){
767 Teuchos::RCP<MV>
cur_soln_vec = problem_->getCurrLHSVec();
768 std::vector<MagnitudeType>
rnorm0(1);
769 MVT::MvNorm( *R_,
rnorm0 );
772 printer_->stream(
Debug) <<
"Solver Manager: dimU_ = " << dimU_ << std::endl;
773 Teuchos::RCP<DM> Z = DMT::Create( dimU_, 1 );
782 Teuchos::RCP<MV>
tempU = MVT::Clone( *R_, 1 );
787 std::vector<MagnitudeType>
rnorm(1);
788 MVT::MvNorm( *R_,
rnorm );
798 tempU = Teuchos::null;
809 if( U_ != Teuchos::null )
pcpgState.U = U_;
810 if( C_ != Teuchos::null )
pcpgState.C = C_;
811 if( dimU_ > 0 )
pcpgState.curDim = dimU_;
818 if( !dimU_ ) printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " <<
currIdx[0] << std::endl << std::endl;
821 if( dimU_ > savedBlocks_ )
822 printer_->stream(
Debug) <<
"Error: dimU_ = " << dimU_ <<
" > savedBlocks_ = " << savedBlocks_ << std::endl;
828 printer_->stream(
Debug) <<
"********** Calling iterate...\n" << std::endl;
836 if ( convTest_->getStatus() ==
Passed ) {
845 else if ( maxIterTest_->getStatus() ==
Passed ) {
861 "Belos::PCPGSolMgr::solve(): Invalid return from PCPGIter::iterate().");
867 achievedTol_ = MT::one();
868 Teuchos::RCP<MV>
X = problem_->getLHS();
869 MVT::MvInit( *
X, SCT::zero() );
870 printer_->stream(
Warnings) <<
"Belos::PCPG::solve(): Warning! NaN has been detected!"
874 catch (
const std::exception &
e) {
876 printer_->stream(
Errors) <<
"Error! Caught exception in PCPGIter::iterate() at iteration "
878 <<
e.what() << std::endl;
885 problem_->updateSolution(
update,
true );
888 problem_->setCurrLS();
896 printer_->stream(
Debug) <<
"SolverManager: dimU_ " << dimU_ <<
" prevUdim= " <<
q << std::endl;
898 if(
q > deflatedBlocks_ )
899 printer_->stream(
Debug) <<
"SolverManager: Error deflatedBlocks = " << deflatedBlocks_ << std::endl;
910 printer_->stream(
Debug) <<
" rank decreased in ARRQR, something to do? " << std::endl;
916 if( dimU_ > deflatedBlocks_ ){
918 if( !deflatedBlocks_ ){
921 dimU_ = deflatedBlocks_;
927 Teuchos::RCP<MV>
Uorth;
940 Teuchos::RCP<DM> R = DMT::Create(dimU_,dimU_);
942 DMT::SyncDeviceToHost( *R );
948 "Belos::PCPGSolMgr::solve(): Failed to compute orthonormal basis for initial recycled subspace.");
956 if( problem_->isHermitian() )
lrwork = dimU_;
958 std::vector<ScalarType>
Svec(dimU_);
960 lapack.GESVD(
'N',
'O',
961 DMT::GetNumRows(*R), DMT::GetNumCols(*R), DMT::GetRawHostPtr(*R), DMT::GetStride(*R),
969 "Belos::PCPGSolMgr::solve(): LAPACK _GESVD failed to compute singular values.");
971 DMT::SyncHostToDevice( *R );
973 if(
work[0] != 67. * dimU_ )
974 printer_->stream(
Debug) <<
" SVD " << dimU_ <<
" lwork " <<
work[0] << std::endl;
975 for(
int i=0;
i< dimU_;
i++)
976 printer_->stream(
Debug) <<
i <<
" " <<
Svec[
i] << std::endl;
978 Teuchos::RCP<DM>
wholeV = DMT::CreateCopy( *R,
true );
987 std::vector<int>
def_cols( deflatedBlocks_ );
997 dimU_ = deflatedBlocks_;
999 printer_->stream(
Debug) <<
" Generated recycled subspace using RHS index " <<
currIdx[0] <<
" of dimension " << dimU_ << std::endl << std::endl;
1002 problem_->setCurrLS();
1010 problem_->setLSIndex(
currIdx );
1022#ifdef BELOS_TEUCHOS_TIME_MONITOR
1027 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1032 using Teuchos::rcp_dynamic_cast;
1039 "Belos::PCPGSolMgr::solve(): The convergence test's getTestValue() "
1040 "method returned NULL. Please report this bug to the Belos developers.");
1043 "Belos::PCPGSolMgr::solve(): The convergence test's getTestValue() "
1044 "method returned a vector of length zero. Please report this bug to the "
1045 "Belos developers.");
1054 numIters_ = maxIterTest_->getNumIters();
1065template<
class ScalarType,
class MV,
class OP,
class DM>
1074 Teuchos::RCP<DM> alpha = DMT::Create( 1, 1 );
1075 std::vector<int>
curind(1);
1076 std::vector<int> ipiv(
p -
q);
1077 std::vector<ScalarType>
Pivots(
p);
1082 for(
i =
q ;
i <
p ;
i++ ){
1087 anorm =
one / Teuchos::ScalarTraits<ScalarType>::squareroot( D[
i-
q] ) ;
1088 MVT::MvScale( *P,
anorm );
1089 MVT::MvScale( *AP,
anorm );
1093 for(
i =
q ;
i <
p ;
i++ ){
1094 if(
q <
i &&
i <
p-1 ){
1097 for(
j =
i+1 ;
j <
p ;
j++ ){
1098 const int k = ipiv[
j-
q];
1119 MVT::MvTransMv(
one, *P, *AP, *alpha);
1120 DMT::SyncDeviceToHost( *alpha );
1121 anorm = Teuchos::ScalarTraits<ScalarType>::squareroot( DMT::ValueConst(*alpha,0,0) ) ;
1131 printer_->stream(
Errors) <<
"ARRQR: Bad case not implemented" << std::endl;
1134 printer_->stream(
Errors) <<
"ARRQR : deficient case not implemented " << std::endl;
1144 MVT::MvScale( *P,
anorm );
1145 MVT::MvScale( *AP,
anorm );
1147 for(
j =
i+1 ;
j <
p ;
j++ ){
1151 MVT::MvTransMv(
one, *
Q, *AP, *alpha);
1152 DMT::SyncDeviceToHost(*alpha);
1153 MVT::MvAddMv( -DMT::ValueConst(*alpha,0,0), *P,
one, *
Q, *
Q );
1155 MVT::MvAddMv( -DMT::ValueConst(*alpha,0,0), *AP,
one, *
AQ, *
AQ );
1156 gamma = (
Pivots[
l] - DMT::ValueConst(*alpha,0,0))*(
Pivots[
l] + DMT::ValueConst(*alpha,0,0));
1158 Pivots[
l] = Teuchos::ScalarTraits<ScalarType>::squareroot(
gamma );
1169template<
class ScalarType,
class MV,
class OP,
class DM>
1172 std::ostringstream
oss;
1173 oss <<
"Belos::PCPGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";
1175 oss <<
"Ortho Type='"<<orthoType_;
Belos header file which uses auto-configuration information to include necessary C++ headers.
Full specialization of Belos::DenseMatTraits for Kokkos::DualView with arbitrary scalarType....
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.
Full specialization of Belos::DenseMatTraits for Teuchos::SerialDenseMatrix with ordinal type int and...
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).
int getNumIters() const
Get the iteration count for the most recent call to solve().
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &problem)
Set the linear problem that needs to be solved.
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const
Get current linear problem being solved for in this object.
virtual ~PCPGSolMgr()
Destructor.
MagnitudeType achievedTol() const
Tolerance achieved by the last solve() invocation.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const
Get a parameter list containing the current parameters for this object.
virtual Teuchos::RCP< SolverManager< ScalarType, MV, OP, DM > > clone() const
clone for Inverted Injection (DII)
bool isLOADetected() const
Return whether a loss of accuracy was detected by this solver during the most current solve.
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, DM > > clone() const override
clone for Inverted Injection (DII)
PCPGSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &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.