128 using SCT = Teuchos::ScalarTraits<ScalarType>;
129 using MagnitudeType =
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType;
130 using MT = Teuchos::ScalarTraits<MagnitudeType>;
181 const Teuchos::RCP<Teuchos::ParameterList> &
pl );
187 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
201 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
const override;
212 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
213 return Teuchos::tuple(timerSolve_);
243 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> &
params )
override;
284 std::string description()
const override;
291 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
294 Teuchos::RCP<OutputManager<ScalarType> > printer_;
296 Teuchos::RCP<std::ostream> outputStream_;
302 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
305 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
308 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
311 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
314 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
317 Teuchos::RCP<Teuchos::ParameterList> params_;
322 static constexpr int maxIters_default_ = 1000;
323 static constexpr bool adaptiveBlockSize_default_ =
true;
324 static constexpr bool showMaxResNormOnly_default_ =
false;
325 static constexpr bool useSingleReduction_default_ =
false;
326 static constexpr int blockSize_default_ = 1;
329 static constexpr int outputFreq_default_ = -1;
330 static constexpr const char * resNorm_default_ =
"TwoNorm";
331 static constexpr bool foldConvergenceDetectionIntoAllreduce_default_ =
false;
332 static constexpr const char * resScale_default_ =
"Norm of Initial Residual";
333 static constexpr const char * label_default_ =
"Belos";
334 static constexpr const char * orthoType_default_ =
"ICGS";
335 static constexpr bool assertPositiveDefiniteness_default_ =
true;
342 MagnitudeType convtol_;
345 MagnitudeType orthoKappa_;
352 MagnitudeType achievedTol_;
361 int blockSize_, verbosity_, outputStyle_, outputFreq_;
362 bool adaptiveBlockSize_, showMaxResNormOnly_, useSingleReduction_;
363 std::string orthoType_, resScale_;
364 bool assertPositiveDefiniteness_;
365 bool foldConvergenceDetectionIntoAllreduce_;
367 Teuchos::RCP<CGIterationStateBase<ScalarType, MV> > state_;
373 Teuchos::RCP<Teuchos::Time> timerSolve_;
387 maxIters_(maxIters_default_),
389 blockSize_(blockSize_default_),
390 verbosity_(verbosity_default_),
391 outputStyle_(outputStyle_default_),
392 outputFreq_(outputFreq_default_),
393 adaptiveBlockSize_(adaptiveBlockSize_default_),
394 showMaxResNormOnly_(showMaxResNormOnly_default_),
395 useSingleReduction_(useSingleReduction_default_),
396 orthoType_(orthoType_default_),
397 resScale_(resScale_default_),
398 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
399 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
400 label_(label_default_),
409 const Teuchos::RCP<Teuchos::ParameterList> &
pl) :
415 maxIters_(maxIters_default_),
417 blockSize_(blockSize_default_),
418 verbosity_(verbosity_default_),
419 outputStyle_(outputStyle_default_),
420 outputFreq_(outputFreq_default_),
421 adaptiveBlockSize_(adaptiveBlockSize_default_),
422 showMaxResNormOnly_(showMaxResNormOnly_default_),
423 useSingleReduction_(useSingleReduction_default_),
424 orthoType_(orthoType_default_),
425 resScale_(resScale_default_),
426 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
427 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
428 label_(label_default_),
432 "BlockCGSolMgr's constructor requires a nonnull LinearProblem instance.");
437 if (!
pl.is_null()) {
448 if (params_ == Teuchos::null) {
449 params_ = Teuchos::rcp(
new Teuchos::ParameterList(*getValidParameters()) );
452 params->validateParameters(*getValidParameters());
456 if (
params->isParameter(
"Maximum Iterations")) {
457 maxIters_ =
params->get(
"Maximum Iterations",maxIters_default_);
460 params_->set(
"Maximum Iterations", maxIters_);
461 if (maxIterTest_!=Teuchos::null)
462 maxIterTest_->setMaxIters( maxIters_ );
466 if (
params->isParameter(
"Block Size")) {
467 blockSize_ =
params->get(
"Block Size",blockSize_default_);
469 "Belos::BlockCGSolMgr: \"Block Size\" must be strictly positive.");
472 params_->set(
"Block Size", blockSize_);
476 if (
params->isParameter(
"Adaptive Block Size")) {
477 adaptiveBlockSize_ =
params->get(
"Adaptive Block Size",adaptiveBlockSize_default_);
480 params_->set(
"Adaptive Block Size", adaptiveBlockSize_);
484 if (
params->isParameter(
"Use Single Reduction")) {
485 useSingleReduction_ =
params->get(
"Use Single Reduction", useSingleReduction_default_);
488 if (
params->isParameter(
"Fold Convergence Detection Into Allreduce")) {
489 foldConvergenceDetectionIntoAllreduce_ =
params->get(
"Fold Convergence Detection Into Allreduce",
490 foldConvergenceDetectionIntoAllreduce_default_);
494 if (
params->isParameter(
"Timer Label")) {
500 params_->set(
"Timer Label", label_);
501 std::string
solveLabel = label_ +
": BlockCGSolMgr total solve time";
502#ifdef BELOS_TEUCHOS_TIME_MONITOR
503 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
505 if (ortho_ != Teuchos::null) {
506 ortho_->setLabel( label_ );
512 if (
params->isParameter(
"Verbosity")) {
513 if (Teuchos::isParameterType<int>(*
params,
"Verbosity")) {
514 verbosity_ =
params->get(
"Verbosity", verbosity_default_);
516 verbosity_ = (
int)Teuchos::getParameter<Belos::MsgType>(*
params,
"Verbosity");
520 params_->set(
"Verbosity", verbosity_);
521 if (printer_ != Teuchos::null)
522 printer_->setVerbosity(verbosity_);
526 if (
params->isParameter(
"Output Style")) {
527 if (Teuchos::isParameterType<int>(*
params,
"Output Style")) {
528 outputStyle_ =
params->get(
"Output Style", outputStyle_default_);
530 outputStyle_ = (
int)Teuchos::getParameter<Belos::OutputType>(*
params,
"Output Style");
534 params_->set(
"Output Style", outputStyle_);
535 outputTest_ = Teuchos::null;
539 if (
params->isParameter(
"Output Stream")) {
540 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*
params,
"Output Stream");
543 params_->set(
"Output Stream", outputStream_);
544 if (printer_ != Teuchos::null)
545 printer_->setOStream( outputStream_ );
550 if (
params->isParameter(
"Output Frequency")) {
551 outputFreq_ =
params->get(
"Output Frequency", outputFreq_default_);
555 params_->set(
"Output Frequency", outputFreq_);
556 if (outputTest_ != Teuchos::null)
557 outputTest_->setOutputFrequency( outputFreq_ );
561 if (printer_ == Teuchos::null) {
567 if (
params->isParameter(
"Orthogonalization")) {
574 params_->set(
"Orthogonalization", orthoType_);
577 if (
params->isParameter(
"Orthogonalization Constant")) {
578 if (
params->isType<MagnitudeType> (
"Orthogonalization Constant")) {
579 orthoKappa_ =
params->get (
"Orthogonalization Constant",
583 orthoKappa_ =
params->get (
"Orthogonalization Constant",
588 params_->set(
"Orthogonalization Constant",orthoKappa_);
589 if (orthoType_==
"DGKS") {
591 Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
600 if (orthoType_==
"DGKS" && orthoKappa_ > 0) {
601 paramsOrtho = Teuchos::rcp(
new Teuchos::ParameterList());
605 ortho_ =
factory.makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_,
paramsOrtho);
613 if (
params->isParameter(
"Convergence Tolerance")) {
614 if (
params->isType<MagnitudeType> (
"Convergence Tolerance")) {
615 convtol_ =
params->get (
"Convergence Tolerance",
623 params_->set(
"Convergence Tolerance", convtol_);
624 if (convTest_ != Teuchos::null)
625 convTest_->setTolerance( convtol_ );
628 if (
params->isParameter(
"Show Maximum Residual Norm Only")) {
629 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*
params,
"Show Maximum Residual Norm Only");
632 params_->set(
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
633 if (convTest_ != Teuchos::null)
634 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
641 if (
params->isParameter (
"Implicit Residual Scaling")) {
652 params_->set (
"Implicit Residual Scaling", resScale_);
654 if (! convTest_.is_null ()) {
657 if (
params->isParameter(
"Residual Norm")) {
658 if (
params->isType<std::string> (
"Residual Norm")) {
662 convTest_->defineResForm(StatusTestResNorm_t::Implicit,
normType);
665 catch (std::exception&
e) {
676 if (maxIterTest_ == Teuchos::null)
683 if (
params->isParameter(
"Residual Norm")) {
684 if (
params->isType<std::string> (
"Residual Norm")) {
689 convTest_ =
rcp (
new StatusTestResNorm_t (convtol_, 1, showMaxResNormOnly_));
690 convTest_->defineResForm(StatusTestResNorm_t::Implicit,
normType);
695 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
711 if (
params->isParameter(
"Assert Positive Definiteness")) {
712 assertPositiveDefiniteness_ = Teuchos::getParameter<bool>(*
params,
"Assert Positive Definiteness");
713 params_->set(
"Assert Positive Definiteness", assertPositiveDefiniteness_);
717 if (timerSolve_ == Teuchos::null) {
718 std::string
solveLabel = label_ +
": BlockCGSolMgr total solve time";
719#ifdef BELOS_TEUCHOS_TIME_MONITOR
720 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(
solveLabel);
733 static Teuchos::RCP<const Teuchos::ParameterList>
validPL;
737 Teuchos::RCP<Teuchos::ParameterList>
pl = Teuchos::parameterList();
739 "The relative residual tolerance that needs to be achieved by the\n"
740 "iterative solver in order for the linear system to be declared converged.");
741 pl->set(
"Maximum Iterations",
static_cast<int>(maxIters_default_),
742 "The maximum number of block iterations allowed for each\n"
743 "set of RHS solved.");
744 pl->set(
"Block Size",
static_cast<int>(blockSize_default_),
745 "The number of vectors in each block.");
746 pl->set(
"Adaptive Block Size",
static_cast<bool>(adaptiveBlockSize_default_),
747 "Whether the solver manager should adapt to the block size\n"
748 "based on the number of RHS to solve.");
749 pl->set(
"Verbosity",
static_cast<int>(verbosity_default_),
750 "What type(s) of solver information should be outputted\n"
751 "to the output stream.");
752 pl->set(
"Output Style",
static_cast<int>(outputStyle_default_),
753 "What style is used for the solver information outputted\n"
754 "to the output stream.");
755 pl->set(
"Output Frequency",
static_cast<int>(outputFreq_default_),
756 "How often convergence information should be outputted\n"
757 "to the output stream.");
758 pl->set(
"Output Stream", Teuchos::rcpFromRef(std::cout),
759 "A reference-counted pointer to the output stream where all\n"
760 "solver output is sent.");
761 pl->set(
"Show Maximum Residual Norm Only",
static_cast<bool>(showMaxResNormOnly_default_),
762 "When convergence information is printed, only show the maximum\n"
763 "relative residual norm when the block size is greater than one.");
764 pl->set(
"Use Single Reduction",
static_cast<bool>(useSingleReduction_default_),
765 "Use single reduction iteration when the block size is one.");
766 pl->set(
"Implicit Residual Scaling", resScale_default_,
767 "The type of scaling used in the residual convergence test.");
768 pl->set(
"Timer Label",
static_cast<const char *
>(label_default_),
769 "The string to use as a prefix for the timer labels.");
770 pl->set(
"Orthogonalization",
static_cast<const char *
>(orthoType_default_),
771 "The type of orthogonalization to use: DGKS, ICGS, or IMGS.");
772 pl->set(
"Assert Positive Definiteness",
static_cast<bool>(assertPositiveDefiniteness_default_),
773 "Assert for positivity of p^H*A*p in CG iteration.");
775 "The constant used by DGKS orthogonalization to determine\n"
776 "whether another step of classical Gram-Schmidt is necessary.");
777 pl->set(
"Residual Norm",
static_cast<const char *
>(resNorm_default_),
778 "Norm used for the convergence check on the residual.");
779 pl->set(
"Fold Convergence Detection Into Allreduce",
static_cast<bool>(foldConvergenceDetectionIntoAllreduce_default_),
780 "Merge the allreduce for convergence detection with the one for CG.\n"
781 "This saves one all-reduce, but incurs more computation.");
793 using Teuchos::rcp_const_cast;
794 using Teuchos::rcp_dynamic_cast;
801 setParameters(Teuchos::parameterList(*getValidParameters()));
804 Teuchos::LAPACK<int,ScalarType> lapack;
808 "Belos::BlockCGSolMgr::solve(): Linear problem is not ready, setProblem() "
809 "has not been called.");
813 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
821 if ( adaptiveBlockSize_ ) {
839 problem_->setLSIndex(
currIdx );
843 Teuchos::ParameterList
plist;
844 plist.set(
"Block Size",blockSize_);
847 outputTest_->reset();
856 plist.set(
"Assert Positive Definiteness", assertPositiveDefiniteness_);
859 if (blockSize_ == 1) {
863 plist.set(
"Fold Convergence Detection Into Allreduce",
864 foldConvergenceDetectionIntoAllreduce_);
865 if (useSingleReduction_) {
868 outputTest_, convTest_,
plist));
876 outputTest_, convTest_,
plist));
891#ifdef BELOS_TEUCHOS_TIME_MONITOR
892 Teuchos::TimeMonitor
slvtimer(*timerSolve_);
906 outputTest_->resetNumCalls();
922 if (convTest_->getStatus() ==
Passed) {
938 problem_->setCurrLS();
946 for (
unsigned int j=0;
j<
convIdx.size(); ++
j) {
966 std::vector<MagnitudeType>
norms;
980 else if (maxIterTest_->getStatus() ==
Passed) {
990 "Belos::BlockCGSolMgr::solve(): Neither the convergence test nor "
991 "the maximum iteration count test passed. Please report this bug "
992 "to the Belos developers.");
997 achievedTol_ = MT::one();
998 Teuchos::RCP<MV>
X = problem_->getLHS();
999 MVT::MvInit( *
X, SCT::zero() );
1000 printer_->stream(
Warnings) <<
"Belos::BlockCGSolMgr::solve(): Warning! NaN has been detected!"
1004 catch (
const std::exception &
e) {
1005 std::ostream&
err = printer_->stream (
Errors);
1006 err <<
"Error! Caught std::exception in CGIteration::iterate() at "
1007 <<
"iteration " <<
block_cg_iter->getNumIters() << std::endl
1008 <<
e.what() << std::endl;
1015 problem_->setCurrLS();
1023 if ( adaptiveBlockSize_ ) {
1039 problem_->setLSIndex(
currIdx );
1056#ifdef BELOS_TEUCHOS_TIME_MONITOR
1062 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1067 numIters_ = maxIterTest_->getNumIters();
1077 "Belos::BlockCGSolMgr::solve(): The convergence test's getTestValue() "
1078 "method returned NULL. Please report this bug to the Belos developers.");
1081 "Belos::BlockCGSolMgr::solve(): The convergence test's getTestValue() "
1082 "method returned a vector of length zero. Please report this bug to the "
1083 "Belos developers.");