42 #ifndef BELOS_TFQMR_SOLMGR_HPP
43 #define BELOS_TFQMR_SOLMGR_HPP
61 #ifdef BELOS_TEUCHOS_TIME_MONITOR
62 #include "Teuchos_TimeMonitor.hpp"
103 template<
class ScalarType,
class MV,
class OP>
109 typedef Teuchos::ScalarTraits<ScalarType> SCT;
110 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
111 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
142 const Teuchos::RCP<Teuchos::ParameterList> &pl );
148 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
173 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
174 return Teuchos::tuple(timerSolve_);
208 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
override;
254 bool checkStatusTest();
257 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
260 Teuchos::RCP<OutputManager<ScalarType> > printer_;
261 Teuchos::RCP<std::ostream> outputStream_;
264 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
265 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
266 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
267 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > expConvTest_, impConvTest_;
268 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
271 Teuchos::RCP<Teuchos::ParameterList> params_;
274 static constexpr
int maxIters_default_ = 1000;
275 static constexpr
bool expResTest_default_ =
false;
278 static constexpr
int outputFreq_default_ = -1;
279 static constexpr
const char * impResScale_default_ =
"Norm of Preconditioned Initial Residual";
280 static constexpr
const char * expResScale_default_ =
"Norm of Initial Residual";
281 static constexpr
const char * label_default_ =
"Belos";
282 static constexpr std::ostream * outputStream_default_ = &std::cout;
285 MagnitudeType convtol_, impTolScale_, achievedTol_;
286 int maxIters_, numIters_;
287 int verbosity_, outputStyle_, outputFreq_;
290 std::string impResScale_, expResScale_;
294 Teuchos::RCP<Teuchos::Time> timerSolve_;
297 bool isSet_, isSTSet_;
302 template<
class ScalarType,
class MV,
class OP>
304 outputStream_(Teuchos::rcp(outputStream_default_,false)),
307 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
308 maxIters_(maxIters_default_),
310 verbosity_(verbosity_default_),
311 outputStyle_(outputStyle_default_),
312 outputFreq_(outputFreq_default_),
314 expResTest_(expResTest_default_),
315 impResScale_(impResScale_default_),
316 expResScale_(expResScale_default_),
317 label_(label_default_),
324 template<
class ScalarType,
class MV,
class OP>
327 const Teuchos::RCP<Teuchos::ParameterList> &pl ) :
329 outputStream_(Teuchos::rcp(outputStream_default_,false)),
332 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
333 maxIters_(maxIters_default_),
335 verbosity_(verbosity_default_),
336 outputStyle_(outputStyle_default_),
337 outputFreq_(outputFreq_default_),
339 expResTest_(expResTest_default_),
340 impResScale_(impResScale_default_),
341 expResScale_(expResScale_default_),
342 label_(label_default_),
346 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument,
"Problem not given to solver manager.");
349 if ( !is_null(pl) ) {
354 template<
class ScalarType,
class MV,
class OP>
358 if (params_ == Teuchos::null) {
359 params_ = Teuchos::rcp(
new Teuchos::ParameterList(*getValidParameters()) );
362 params->validateParameters(*getValidParameters());
366 if (params->isParameter(
"Maximum Iterations")) {
367 maxIters_ = params->get(
"Maximum Iterations",maxIters_default_);
370 params_->set(
"Maximum Iterations", maxIters_);
371 if (maxIterTest_!=Teuchos::null)
372 maxIterTest_->setMaxIters( maxIters_ );
376 if (params->isParameter(
"Block Size")) {
377 blockSize_ = params->get(
"Block Size",1);
378 TEUCHOS_TEST_FOR_EXCEPTION(blockSize_ != 1, std::invalid_argument,
379 "Belos::TFQMRSolMgr: \"Block Size\" must be 1.");
382 params_->set(
"Block Size", blockSize_);
386 if (params->isParameter(
"Timer Label")) {
387 std::string tempLabel = params->get(
"Timer Label", label_default_);
390 if (tempLabel != label_) {
392 params_->set(
"Timer Label", label_);
393 std::string solveLabel = label_ +
": TFQMRSolMgr total solve time";
394 #ifdef BELOS_TEUCHOS_TIME_MONITOR
395 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
401 if (params->isParameter(
"Verbosity")) {
402 if (Teuchos::isParameterType<int>(*params,
"Verbosity")) {
403 verbosity_ = params->get(
"Verbosity", verbosity_default_);
405 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,
"Verbosity");
409 params_->set(
"Verbosity", verbosity_);
410 if (printer_ != Teuchos::null)
411 printer_->setVerbosity(verbosity_);
415 if (params->isParameter(
"Output Style")) {
416 if (Teuchos::isParameterType<int>(*params,
"Output Style")) {
417 outputStyle_ = params->get(
"Output Style", outputStyle_default_);
419 outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,
"Output Style");
423 params_->set(
"Output Style", outputStyle_);
428 if (params->isParameter(
"Output Stream")) {
429 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
432 params_->set(
"Output Stream", outputStream_);
433 if (printer_ != Teuchos::null)
434 printer_->setOStream( outputStream_ );
439 if (params->isParameter(
"Output Frequency")) {
440 outputFreq_ = params->get(
"Output Frequency", outputFreq_default_);
444 params_->set(
"Output Frequency", outputFreq_);
445 if (outputTest_ != Teuchos::null)
446 outputTest_->setOutputFrequency( outputFreq_ );
450 if (printer_ == Teuchos::null) {
455 if (params->isParameter(
"Convergence Tolerance")) {
456 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
457 convtol_ = params->get (
"Convergence Tolerance",
465 params_->set(
"Convergence Tolerance", convtol_);
470 if (params->isParameter(
"Implicit Tolerance Scale Factor")) {
471 if (params->isType<MagnitudeType> (
"Implicit Tolerance Scale Factor")) {
472 impTolScale_ = params->get (
"Implicit Tolerance Scale Factor",
477 impTolScale_ = params->get (
"Implicit Tolerance Scale Factor",
482 params_->set(
"Implicit Tolerance Scale Factor", impTolScale_);
487 if (params->isParameter(
"Implicit Residual Scaling")) {
488 std::string tempImpResScale = Teuchos::getParameter<std::string>( *params,
"Implicit Residual Scaling" );
491 if (impResScale_ != tempImpResScale) {
492 impResScale_ = tempImpResScale;
495 params_->set(
"Implicit Residual Scaling", impResScale_);
502 if (params->isParameter(
"Explicit Residual Scaling")) {
503 std::string tempExpResScale = Teuchos::getParameter<std::string>( *params,
"Explicit Residual Scaling" );
506 if (expResScale_ != tempExpResScale) {
507 expResScale_ = tempExpResScale;
510 params_->set(
"Explicit Residual Scaling", expResScale_);
517 if (params->isParameter(
"Explicit Residual Test")) {
518 expResTest_ = Teuchos::getParameter<bool>( *params,
"Explicit Residual Test" );
521 params_->set(
"Explicit Residual Test", expResTest_);
522 if (expConvTest_ == Teuchos::null) {
528 if (timerSolve_ == Teuchos::null) {
529 std::string solveLabel = label_ +
": TFQMRSolMgr total solve time";
530 #ifdef BELOS_TEUCHOS_TIME_MONITOR
531 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
541 template<
class ScalarType,
class MV,
class OP>
553 Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
554 Teuchos::rcp(
new StatusTestGenResNorm_t( impTolScale_*convtol_ ) );
556 impConvTest_ = tmpImpConvTest;
559 Teuchos::RCP<StatusTestGenResNorm_t> tmpExpConvTest =
560 Teuchos::rcp(
new StatusTestGenResNorm_t( convtol_ ) );
561 tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit,
Belos::TwoNorm );
563 expConvTest_ = tmpExpConvTest;
566 convTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) );
571 Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
572 Teuchos::rcp(
new StatusTestGenResNorm_t( convtol_ ) );
574 impConvTest_ = tmpImpConvTest;
577 expConvTest_ = impConvTest_;
578 convTest_ = impConvTest_;
580 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
584 StatusTestOutputFactory<ScalarType,MV,OP> stoFactory( outputStyle_ );
588 std::string solverDesc =
" TFQMR ";
589 outputTest_->setSolverDesc( solverDesc );
599 template<
class ScalarType,
class MV,
class OP>
600 Teuchos::RCP<const Teuchos::ParameterList>
603 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
606 if(is_null(validPL)) {
607 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
612 "The relative residual tolerance that needs to be achieved by the\n"
613 "iterative solver in order for the linear system to be declared converged.");
615 "The scale factor used by the implicit residual test when explicit residual\n"
616 "testing is used. May enable faster convergence when TFQMR bound is too loose.");
617 pl->set(
"Maximum Iterations", static_cast<int>(maxIters_default_),
618 "The maximum number of block iterations allowed for each\n"
619 "set of RHS solved.");
620 pl->set(
"Verbosity", static_cast<int>(verbosity_default_),
621 "What type(s) of solver information should be outputted\n"
622 "to the output stream.");
623 pl->set(
"Output Style", static_cast<int>(outputStyle_default_),
624 "What style is used for the solver information outputted\n"
625 "to the output stream.");
626 pl->set(
"Output Frequency", static_cast<int>(outputFreq_default_),
627 "How often convergence information should be outputted\n"
628 "to the output stream.");
629 pl->set(
"Output Stream", Teuchos::rcp(outputStream_default_,
false),
630 "A reference-counted pointer to the output stream where all\n"
631 "solver output is sent.");
632 pl->set(
"Explicit Residual Test", static_cast<bool>(expResTest_default_),
633 "Whether the explicitly computed residual should be used in the convergence test.");
634 pl->set(
"Implicit Residual Scaling", static_cast<const char *>(impResScale_default_),
635 "The type of scaling used in the implicit residual convergence test.");
636 pl->set(
"Explicit Residual Scaling", static_cast<const char *>(expResScale_default_),
637 "The type of scaling used in the explicit residual convergence test.");
638 pl->set(
"Timer Label", static_cast<const char *>(label_default_),
639 "The string to use as a prefix for the timer labels.");
647 template<
class ScalarType,
class MV,
class OP>
654 setParameters(Teuchos::parameterList(*getValidParameters()));
658 "Belos::TFQMRSolMgr::solve(): Linear problem is not a valid object.");
661 "Belos::TFQMRSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
665 "Belos::TFQMRSolMgr::solve(): Linear problem and requested status tests are incompatible.");
670 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
671 int numCurrRHS = blockSize_;
673 std::vector<int> currIdx, currIdx2;
676 currIdx.resize( blockSize_ );
677 currIdx2.resize( blockSize_ );
678 for (
int i=0; i<numCurrRHS; ++i)
679 { currIdx[i] = startPtr+i; currIdx2[i]=i; }
682 problem_->setLSIndex( currIdx );
686 Teuchos::ParameterList plist;
687 plist.set(
"Block Size",blockSize_);
690 outputTest_->reset();
693 bool isConverged =
true;
698 Teuchos::RCP<TFQMRIter<ScalarType,MV,OP> > tfqmr_iter =
703 #ifdef BELOS_TEUCHOS_TIME_MONITOR
704 Teuchos::TimeMonitor slvtimer(*timerSolve_);
707 while ( numRHS2Solve > 0 ) {
710 std::vector<int> convRHSIdx;
711 std::vector<int> currRHSIdx( currIdx );
712 currRHSIdx.resize(numCurrRHS);
715 tfqmr_iter->resetNumIters();
718 outputTest_->resetNumCalls();
721 Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitPrecResVec())), currIdx );
726 tfqmr_iter->initializeTFQMR(newstate);
732 tfqmr_iter->iterate();
739 if ( convTest_->getStatus() ==
Passed ) {
748 else if ( maxIterTest_->getStatus() ==
Passed ) {
762 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
763 "Belos::TFQMRSolMgr::solve(): Invalid return from TFQMRIter::iterate().");
766 catch (
const std::exception &e) {
767 printer_->stream(
Errors) <<
"Error! Caught std::exception in TFQMRIter::iterate() at iteration "
768 << tfqmr_iter->getNumIters() << std::endl
769 << e.what() << std::endl;
775 problem_->updateSolution( tfqmr_iter->getCurrentUpdate(), true );
778 problem_->setCurrLS();
781 startPtr += numCurrRHS;
782 numRHS2Solve -= numCurrRHS;
783 if ( numRHS2Solve > 0 ) {
784 numCurrRHS = blockSize_;
786 currIdx.resize( blockSize_ );
787 currIdx2.resize( blockSize_ );
788 for (
int i=0; i<numCurrRHS; ++i)
789 { currIdx[i] = startPtr+i; currIdx2[i] = i; }
791 problem_->setLSIndex( currIdx );
794 tfqmr_iter->setBlockSize( blockSize_ );
797 currIdx.resize( numRHS2Solve );
808 #ifdef BELOS_TEUCHOS_TIME_MONITOR
813 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
817 numIters_ = maxIterTest_->getNumIters();
830 const std::vector<MagnitudeType>* pTestValues = NULL;
832 pTestValues = expConvTest_->getTestValue();
833 if (pTestValues == NULL || pTestValues->size() < 1) {
834 pTestValues = impConvTest_->getTestValue();
839 pTestValues = impConvTest_->getTestValue();
841 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
842 "Belos::TFQMRSolMgr::solve(): The implicit convergence test's "
843 "getTestValue() method returned NULL. Please report this bug to the "
844 "Belos developers.");
845 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
846 "Belos::TMQMRSolMgr::solve(): The implicit convergence test's "
847 "getTestValue() method returned a vector of length zero. Please report "
848 "this bug to the Belos developers.");
853 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
863 template<
class ScalarType,
class MV,
class OP>
866 std::ostringstream oss;
867 oss <<
"Belos::TFQMRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";