95 typedef Teuchos::ScalarTraits<ScalarType> SCT;
96 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
97 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
121 const Teuchos::RCP<Teuchos::ParameterList> &pl );
127 Teuchos::RCP<SolverManager<ScalarType, MV, OP> >
clone ()
const override {
152 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
153 return Teuchos::tuple(timerSolve_);
175 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
override;
226 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
229 Teuchos::RCP<OutputManager<ScalarType> > printer_;
230 Teuchos::RCP<std::ostream> outputStream_;
233 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
234 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
235 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
236 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
239 Teuchos::RCP<Teuchos::ParameterList> params_;
246 mutable Teuchos::RCP<const Teuchos::ParameterList> validParams_;
249 static constexpr int maxIters_default_ = 1000;
250 static constexpr bool assertPositiveDefiniteness_default_ =
true;
251 static constexpr bool showMaxResNormOnly_default_ =
false;
254 static constexpr int outputFreq_default_ = -1;
255 static constexpr int defQuorum_default_ = 1;
256 static constexpr const char * resScale_default_ =
"Norm of Initial Residual";
257 static constexpr const char * label_default_ =
"Belos";
259#if defined(_WIN32) && defined(__clang__)
260 static constexpr std::ostream * outputStream_default_ =
261 __builtin_constant_p(
reinterpret_cast<const std::ostream*
>(&std::cout));
263 static constexpr std::ostream * outputStream_default_ = &std::cout;
267 MagnitudeType convtol_;
268 int maxIters_, numIters_;
269 int verbosity_, outputStyle_, outputFreq_, defQuorum_;
270 bool assertPositiveDefiniteness_, showMaxResNormOnly_;
271 std::string resScale_;
275 Teuchos::RCP<Teuchos::Time> timerSolve_;
289 outputStream_(Teuchos::rcp(outputStream_default_,false)),
291 maxIters_(maxIters_default_),
293 verbosity_(verbosity_default_),
294 outputStyle_(outputStyle_default_),
295 outputFreq_(outputFreq_default_),
296 defQuorum_(defQuorum_default_),
297 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
298 showMaxResNormOnly_(showMaxResNormOnly_default_),
299 resScale_(resScale_default_),
300 label_(label_default_),
308 const Teuchos::RCP<Teuchos::ParameterList> &pl ) :
310 outputStream_(Teuchos::rcp(outputStream_default_,false)),
312 maxIters_(maxIters_default_),
314 verbosity_(verbosity_default_),
315 outputStyle_(outputStyle_default_),
316 outputFreq_(outputFreq_default_),
317 defQuorum_(defQuorum_default_),
318 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
319 showMaxResNormOnly_(showMaxResNormOnly_default_),
320 resScale_(resScale_default_),
321 label_(label_default_),
324 TEUCHOS_TEST_FOR_EXCEPTION(
325 problem_.is_null (), std::invalid_argument,
326 "Belos::PseudoBlockStochasticCGSolMgr two-argument constructor: "
327 "'problem' is null. You must supply a non-null Belos::LinearProblem "
328 "instance when calling this constructor.");
330 if (! pl.is_null ()) {
339 using Teuchos::ParameterList;
340 using Teuchos::parameterList;
343 RCP<const ParameterList> defaultParams = getValidParameters();
346 if (params_.is_null()) {
347 params_ = parameterList (*defaultParams);
349 params->validateParameters (*defaultParams);
353 if (params->isParameter(
"Maximum Iterations")) {
354 maxIters_ = params->get(
"Maximum Iterations",maxIters_default_);
357 params_->set(
"Maximum Iterations", maxIters_);
358 if (maxIterTest_!=Teuchos::null)
359 maxIterTest_->setMaxIters( maxIters_ );
363 if (params->isParameter(
"Assert Positive Definiteness")) {
364 assertPositiveDefiniteness_ = params->get(
"Assert Positive Definiteness",assertPositiveDefiniteness_default_);
367 params_->set(
"Assert Positive Definiteness", assertPositiveDefiniteness_);
371 if (params->isParameter(
"Timer Label")) {
372 std::string tempLabel = params->get(
"Timer Label", label_default_);
375 if (tempLabel != label_) {
377 params_->set(
"Timer Label", label_);
378 std::string solveLabel = label_ +
": PseudoBlockStochasticCGSolMgr total solve time";
379#ifdef BELOS_TEUCHOS_TIME_MONITOR
380 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
386 if (params->isParameter(
"Verbosity")) {
387 if (Teuchos::isParameterType<int>(*params,
"Verbosity")) {
388 verbosity_ = params->get(
"Verbosity", verbosity_default_);
390 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,
"Verbosity");
394 params_->set(
"Verbosity", verbosity_);
395 if (printer_ != Teuchos::null)
396 printer_->setVerbosity(verbosity_);
400 if (params->isParameter(
"Output Style")) {
401 if (Teuchos::isParameterType<int>(*params,
"Output Style")) {
402 outputStyle_ = params->get(
"Output Style", outputStyle_default_);
404 outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,
"Output Style");
408 params_->set(
"Output Style", outputStyle_);
409 outputTest_ = Teuchos::null;
413 if (params->isParameter(
"Output Stream")) {
414 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
417 params_->set(
"Output Stream", outputStream_);
418 if (printer_ != Teuchos::null)
419 printer_->setOStream( outputStream_ );
424 if (params->isParameter(
"Output Frequency")) {
425 outputFreq_ = params->get(
"Output Frequency", outputFreq_default_);
429 params_->set(
"Output Frequency", outputFreq_);
430 if (outputTest_ != Teuchos::null)
431 outputTest_->setOutputFrequency( outputFreq_ );
435 if (printer_ == Teuchos::null) {
444 if (params->isParameter(
"Convergence Tolerance")) {
445 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
446 convtol_ = params->get (
"Convergence Tolerance",
454 params_->set(
"Convergence Tolerance", convtol_);
455 if (convTest_ != Teuchos::null)
459 if (params->isParameter(
"Show Maximum Residual Norm Only")) {
460 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,
"Show Maximum Residual Norm Only");
463 params_->set(
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
464 if (convTest_ != Teuchos::null)
465 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
469 bool newResTest =
false;
474 std::string tempResScale = resScale_;
475 bool implicitResidualScalingName =
false;
476 if (params->isParameter (
"Residual Scaling")) {
477 tempResScale = params->get<std::string> (
"Residual Scaling");
479 else if (params->isParameter (
"Implicit Residual Scaling")) {
480 tempResScale = params->get<std::string> (
"Implicit Residual Scaling");
481 implicitResidualScalingName =
true;
485 if (resScale_ != tempResScale) {
487 resScale_ = tempResScale;
491 if (implicitResidualScalingName) {
492 params_->set (
"Implicit Residual Scaling", resScale_);
495 params_->set (
"Residual Scaling", resScale_);
498 if (! convTest_.is_null()) {
502 catch (std::exception& e) {
511 if (params->isParameter(
"Deflation Quorum")) {
512 defQuorum_ = params->get(
"Deflation Quorum", defQuorum_);
513 params_->set(
"Deflation Quorum", defQuorum_);
514 if (convTest_ != Teuchos::null)
515 convTest_->setQuorum( defQuorum_ );
521 if (maxIterTest_ == Teuchos::null)
525 if (convTest_ == Teuchos::null || newResTest) {
526 convTest_ = Teuchos::rcp(
new StatusTestResNorm_t( convtol_, defQuorum_, showMaxResNormOnly_ ) );
530 if (sTest_ == Teuchos::null || newResTest)
531 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
533 if (outputTest_ == Teuchos::null || newResTest) {
541 std::string solverDesc =
" Pseudo Block CG ";
542 outputTest_->setSolverDesc( solverDesc );
547 if (timerSolve_ == Teuchos::null) {
548 std::string solveLabel = label_ +
": PseudoBlockStochasticCGSolMgr total solve time";
549#ifdef BELOS_TEUCHOS_TIME_MONITOR
550 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
625 if (!isSet_) { setParameters( params_ ); }
628 "Belos::PseudoBlockStochasticCGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
632 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
633 int numCurrRHS = numRHS2Solve;
635 std::vector<int> currIdx( numRHS2Solve ), currIdx2( numRHS2Solve );
636 for (
int i=0; i<numRHS2Solve; ++i) {
637 currIdx[i] = startPtr+i;
642 problem_->setLSIndex( currIdx );
646 Teuchos::ParameterList plist;
648 plist.set(
"Assert Positive Definiteness",assertPositiveDefiniteness_);
651 outputTest_->reset();
654 bool isConverged =
true;
659 Teuchos::RCP<PseudoBlockStochasticCGIter<ScalarType,MV,OP> > block_cg_iter
664#ifdef BELOS_TEUCHOS_TIME_MONITOR
665 Teuchos::TimeMonitor slvtimer(*timerSolve_);
668 while ( numRHS2Solve > 0 ) {
671 std::vector<int> convRHSIdx;
672 std::vector<int> currRHSIdx( currIdx );
673 currRHSIdx.resize(numCurrRHS);
676 block_cg_iter->resetNumIters();
679 outputTest_->resetNumCalls();
682 Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
687 block_cg_iter->initializeCG(newState);
693 block_cg_iter->iterate();
700 if ( convTest_->getStatus() ==
Passed ) {
703 std::vector<int> convIdx = Teuchos::rcp_dynamic_cast<StatusTestGenResNorm<ScalarType,MV,OP> >(convTest_)->convIndices();
707 if (convIdx.size() == currRHSIdx.size())
711 problem_->setCurrLS();
715 std::vector<int> unconvIdx(currRHSIdx.size());
716 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
718 for (
unsigned int j=0; j<convIdx.size(); ++j) {
719 if (currRHSIdx[i] == convIdx[j]) {
725 currIdx2[have] = currIdx2[i];
726 currRHSIdx[have++] = currRHSIdx[i];
729 currRHSIdx.resize(have);
730 currIdx2.resize(have);
733 problem_->setLSIndex( currRHSIdx );
736 std::vector<MagnitudeType> norms;
737 R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
738 for (
int i=0; i<have; ++i) { currIdx2[i] = i; }
743 block_cg_iter->initializeCG(defstate);
751 else if ( maxIterTest_->getStatus() ==
Passed ) {
765 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
766 "Belos::PseudoBlockStochasticCGSolMgr::solve(): Invalid return from PseudoBlockStochasticCGIter::iterate().");
769 catch (
const std::exception &e) {
770 printer_->stream(
Errors) <<
"Error! Caught std::exception in PseudoBlockStochasticCGIter::iterate() at iteration "
771 << block_cg_iter->getNumIters() << std::endl
772 << e.what() << std::endl;
778 problem_->setCurrLS();
781 startPtr += numCurrRHS;
782 numRHS2Solve -= numCurrRHS;
784 if ( numRHS2Solve > 0 ) {
786 numCurrRHS = numRHS2Solve;
787 currIdx.resize( numCurrRHS );
788 currIdx2.resize( numCurrRHS );
789 for (
int i=0; i<numCurrRHS; ++i)
790 { currIdx[i] = startPtr+i; currIdx2[i] = i; }
793 problem_->setLSIndex( currIdx );
796 currIdx.resize( numRHS2Solve );
804 Y_=block_cg_iter->getStochasticVector();
811#ifdef BELOS_TEUCHOS_TIME_MONITOR
816 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
820 numIters_ = maxIterTest_->getNumIters();