103 using SCT = Teuchos::ScalarTraits<ScalarType>;
104 using MagnitudeType =
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType;
105 using MT = Teuchos::ScalarTraits<MagnitudeType>;
156 const Teuchos::RCP<Teuchos::ParameterList> &
pl );
162 Teuchos::RCP<SolverManager<ScalarType, MV, OP, DM> >
clone ()
const override {
176 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const override;
187 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
188 return Teuchos::tuple(timerSolve_);
218 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> &
params )
override;
227 sTest_ = Teuchos::null;
228 outputTest_ = Teuchos::null;
271 std::string description()
const override;
278 Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > problem_;
281 Teuchos::RCP<OutputManager<ScalarType> > printer_;
283 Teuchos::RCP<std::ostream> outputStream_;
289 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > sTest_;
292 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP,DM> > maxIterTest_;
295 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP,DM> > convTest_;
298 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP,DM> > outputTest_;
299 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > debugStatusTest_;
302 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > ortho_;
305 Teuchos::RCP<Teuchos::ParameterList> params_;
310 static constexpr int maxIters_default_ = 1000;
311 static constexpr bool adaptiveBlockSize_default_ =
true;
312 static constexpr bool showMaxResNormOnly_default_ =
false;
313 static constexpr bool useSingleReduction_default_ =
false;
314 static constexpr int blockSize_default_ = 1;
317 static constexpr int outputFreq_default_ = -1;
318 static constexpr const char * resNorm_default_ =
"TwoNorm";
319 static constexpr bool foldConvergenceDetectionIntoAllreduce_default_ =
false;
320 static constexpr const char * resScale_default_ =
"Norm of Initial Residual";
321 static constexpr const char * label_default_ =
"Belos";
322 static constexpr const char * orthoType_default_ =
"ICGS";
323 static constexpr bool assertPositiveDefiniteness_default_ =
true;
330 MagnitudeType convtol_;
333 MagnitudeType orthoKappa_;
340 MagnitudeType achievedTol_;
349 int blockSize_, verbosity_, outputStyle_, outputFreq_;
350 bool adaptiveBlockSize_, showMaxResNormOnly_, useSingleReduction_;
351 std::string orthoType_, resScale_;
352 bool assertPositiveDefiniteness_;
353 bool foldConvergenceDetectionIntoAllreduce_;
355 Teuchos::RCP<CGIterationStateBase<ScalarType, MV, DM> > state_;
361 Teuchos::RCP<Teuchos::Time> timerSolve_;
375 maxIters_(maxIters_default_),
377 blockSize_(blockSize_default_),
378 verbosity_(verbosity_default_),
379 outputStyle_(outputStyle_default_),
380 outputFreq_(outputFreq_default_),
381 adaptiveBlockSize_(adaptiveBlockSize_default_),
382 showMaxResNormOnly_(showMaxResNormOnly_default_),
383 useSingleReduction_(useSingleReduction_default_),
384 orthoType_(orthoType_default_),
385 resScale_(resScale_default_),
386 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
387 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
388 label_(label_default_),
397 const Teuchos::RCP<Teuchos::ParameterList> &
pl) :
403 maxIters_(maxIters_default_),
405 blockSize_(blockSize_default_),
406 verbosity_(verbosity_default_),
407 outputStyle_(outputStyle_default_),
408 outputFreq_(outputFreq_default_),
409 adaptiveBlockSize_(adaptiveBlockSize_default_),
410 showMaxResNormOnly_(showMaxResNormOnly_default_),
411 useSingleReduction_(useSingleReduction_default_),
412 orthoType_(orthoType_default_),
413 resScale_(resScale_default_),
414 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
415 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
416 label_(label_default_),
420 "BlockCGSolMgr's constructor requires a nonnull LinearProblem instance.");
425 if (!
pl.is_null()) {
436 if (params_ == Teuchos::null) {
437 params_ = Teuchos::rcp(
new Teuchos::ParameterList(*getValidParameters()) );
440 params->validateParameters(*getValidParameters());
444 if (
params->isParameter(
"Maximum Iterations")) {
445 maxIters_ =
params->get(
"Maximum Iterations",maxIters_default_);
448 params_->set(
"Maximum Iterations", maxIters_);
449 if (maxIterTest_!=Teuchos::null)
450 maxIterTest_->setMaxIters( maxIters_ );
454 if (
params->isParameter(
"Block Size")) {
455 blockSize_ =
params->get(
"Block Size",blockSize_default_);
457 "Belos::BlockCGSolMgr: \"Block Size\" must be strictly positive.");
460 params_->set(
"Block Size", blockSize_);
464 if (
params->isParameter(
"Adaptive Block Size")) {
465 adaptiveBlockSize_ =
params->get(
"Adaptive Block Size",adaptiveBlockSize_default_);
468 params_->set(
"Adaptive Block Size", adaptiveBlockSize_);
472 if (
params->isParameter(
"Use Single Reduction")) {
473 useSingleReduction_ =
params->get(
"Use Single Reduction", useSingleReduction_default_);
476 if (
params->isParameter(
"Fold Convergence Detection Into Allreduce")) {
477 foldConvergenceDetectionIntoAllreduce_ =
params->get(
"Fold Convergence Detection Into Allreduce",
478 foldConvergenceDetectionIntoAllreduce_default_);
482 if (
params->isParameter(
"Timer Label")) {
488 params_->set(
"Timer Label", label_);
489 std::string
solveLabel = label_ +
": BlockCGSolMgr total solve time";
490#ifdef BELOS_TEUCHOS_TIME_MONITOR
491 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
493 if (ortho_ != Teuchos::null) {
494 ortho_->setLabel( label_ );
500 if (
params->isParameter(
"Verbosity")) {
501 if (Teuchos::isParameterType<int>(*
params,
"Verbosity")) {
502 verbosity_ =
params->get(
"Verbosity", verbosity_default_);
504 verbosity_ = (
int)Teuchos::getParameter<Belos::MsgType>(*
params,
"Verbosity");
508 params_->set(
"Verbosity", verbosity_);
509 if (printer_ != Teuchos::null)
510 printer_->setVerbosity(verbosity_);
514 if (
params->isParameter(
"Output Style")) {
515 if (Teuchos::isParameterType<int>(*
params,
"Output Style")) {
516 outputStyle_ =
params->get(
"Output Style", outputStyle_default_);
518 outputStyle_ = (
int)Teuchos::getParameter<Belos::OutputType>(*
params,
"Output Style");
522 params_->set(
"Output Style", outputStyle_);
523 outputTest_ = Teuchos::null;
527 if (
params->isParameter(
"Output Stream")) {
528 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*
params,
"Output Stream");
531 params_->set(
"Output Stream", outputStream_);
532 if (printer_ != Teuchos::null)
533 printer_->setOStream( outputStream_ );
538 if (
params->isParameter(
"Output Frequency")) {
539 outputFreq_ =
params->get(
"Output Frequency", outputFreq_default_);
543 params_->set(
"Output Frequency", outputFreq_);
544 if (outputTest_ != Teuchos::null)
545 outputTest_->setOutputFrequency( outputFreq_ );
549 if (printer_ == Teuchos::null) {
555 if (
params->isParameter(
"Orthogonalization")) {
562 params_->set(
"Orthogonalization", orthoType_);
565 if (
params->isParameter(
"Orthogonalization Constant")) {
566 if (
params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
567 orthoKappa_ =
params->get (
"Orthogonalization Constant",
571 orthoKappa_ =
params->get (
"Orthogonalization Constant",
576 params_->set(
"Orthogonalization Constant",orthoKappa_);
577 if (orthoType_==
"DGKS") {
579 Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP,DM> >(ortho_)->setDepTol( orthoKappa_ );
588 if (orthoType_==
"DGKS" && orthoKappa_ > 0) {
589 paramsOrtho = Teuchos::rcp(
new Teuchos::ParameterList());
593 ortho_ =
factory.makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_,
paramsOrtho);
601 if (
params->isParameter(
"Convergence Tolerance")) {
602 if (
params->isType<MagnitudeType> (
"Convergence Tolerance")) {
603 convtol_ =
params->get (
"Convergence Tolerance",
611 params_->set(
"Convergence Tolerance", convtol_);
612 if (convTest_ != Teuchos::null)
613 convTest_->setTolerance( convtol_ );
616 if (
params->isParameter(
"Show Maximum Residual Norm Only")) {
617 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*
params,
"Show Maximum Residual Norm Only");
620 params_->set(
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
621 if (convTest_ != Teuchos::null)
622 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
629 if (
params->isParameter (
"Implicit Residual Scaling")) {
640 params_->set (
"Implicit Residual Scaling", resScale_);
642 if (! convTest_.is_null ()) {
645 if (
params->isParameter(
"Residual Norm")) {
646 if (
params->isType<std::string> (
"Residual Norm")) {
650 convTest_->defineResForm(StatusTestResNorm_t::Implicit,
normType);
653 catch (std::exception&
e) {
664 if (maxIterTest_ == Teuchos::null)
671 if (
params->isParameter(
"Residual Norm")) {
672 if (
params->isType<std::string> (
"Residual Norm")) {
677 convTest_ =
rcp (
new StatusTestResNorm_t (convtol_, 1, showMaxResNormOnly_));
678 convTest_->defineResForm(StatusTestResNorm_t::Implicit,
normType);
683 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
684 if (Teuchos::nonnull(debugStatusTest_)) {
686 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, sTest_, debugStatusTest_ ) );
704 if (
params->isParameter(
"Assert Positive Definiteness")) {
705 assertPositiveDefiniteness_ = Teuchos::getParameter<bool>(*
params,
"Assert Positive Definiteness");
706 params_->set(
"Assert Positive Definiteness", assertPositiveDefiniteness_);
710 if (timerSolve_ == Teuchos::null) {
711 std::string
solveLabel = label_ +
": BlockCGSolMgr total solve time";
712#ifdef BELOS_TEUCHOS_TIME_MONITOR
713 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
726 static Teuchos::RCP<const Teuchos::ParameterList>
validPL;
730 Teuchos::RCP<Teuchos::ParameterList>
pl = Teuchos::parameterList();
732 "The relative residual tolerance that needs to be achieved by the\n"
733 "iterative solver in order for the linear system to be declared converged.");
734 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
735 "The maximum number of block iterations allowed for each\n"
736 "set of RHS solved.");
737 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
738 "The number of vectors in each block.");
739 pl->set(
"Adaptive Block Size",
static_cast<bool>(adaptiveBlockSize_default_),
740 "Whether the solver manager should adapt to the block size\n"
741 "based on the number of RHS to solve.");
742 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
743 "What type(s) of solver information should be outputted\n"
744 "to the output stream.");
745 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
746 "What style is used for the solver information outputted\n"
747 "to the output stream.");
748 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
749 "How often convergence information should be outputted\n"
750 "to the output stream.");
751 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
752 "A reference-counted pointer to the output stream where all\n"
753 "solver output is sent.");
754 pl->set(
"Show Maximum Residual Norm Only",
static_cast<bool>(showMaxResNormOnly_default_),
755 "When convergence information is printed, only show the maximum\n"
756 "relative residual norm when the block size is greater than one.");
757 pl->set(
"Use Single Reduction",
static_cast<bool>(useSingleReduction_default_),
758 "Use single reduction iteration when the block size is one.");
759 pl->set(
"Implicit Residual Scaling", resScale_default_,
760 "The type of scaling used in the residual convergence test.");
761 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
762 "The string to use as a prefix for the timer labels.");
763 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
764 "The type of orthogonalization to use: DGKS, ICGS, or IMGS.");
765 pl->set(
"Assert Positive Definiteness",
static_cast<bool>(assertPositiveDefiniteness_default_),
766 "Assert for positivity of p^H*A*p in CG iteration.");
768 "The constant used by DGKS orthogonalization to determine\n"
769 "whether another step of classical Gram-Schmidt is necessary.");
770 pl->set(
"Residual Norm",
static_cast<const char *
>(resNorm_default_),
771 "Norm used for the convergence check on the residual.");
772 pl->set(
"Fold Convergence Detection Into Allreduce",
static_cast<bool>(foldConvergenceDetectionIntoAllreduce_default_),
773 "Merge the allreduce for convergence detection with the one for CG.\n"
774 "This saves one all-reduce, but incurs more computation.");
786 using Teuchos::rcp_const_cast;
787 using Teuchos::rcp_dynamic_cast;
796 setParameters(Teuchos::parameterList(*getValidParameters()));
801 "Belos::BlockCGSolMgr::solve(): Linear problem is not ready, setProblem() "
802 "has not been called.");
806 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
814 if ( adaptiveBlockSize_ ) {
832 problem_->setLSIndex(
currIdx );
836 Teuchos::ParameterList
plist;
837 plist.set(
"Block Size",blockSize_);
840 outputTest_->reset();
849 plist.set(
"Assert Positive Definiteness", assertPositiveDefiniteness_);
852 if (blockSize_ == 1) {
856 plist.set(
"Fold Convergence Detection Into Allreduce",
857 foldConvergenceDetectionIntoAllreduce_);
858 if (useSingleReduction_) {
861 outputTest_, convTest_,
plist));
869 outputTest_, convTest_,
plist));
884#ifdef BELOS_TEUCHOS_TIME_MONITOR
885 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
899 outputTest_->resetNumCalls();
915 if (convTest_->getStatus() ==
Passed) {
931 problem_->setCurrLS();
939 for (
unsigned int j=0;
j<
convIdx.size(); ++
j) {
959 std::vector<MagnitudeType>
norms;
973 else if (maxIterTest_->getStatus() ==
Passed) {
981 else if (Teuchos::nonnull(debugStatusTest_) &&
982 debugStatusTest_->getStatus() ==
Passed) {
994 "Belos::BlockCGSolMgr::solve(): Neither the convergence test nor "
995 "the maximum iteration count test passed. Please report this bug "
996 "to the Belos developers.");
1002 achievedTol_ = MT::one();
1003 Teuchos::RCP<MV>
X = problem_->getLHS();
1004 MVT::MvInit( *
X, SCT::zero() );
1005 printer_->stream(
Warnings) <<
"Belos::BlockCGSolMgr::solve(): Warning! NaN has been detected!"
1009 catch (
const std::exception &
e) {
1011 std::ostream&
err = printer_->stream (
Errors);
1012 err <<
"Error! Caught std::exception in CGIteration::iterate() at "
1013 <<
"iteration " <<
block_cg_iter->getNumIters() << std::endl
1014 <<
e.what() << std::endl;
1021 problem_->setCurrLS();
1029 if ( adaptiveBlockSize_ ) {
1045 problem_->setLSIndex(
currIdx );
1062#ifdef BELOS_TEUCHOS_TIME_MONITOR
1068 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1073 numIters_ = maxIterTest_->getNumIters();
1083 "Belos::BlockCGSolMgr::solve(): The convergence test's getTestValue() "
1084 "method returned NULL. Please report this bug to the Belos developers.");
1087 "Belos::BlockCGSolMgr::solve(): The convergence test's getTestValue() "
1088 "method returned a vector of length zero. Please report this bug to the "
1089 "Belos developers.");