42 #ifndef BELOS_FIXEDPOINT_SOLMGR_HPP
43 #define BELOS_FIXEDPOINT_SOLMGR_HPP
62 #include "Teuchos_BLAS.hpp"
63 #include "Teuchos_LAPACK.hpp"
64 #ifdef BELOS_TEUCHOS_TIME_MONITOR
65 # include "Teuchos_TimeMonitor.hpp"
92 template<
class ScalarType,
class MV,
class OP>
98 typedef Teuchos::ScalarTraits<ScalarType> SCT;
99 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
100 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_);
193 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
override;
199 convTest_ = userConvStatusTest;
202 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
207 std::string solverDesc =
" Fixed Point ";
208 outputTest_->setSolverDesc( solverDesc );
255 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
258 Teuchos::RCP<OutputManager<ScalarType> > printer_;
260 Teuchos::RCP<std::ostream> outputStream_;
266 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
269 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
272 Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > convTest_;
275 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
278 Teuchos::RCP<Teuchos::ParameterList> params_;
283 static constexpr
int maxIters_default_ = 1000;
284 static constexpr
bool showMaxResNormOnly_default_ =
false;
285 static constexpr
int blockSize_default_ = 1;
288 static constexpr
int outputFreq_default_ = -1;
289 static constexpr
const char * label_default_ =
"Belos";
290 static constexpr std::ostream * outputStream_default_ = &std::cout;
297 MagnitudeType convtol_;
304 MagnitudeType achievedTol_;
312 int blockSize_, verbosity_, outputStyle_, outputFreq_;
313 bool showMaxResNormOnly_;
319 Teuchos::RCP<Teuchos::Time> timerSolve_;
327 template<
class ScalarType,
class MV,
class OP>
329 outputStream_(Teuchos::rcp(outputStream_default_,false)),
331 achievedTol_(Teuchos::ScalarTraits<MagnitudeType>::zero()),
332 maxIters_(maxIters_default_),
334 blockSize_(blockSize_default_),
335 verbosity_(verbosity_default_),
336 outputStyle_(outputStyle_default_),
337 outputFreq_(outputFreq_default_),
338 showMaxResNormOnly_(showMaxResNormOnly_default_),
339 label_(label_default_),
345 template<
class ScalarType,
class MV,
class OP>
348 const Teuchos::RCP<Teuchos::ParameterList> &pl) :
350 outputStream_(Teuchos::rcp(outputStream_default_,false)),
352 achievedTol_(Teuchos::ScalarTraits<MagnitudeType>::zero()),
353 maxIters_(maxIters_default_),
355 blockSize_(blockSize_default_),
356 verbosity_(verbosity_default_),
357 outputStyle_(outputStyle_default_),
358 outputFreq_(outputFreq_default_),
359 showMaxResNormOnly_(showMaxResNormOnly_default_),
360 label_(label_default_),
363 TEUCHOS_TEST_FOR_EXCEPTION(problem_.is_null(), std::invalid_argument,
364 "FixedPointSolMgr's constructor requires a nonnull LinearProblem instance.");
369 if (! pl.is_null()) {
374 template<
class ScalarType,
class MV,
class OP>
380 if (params_ == Teuchos::null) {
381 params_ = Teuchos::rcp(
new Teuchos::ParameterList(*getValidParameters()) );
384 params->validateParameters(*getValidParameters());
388 if (params->isParameter(
"Maximum Iterations")) {
389 maxIters_ = params->get(
"Maximum Iterations",maxIters_default_);
392 params_->set(
"Maximum Iterations", maxIters_);
393 if (maxIterTest_!=Teuchos::null)
394 maxIterTest_->setMaxIters( maxIters_ );
398 if (params->isParameter(
"Block Size")) {
399 blockSize_ = params->get(
"Block Size",blockSize_default_);
400 TEUCHOS_TEST_FOR_EXCEPTION(blockSize_ <= 0, std::invalid_argument,
401 "Belos::FixedPointSolMgr: \"Block Size\" must be strictly positive.");
404 params_->set(
"Block Size", blockSize_);
408 if (params->isParameter(
"Timer Label")) {
409 std::string tempLabel = params->get(
"Timer Label", label_default_);
412 if (tempLabel != label_) {
414 params_->set(
"Timer Label", label_);
415 std::string solveLabel = label_ +
": FixedPointSolMgr total solve time";
416 #ifdef BELOS_TEUCHOS_TIME_MONITOR
417 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
423 if (params->isParameter(
"Verbosity")) {
424 if (Teuchos::isParameterType<int>(*params,
"Verbosity")) {
425 verbosity_ = params->get(
"Verbosity", verbosity_default_);
427 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,
"Verbosity");
431 params_->set(
"Verbosity", verbosity_);
432 if (printer_ != Teuchos::null)
433 printer_->setVerbosity(verbosity_);
437 if (params->isParameter(
"Output Style")) {
438 if (Teuchos::isParameterType<int>(*params,
"Output Style")) {
439 outputStyle_ = params->get(
"Output Style", outputStyle_default_);
441 outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,
"Output Style");
445 params_->set(
"Output Style", outputStyle_);
446 outputTest_ = Teuchos::null;
450 if (params->isParameter(
"Output Stream")) {
451 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,
"Output Stream");
454 params_->set(
"Output Stream", outputStream_);
455 if (printer_ != Teuchos::null)
456 printer_->setOStream( outputStream_ );
461 if (params->isParameter(
"Output Frequency")) {
462 outputFreq_ = params->get(
"Output Frequency", outputFreq_default_);
466 params_->set(
"Output Frequency", outputFreq_);
467 if (outputTest_ != Teuchos::null)
468 outputTest_->setOutputFrequency( outputFreq_ );
472 if (printer_ == Teuchos::null) {
481 if (params->isParameter(
"Convergence Tolerance")) {
482 if (params->isType<MagnitudeType> (
"Convergence Tolerance")) {
483 convtol_ = params->get (
"Convergence Tolerance",
491 params_->set(
"Convergence Tolerance", convtol_);
492 if (convTest_ != Teuchos::null)
496 if (params->isParameter(
"Show Maximum Residual Norm Only")) {
497 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,
"Show Maximum Residual Norm Only");
500 params_->set(
"Show Maximum Residual Norm Only", showMaxResNormOnly_);
501 if (convTest_ != Teuchos::null)
502 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
508 if (maxIterTest_ == Teuchos::null)
512 if (convTest_ == Teuchos::null)
513 convTest_ = Teuchos::rcp(
new StatusTestResNorm_t( convtol_, 1 ) );
515 if (sTest_ == Teuchos::null)
516 sTest_ = Teuchos::rcp(
new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
518 if (outputTest_ == Teuchos::null) {
526 std::string solverDesc =
" Fixed Point ";
527 outputTest_->setSolverDesc( solverDesc );
532 if (timerSolve_ == Teuchos::null) {
533 std::string solveLabel = label_ +
": FixedPointSolMgr total solve time";
534 #ifdef BELOS_TEUCHOS_TIME_MONITOR
535 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
544 template<
class ScalarType,
class MV,
class OP>
545 Teuchos::RCP<const Teuchos::ParameterList>
548 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
551 if(is_null(validPL)) {
552 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
557 "The relative residual tolerance that needs to be achieved by the\n"
558 "iterative solver in order for the linear system to be declared converged.");
559 pl->set(
"Maximum Iterations", static_cast<int>(maxIters_default_),
560 "The maximum number of block iterations allowed for each\n"
561 "set of RHS solved.");
562 pl->set(
"Block Size", static_cast<int>(blockSize_default_),
563 "The number of vectors in each block.");
564 pl->set(
"Verbosity", static_cast<int>(verbosity_default_),
565 "What type(s) of solver information should be outputted\n"
566 "to the output stream.");
567 pl->set(
"Output Style", static_cast<int>(outputStyle_default_),
568 "What style is used for the solver information outputted\n"
569 "to the output stream.");
570 pl->set(
"Output Frequency", static_cast<int>(outputFreq_default_),
571 "How often convergence information should be outputted\n"
572 "to the output stream.");
573 pl->set(
"Output Stream", Teuchos::rcp(outputStream_default_,
false),
574 "A reference-counted pointer to the output stream where all\n"
575 "solver output is sent.");
576 pl->set(
"Show Maximum Residual Norm Only", static_cast<bool>(showMaxResNormOnly_default_),
577 "When convergence information is printed, only show the maximum\n"
578 "relative residual norm when the block size is greater than one.");
579 pl->set(
"Timer Label", static_cast<const char *>(label_default_),
580 "The string to use as a prefix for the timer labels.");
588 template<
class ScalarType,
class MV,
class OP>
592 using Teuchos::rcp_const_cast;
593 using Teuchos::rcp_dynamic_cast;
600 setParameters(Teuchos::parameterList(*getValidParameters()));
603 Teuchos::BLAS<int,ScalarType> blas;
604 Teuchos::LAPACK<int,ScalarType> lapack;
606 TEUCHOS_TEST_FOR_EXCEPTION( !problem_->isProblemSet(),
608 "Belos::FixedPointSolMgr::solve(): Linear problem is not ready, setProblem() "
609 "has not been called.");
613 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
614 int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
616 std::vector<int> currIdx, currIdx2;
617 currIdx.resize( blockSize_ );
618 currIdx2.resize( blockSize_ );
619 for (
int i=0; i<numCurrRHS; ++i)
620 { currIdx[i] = startPtr+i; currIdx2[i]=i; }
621 for (
int i=numCurrRHS; i<blockSize_; ++i)
622 { currIdx[i] = -1; currIdx2[i] = i; }
625 problem_->setLSIndex( currIdx );
629 Teuchos::ParameterList plist;
630 plist.set(
"Block Size",blockSize_);
633 outputTest_->reset();
637 bool isConverged =
true;
642 RCP<FixedPointIteration<ScalarType,MV,OP> > block_fp_iter;
647 #ifdef BELOS_TEUCHOS_TIME_MONITOR
648 Teuchos::TimeMonitor slvtimer(*timerSolve_);
651 while ( numRHS2Solve > 0 ) {
654 std::vector<int> convRHSIdx;
655 std::vector<int> currRHSIdx( currIdx );
656 currRHSIdx.resize(numCurrRHS);
659 block_fp_iter->resetNumIters();
662 outputTest_->resetNumCalls();
665 RCP<MV> R_0 = MVT::CloneViewNonConst( *(rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
670 block_fp_iter->initializeFixedPoint(newstate);
676 block_fp_iter->iterate();
680 if (convTest_->getStatus() ==
Passed) {
684 std::vector<int> convIdx = convTest_->convIndices();
689 if (convIdx.size() == currRHSIdx.size())
694 problem_->setCurrLS();
699 std::vector<int> unconvIdx(currRHSIdx.size());
700 for (
unsigned int i=0; i<currRHSIdx.size(); ++i) {
702 for (
unsigned int j=0; j<convIdx.size(); ++j) {
703 if (currRHSIdx[i] == convIdx[j]) {
709 currIdx2[have] = currIdx2[i];
710 currRHSIdx[have++] = currRHSIdx[i];
715 currRHSIdx.resize(have);
716 currIdx2.resize(have);
719 problem_->setLSIndex( currRHSIdx );
722 std::vector<MagnitudeType> norms;
723 R_0 = MVT::CloneCopy( *(block_fp_iter->getNativeResiduals(&norms)),currIdx2 );
724 for (
int i=0; i<have; ++i) { currIdx2[i] = i; }
727 block_fp_iter->setBlockSize( have );
732 block_fp_iter->initializeFixedPoint(defstate);
738 else if (maxIterTest_->getStatus() ==
Passed) {
747 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
748 "Belos::FixedPointSolMgr::solve(): Neither the convergence test nor "
749 "the maximum iteration count test passed. Please report this bug "
750 "to the Belos developers.");
753 catch (
const std::exception &e) {
754 std::ostream& err = printer_->stream (
Errors);
755 err <<
"Error! Caught std::exception in FixedPointIteration::iterate() at "
756 <<
"iteration " << block_fp_iter->getNumIters() << std::endl
757 << e.what() << std::endl;
764 problem_->setCurrLS();
767 startPtr += numCurrRHS;
768 numRHS2Solve -= numCurrRHS;
769 if ( numRHS2Solve > 0 ) {
770 numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
773 currIdx.resize( blockSize_ );
774 currIdx2.resize( blockSize_ );
775 for (
int i=0; i<numCurrRHS; ++i)
776 { currIdx[i] = startPtr+i; currIdx2[i] = i; }
777 for (
int i=numCurrRHS; i<blockSize_; ++i)
778 { currIdx[i] = -1; currIdx2[i] = i; }
781 problem_->setLSIndex( currIdx );
784 block_fp_iter->setBlockSize( blockSize_ );
787 currIdx.resize( numRHS2Solve );
798 #ifdef BELOS_TEUCHOS_TIME_MONITOR
804 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
809 numIters_ = maxIterTest_->getNumIters();
814 const std::vector<MagnitudeType>* pTestValues = convTest_->getTestValue();
816 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
817 "Belos::FixedPointSolMgr::solve(): The convergence test's getTestValue() "
818 "method returned NULL. Please report this bug to the Belos developers.");
820 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
821 "Belos::FixedPointSolMgr::solve(): The convergence test's getTestValue() "
822 "method returned a vector of length zero. Please report this bug to the "
823 "Belos developers.");
828 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
838 template<
class ScalarType,
class MV,
class OP>
841 std::ostringstream oss;
842 oss <<
"Belos::FixedPointSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<
">";