185 typedef Teuchos::ScalarTraits<ScalarType> SCT;
186 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
187 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
237 const Teuchos::RCP<Teuchos::ParameterList> &pl );
243 virtual Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const {
259 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const;
270 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
271 return Teuchos::tuple(timerSolve_);
301 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms );
342 std::string description()
const;
350 int ARRQR(
int numVecs,
int numOrthVecs,
const Teuchos::SerialDenseMatrix<int,ScalarType>& D);
353 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
356 Teuchos::RCP<OutputManager<ScalarType> > printer_;
357 Teuchos::RCP<std::ostream> outputStream_;
360 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
361 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
362 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
363 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
366 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
369 Teuchos::RCP<Teuchos::ParameterList> params_;
372 static constexpr int maxIters_default_ = 1000;
373 static constexpr int deflatedBlocks_default_ = 2;
374 static constexpr int savedBlocks_default_ = 16;
377 static constexpr int outputFreq_default_ = -1;
378 static constexpr const char * label_default_ =
"Belos";
379 static constexpr const char * orthoType_default_ =
"ICGS";
381#if defined(_WIN32) && defined(__clang__)
382 static constexpr std::ostream * outputStream_default_ =
383 __builtin_constant_p(
reinterpret_cast<const std::ostream*
>(&std::cout));
385 static constexpr std::ostream * outputStream_default_ = &std::cout;
393 MagnitudeType convtol_;
396 MagnitudeType orthoKappa_;
399 MagnitudeType achievedTol_;
407 int deflatedBlocks_, savedBlocks_, verbosity_, outputStyle_, outputFreq_;
408 std::string orthoType_;
411 Teuchos::RCP<MV> U_, C_, R_;
418 Teuchos::RCP<Teuchos::Time> timerSolve_;
486 if (params_ == Teuchos::null) {
487 params_ = Teuchos::rcp(
new Teuchos::ParameterList(*getValidParameters()) );
490 params->validateParameters(*getValidParameters());
494 if (params->isParameter(
"Maximum Iterations")) {
495 maxIters_ = params->get(
"Maximum Iterations",maxIters_default_);
498 params_->set(
"Maximum Iterations", maxIters_);
499 if (maxIterTest_!=Teuchos::null)
500 maxIterTest_->setMaxIters( maxIters_ );
504 if (params->isParameter(
"Num Saved Blocks")) {
505 savedBlocks_ = params->get(
"Num Saved Blocks",savedBlocks_default_);
506 TEUCHOS_TEST_FOR_EXCEPTION(savedBlocks_ <= 0, std::invalid_argument,
507 "Belos::PCPGSolMgr: \"Num Saved Blocks\" must be strictly positive.");
514 params_->set(
"Num Saved Blocks", savedBlocks_);
516 if (params->isParameter(
"Num Deflated Blocks")) {
517 deflatedBlocks_ = params->get(
"Num Deflated Blocks",deflatedBlocks_default_);
518 TEUCHOS_TEST_FOR_EXCEPTION(deflatedBlocks_ < 0, std::invalid_argument,
519 "Belos::PCPGSolMgr: \"Num Deflated Blocks\" must be positive.");
521 TEUCHOS_TEST_FOR_EXCEPTION(deflatedBlocks_ > savedBlocks_, std::invalid_argument,
522 "Belos::PCPGSolMgr: \"Num Deflated Blocks\" must be <= \"Num Saved Blocks\".");
526 params_->set(
"Num Deflated Blocks",
static_cast<int>(deflatedBlocks_));
530 if (params->isParameter(
"Timer Label")) {
531 std::string tempLabel = params->get(
"Timer Label", label_default_);
534 if (tempLabel != label_) {
536 params_->set(
"Timer Label", label_);
537 std::string solveLabel = label_ +
": PCPGSolMgr total solve time";
538#ifdef BELOS_TEUCHOS_TIME_MONITOR
539 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
541 if (ortho_ != Teuchos::null) {
542 ortho_->setLabel( label_ );
548 if (params->isParameter(
"Verbosity")) {
549 if (Teuchos::isParameterType<int>(*params,
"Verbosity")) {
550 verbosity_ = params->get(
"Verbosity", verbosity_default_);
552 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,
"Verbosity");
556 params_->set(
"Verbosity", verbosity_);
557 if (printer_ != Teuchos::null)
558 printer_->setVerbosity(verbosity_);
562 if (params->isParameter(
"Output Style")) {
563 if (Teuchos::isParameterType<int>(*params,
"Output Style")) {
564 outputStyle_ = params->get(
"Output Style", outputStyle_default_);
566 outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,
"Output Style");
570 params_->set(
"Output Style", outputStyle_);
571 outputTest_ = Teuchos::null;
575 if (params->isParameter(
"Output Stream")) {
576 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
579 params_->set(
"Output Stream", outputStream_);
580 if (printer_ != Teuchos::null)
581 printer_->setOStream( outputStream_ );
586 if (params->isParameter(
"Output Frequency")) {
587 outputFreq_ = params->get(
"Output Frequency", outputFreq_default_);
591 params_->set(
"Output Frequency", outputFreq_);
592 if (outputTest_ != Teuchos::null)
593 outputTest_->setOutputFrequency( outputFreq_ );
597 if (printer_ == Teuchos::null) {
602 bool changedOrthoType =
false;
603 if (params->isParameter(
"Orthogonalization")) {
604 std::string tempOrthoType = params->get(
"Orthogonalization",orthoType_default_);
605 if (tempOrthoType != orthoType_) {
606 orthoType_ = tempOrthoType;
607 changedOrthoType =
true;
610 params_->set(
"Orthogonalization", orthoType_);
613 if (params->isParameter(
"Orthogonalization Constant")) {
614 if (params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
615 orthoKappa_ = params->get (
"Orthogonalization Constant",
619 orthoKappa_ = params->get (
"Orthogonalization Constant",
624 params_->set(
"Orthogonalization Constant",orthoKappa_);
625 if (orthoType_==
"DGKS") {
626 if (orthoKappa_ > 0 && ortho_ != Teuchos::null && !changedOrthoType) {
627 Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
633 if (ortho_ == Teuchos::null || changedOrthoType) {
635 Teuchos::RCP<Teuchos::ParameterList> paramsOrtho;
636 if (orthoType_==
"DGKS" && orthoKappa_ > 0) {
637 paramsOrtho->set (
"depTol", orthoKappa_ );
640 ortho_ = factory.
makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_, paramsOrtho);
648 if (params->isParameter(
"Convergence Tolerance")) {
649 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
650 convtol_ = params->get (
"Convergence Tolerance",
658 params_->set(
"Convergence Tolerance", convtol_);
659 if (convTest_ != Teuchos::null)
666 if (maxIterTest_ == Teuchos::null)
669 if (convTest_ == Teuchos::null)
670 convTest_ = Teuchos::rcp(
new StatusTestResNorm_t( convtol_, 1 ) );
672 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
680 std::string solverDesc =
" PCPG ";
681 outputTest_->setSolverDesc( solverDesc );
684 if (timerSolve_ == Teuchos::null) {
685 std::string solveLabel = label_ +
": PCPGSolMgr total solve time";
686#ifdef BELOS_TEUCHOS_TIME_MONITOR
687 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
744 if (!isSet_) { setParameters( params_ ); }
746 Teuchos::LAPACK<int,ScalarType> lapack;
747 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
748 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
751 "Belos::PCPGSolMgr::solve(): Linear problem is not a valid object.");
754 "Belos::PCPGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
757 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
758 std::vector<int> currIdx(1);
764 problem_->setLSIndex( currIdx );
767 bool isConverged =
true;
771 Teuchos::ParameterList plist;
772 plist.set(
"Saved Blocks", savedBlocks_);
773 plist.set(
"Block Size", 1);
774 plist.set(
"Keep Diagonal",
true);
775 plist.set(
"Initialize Diagonal",
true);
780 Teuchos::RCP<PCPGIter<ScalarType,MV,OP> > pcpg_iter;
786#ifdef BELOS_TEUCHOS_TIME_MONITOR
787 Teuchos::TimeMonitor slvtimer(*timerSolve_);
789 while ( numRHS2Solve > 0 ) {
792 outputTest_->reset();
795 if (R_ == Teuchos::null)
796 R_ = MVT::Clone( *(problem_->getRHS()), 1 );
798 problem_->computeCurrResVec( &*R_ );
804 if( U_ != Teuchos::null ){
809 Teuchos::RCP<MV> cur_soln_vec = problem_->getCurrLHSVec();
810 std::vector<MagnitudeType> rnorm0(1);
811 MVT::MvNorm( *R_, rnorm0 );
814 std::cout <<
"Solver Manager: dimU_ = " << dimU_ << std::endl;
815 Teuchos::SerialDenseMatrix<int,ScalarType> Z( dimU_, 1 );
817 Teuchos::RCP<const MV> Uactive, Cactive;
818 std::vector<int> active_columns( dimU_ );
819 for (
int i=0; i < dimU_; ++i) active_columns[i] = i;
820 Uactive = MVT::CloneView(*U_, active_columns);
821 Cactive = MVT::CloneView(*C_, active_columns);
824 std::cout <<
" Solver Manager : check duality of seed basis " << std::endl;
825 Teuchos::SerialDenseMatrix<int,ScalarType> H( dimU_, dimU_ );
826 MVT::MvTransMv( one, *Uactive, *Cactive, H );
827 H.print( std::cout );
830 MVT::MvTransMv( one, *Uactive, *R_, Z );
831 Teuchos::RCP<MV> tempU = MVT::Clone( *R_, 1 );
832 MVT::MvTimesMatAddMv( one, *Uactive, Z, zero, *tempU );
833 MVT::MvAddMv( one, *tempU, one, *cur_soln_vec, *cur_soln_vec );
834 MVT::MvTimesMatAddMv( one, *Cactive, Z, zero, *tempU );
835 MVT::MvAddMv( -one, *tempU, one, *R_, *R_ );
836 std::vector<MagnitudeType> rnorm(1);
837 MVT::MvNorm( *R_, rnorm );
838 if( rnorm[0] < rnorm0[0] * .001 ){
839 MVT::MvTransMv( one, *Uactive, *R_, Z );
840 MVT::MvTimesMatAddMv( one, *Uactive, Z, zero, *tempU );
841 MVT::MvAddMv( one, *tempU, one, *cur_soln_vec, *cur_soln_vec );
842 MVT::MvTimesMatAddMv( one, *Cactive, Z, zero, *tempU );
843 MVT::MvAddMv( -one, *tempU, one, *R_, *R_ );
845 Uactive = Teuchos::null;
846 Cactive = Teuchos::null;
847 tempU = Teuchos::null;
858 if( U_ != Teuchos::null ) pcpgState.
U = U_;
859 if( C_ != Teuchos::null ) pcpgState.
C = C_;
860 if( dimU_ > 0 ) pcpgState.
curDim = dimU_;
861 pcpg_iter->initialize(pcpgState);
867 if( !dimU_ ) printer_->stream(
Debug) <<
" No recycled subspace available for RHS index " << currIdx[0] << std::endl << std::endl;
868 pcpg_iter->resetNumIters();
870 if( dimU_ > savedBlocks_ )
871 std::cout <<
"Error: dimU_ = " << dimU_ <<
" > savedBlocks_ = " << savedBlocks_ << std::endl;
877 if( debug ) printf(
"********** Calling iterate...\n");
878 pcpg_iter->iterate();
885 if ( convTest_->getStatus() ==
Passed ) {
894 else if ( maxIterTest_->getStatus() ==
Passed ) {
908 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
909 "Belos::PCPGSolMgr::solve(): Invalid return from PCPGIter::iterate().");
915 sTest_->checkStatus( &*pcpg_iter );
916 if (convTest_->getStatus() !=
Passed)
920 catch (
const std::exception &e) {
921 printer_->stream(
Errors) <<
"Error! Caught exception in PCPGIter::iterate() at iteration "
922 << pcpg_iter->getNumIters() << std::endl
923 << e.what() << std::endl;
929 Teuchos::RCP<MV> update = pcpg_iter->getCurrentUpdate();
930 problem_->updateSolution( update,
true );
933 problem_->setCurrLS();
941 std::cout <<
"SolverManager: dimU_ " << dimU_ <<
" prevUdim= " << q << std::endl;
943 if( q > deflatedBlocks_ )
944 std::cout <<
"SolverManager: Error deflatedBlocks = " << deflatedBlocks_ << std::endl;
955 rank = ARRQR(dimU_,q, *oldState.
D );
957 std::cout <<
" rank decreased in ARRQR, something to do? " << std::endl;
963 if( dimU_ > deflatedBlocks_ ){
965 if( !deflatedBlocks_ ){
968 dimU_ = deflatedBlocks_;
972 bool Harmonic =
false;
974 Teuchos::RCP<MV> Uorth;
976 std::vector<int> active_cols( dimU_ );
977 for (
int i=0; i < dimU_; ++i) active_cols[i] = i;
980 Uorth = MVT::CloneCopy(*C_, active_cols);
983 Uorth = MVT::CloneCopy(*U_, active_cols);
987 Teuchos::SerialDenseMatrix<int,ScalarType> R(dimU_,dimU_);
988 rank = ortho_->normalize(*Uorth, Teuchos::rcp(&R,
false));
989 Uorth = Teuchos::null;
995 "Belos::PCPGSolMgr::solve(): Failed to compute orthonormal basis for initial recycled subspace.");
999 Teuchos::SerialDenseMatrix<int,ScalarType> VT;
1000 Teuchos::SerialDenseMatrix<int,ScalarType> Ur;
1001 int lwork = 5*dimU_;
1004 if( problem_->isHermitian() ) lrwork = dimU_;
1005 std::vector<ScalarType> work(lwork);
1006 std::vector<ScalarType> Svec(dimU_);
1007 std::vector<ScalarType> rwork(lrwork);
1008 lapack.GESVD(
'N',
'O',
1009 R.numRows(),R.numCols(),R.values(), R.numRows(),
1017 "Belos::PCPGSolMgr::solve(): LAPACK _GESVD failed to compute singular values.");
1019 if( work[0] != 67. * dimU_ )
1020 std::cout <<
" SVD " << dimU_ <<
" lwork " << work[0] << std::endl;
1021 for(
int i=0; i< dimU_; i++)
1022 std::cout << i <<
" " << Svec[i] << std::endl;
1024 Teuchos::SerialDenseMatrix<int,ScalarType> wholeV( R, Teuchos::TRANS);
1026 int startRow = 0, startCol = 0;
1028 startCol = dimU_ - deflatedBlocks_;
1030 Teuchos::SerialDenseMatrix<int,ScalarType> V(Teuchos::Copy,
1036 std::vector<int> active_columns( dimU_ );
1037 std::vector<int> def_cols( deflatedBlocks_ );
1038 for (
int i=0; i < dimU_; ++i) active_columns[i] = i;
1039 for (
int i=0; i < deflatedBlocks_; ++i) def_cols[i] = i;
1041 Teuchos::RCP<MV> Uactive = MVT::CloneViewNonConst(*U_, def_cols);
1042 Teuchos::RCP<MV> Ucopy = MVT::CloneCopy( *U_, active_columns );
1043 MVT::MvTimesMatAddMv( one, *Ucopy, V, zero, *Uactive );
1044 Ucopy = Teuchos::null;
1045 Uactive = Teuchos::null;
1046 Teuchos::RCP<MV> Cactive = MVT::CloneViewNonConst(*C_, def_cols);
1047 Teuchos::RCP<MV> Ccopy = MVT::CloneCopy( *C_, active_columns );
1048 MVT::MvTimesMatAddMv( one, *Ccopy, V, zero, *Cactive );
1049 Ccopy = Teuchos::null;
1050 Cactive = Teuchos::null;
1051 dimU_ = deflatedBlocks_;
1053 printer_->stream(
Debug) <<
" Generated recycled subspace using RHS index " << currIdx[0] <<
" of dimension " << dimU_ << std::endl << std::endl;
1056 problem_->setCurrLS();
1060 if ( numRHS2Solve > 0 ) {
1064 problem_->setLSIndex( currIdx );
1067 currIdx.resize( numRHS2Solve );
1076#ifdef BELOS_TEUCHOS_TIME_MONITOR
1081 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1086 using Teuchos::rcp_dynamic_cast;
1089 const std::vector<MagnitudeType>* pTestValues =
1090 rcp_dynamic_cast<conv_test_type>(convTest_)->
getTestValue();
1092 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1093 "Belos::PCPGSolMgr::solve(): The convergence test's getTestValue() "
1094 "method returned NULL. Please report this bug to the Belos developers.");
1096 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1097 "Belos::PCPGSolMgr::solve(): The convergence test's getTestValue() "
1098 "method returned a vector of length zero. Please report this bug to the "
1099 "Belos developers.");
1104 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1108 numIters_ = maxIterTest_->getNumIters();