42 #ifndef BELOS_BICGSTAB_SOLMGR_HPP
43 #define BELOS_BICGSTAB_SOLMGR_HPP
63 #ifdef BELOS_TEUCHOS_TIME_MONITOR
108 template<
class ScalarType,
class MV,
class OP>
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>
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_),
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.");
352 template<
class ScalarType,
class MV,
class OP>
356 using Teuchos::parameterList;
359 RCP<const ParameterList> defaultParams = getValidParameters();
362 if (params_.is_null()) {
363 params_ = parameterList (*defaultParams);
370 maxIters_ = params->
get(
"Maximum Iterations",maxIters_default_);
373 params_->set(
"Maximum Iterations", maxIters_);
374 if (maxIterTest_!=Teuchos::null)
375 maxIterTest_->setMaxIters( maxIters_ );
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
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_);
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;
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_ );
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")) {
454 convtol_ = params->
get (
"Convergence Tolerance",
462 params_->set(
"Convergence Tolerance", convtol_);
463 if (convTest_ != Teuchos::null)
464 convTest_->setTolerance( convtol_ );
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;
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) {
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
567 template<
class ScalarType,
class MV,
class OP>
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_);
637 "Belos::BiCGStabSolMgr::solve: Linear problem is not ready. "
638 "You must call setProblem() on the LinearProblem before you may solve it.");
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 );
666 outputTest_->reset();
669 bool isConverged =
true;
679 #ifdef BELOS_TEUCHOS_TIME_MONITOR
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 ) {
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
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;