42 #ifndef BELOS_TFQMR_SOLMGR_HPP
43 #define BELOS_TFQMR_SOLMGR_HPP
61 #ifdef BELOS_TEUCHOS_TIME_MONITOR
103 template<
class ScalarType,
class MV,
class OP>
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>
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_),
354 template<
class ScalarType,
class MV,
class OP>
358 if (params_ == Teuchos::null) {
367 maxIters_ = params->
get(
"Maximum Iterations",maxIters_default_);
370 params_->set(
"Maximum Iterations", maxIters_);
371 if (maxIterTest_!=Teuchos::null)
372 maxIterTest_->setMaxIters( maxIters_ );
377 blockSize_ = params->
get(
"Block Size",1);
379 "Belos::TFQMRSolMgr: \"Block Size\" must be 1.");
382 params_->set(
"Block Size", blockSize_);
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
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_);
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_);
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_ );
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")) {
457 convtol_ = params->
get (
"Convergence Tolerance",
465 params_->set(
"Convergence Tolerance", convtol_);
470 if (params->
isParameter(
"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
541 template<
class ScalarType,
class MV,
class OP>
554 Teuchos::rcp(
new StatusTestGenResNorm_t( impTolScale_*convtol_ ) );
556 impConvTest_ = tmpImpConvTest;
561 tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit,
Belos::TwoNorm );
563 expConvTest_ = tmpExpConvTest;
566 convTest_ =
Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) );
574 impConvTest_ = tmpImpConvTest;
577 expConvTest_ = impConvTest_;
578 convTest_ = impConvTest_;
580 sTest_ =
Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
588 std::string solverDesc =
" TFQMR ";
589 outputTest_->setSolverDesc( solverDesc );
599 template<
class ScalarType,
class MV,
class OP>
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.");
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 );
687 plist.
set(
"Block Size",blockSize_);
690 outputTest_->reset();
693 bool isConverged =
true;
703 #ifdef BELOS_TEUCHOS_TIME_MONITOR
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 ) {
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
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();
842 "Belos::TFQMRSolMgr::solve(): The implicit convergence test's "
843 "getTestValue() method returned NULL. Please report this bug to the "
844 "Belos developers.");
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;