42 #ifndef BELOS_BICGSTAB_SOLMGR_HPP
43 #define BELOS_BICGSTAB_SOLMGR_HPP
61 #include "Teuchos_BLAS.hpp"
62 #include "Teuchos_LAPACK.hpp"
63 #ifdef BELOS_TEUCHOS_TIME_MONITOR
64 #include "Teuchos_TimeMonitor.hpp"
108 template<
class ScalarType,
class MV,
class OP>
114 typedef Teuchos::ScalarTraits<ScalarType> SCT;
115 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
116 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
140 const Teuchos::RCP<Teuchos::ParameterList> &pl );
146 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
171 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
172 return Teuchos::tuple(timerSolve_);
209 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
override;
256 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
259 Teuchos::RCP<OutputManager<ScalarType> > printer_;
260 Teuchos::RCP<std::ostream> outputStream_;
263 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
264 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
265 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
266 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
269 Teuchos::RCP<Teuchos::ParameterList> params_;
276 mutable Teuchos::RCP<const Teuchos::ParameterList> validParams_;
279 static constexpr
int maxIters_default_ = 1000;
280 static constexpr
bool showMaxResNormOnly_default_ =
false;
283 static constexpr
int outputFreq_default_ = -1;
284 static constexpr
int defQuorum_default_ = 1;
285 static constexpr
const char * resScale_default_ =
"Norm of Initial Residual";
286 static constexpr
const char * label_default_ =
"Belos";
287 static constexpr std::ostream * outputStream_default_ = &std::cout;
290 MagnitudeType convtol_,achievedTol_;
291 int maxIters_, numIters_;
292 int verbosity_, outputStyle_, outputFreq_, defQuorum_;
293 bool showMaxResNormOnly_;
294 std::string resScale_;
298 Teuchos::RCP<Teuchos::Time> timerSolve_;
305 template<
class ScalarType,
class MV,
class OP>
307 outputStream_(Teuchos::rcp(outputStream_default_,false)),
309 maxIters_(maxIters_default_),
311 verbosity_(verbosity_default_),
312 outputStyle_(outputStyle_default_),
313 outputFreq_(outputFreq_default_),
314 defQuorum_(defQuorum_default_),
315 showMaxResNormOnly_(showMaxResNormOnly_default_),
316 resScale_(resScale_default_),
317 label_(label_default_),
322 template<
class ScalarType,
class MV,
class OP>
325 const Teuchos::RCP<Teuchos::ParameterList> &pl ) :
327 outputStream_(Teuchos::rcp(outputStream_default_,false)),
329 maxIters_(maxIters_default_),
331 verbosity_(verbosity_default_),
332 outputStyle_(outputStyle_default_),
333 outputFreq_(outputFreq_default_),
334 defQuorum_(defQuorum_default_),
335 showMaxResNormOnly_(showMaxResNormOnly_default_),
336 resScale_(resScale_default_),
337 label_(label_default_),
340 TEUCHOS_TEST_FOR_EXCEPTION(
341 problem_.is_null (), std::invalid_argument,
342 "Belos::BiCGStabSolMgr two-argument constructor: "
343 "'problem' is null. You must supply a non-null Belos::LinearProblem "
344 "instance when calling this constructor.");
346 if (! pl.is_null ()) {
352 template<
class ScalarType,
class MV,
class OP>
355 using Teuchos::ParameterList;
356 using Teuchos::parameterList;
359 RCP<const ParameterList> defaultParams = getValidParameters();
362 if (params_.is_null()) {
363 params_ = parameterList (*defaultParams);
365 params->validateParameters (*defaultParams);
369 if (params->isParameter(
"Maximum Iterations")) {
370 maxIters_ = params->get(
"Maximum Iterations",maxIters_default_);
373 params_->set(
"Maximum Iterations", maxIters_);
374 if (maxIterTest_!=Teuchos::null)
375 maxIterTest_->setMaxIters( maxIters_ );
379 if (params->isParameter(
"Timer Label")) {
380 std::string tempLabel = params->get(
"Timer Label", label_default_);
383 if (tempLabel != label_) {
385 params_->set(
"Timer Label", label_);
386 std::string solveLabel = label_ +
": BiCGStabSolMgr total solve time";
387 #ifdef BELOS_TEUCHOS_TIME_MONITOR
388 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
394 if (params->isParameter(
"Verbosity")) {
395 if (Teuchos::isParameterType<int>(*params,
"Verbosity")) {
396 verbosity_ = params->get(
"Verbosity", verbosity_default_);
398 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,
"Verbosity");
402 params_->set(
"Verbosity", verbosity_);
403 if (printer_ != Teuchos::null)
404 printer_->setVerbosity(verbosity_);
408 if (params->isParameter(
"Output Style")) {
409 if (Teuchos::isParameterType<int>(*params,
"Output Style")) {
410 outputStyle_ = params->get(
"Output Style", outputStyle_default_);
412 outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,
"Output Style");
416 params_->set(
"Output Style", outputStyle_);
417 outputTest_ = Teuchos::null;
421 if (params->isParameter(
"Output Stream")) {
422 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
425 params_->set(
"Output Stream", outputStream_);
426 if (printer_ != Teuchos::null)
427 printer_->setOStream( outputStream_ );
432 if (params->isParameter(
"Output Frequency")) {
433 outputFreq_ = params->get(
"Output Frequency", outputFreq_default_);
437 params_->set(
"Output Frequency", outputFreq_);
438 if (outputTest_ != Teuchos::null)
439 outputTest_->setOutputFrequency( outputFreq_ );
443 if (printer_ == Teuchos::null) {
452 if (params->isParameter(
"Convergence Tolerance")) {
453 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
454 convtol_ = params->get (
"Convergence Tolerance",
462 params_->set(
"Convergence Tolerance", convtol_);
463 if (convTest_ != Teuchos::null)
467 if (params->isParameter(
"Show Maximum Residual Norm Only")) {
468 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,
"Show Maximum Residual Norm Only");
471 params_->set(
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
472 if (convTest_ != Teuchos::null)
473 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
477 bool newResTest =
false;
482 std::string tempResScale = resScale_;
483 bool implicitResidualScalingName =
false;
484 if (params->isParameter (
"Residual Scaling")) {
485 tempResScale = params->get<std::string> (
"Residual Scaling");
487 else if (params->isParameter (
"Implicit Residual Scaling")) {
488 tempResScale = params->get<std::string> (
"Implicit Residual Scaling");
489 implicitResidualScalingName =
true;
493 if (resScale_ != tempResScale) {
495 resScale_ = tempResScale;
499 if (implicitResidualScalingName) {
500 params_->set (
"Implicit Residual Scaling", resScale_);
503 params_->set (
"Residual Scaling", resScale_);
506 if (! convTest_.is_null()) {
510 catch (std::exception& e) {
519 if (params->isParameter(
"Deflation Quorum")) {
520 defQuorum_ = params->get(
"Deflation Quorum", defQuorum_);
521 params_->set(
"Deflation Quorum", defQuorum_);
522 if (convTest_ != Teuchos::null)
523 convTest_->setQuorum( defQuorum_ );
529 if (maxIterTest_ == Teuchos::null)
533 if (convTest_ == Teuchos::null || newResTest) {
534 convTest_ = Teuchos::rcp(
new StatusTestResNorm_t( convtol_, defQuorum_, showMaxResNormOnly_ ) );
538 if (sTest_ == Teuchos::null || newResTest)
539 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
541 if (outputTest_ == Teuchos::null || newResTest) {
549 std::string solverDesc =
" Pseudo Block BiCGStab ";
550 outputTest_->setSolverDesc( solverDesc );
555 if (timerSolve_ == Teuchos::null) {
556 std::string solveLabel = label_ +
": BiCGStabSolMgr total solve time";
557 #ifdef BELOS_TEUCHOS_TIME_MONITOR
558 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
567 template<
class ScalarType,
class MV,
class OP>
568 Teuchos::RCP<const Teuchos::ParameterList>
571 using Teuchos::ParameterList;
572 using Teuchos::parameterList;
575 if (validParams_.is_null()) {
577 RCP<ParameterList> pl = parameterList ();
582 "The relative residual tolerance that needs to be achieved by the\n"
583 "iterative solver in order for the linera system to be declared converged.");
584 pl->set(
"Maximum Iterations", static_cast<int>(maxIters_default_),
585 "The maximum number of block iterations allowed for each\n"
586 "set of RHS solved.");
587 pl->set(
"Verbosity", static_cast<int>(verbosity_default_),
588 "What type(s) of solver information should be outputted\n"
589 "to the output stream.");
590 pl->set(
"Output Style", static_cast<int>(outputStyle_default_),
591 "What style is used for the solver information outputted\n"
592 "to the output stream.");
593 pl->set(
"Output Frequency", static_cast<int>(outputFreq_default_),
594 "How often convergence information should be outputted\n"
595 "to the output stream.");
596 pl->set(
"Deflation Quorum", static_cast<int>(defQuorum_default_),
597 "The number of linear systems that need to converge before\n"
598 "they are deflated. This number should be <= block size.");
599 pl->set(
"Output Stream", Teuchos::rcp(outputStream_default_,
false),
600 "A reference-counted pointer to the output stream where all\n"
601 "solver output is sent.");
602 pl->set(
"Show Maximum Residual Norm Only", static_cast<bool>(showMaxResNormOnly_default_),
603 "When convergence information is printed, only show the maximum\n"
604 "relative residual norm when the block size is greater than one.");
605 pl->set(
"Implicit Residual Scaling", static_cast<const char *>(resScale_default_),
606 "The type of scaling used in the residual convergence test.");
612 pl->set(
"Residual Scaling", static_cast<const char *>(resScale_default_),
613 "The type of scaling used in the residual convergence test. This "
614 "name is deprecated; the new name is \"Implicit Residual Scaling\".");
615 pl->set(
"Timer Label", static_cast<const char *>(label_default_),
616 "The string to use as a prefix for the timer labels.");
623 template<
class ScalarType,
class MV,
class OP>
630 setParameters (params_);
633 Teuchos::BLAS<int,ScalarType> blas;
635 TEUCHOS_TEST_FOR_EXCEPTION
637 "Belos::BiCGStabSolMgr::solve: Linear problem is not ready. "
638 "You must call setProblem() on the LinearProblem before you may solve it.");
639 TEUCHOS_TEST_FOR_EXCEPTION
640 (problem_->isLeftPrec (), std::logic_error,
"Belos::BiCGStabSolMgr::solve: "
641 "The left-preconditioned case has not yet been implemented. Please use "
642 "right preconditioning for now. If you need to use left preconditioning, "
643 "please contact the Belos developers. Left preconditioning is more "
644 "interesting in BiCGStab because whether it works depends on the initial "
645 "guess (e.g., an initial guess of all zeros might NOT work).");
649 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
650 int numCurrRHS = numRHS2Solve;
652 std::vector<int> currIdx( numRHS2Solve ), currIdx2( numRHS2Solve );
653 for (
int i=0; i<numRHS2Solve; ++i) {
654 currIdx[i] = startPtr+i;
659 problem_->setLSIndex( currIdx );
663 Teuchos::ParameterList plist;
666 outputTest_->reset();
669 bool isConverged =
true;
674 Teuchos::RCP<BiCGStabIter<ScalarType,MV,OP> > block_cg_iter
679 #ifdef BELOS_TEUCHOS_TIME_MONITOR
680 Teuchos::TimeMonitor slvtimer(*timerSolve_);
684 while ( numRHS2Solve > 0 ) {
686 std::vector<int> convRHSIdx;
687 std::vector<int> currRHSIdx( currIdx );
688 currRHSIdx.resize(numCurrRHS);
691 block_cg_iter->resetNumIters();
694 outputTest_->resetNumCalls();
697 Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
702 block_cg_iter->initializeBiCGStab(newState);
709 block_cg_iter->iterate();
716 if ( convTest_->getStatus() ==
Passed ) {
723 if (convIdx.size() == currRHSIdx.size())
727 problem_->setCurrLS();
731 std::vector<int> unconvIdx(currRHSIdx.size());
732 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
734 for (
unsigned int j=0; j<convIdx.size(); ++j) {
735 if (currRHSIdx[i] == convIdx[j]) {
741 currIdx2[have] = currIdx2[i];
742 currRHSIdx[have++] = currRHSIdx[i];
745 currRHSIdx.resize(have);
746 currIdx2.resize(have);
749 problem_->setLSIndex( currRHSIdx );
752 std::vector<MagnitudeType> norms;
753 R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
754 for (
int i=0; i<have; ++i) { currIdx2[i] = i; }
759 block_cg_iter->initializeBiCGStab(defstate);
767 else if ( maxIterTest_->getStatus() ==
Passed ) {
781 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
782 "Belos::BiCGStabSolMgr::solve(): Invalid return from BiCGStabIter::iterate().");
785 catch (
const std::exception &e) {
786 printer_->stream(
Errors) <<
"Error! Caught std::exception in BiCGStabIter::iterate() at iteration "
787 << block_cg_iter->getNumIters() << std::endl
788 << e.what() << std::endl;
794 problem_->setCurrLS();
797 startPtr += numCurrRHS;
798 numRHS2Solve -= numCurrRHS;
800 if ( numRHS2Solve > 0 ) {
802 numCurrRHS = numRHS2Solve;
803 currIdx.resize( numCurrRHS );
804 currIdx2.resize( numCurrRHS );
805 for (
int i=0; i<numCurrRHS; ++i)
806 { currIdx[i] = startPtr+i; currIdx2[i] = i; }
809 problem_->setLSIndex( currIdx );
812 currIdx.resize( numRHS2Solve );
824 #ifdef BELOS_TEUCHOS_TIME_MONITOR
829 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
833 numIters_ = maxIterTest_->getNumIters();
838 const std::vector<MagnitudeType>* pTestValues = convTest_->getTestValue();
839 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
849 template<
class ScalarType,
class MV,
class OP>
852 std::ostringstream oss;
853 oss <<
"Belos::BiCGStabSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";