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;
259 std::string description()
const override;
266 Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > problem_;
269 Teuchos::RCP<OutputManager<ScalarType> > printer_;
271 Teuchos::RCP<std::ostream> outputStream_;
277 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > sTest_;
280 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP,DM> > maxIterTest_;
283 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP,DM> > convTest_;
286 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP,DM> > outputTest_;
289 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > ortho_;
292 Teuchos::RCP<Teuchos::ParameterList> params_;
297 static constexpr int maxIters_default_ = 1000;
298 static constexpr bool adaptiveBlockSize_default_ =
true;
299 static constexpr bool showMaxResNormOnly_default_ =
false;
300 static constexpr bool useSingleReduction_default_ =
false;
301 static constexpr int blockSize_default_ = 1;
304 static constexpr int outputFreq_default_ = -1;
305 static constexpr const char * resNorm_default_ =
"TwoNorm";
306 static constexpr bool foldConvergenceDetectionIntoAllreduce_default_ =
false;
307 static constexpr const char * resScale_default_ =
"Norm of Initial Residual";
308 static constexpr const char * label_default_ =
"Belos";
309 static constexpr const char * orthoType_default_ =
"ICGS";
310 static constexpr bool assertPositiveDefiniteness_default_ =
true;
317 MagnitudeType convtol_;
320 MagnitudeType orthoKappa_;
327 MagnitudeType achievedTol_;
336 int blockSize_, verbosity_, outputStyle_, outputFreq_;
337 bool adaptiveBlockSize_, showMaxResNormOnly_, useSingleReduction_;
338 std::string orthoType_, resScale_;
339 bool assertPositiveDefiniteness_;
340 bool foldConvergenceDetectionIntoAllreduce_;
342 Teuchos::RCP<CGIterationStateBase<ScalarType, MV, DM> > state_;
348 Teuchos::RCP<Teuchos::Time> timerSolve_;
362 maxIters_(maxIters_default_),
364 blockSize_(blockSize_default_),
365 verbosity_(verbosity_default_),
366 outputStyle_(outputStyle_default_),
367 outputFreq_(outputFreq_default_),
368 adaptiveBlockSize_(adaptiveBlockSize_default_),
369 showMaxResNormOnly_(showMaxResNormOnly_default_),
370 useSingleReduction_(useSingleReduction_default_),
371 orthoType_(orthoType_default_),
372 resScale_(resScale_default_),
373 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
374 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
375 label_(label_default_),
384 const Teuchos::RCP<Teuchos::ParameterList> &
pl) :
390 maxIters_(maxIters_default_),
392 blockSize_(blockSize_default_),
393 verbosity_(verbosity_default_),
394 outputStyle_(outputStyle_default_),
395 outputFreq_(outputFreq_default_),
396 adaptiveBlockSize_(adaptiveBlockSize_default_),
397 showMaxResNormOnly_(showMaxResNormOnly_default_),
398 useSingleReduction_(useSingleReduction_default_),
399 orthoType_(orthoType_default_),
400 resScale_(resScale_default_),
401 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
402 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
403 label_(label_default_),
407 "BlockCGSolMgr's constructor requires a nonnull LinearProblem instance.");
412 if (!
pl.is_null()) {
423 if (params_ == Teuchos::null) {
424 params_ = Teuchos::rcp(
new Teuchos::ParameterList(*getValidParameters()) );
427 params->validateParameters(*getValidParameters());
431 if (
params->isParameter(
"Maximum Iterations")) {
432 maxIters_ =
params->get(
"Maximum Iterations",maxIters_default_);
435 params_->set(
"Maximum Iterations", maxIters_);
436 if (maxIterTest_!=Teuchos::null)
437 maxIterTest_->setMaxIters( maxIters_ );
441 if (
params->isParameter(
"Block Size")) {
442 blockSize_ =
params->get(
"Block Size",blockSize_default_);
444 "Belos::BlockCGSolMgr: \"Block Size\" must be strictly positive.");
447 params_->set(
"Block Size", blockSize_);
451 if (
params->isParameter(
"Adaptive Block Size")) {
452 adaptiveBlockSize_ =
params->get(
"Adaptive Block Size",adaptiveBlockSize_default_);
455 params_->set(
"Adaptive Block Size", adaptiveBlockSize_);
459 if (
params->isParameter(
"Use Single Reduction")) {
460 useSingleReduction_ =
params->get(
"Use Single Reduction", useSingleReduction_default_);
463 if (
params->isParameter(
"Fold Convergence Detection Into Allreduce")) {
464 foldConvergenceDetectionIntoAllreduce_ =
params->get(
"Fold Convergence Detection Into Allreduce",
465 foldConvergenceDetectionIntoAllreduce_default_);
469 if (
params->isParameter(
"Timer Label")) {
475 params_->set(
"Timer Label", label_);
476 std::string
solveLabel = label_ +
": BlockCGSolMgr total solve time";
477#ifdef BELOS_TEUCHOS_TIME_MONITOR
478 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
480 if (ortho_ != Teuchos::null) {
481 ortho_->setLabel( label_ );
487 if (
params->isParameter(
"Verbosity")) {
488 if (Teuchos::isParameterType<int>(*
params,
"Verbosity")) {
489 verbosity_ =
params->get(
"Verbosity", verbosity_default_);
491 verbosity_ = (
int)Teuchos::getParameter<Belos::MsgType>(*
params,
"Verbosity");
495 params_->set(
"Verbosity", verbosity_);
496 if (printer_ != Teuchos::null)
497 printer_->setVerbosity(verbosity_);
501 if (
params->isParameter(
"Output Style")) {
502 if (Teuchos::isParameterType<int>(*
params,
"Output Style")) {
503 outputStyle_ =
params->get(
"Output Style", outputStyle_default_);
505 outputStyle_ = (
int)Teuchos::getParameter<Belos::OutputType>(*
params,
"Output Style");
509 params_->set(
"Output Style", outputStyle_);
510 outputTest_ = Teuchos::null;
514 if (
params->isParameter(
"Output Stream")) {
515 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*
params,
"Output Stream");
518 params_->set(
"Output Stream", outputStream_);
519 if (printer_ != Teuchos::null)
520 printer_->setOStream( outputStream_ );
525 if (
params->isParameter(
"Output Frequency")) {
526 outputFreq_ =
params->get(
"Output Frequency", outputFreq_default_);
530 params_->set(
"Output Frequency", outputFreq_);
531 if (outputTest_ != Teuchos::null)
532 outputTest_->setOutputFrequency( outputFreq_ );
536 if (printer_ == Teuchos::null) {
542 if (
params->isParameter(
"Orthogonalization")) {
549 params_->set(
"Orthogonalization", orthoType_);
552 if (
params->isParameter(
"Orthogonalization Constant")) {
553 if (
params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
554 orthoKappa_ =
params->get (
"Orthogonalization Constant",
558 orthoKappa_ =
params->get (
"Orthogonalization Constant",
563 params_->set(
"Orthogonalization Constant",orthoKappa_);
564 if (orthoType_==
"DGKS") {
566 Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP,DM> >(ortho_)->setDepTol( orthoKappa_ );
575 if (orthoType_==
"DGKS" && orthoKappa_ > 0) {
576 paramsOrtho = Teuchos::rcp(
new Teuchos::ParameterList());
580 ortho_ =
factory.makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_,
paramsOrtho);
588 if (
params->isParameter(
"Convergence Tolerance")) {
589 if (
params->isType<MagnitudeType> (
"Convergence Tolerance")) {
590 convtol_ =
params->get (
"Convergence Tolerance",
598 params_->set(
"Convergence Tolerance", convtol_);
599 if (convTest_ != Teuchos::null)
600 convTest_->setTolerance( convtol_ );
603 if (
params->isParameter(
"Show Maximum Residual Norm Only")) {
604 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*
params,
"Show Maximum Residual Norm Only");
607 params_->set(
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
608 if (convTest_ != Teuchos::null)
609 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
616 if (
params->isParameter (
"Implicit Residual Scaling")) {
627 params_->set (
"Implicit Residual Scaling", resScale_);
629 if (! convTest_.is_null ()) {
632 if (
params->isParameter(
"Residual Norm")) {
633 if (
params->isType<std::string> (
"Residual Norm")) {
637 convTest_->defineResForm(StatusTestResNorm_t::Implicit,
normType);
640 catch (std::exception&
e) {
651 if (maxIterTest_ == Teuchos::null)
658 if (
params->isParameter(
"Residual Norm")) {
659 if (
params->isType<std::string> (
"Residual Norm")) {
664 convTest_ =
rcp (
new StatusTestResNorm_t (convtol_, 1, showMaxResNormOnly_));
665 convTest_->defineResForm(StatusTestResNorm_t::Implicit,
normType);
670 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
686 if (
params->isParameter(
"Assert Positive Definiteness")) {
687 assertPositiveDefiniteness_ = Teuchos::getParameter<bool>(*
params,
"Assert Positive Definiteness");
688 params_->set(
"Assert Positive Definiteness", assertPositiveDefiniteness_);
692 if (timerSolve_ == Teuchos::null) {
693 std::string
solveLabel = label_ +
": BlockCGSolMgr total solve time";
694#ifdef BELOS_TEUCHOS_TIME_MONITOR
695 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
708 static Teuchos::RCP<const Teuchos::ParameterList>
validPL;
712 Teuchos::RCP<Teuchos::ParameterList>
pl = Teuchos::parameterList();
714 "The relative residual tolerance that needs to be achieved by the\n"
715 "iterative solver in order for the linear system to be declared converged.");
716 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
717 "The maximum number of block iterations allowed for each\n"
718 "set of RHS solved.");
719 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
720 "The number of vectors in each block.");
721 pl->set(
"Adaptive Block Size",
static_cast<bool>(adaptiveBlockSize_default_),
722 "Whether the solver manager should adapt to the block size\n"
723 "based on the number of RHS to solve.");
724 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
725 "What type(s) of solver information should be outputted\n"
726 "to the output stream.");
727 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
728 "What style is used for the solver information outputted\n"
729 "to the output stream.");
730 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
731 "How often convergence information should be outputted\n"
732 "to the output stream.");
733 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
734 "A reference-counted pointer to the output stream where all\n"
735 "solver output is sent.");
736 pl->set(
"Show Maximum Residual Norm Only",
static_cast<bool>(showMaxResNormOnly_default_),
737 "When convergence information is printed, only show the maximum\n"
738 "relative residual norm when the block size is greater than one.");
739 pl->set(
"Use Single Reduction",
static_cast<bool>(useSingleReduction_default_),
740 "Use single reduction iteration when the block size is one.");
741 pl->set(
"Implicit Residual Scaling", resScale_default_,
742 "The type of scaling used in the residual convergence test.");
743 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
744 "The string to use as a prefix for the timer labels.");
745 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
746 "The type of orthogonalization to use: DGKS, ICGS, or IMGS.");
747 pl->set(
"Assert Positive Definiteness",
static_cast<bool>(assertPositiveDefiniteness_default_),
748 "Assert for positivity of p^H*A*p in CG iteration.");
750 "The constant used by DGKS orthogonalization to determine\n"
751 "whether another step of classical Gram-Schmidt is necessary.");
752 pl->set(
"Residual Norm",
static_cast<const char *
>(resNorm_default_),
753 "Norm used for the convergence check on the residual.");
754 pl->set(
"Fold Convergence Detection Into Allreduce",
static_cast<bool>(foldConvergenceDetectionIntoAllreduce_default_),
755 "Merge the allreduce for convergence detection with the one for CG.\n"
756 "This saves one all-reduce, but incurs more computation.");
768 using Teuchos::rcp_const_cast;
769 using Teuchos::rcp_dynamic_cast;
778 setParameters(Teuchos::parameterList(*getValidParameters()));
783 "Belos::BlockCGSolMgr::solve(): Linear problem is not ready, setProblem() "
784 "has not been called.");
788 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
796 if ( adaptiveBlockSize_ ) {
814 problem_->setLSIndex(
currIdx );
818 Teuchos::ParameterList
plist;
819 plist.set(
"Block Size",blockSize_);
822 outputTest_->reset();
831 plist.set(
"Assert Positive Definiteness", assertPositiveDefiniteness_);
834 if (blockSize_ == 1) {
838 plist.set(
"Fold Convergence Detection Into Allreduce",
839 foldConvergenceDetectionIntoAllreduce_);
840 if (useSingleReduction_) {
843 outputTest_, convTest_,
plist));
851 outputTest_, convTest_,
plist));
866#ifdef BELOS_TEUCHOS_TIME_MONITOR
867 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
881 outputTest_->resetNumCalls();
897 if (convTest_->getStatus() ==
Passed) {
913 problem_->setCurrLS();
921 for (
unsigned int j=0;
j<
convIdx.size(); ++
j) {
941 std::vector<MagnitudeType>
norms;
955 else if (maxIterTest_->getStatus() ==
Passed) {
967 "Belos::BlockCGSolMgr::solve(): Neither the convergence test nor "
968 "the maximum iteration count test passed. Please report this bug "
969 "to the Belos developers.");
975 achievedTol_ = MT::one();
976 Teuchos::RCP<MV>
X = problem_->getLHS();
977 MVT::MvInit( *
X, SCT::zero() );
978 printer_->stream(
Warnings) <<
"Belos::BlockCGSolMgr::solve(): Warning! NaN has been detected!"
982 catch (
const std::exception &
e) {
984 std::ostream&
err = printer_->stream (
Errors);
985 err <<
"Error! Caught std::exception in CGIteration::iterate() at "
987 <<
e.what() << std::endl;
994 problem_->setCurrLS();
1002 if ( adaptiveBlockSize_ ) {
1018 problem_->setLSIndex(
currIdx );
1035#ifdef BELOS_TEUCHOS_TIME_MONITOR
1041 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1046 numIters_ = maxIterTest_->getNumIters();
1056 "Belos::BlockCGSolMgr::solve(): The convergence test's getTestValue() "
1057 "method returned NULL. Please report this bug to the Belos developers.");
1060 "Belos::BlockCGSolMgr::solve(): The convergence test's getTestValue() "
1061 "method returned a vector of length zero. Please report this bug to the "
1062 "Belos developers.");