42 #ifndef BELOS_PSEUDO_BLOCK_STOCHASTIC_CG_SOLMGR_HPP
43 #define BELOS_PSEUDO_BLOCK_STOCHASTIC_CG_SOLMGR_HPP
61 #include "Teuchos_BLAS.hpp"
62 #ifdef BELOS_TEUCHOS_TIME_MONITOR
63 #include "Teuchos_TimeMonitor.hpp"
100 template<
class ScalarType,
class MV,
class OP>
106 typedef Teuchos::ScalarTraits<ScalarType> SCT;
107 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
108 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
132 const Teuchos::RCP<Teuchos::ParameterList> &pl );
138 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
163 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
164 return Teuchos::tuple(timerSolve_);
186 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
override;
237 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
240 Teuchos::RCP<OutputManager<ScalarType> > printer_;
241 Teuchos::RCP<std::ostream> outputStream_;
244 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
245 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
246 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
247 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
250 Teuchos::RCP<Teuchos::ParameterList> params_;
257 mutable Teuchos::RCP<const Teuchos::ParameterList> validParams_;
260 static constexpr
int maxIters_default_ = 1000;
261 static constexpr
bool assertPositiveDefiniteness_default_ =
true;
262 static constexpr
bool showMaxResNormOnly_default_ =
false;
265 static constexpr
int outputFreq_default_ = -1;
266 static constexpr
int defQuorum_default_ = 1;
267 static constexpr
const char * resScale_default_ =
"Norm of Initial Residual";
268 static constexpr
const char * label_default_ =
"Belos";
269 static constexpr std::ostream * outputStream_default_ = &std::cout;
272 MagnitudeType convtol_;
273 int maxIters_, numIters_;
274 int verbosity_, outputStyle_, outputFreq_, defQuorum_;
275 bool assertPositiveDefiniteness_, showMaxResNormOnly_;
276 std::string resScale_;
280 Teuchos::RCP<Teuchos::Time> timerSolve_;
292 template<
class ScalarType,
class MV,
class OP>
294 outputStream_(Teuchos::rcp(outputStream_default_,false)),
296 maxIters_(maxIters_default_),
298 verbosity_(verbosity_default_),
299 outputStyle_(outputStyle_default_),
300 outputFreq_(outputFreq_default_),
301 defQuorum_(defQuorum_default_),
302 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
303 showMaxResNormOnly_(showMaxResNormOnly_default_),
304 resScale_(resScale_default_),
305 label_(label_default_),
310 template<
class ScalarType,
class MV,
class OP>
313 const Teuchos::RCP<Teuchos::ParameterList> &pl ) :
315 outputStream_(Teuchos::rcp(outputStream_default_,false)),
317 maxIters_(maxIters_default_),
319 verbosity_(verbosity_default_),
320 outputStyle_(outputStyle_default_),
321 outputFreq_(outputFreq_default_),
322 defQuorum_(defQuorum_default_),
323 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
324 showMaxResNormOnly_(showMaxResNormOnly_default_),
325 resScale_(resScale_default_),
326 label_(label_default_),
329 TEUCHOS_TEST_FOR_EXCEPTION(
330 problem_.is_null (), std::invalid_argument,
331 "Belos::PseudoBlockStochasticCGSolMgr two-argument constructor: "
332 "'problem' is null. You must supply a non-null Belos::LinearProblem "
333 "instance when calling this constructor.");
335 if (! pl.is_null ()) {
341 template<
class ScalarType,
class MV,
class OP>
344 using Teuchos::ParameterList;
345 using Teuchos::parameterList;
348 RCP<const ParameterList> defaultParams = getValidParameters();
351 if (params_.is_null()) {
352 params_ = parameterList (*defaultParams);
354 params->validateParameters (*defaultParams);
358 if (params->isParameter(
"Maximum Iterations")) {
359 maxIters_ = params->get(
"Maximum Iterations",maxIters_default_);
362 params_->set(
"Maximum Iterations", maxIters_);
363 if (maxIterTest_!=Teuchos::null)
364 maxIterTest_->setMaxIters( maxIters_ );
368 if (params->isParameter(
"Assert Positive Definiteness")) {
369 assertPositiveDefiniteness_ = params->get(
"Assert Positive Definiteness",assertPositiveDefiniteness_default_);
372 params_->set(
"Assert Positive Definiteness", assertPositiveDefiniteness_);
376 if (params->isParameter(
"Timer Label")) {
377 std::string tempLabel = params->get(
"Timer Label", label_default_);
380 if (tempLabel != label_) {
382 params_->set(
"Timer Label", label_);
383 std::string solveLabel = label_ +
": PseudoBlockStochasticCGSolMgr total solve time";
384 #ifdef BELOS_TEUCHOS_TIME_MONITOR
385 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
391 if (params->isParameter(
"Verbosity")) {
392 if (Teuchos::isParameterType<int>(*params,
"Verbosity")) {
393 verbosity_ = params->get(
"Verbosity", verbosity_default_);
395 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,
"Verbosity");
399 params_->set(
"Verbosity", verbosity_);
400 if (printer_ != Teuchos::null)
401 printer_->setVerbosity(verbosity_);
405 if (params->isParameter(
"Output Style")) {
406 if (Teuchos::isParameterType<int>(*params,
"Output Style")) {
407 outputStyle_ = params->get(
"Output Style", outputStyle_default_);
409 outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,
"Output Style");
413 params_->set(
"Output Style", outputStyle_);
414 outputTest_ = Teuchos::null;
418 if (params->isParameter(
"Output Stream")) {
419 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
422 params_->set(
"Output Stream", outputStream_);
423 if (printer_ != Teuchos::null)
424 printer_->setOStream( outputStream_ );
429 if (params->isParameter(
"Output Frequency")) {
430 outputFreq_ = params->get(
"Output Frequency", outputFreq_default_);
434 params_->set(
"Output Frequency", outputFreq_);
435 if (outputTest_ != Teuchos::null)
436 outputTest_->setOutputFrequency( outputFreq_ );
440 if (printer_ == Teuchos::null) {
449 if (params->isParameter(
"Convergence Tolerance")) {
450 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
451 convtol_ = params->get (
"Convergence Tolerance",
459 params_->set(
"Convergence Tolerance", convtol_);
460 if (convTest_ != Teuchos::null)
464 if (params->isParameter(
"Show Maximum Residual Norm Only")) {
465 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,
"Show Maximum Residual Norm Only");
468 params_->set(
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
469 if (convTest_ != Teuchos::null)
470 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
474 bool newResTest =
false;
479 std::string tempResScale = resScale_;
480 bool implicitResidualScalingName =
false;
481 if (params->isParameter (
"Residual Scaling")) {
482 tempResScale = params->get<std::string> (
"Residual Scaling");
484 else if (params->isParameter (
"Implicit Residual Scaling")) {
485 tempResScale = params->get<std::string> (
"Implicit Residual Scaling");
486 implicitResidualScalingName =
true;
490 if (resScale_ != tempResScale) {
492 resScale_ = tempResScale;
496 if (implicitResidualScalingName) {
497 params_->set (
"Implicit Residual Scaling", resScale_);
500 params_->set (
"Residual Scaling", resScale_);
503 if (! convTest_.is_null()) {
507 catch (std::exception& e) {
516 if (params->isParameter(
"Deflation Quorum")) {
517 defQuorum_ = params->get(
"Deflation Quorum", defQuorum_);
518 params_->set(
"Deflation Quorum", defQuorum_);
519 if (convTest_ != Teuchos::null)
520 convTest_->setQuorum( defQuorum_ );
526 if (maxIterTest_ == Teuchos::null)
530 if (convTest_ == Teuchos::null || newResTest) {
531 convTest_ = Teuchos::rcp(
new StatusTestResNorm_t( convtol_, defQuorum_, showMaxResNormOnly_ ) );
535 if (sTest_ == Teuchos::null || newResTest)
536 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
538 if (outputTest_ == Teuchos::null || newResTest) {
546 std::string solverDesc =
" Pseudo Block CG ";
547 outputTest_->setSolverDesc( solverDesc );
552 if (timerSolve_ == Teuchos::null) {
553 std::string solveLabel = label_ +
": PseudoBlockStochasticCGSolMgr total solve time";
554 #ifdef BELOS_TEUCHOS_TIME_MONITOR
555 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
564 template<
class ScalarType,
class MV,
class OP>
565 Teuchos::RCP<const Teuchos::ParameterList>
568 using Teuchos::ParameterList;
569 using Teuchos::parameterList;
572 if (validParams_.is_null()) {
577 RCP<ParameterList> pl = parameterList ();
579 "The relative residual tolerance that needs to be achieved by the\n"
580 "iterative solver in order for the linera system to be declared converged.");
581 pl->set(
"Maximum Iterations", static_cast<int>(maxIters_default_),
582 "The maximum number of block iterations allowed for each\n"
583 "set of RHS solved.");
584 pl->set(
"Assert Positive Definiteness", static_cast<bool>(assertPositiveDefiniteness_default_),
585 "Whether or not to assert that the linear operator\n"
586 "and the preconditioner are indeed positive definite.");
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", resScale_default_,
606 "The type of scaling used in the residual convergence test.");
612 pl->set(
"Residual Scaling", 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.");
624 template<
class ScalarType,
class MV,
class OP>
630 if (!isSet_) { setParameters( params_ ); }
632 Teuchos::BLAS<int,ScalarType> blas;
635 "Belos::PseudoBlockStochasticCGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
639 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
640 int numCurrRHS = numRHS2Solve;
642 std::vector<int> currIdx( numRHS2Solve ), currIdx2( numRHS2Solve );
643 for (
int i=0; i<numRHS2Solve; ++i) {
644 currIdx[i] = startPtr+i;
649 problem_->setLSIndex( currIdx );
653 Teuchos::ParameterList plist;
655 plist.set(
"Assert Positive Definiteness",assertPositiveDefiniteness_);
658 outputTest_->reset();
661 bool isConverged =
true;
666 Teuchos::RCP<PseudoBlockStochasticCGIter<ScalarType,MV,OP> > block_cg_iter
671 #ifdef BELOS_TEUCHOS_TIME_MONITOR
672 Teuchos::TimeMonitor slvtimer(*timerSolve_);
675 while ( numRHS2Solve > 0 ) {
678 std::vector<int> convRHSIdx;
679 std::vector<int> currRHSIdx( currIdx );
680 currRHSIdx.resize(numCurrRHS);
683 block_cg_iter->resetNumIters();
686 outputTest_->resetNumCalls();
689 Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
694 block_cg_iter->initializeCG(newState);
700 block_cg_iter->iterate();
707 if ( convTest_->getStatus() ==
Passed ) {
714 if (convIdx.size() == currRHSIdx.size())
718 problem_->setCurrLS();
722 std::vector<int> unconvIdx(currRHSIdx.size());
723 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
725 for (
unsigned int j=0; j<convIdx.size(); ++j) {
726 if (currRHSIdx[i] == convIdx[j]) {
732 currIdx2[have] = currIdx2[i];
733 currRHSIdx[have++] = currRHSIdx[i];
736 currRHSIdx.resize(have);
737 currIdx2.resize(have);
740 problem_->setLSIndex( currRHSIdx );
743 std::vector<MagnitudeType> norms;
744 R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
745 for (
int i=0; i<have; ++i) { currIdx2[i] = i; }
750 block_cg_iter->initializeCG(defstate);
758 else if ( maxIterTest_->getStatus() ==
Passed ) {
772 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
773 "Belos::PseudoBlockStochasticCGSolMgr::solve(): Invalid return from PseudoBlockStochasticCGIter::iterate().");
776 catch (
const std::exception &e) {
777 printer_->stream(
Errors) <<
"Error! Caught std::exception in PseudoBlockStochasticCGIter::iterate() at iteration "
778 << block_cg_iter->getNumIters() << std::endl
779 << e.what() << std::endl;
785 problem_->setCurrLS();
788 startPtr += numCurrRHS;
789 numRHS2Solve -= numCurrRHS;
791 if ( numRHS2Solve > 0 ) {
793 numCurrRHS = numRHS2Solve;
794 currIdx.resize( numCurrRHS );
795 currIdx2.resize( numCurrRHS );
796 for (
int i=0; i<numCurrRHS; ++i)
797 { currIdx[i] = startPtr+i; currIdx2[i] = i; }
800 problem_->setLSIndex( currIdx );
803 currIdx.resize( numRHS2Solve );
811 Y_=block_cg_iter->getStochasticVector();
818 #ifdef BELOS_TEUCHOS_TIME_MONITOR
823 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
827 numIters_ = maxIterTest_->getNumIters();
836 template<
class ScalarType,
class MV,
class OP>
839 std::ostringstream oss;
840 oss <<
"Belos::PseudoBlockStochasticCGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";