Belos Version of the Day
Loading...
Searching...
No Matches
BelosPseudoBlockGmresSolMgr.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Belos: Block Linear Solvers Package
4//
5// Copyright 2004-2016 NTESS and the Belos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
11#define BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
12
17#include "BelosConfigDefs.hpp"
18#include "BelosTypes.hpp"
19
23
29#ifdef BELOS_TEUCHOS_TIME_MONITOR
30#include "Teuchos_TimeMonitor.hpp"
31#endif
32
43namespace Belos {
44
46
47
57
67
91 template<class ScalarType, class MV, class OP, class DM = DefaultDenseMatrix<int,ScalarType>>
92 class PseudoBlockGmresSolMgr : public SolverManager<ScalarType,MV,OP,DM> {
93
94 private:
98 typedef Teuchos::ScalarTraits<ScalarType> SCT;
99 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
100 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
101
102 public:
103
105
106
115
227 const Teuchos::RCP<Teuchos::ParameterList> &pl );
228
231
233 Teuchos::RCP<SolverManager<ScalarType, MV, OP, DM> > clone () const override {
234 return Teuchos::rcp(new PseudoBlockGmresSolMgr<ScalarType,MV,OP,DM>);
235 }
237
239
240
242 return *problem_;
243 }
244
246 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const override;
247
249 Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const override { return params_; }
250
256 Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
257 return Teuchos::tuple(timerSolve_);
258 }
259
270 MagnitudeType achievedTol() const override {
271 return achievedTol_;
272 }
273
275 int getNumIters() const override {
276 return numIters_;
277 }
278
334 bool isLOADetected() const override { return loaDetected_; }
335
338 getResidualStatusTest() const { return impConvTest_.getRawPtr(); }
340
342
343
345 void setProblem (const Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > &problem) override {
346 problem_ = problem;
347 // Force the status tests to be rebuilt on the next solve() (as
348 // BlockGmresSolMgr does). Without this, a solver manager reused across
349 // multiple solves keeps the status-test tree from the first solve, so a
350 // status test installed via setDebugStatusTest() before a later solve is
351 // never wired into sTest_ and never evaluated.
352 isSTSet_ = false;
353 }
354
356 void setParameters (const Teuchos::RCP<Teuchos::ParameterList> &params) override;
357
364 virtual void setUserConvStatusTest(
368 ) override;
369
371 void setDebugStatusTest( const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > &debugStatusTest ) override;
372
374
376
377
381 void reset( const ResetType type ) override { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
383
385
386
404 ReturnType solve() override;
405
407
410
417 void
418 describe (Teuchos::FancyOStream& out,
419 const Teuchos::EVerbosityLevel verbLevel =
420 Teuchos::Describable::verbLevel_default) const override;
421
423 std::string description () const override;
424
426
427 private:
428
443 bool checkStatusTest();
444
446 Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > problem_;
447
448 // Output manager.
449 Teuchos::RCP<OutputManager<ScalarType> > printer_;
450 Teuchos::RCP<std::ostream> outputStream_;
451
452 // Status tests.
453 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > userConvStatusTest_;
454 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > debugStatusTest_;
455 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > sTest_;
456 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP,DM> > maxIterTest_;
457 Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > convTest_;
458 Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP,DM> > impConvTest_, expConvTest_;
459 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP,DM> > outputTest_;
461 Teuchos::RCP<std::map<std::string, Teuchos::RCP<StatusTest<ScalarType, MV, OP, DM> > > > taggedTests_;
462
463 // Orthogonalization manager.
464 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > ortho_;
465
466 // Current parameter list.
467 Teuchos::RCP<Teuchos::ParameterList> params_;
468
469 // Default solver values.
470 static constexpr int maxRestarts_default_ = 20;
471 static constexpr int maxIters_default_ = 1000;
472 static constexpr bool showMaxResNormOnly_default_ = false;
473 static constexpr int blockSize_default_ = 1;
474 static constexpr int numBlocks_default_ = 300;
475 static constexpr int verbosity_default_ = Belos::Errors;
476 static constexpr int outputStyle_default_ = Belos::General;
477 static constexpr int outputFreq_default_ = -1;
478 static constexpr int defQuorum_default_ = 1;
479 static constexpr const char * impResScale_default_ = "Norm of Preconditioned Initial Residual";
480 static constexpr const char * expResScale_default_ = "Norm of Initial Residual";
481 static constexpr const char * label_default_ = "Belos";
482 static constexpr const char * orthoType_default_ = "ICGS";
483
484 // Current solver values.
485 MagnitudeType convtol_, orthoKappa_, achievedTol_;
486 int maxRestarts_, maxIters_, numIters_;
487 int blockSize_, numBlocks_, verbosity_, outputStyle_, outputFreq_, defQuorum_;
488 bool showMaxResNormOnly_;
489 std::string orthoType_;
490 std::string impResScale_, expResScale_;
491 MagnitudeType resScaleFactor_;
492
493 // Timers.
494 std::string label_;
495 Teuchos::RCP<Teuchos::Time> timerSolve_;
496
497 // Internal state variables.
498 bool isSet_, isSTSet_, expResTest_;
499 bool loaDetected_;
500 };
501
502
503// Empty Constructor
504template<class ScalarType, class MV, class OP, class DM>
506 outputStream_(Teuchos::rcpFromRef(std::cout)),
507 taggedTests_(Teuchos::null),
508 convtol_(DefaultSolverParameters::convTol),
509 orthoKappa_(DefaultSolverParameters::orthoKappa),
510 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
511 maxRestarts_(maxRestarts_default_),
512 maxIters_(maxIters_default_),
513 numIters_(0),
514 blockSize_(blockSize_default_),
515 numBlocks_(numBlocks_default_),
516 verbosity_(verbosity_default_),
517 outputStyle_(outputStyle_default_),
518 outputFreq_(outputFreq_default_),
519 defQuorum_(defQuorum_default_),
520 showMaxResNormOnly_(showMaxResNormOnly_default_),
521 orthoType_(orthoType_default_),
522 impResScale_(impResScale_default_),
523 expResScale_(expResScale_default_),
524 resScaleFactor_(DefaultSolverParameters::resScaleFactor),
525 label_(label_default_),
526 isSet_(false),
527 isSTSet_(false),
528 expResTest_(false),
529 loaDetected_(false)
530{}
531
532// Basic Constructor
533template<class ScalarType, class MV, class OP, class DM>
536 const Teuchos::RCP<Teuchos::ParameterList> &pl) :
537 problem_(problem),
538 outputStream_(Teuchos::rcpFromRef(std::cout)),
539 taggedTests_(Teuchos::null),
540 convtol_(DefaultSolverParameters::convTol),
541 orthoKappa_(DefaultSolverParameters::orthoKappa),
542 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
543 maxRestarts_(maxRestarts_default_),
544 maxIters_(maxIters_default_),
545 numIters_(0),
546 blockSize_(blockSize_default_),
547 numBlocks_(numBlocks_default_),
548 verbosity_(verbosity_default_),
549 outputStyle_(outputStyle_default_),
550 outputFreq_(outputFreq_default_),
551 defQuorum_(defQuorum_default_),
552 showMaxResNormOnly_(showMaxResNormOnly_default_),
553 orthoType_(orthoType_default_),
554 impResScale_(impResScale_default_),
555 expResScale_(expResScale_default_),
556 resScaleFactor_(DefaultSolverParameters::resScaleFactor),
557 label_(label_default_),
558 isSet_(false),
559 isSTSet_(false),
560 expResTest_(false),
561 loaDetected_(false)
562{
563 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
564
565 // If the parameter list pointer is null, then set the current parameters to the default parameter list.
566 if (!is_null(pl)) {
567 // Set the parameters using the list that was passed in.
568 setParameters( pl );
569 }
570}
571
572template<class ScalarType, class MV, class OP, class DM>
573void
575setParameters (const Teuchos::RCP<Teuchos::ParameterList>& params)
576{
577 using Teuchos::ParameterList;
578 using Teuchos::parameterList;
579 using Teuchos::rcp;
580 using Teuchos::rcp_dynamic_cast;
581
582 // Create the internal parameter list if one doesn't already exist.
583 if (params_ == Teuchos::null) {
584 params_ = parameterList (*getValidParameters ());
585 } else {
586 // TAW: 3/8/2016: do not validate sub parameter lists as they
587 // might not have a pre-defined structure
588 // e.g. user-specified status tests
589 // The Belos Pseudo Block GMRES parameters on the first level are
590 // not affected and verified.
591 params->validateParameters (*getValidParameters (), 0);
592 }
593
594 // Check for maximum number of restarts
595 if (params->isParameter ("Maximum Restarts")) {
596 maxRestarts_ = params->get ("Maximum Restarts", maxRestarts_default_);
597
598 // Update parameter in our list.
599 params_->set ("Maximum Restarts", maxRestarts_);
600 }
601
602 // Check for maximum number of iterations
603 if (params->isParameter ("Maximum Iterations")) {
604 maxIters_ = params->get ("Maximum Iterations", maxIters_default_);
605
606 // Update parameter in our list and in status test.
607 params_->set ("Maximum Iterations", maxIters_);
608 if (! maxIterTest_.is_null ()) {
609 maxIterTest_->setMaxIters (maxIters_);
610 }
611 }
612
613 // Check for blocksize
614 if (params->isParameter ("Block Size")) {
615 blockSize_ = params->get ("Block Size", blockSize_default_);
617 blockSize_ <= 0, std::invalid_argument,
618 "Belos::PseudoBlockGmresSolMgr::setParameters: "
619 "The \"Block Size\" parameter must be strictly positive, "
620 "but you specified a value of " << blockSize_ << ".");
621
622 // Update parameter in our list.
623 params_->set ("Block Size", blockSize_);
624 }
625
626 // Check for the maximum number of blocks.
627 if (params->isParameter ("Num Blocks")) {
628 numBlocks_ = params->get ("Num Blocks", numBlocks_default_);
630 numBlocks_ <= 0, std::invalid_argument,
631 "Belos::PseudoBlockGmresSolMgr::setParameters: "
632 "The \"Num Blocks\" parameter must be strictly positive, "
633 "but you specified a value of " << numBlocks_ << ".");
634
635 // Update parameter in our list.
636 params_->set ("Num Blocks", numBlocks_);
637 }
638
639 // Check to see if the timer label changed.
640 if (params->isParameter ("Timer Label")) {
641 const std::string tempLabel = params->get ("Timer Label", label_default_);
642
643 // Update parameter in our list and solver timer
644 if (tempLabel != label_) {
645 label_ = tempLabel;
646 params_->set ("Timer Label", label_);
647 const std::string solveLabel =
648 label_ + ": PseudoBlockGmresSolMgr total solve time";
649#ifdef BELOS_TEUCHOS_TIME_MONITOR
650 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
651#endif // BELOS_TEUCHOS_TIME_MONITOR
652 if (ortho_ != Teuchos::null) {
653 ortho_->setLabel( label_ );
654 }
655 }
656 }
657
658
659 // Check for a change in verbosity level
660 if (params->isParameter ("Verbosity")) {
661 if (Teuchos::isParameterType<int> (*params, "Verbosity")) {
662 verbosity_ = params->get ("Verbosity", verbosity_default_);
663 } else {
664 verbosity_ = (int) Teuchos::getParameter<Belos::MsgType> (*params, "Verbosity");
665 }
666
667 // Update parameter in our list.
668 params_->set ("Verbosity", verbosity_);
669 if (! printer_.is_null ()) {
670 printer_->setVerbosity (verbosity_);
671 }
672 }
673
674 // Check for a change in output style.
675 if (params->isParameter ("Output Style")) {
676 if (Teuchos::isParameterType<int> (*params, "Output Style")) {
677 outputStyle_ = params->get ("Output Style", outputStyle_default_);
678 } else {
679 outputStyle_ = (int) Teuchos::getParameter<Belos::OutputType> (*params, "Output Style");
680 }
681
682 // Update parameter in our list.
683 params_->set ("Output Style", outputStyle_);
684 if (! outputTest_.is_null ()) {
685 isSTSet_ = false;
686 }
687
688 }
689
690 // Check if user has specified his own status tests
691 if (params->isSublist ("User Status Tests")) {
692 Teuchos::ParameterList userStatusTestsList = params->sublist("User Status Tests",true);
693 if ( userStatusTestsList.numParams() > 0 ) {
694 std::string userCombo_string = params->get<std::string>("User Status Tests Combo Type", "SEQ");
695 Teuchos::RCP<StatusTestFactory<ScalarType,MV,OP,DM> > testFactory = Teuchos::rcp(new StatusTestFactory<ScalarType,MV,OP,DM>());
696 setUserConvStatusTest( testFactory->buildStatusTests(userStatusTestsList), testFactory->stringToComboType(userCombo_string) );
697 taggedTests_ = testFactory->getTaggedTests();
698 isSTSet_ = false;
699 }
700 }
701
702 // output stream
703 if (params->isParameter ("Output Stream")) {
704 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> > (*params, "Output Stream");
705
706 // Update parameter in our list.
707 params_->set("Output Stream", outputStream_);
708 if (! printer_.is_null ()) {
709 printer_->setOStream (outputStream_);
710 }
711 }
712
713 // frequency level
714 if (verbosity_ & Belos::StatusTestDetails) {
715 if (params->isParameter ("Output Frequency")) {
716 outputFreq_ = params->get ("Output Frequency", outputFreq_default_);
717 }
718
719 // Update parameter in out list and output status test.
720 params_->set ("Output Frequency", outputFreq_);
721 if (! outputTest_.is_null ()) {
722 outputTest_->setOutputFrequency (outputFreq_);
723 }
724 }
725
726 // Create output manager if we need to.
727 if (printer_.is_null ()) {
728 printer_ = rcp (new OutputManager<ScalarType> (verbosity_, outputStream_));
729 }
730
731 // Check if the orthogonalization changed.
732 bool changedOrthoType = false;
733 if (params->isParameter ("Orthogonalization")) {
734 std::string tempOrthoType = params->get ("Orthogonalization", orthoType_default_);
735 if (tempOrthoType != orthoType_) {
736 orthoType_ = tempOrthoType;
737 changedOrthoType = true;
738 }
739 }
740 params_->set("Orthogonalization", orthoType_);
741
742 // Check which orthogonalization constant to use.
743 if (params->isParameter ("Orthogonalization Constant")) {
744 if (params->isType<MagnitudeType> ("Orthogonalization Constant")) {
745 orthoKappa_ = params->get ("Orthogonalization Constant",
746 static_cast<MagnitudeType> (DefaultSolverParameters::orthoKappa));
747 }
748 else {
749 orthoKappa_ = params->get ("Orthogonalization Constant",
751 }
752
753 // Update parameter in our list.
754 params_->set ("Orthogonalization Constant", orthoKappa_);
755 if (orthoType_ == "DGKS") {
756 if (orthoKappa_ > 0 && ! ortho_.is_null() && !changedOrthoType) {
758 rcp_dynamic_cast<ortho_type> (ortho_)->setDepTol (orthoKappa_);
759 }
760 }
761 }
762
763 // Create orthogonalization manager if we need to.
764 if (ortho_.is_null() || changedOrthoType) {
766 Teuchos::RCP<Teuchos::ParameterList> paramsOrtho; // can be null
767 if (orthoType_=="DGKS" && orthoKappa_ > 0) {
768 paramsOrtho = Teuchos::rcp(new Teuchos::ParameterList());
769 paramsOrtho->set ("depTol", orthoKappa_ );
770 }
771
772 ortho_ = factory.makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_, paramsOrtho);
773 }
774
775 // Convergence
776
777 // Check for convergence tolerance
778 if (params->isParameter ("Convergence Tolerance")) {
779 if (params->isType<MagnitudeType> ("Convergence Tolerance")) {
780 convtol_ = params->get ("Convergence Tolerance",
781 static_cast<MagnitudeType> (DefaultSolverParameters::convTol));
782 }
783 else {
784 convtol_ = params->get ("Convergence Tolerance", DefaultSolverParameters::convTol);
785 }
786
787 // Update parameter in our list and residual tests.
788 params_->set ("Convergence Tolerance", convtol_);
789 if (! impConvTest_.is_null ()) {
790 impConvTest_->setTolerance (convtol_);
791 }
792 if (! expConvTest_.is_null ()) {
793 expConvTest_->setTolerance (convtol_);
794 }
795 }
796
797 // Grab the user defined residual scaling
799 if (params->isParameter ("User Defined Residual Scaling")) {
801 if (params->isType<MagnitudeType> ("User Defined Residual Scaling")) {
802 tempResScaleFactor = params->get ("User Defined Residual Scaling",
803 static_cast<MagnitudeType> (DefaultSolverParameters::resScaleFactor));
804 }
805 else {
806 tempResScaleFactor = params->get ("User Defined Residual Scaling",
808 }
809
810 // Only update the scaling if it's different.
811 if (resScaleFactor_ != tempResScaleFactor) {
812 resScaleFactor_ = tempResScaleFactor;
814 }
815
817 {
818 if (! params->isParameter ("Implicit Residual Scaling") && ! impConvTest_.is_null ()) {
819 try {
820 if(impResScale_ == "User Provided")
821 impConvTest_->defineScaleForm (Belos::UserProvided, Belos::TwoNorm, resScaleFactor_);
822 }
823 catch (std::exception& e) {
824 // Make sure the convergence test gets constructed again.
825 isSTSet_ = false;
826 }
827 }
828 if (! params->isParameter ("Explicit Residual Scaling") && ! expConvTest_.is_null ()) {
829 try {
830 if(expResScale_ == "User Provided")
831 expConvTest_->defineScaleForm (Belos::UserProvided, Belos::TwoNorm, resScaleFactor_);
832 }
833 catch (std::exception& e) {
834 // Make sure the convergence test gets constructed again.
835 isSTSet_ = false;
836 }
837 }
838 }
839 }
840
841 // Check for a change in scaling, if so we need to build new residual tests.
842 if (params->isParameter ("Implicit Residual Scaling")) {
843 const std::string tempImpResScale =
844 Teuchos::getParameter<std::string> (*params, "Implicit Residual Scaling");
845
846 // Only update the scaling if it's different.
847 if (impResScale_ != tempImpResScale) {
849 impResScale_ = tempImpResScale;
850
851 // Update parameter in our list and residual tests
852 params_->set ("Implicit Residual Scaling", impResScale_);
853 if (! impConvTest_.is_null ()) {
854 try {
855 if(impResScale_ == "User Provided")
856 impConvTest_->defineScaleForm (impResScaleType, Belos::TwoNorm, resScaleFactor_);
857 else
858 impConvTest_->defineScaleForm (impResScaleType, Belos::TwoNorm);
859 }
860 catch (std::exception& e) {
861 // Make sure the convergence test gets constructed again.
862 isSTSet_ = false;
863 }
864 }
865 }
868
869 if (! impConvTest_.is_null ()) {
870 try {
871 if(impResScale_ == "User Provided")
872 impConvTest_->defineScaleForm (impResScaleType, Belos::TwoNorm, resScaleFactor_);
873 }
874 catch (std::exception& e) {
875 // Make sure the convergence test gets constructed again.
876 isSTSet_ = false;
877 }
878 }
879 }
880 }
881
882 if (params->isParameter ("Explicit Residual Scaling")) {
883 const std::string tempExpResScale =
884 Teuchos::getParameter<std::string> (*params, "Explicit Residual Scaling");
885
886 // Only update the scaling if it's different.
887 if (expResScale_ != tempExpResScale) {
889 expResScale_ = tempExpResScale;
890
891 // Update parameter in our list and residual tests
892 params_->set ("Explicit Residual Scaling", expResScale_);
893 if (! expConvTest_.is_null ()) {
894 try {
895 if(expResScale_ == "User Provided")
896 expConvTest_->defineScaleForm (expResScaleType, Belos::TwoNorm, resScaleFactor_);
897 else
898 expConvTest_->defineScaleForm (expResScaleType, Belos::TwoNorm);
899 }
900 catch (std::exception& e) {
901 // Make sure the convergence test gets constructed again.
902 isSTSet_ = false;
903 }
904 }
905 }
908
909 if (! expConvTest_.is_null ()) {
910 try {
911 if(expResScale_ == "User Provided")
912 expConvTest_->defineScaleForm (expResScaleType, Belos::TwoNorm, resScaleFactor_);
913 }
914 catch (std::exception& e) {
915 // Make sure the convergence test gets constructed again.
916 isSTSet_ = false;
917 }
918 }
919 }
920 }
921
922
923 if (params->isParameter ("Show Maximum Residual Norm Only")) {
924 showMaxResNormOnly_ =
925 Teuchos::getParameter<bool> (*params, "Show Maximum Residual Norm Only");
926
927 // Update parameter in our list and residual tests
928 params_->set ("Show Maximum Residual Norm Only", showMaxResNormOnly_);
929 if (! impConvTest_.is_null ()) {
930 impConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
931 }
932 if (! expConvTest_.is_null ()) {
933 expConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
934 }
935 }
936
937 // Create status tests if we need to.
938
939 // Get the deflation quorum, or number of converged systems before deflation is allowed
940 if (params->isParameter("Deflation Quorum")) {
941 defQuorum_ = params->get("Deflation Quorum", defQuorum_);
943 defQuorum_ > blockSize_, std::invalid_argument,
944 "Belos::PseudoBlockGmresSolMgr::setParameters: "
945 "The \"Deflation Quorum\" parameter (= " << defQuorum_ << ") must not be "
946 "larger than \"Block Size\" (= " << blockSize_ << ").");
947 params_->set ("Deflation Quorum", defQuorum_);
948 if (! impConvTest_.is_null ()) {
949 impConvTest_->setQuorum (defQuorum_);
950 }
951 if (! expConvTest_.is_null ()) {
952 expConvTest_->setQuorum (defQuorum_);
953 }
954 }
955
956 // Create the timer if we need to.
957 if (timerSolve_ == Teuchos::null) {
958 std::string solveLabel = label_ + ": PseudoBlockGmresSolMgr total solve time";
959#ifdef BELOS_TEUCHOS_TIME_MONITOR
960 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
961#endif
962 }
963
964 // Inform the solver manager that the current parameters were set.
965 isSet_ = true;
966}
967
968
969template<class ScalarType, class MV, class OP, class DM>
978
979template<class ScalarType, class MV, class OP, class DM>
986
987
988
989template<class ScalarType, class MV, class OP, class DM>
990Teuchos::RCP<const Teuchos::ParameterList>
992{
993 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
994 if (is_null(validPL)) {
995 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
996 // Set all the valid parameters and their default values.
997
998 // The static_cast is to resolve an issue with older clang versions which
999 // would cause the constexpr to link fail. With c++17 the problem is resolved.
1000 pl= Teuchos::rcp( new Teuchos::ParameterList() );
1001 pl->set("Convergence Tolerance", static_cast<MagnitudeType>(DefaultSolverParameters::convTol),
1002 "The relative residual tolerance that needs to be achieved by the\n"
1003 "iterative solver in order for the linear system to be declared converged.");
1004 pl->set("Maximum Restarts", static_cast<int>(maxRestarts_default_),
1005 "The maximum number of restarts allowed for each\n"
1006 "set of RHS solved.");
1007 pl->set("Maximum Iterations", static_cast<int>(maxIters_default_),
1008 "The maximum number of block iterations allowed for each\n"
1009 "set of RHS solved.");
1010 pl->set("Num Blocks", static_cast<int>(numBlocks_default_),
1011 "The maximum number of vectors allowed in the Krylov subspace\n"
1012 "for each set of RHS solved.");
1013 pl->set("Block Size", static_cast<int>(blockSize_default_),
1014 "The number of RHS solved simultaneously.");
1015 pl->set("Verbosity", static_cast<int>(verbosity_default_),
1016 "What type(s) of solver information should be outputted\n"
1017 "to the output stream.");
1018 pl->set("Output Style", static_cast<int>(outputStyle_default_),
1019 "What style is used for the solver information outputted\n"
1020 "to the output stream.");
1021 pl->set("Output Frequency", static_cast<int>(outputFreq_default_),
1022 "How often convergence information should be outputted\n"
1023 "to the output stream.");
1024 pl->set("Deflation Quorum", static_cast<int>(defQuorum_default_),
1025 "The number of linear systems that need to converge before\n"
1026 "they are deflated. This number should be <= block size.");
1027 pl->set("Output Stream", Teuchos::rcpFromRef(std::cout),
1028 "A reference-counted pointer to the output stream where all\n"
1029 "solver output is sent.");
1030 pl->set("Show Maximum Residual Norm Only", static_cast<bool>(showMaxResNormOnly_default_),
1031 "When convergence information is printed, only show the maximum\n"
1032 "relative residual norm when the block size is greater than one.");
1033 pl->set("Implicit Residual Scaling", static_cast<const char *>(impResScale_default_),
1034 "The type of scaling used in the implicit residual convergence test.");
1035 pl->set("Explicit Residual Scaling", static_cast<const char *>(expResScale_default_),
1036 "The type of scaling used in the explicit residual convergence test.");
1037 pl->set("Timer Label", static_cast<const char *>(label_default_),
1038 "The string to use as a prefix for the timer labels.");
1039 pl->set("Orthogonalization", static_cast<const char *>(orthoType_default_),
1040 "The type of orthogonalization to use.");
1041 pl->set("Orthogonalization Constant",static_cast<MagnitudeType>(DefaultSolverParameters::orthoKappa),
1042 "The constant used by DGKS orthogonalization to determine\n"
1043 "whether another step of classical Gram-Schmidt is necessary.");
1044 pl->sublist("User Status Tests");
1045 pl->set("User Status Tests Combo Type", "SEQ",
1046 "Type of logical combination operation of user-defined\n"
1047 "and/or solver-specific status tests.");
1048 validPL = pl;
1049 }
1050 return validPL;
1051}
1052
1053// Check the status test versus the defined linear problem
1054template<class ScalarType, class MV, class OP, class DM>
1056
1057 typedef Belos::StatusTestCombo<ScalarType,MV,OP,DM> StatusTestCombo_t;
1060
1061 // Basic test checks maximum iterations and native residual.
1062 maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP,DM>( maxIters_ ) );
1063
1064 // If there is a left preconditioner, we create a combined status test that checks the implicit
1065 // and then explicit residual norm to see if we have convergence.
1066 if ( !Teuchos::is_null(problem_->getLeftPrec()) ) {
1067 expResTest_ = true;
1068 }
1069
1070 if (expResTest_) {
1071
1072 // Implicit residual test, using the native residual to determine if convergence was achieved.
1073 Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
1074 Teuchos::rcp( new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1075 if(impResScale_ == "User Provided")
1076 tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm, resScaleFactor_ );
1077 else
1078 tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm );
1079
1080 tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1081 impConvTest_ = tmpImpConvTest;
1082
1083 // Explicit residual test once the native residual is below the tolerance
1084 Teuchos::RCP<StatusTestGenResNorm_t> tmpExpConvTest =
1085 Teuchos::rcp( new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1086 tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit, Belos::TwoNorm );
1087 if(expResScale_ == "User Provided")
1088 tmpExpConvTest->defineScaleForm( convertStringToScaleType(expResScale_), Belos::TwoNorm, resScaleFactor_ );
1089 else
1090 tmpExpConvTest->defineScaleForm( convertStringToScaleType(expResScale_), Belos::TwoNorm );
1091 tmpExpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1092 expConvTest_ = tmpExpConvTest;
1093
1094 // The convergence test is a combination of the "cheap" implicit test and explicit test.
1095 convTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) );
1096 }
1097 else {
1098
1099 // Implicit residual test, using the native residual to determine if convergence was achieved.
1100 // Use test that checks for loss of accuracy.
1101 Teuchos::RCP<StatusTestImpResNorm_t> tmpImpConvTest =
1102 Teuchos::rcp( new StatusTestImpResNorm_t( convtol_, defQuorum_ ) );
1103 if(impResScale_ == "User Provided")
1104 tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm, resScaleFactor_ );
1105 else
1106 tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm );
1107 tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1108 impConvTest_ = tmpImpConvTest;
1109
1110 // Set the explicit and total convergence test to this implicit test that checks for accuracy loss.
1111 expConvTest_ = impConvTest_;
1112 convTest_ = impConvTest_;
1113 }
1114
1115 if (Teuchos::nonnull(userConvStatusTest_) ) {
1116 // Check if this is a combination of several StatusTestResNorm objects
1117 Teuchos::RCP<StatusTestCombo_t> tmpComboTest = Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(userConvStatusTest_);
1118 if (tmpComboTest != Teuchos::null) {
1119 std::vector<Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > > tmpVec = tmpComboTest->getStatusTests();
1120 comboType_ = tmpComboTest->getComboType();
1121 const int numResTests = static_cast<int>(tmpVec.size());
1122 auto newConvTest = Teuchos::rcp(new StatusTestCombo_t(comboType_));
1123 newConvTest->addStatusTest(convTest_);
1124 for (int j = 0; j < numResTests; ++j) {
1125 newConvTest->addStatusTest(tmpVec[j]);
1126 }
1127 convTest_ = newConvTest;
1128 }
1129 else{
1130 // Override the overall convergence test with the users convergence test
1131 convTest_ = Teuchos::rcp(
1132 new StatusTestCombo_t( comboType_, convTest_, userConvStatusTest_ ) );
1133 // brief output style not compatible with more general combinations
1134 //outputStyle_ = Belos::General;
1135 // NOTE: Above, you have to run the other convergence tests also because
1136 // the logic in this class depends on it. This is very unfortunate.
1137 }
1138 }
1139
1140 sTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
1141
1142 // Add debug status test, if one is provided by the user
1143 if (Teuchos::nonnull(debugStatusTest_) ) {
1144 // Add debug convergence test
1145 Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(sTest_)->addStatusTest( debugStatusTest_ );
1146 }
1147
1148 // Create the status test output class.
1149 // This class manages and formats the output from the status test.
1150 StatusTestOutputFactory<ScalarType,MV,OP,DM> stoFactory( outputStyle_, taggedTests_ );
1151 outputTest_ = stoFactory.create( printer_, sTest_, outputFreq_, Passed+Failed+Undefined );
1152
1153 // Set the solver string for the output test
1154 std::string solverDesc = " Pseudo Block Gmres ";
1155 outputTest_->setSolverDesc( solverDesc );
1156
1157
1158 // The status test is now set.
1159 isSTSet_ = true;
1160
1161 return false;
1162}
1163
1164
1165// solve()
1166template<class ScalarType, class MV, class OP, class DM>
1169 // Set the current parameters if they were not set before.
1170 // NOTE: This may occur if the user generated the solver manager with the default constructor and
1171 // then didn't set any parameters using setParameters().
1172 if (!isSet_) { setParameters( params_ ); }
1173
1175 "Belos::PseudoBlockGmresSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1176
1177 // Check if we have to create the status tests.
1178 if (!isSTSet_ || (!expResTest_ && !Teuchos::is_null(problem_->getLeftPrec())) ) {
1180 "Belos::BlockGmresSolMgr::solve(): Linear problem and requested status tests are incompatible.");
1181 }
1182
1183 // Create indices for the linear systems to be solved.
1184 int startPtr = 0;
1185 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1186 int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1187
1188 std::vector<int> currIdx( numCurrRHS );
1189 blockSize_ = numCurrRHS;
1190 for (int i=0; i<numCurrRHS; ++i)
1191 { currIdx[i] = startPtr+i; }
1192
1193 // Inform the linear problem of the current linear system to solve.
1194 problem_->setLSIndex( currIdx );
1195
1197 // Parameter list
1198 Teuchos::ParameterList plist;
1199 plist.set("Num Blocks",numBlocks_);
1200
1201 // Reset the status test.
1202 outputTest_->reset();
1203 loaDetected_ = false;
1204
1205 // Assume convergence is achieved, then let any failed convergence set this to false.
1206 bool isConverged = true;
1207
1209 // BlockGmres solver
1210
1211 Teuchos::RCP<PseudoBlockGmresIter<ScalarType,MV,OP,DM> > block_gmres_iter
1212 = Teuchos::rcp( new PseudoBlockGmresIter<ScalarType,MV,OP,DM>(problem_,printer_,outputTest_,ortho_,plist) );
1213
1214 // Enter solve() iterations
1215 {
1216#ifdef BELOS_TEUCHOS_TIME_MONITOR
1217 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1218#endif
1219
1220 while ( numRHS2Solve > 0 ) {
1221
1222 // Reset the active / converged vectors from this block
1223 std::vector<int> convRHSIdx;
1224 std::vector<int> currRHSIdx( currIdx );
1225 currRHSIdx.resize(numCurrRHS);
1226
1227 // Set the current number of blocks with the pseudo Gmres iteration.
1228 block_gmres_iter->setNumBlocks( numBlocks_ );
1229
1230 // Reset the number of iterations.
1231 block_gmres_iter->resetNumIters();
1232
1233 // Reset the number of calls that the status test output knows about.
1234 outputTest_->resetNumCalls();
1235
1236 // Get a new state struct and initialize the solver.
1238
1239 // Create the first block in the current Krylov basis for each right-hand side.
1240 std::vector<int> index(1);
1241 Teuchos::RCP<MV> tmpV, R_0 = MVT::CloneCopy( *(problem_->getInitPrecResVec()), currIdx );
1242 newState.V.resize( blockSize_ );
1243 newState.Z.resize( blockSize_ );
1244 for (int i=0; i<blockSize_; ++i) {
1245 index[0]=i;
1246 tmpV = MVT::CloneViewNonConst( *R_0, index );
1247
1248 // Get a matrix to hold the orthonormalization coefficients.
1249 Teuchos::RCP<DM> tmpZ = DMT::Create( 1, 1 );
1250
1251 // Orthonormalize the new V_0
1252 int rank = ortho_->normalize( *tmpV, tmpZ );
1254 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors.");
1255
1256 newState.V[i] = tmpV;
1257 newState.Z[i] = tmpZ;
1258 }
1259
1260 newState.curDim = 0;
1261 block_gmres_iter->initialize(newState);
1262 int numRestarts = 0;
1263
1264 while(1) {
1265
1266 // tell block_gmres_iter to iterate
1267 try {
1268 block_gmres_iter->iterate();
1269
1271 //
1272 // check convergence first
1273 //
1275 if ( convTest_->getStatus() == Passed ) {
1276
1277 if ( expConvTest_->getLOADetected() ) {
1278 // Oops! There was a loss of accuracy (LOA) for one or
1279 // more right-hand sides. That means the implicit
1280 // (a.k.a. "native") residuals claim convergence,
1281 // whereas the explicit (hence expConvTest_, i.e.,
1282 // "explicit convergence test") residuals have not
1283 // converged.
1284 //
1285 // We choose to deal with this situation by deflating
1286 // out the affected right-hand sides and moving on.
1288 loaDetected_ = true;
1289 printer_->stream(Warnings) <<
1290 "Belos::PseudoBlockGmresSolMgr::solve(): Warning! Solver has experienced a loss of accuracy!" << std::endl;
1291 isConverged = false;
1292 }
1293
1294 // Figure out which linear systems converged.
1295 std::vector<int> convIdx = expConvTest_->convIndices();
1296
1297 // If the number of converged linear systems is equal to the
1298 // number of current linear systems, then we are done with this block.
1299 if (convIdx.size() == currRHSIdx.size())
1300 break; // break from while(1){block_gmres_iter->iterate()}
1301
1302 // Get a new state struct and initialize the solver.
1304
1305 // Inform the linear problem that we are finished with this current linear system.
1306 problem_->setCurrLS();
1307
1308 // Get the state.
1310 int curDim = oldState.curDim;
1311
1312 // Get a new state struct and reset currRHSIdx to have the right-hand sides that
1313 // are left to converge for this block.
1314 int have = 0;
1315 std::vector<int> oldRHSIdx( currRHSIdx );
1316 std::vector<int> defRHSIdx;
1317 for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
1318 bool found = false;
1319 for (unsigned int j=0; j<convIdx.size(); ++j) {
1320 if (currRHSIdx[i] == convIdx[j]) {
1321 found = true;
1322 break;
1323 }
1324 }
1325 if (found) {
1326 defRHSIdx.push_back( i );
1327 }
1328 else {
1329 defState.V.push_back( Teuchos::rcp_const_cast<MV>( oldState.V[i] ) );
1330 defState.Z.push_back( Teuchos::rcp_const_cast<DM>( oldState.Z[i] ) );
1331 defState.H.push_back( Teuchos::rcp_const_cast<DM>( oldState.H[i] ) );
1332 defState.sn.push_back( Teuchos::rcp_const_cast<std::vector<ScalarType> >( oldState.sn[i] ) );
1333 defState.cs.push_back( Teuchos::rcp_const_cast<std::vector<MagnitudeType> >(oldState.cs[i] ) );
1335 have++;
1336 }
1337 }
1338 defRHSIdx.resize(currRHSIdx.size()-have);
1339 currRHSIdx.resize(have);
1340
1341 // Compute the current solution that needs to be deflated if this solver has taken any steps.
1342 if (curDim) {
1343 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1344 Teuchos::RCP<MV> defUpdate = MVT::CloneViewNonConst( *update, defRHSIdx );
1345
1346 // Set the deflated indices so we can update the solution.
1347 problem_->setLSIndex( convIdx );
1348
1349 // Update the linear problem.
1350 problem_->updateSolution( defUpdate, true );
1351 }
1352
1353 // Set the remaining indices after deflation.
1354 problem_->setLSIndex( currRHSIdx );
1355
1356 // Set the dimension of the subspace, which is the same as the old subspace size.
1357 defState.curDim = curDim;
1358
1359 // Initialize the solver with the deflated system.
1360 block_gmres_iter->initialize(defState);
1361 }
1363 //
1364 // check for maximum iterations
1365 //
1367 else if ( maxIterTest_->getStatus() == Passed ) {
1368 // we don't have convergence
1370 isConverged = false;
1371 break; // break from while(1){block_gmres_iter->iterate()}
1372 }
1374 //
1375 // check for restarting, i.e. the subspace is full
1376 //
1378 else if ( block_gmres_iter->getCurSubspaceDim() == block_gmres_iter->getMaxSubspaceDim() ) {
1379
1380 if ( numRestarts >= maxRestarts_ ) {
1382 isConverged = false;
1383 break; // break from while(1){block_gmres_iter->iterate()}
1384 }
1385 numRestarts++;
1386
1387 printer_->stream(Debug) << " Performing restart number " << numRestarts << " of " << maxRestarts_ << std::endl << std::endl;
1388
1389 // Update the linear problem.
1390 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1391 problem_->updateSolution( update, true );
1392
1393 // Get the state.
1395
1396 // Set the new state.
1398 newstate.V.resize(currRHSIdx.size());
1399 newstate.Z.resize(currRHSIdx.size());
1400
1401 // Compute the restart vectors
1402 // NOTE: Force the linear problem to update the current residual since the solution was updated.
1403 R_0 = MVT::Clone( *(problem_->getInitPrecResVec()), currRHSIdx.size() );
1404 problem_->computeCurrPrecResVec( &*R_0 );
1405 for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
1406 index[0] = i; // index(1) vector declared on line 891
1407
1408 tmpV = MVT::CloneViewNonConst( *R_0, index );
1409
1410 // Get a matrix to hold the orthonormalization coefficients.
1411 Teuchos::RCP<DM> tmpZ = DMT::Create( 1, 1 );
1412
1413 // Orthonormalize the new V_0
1414 int rank = ortho_->normalize( *tmpV, tmpZ );
1416 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors after the restart.");
1417
1418 newstate.V[i] = tmpV;
1419 newstate.Z[i] = tmpZ;
1420 }
1421
1422 // Initialize the solver.
1423 newstate.curDim = 0;
1424 block_gmres_iter->initialize(newstate);
1425
1426 } // end of restarting
1427
1429 //
1430 // check for a debug status test requesting termination
1431 //
1432 // A status test installed via setDebugStatusTest() is OR-combined
1433 // into sTest_, so it can legitimately stop iterate() (e.g. a
1434 // wall-clock time limit). Treat that as an unconverged termination
1435 // rather than an inconsistent internal state.
1436 //
1438 else if (Teuchos::nonnull(debugStatusTest_) &&
1439 debugStatusTest_->getStatus() == Passed) {
1441 isConverged = false;
1442 break; // break from while(1){block_gmres_iter->iterate()}
1443 }
1445 //
1446 // we returned from iterate(), but none of our status tests Passed.
1447 // something is wrong, and it is probably our fault.
1448 //
1450
1451 else {
1453 TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
1454 "Belos::PseudoBlockGmresSolMgr::solve(): Invalid return from PseudoBlockGmresIter::iterate().");
1455 }
1456 }
1457 catch (const PseudoBlockGmresIterOrthoFailure &e) {
1458
1459 // Try to recover the most recent least-squares solution
1460 block_gmres_iter->updateLSQR( block_gmres_iter->getCurSubspaceDim() );
1461
1462 // Check to see if the most recent least-squares solution yielded convergence.
1463 sTest_->checkStatus( &*block_gmres_iter );
1464 if (convTest_->getStatus() != Passed) {
1466 isConverged = false;
1467 }
1468 break;
1469 }
1470 catch (const StatusTestNaNError& e) {
1471 // A NaN was detected in the solver. Set the solution to zero and return unconverged.
1473 achievedTol_ = MT::one();
1474 Teuchos::RCP<MV> X = problem_->getLHS();
1475 MVT::MvInit( *X, SCT::zero() );
1476 printer_->stream(Warnings) << "Belos::PseudoBlockGmresSolMgr::solve(): Warning! NaN has been detected!"
1477 << std::endl;
1478 return retType;
1479 }
1480 catch (const std::exception &e) {
1482 printer_->stream(Errors) << "Error! Caught std::exception in PseudoBlockGmresIter::iterate() at iteration "
1483 << block_gmres_iter->getNumIters() << std::endl
1484 << e.what() << std::endl;
1485 throw;
1486 }
1487 }
1488
1489 // Compute the current solution.
1490 // Update the linear problem.
1491 if (Teuchos::nonnull(userConvStatusTest_)) {
1492 //std::cout << "\nTeuchos::nonnull(userConvStatusTest_)\n";
1493 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1494 problem_->updateSolution( update, true );
1495 }
1496 else if (Teuchos::nonnull(expConvTest_->getSolution())) {
1497 //std::cout << "\nexpConvTest_->getSolution()\n";
1498 Teuchos::RCP<MV> newX = expConvTest_->getSolution();
1499 Teuchos::RCP<MV> curX = problem_->getCurrLHSVec();
1500 MVT::Assign( *newX, *curX );
1501 }
1502 else {
1503 //std::cout << "\nblock_gmres_iter->getCurrentUpdate()\n";
1504 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1505 problem_->updateSolution( update, true );
1506 }
1507
1508 // Inform the linear problem that we are finished with this block linear system.
1509 problem_->setCurrLS();
1510
1511 // Update indices for the linear systems to be solved.
1514 if ( numRHS2Solve > 0 ) {
1515 numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1516
1517 blockSize_ = numCurrRHS;
1518 currIdx.resize( numCurrRHS );
1519 for (int i=0; i<numCurrRHS; ++i)
1520 { currIdx[i] = startPtr+i; }
1521
1522 // Adapt the status test quorum if we need to.
1523 if (defQuorum_ > blockSize_) {
1524 if (impConvTest_ != Teuchos::null)
1525 impConvTest_->setQuorum( blockSize_ );
1526 if (expConvTest_ != Teuchos::null)
1527 expConvTest_->setQuorum( blockSize_ );
1528 }
1529
1530 // Set the next indices.
1531 problem_->setLSIndex( currIdx );
1532 }
1533 else {
1534 currIdx.resize( numRHS2Solve );
1535 }
1536
1537 }// while ( numRHS2Solve > 0 )
1538
1539 }
1540
1541 // print final summary
1542 sTest_->print( printer_->stream(FinalSummary) );
1543
1544 // print timing information
1545#ifdef BELOS_TEUCHOS_TIME_MONITOR
1546 // Calling summarize() can be expensive, so don't call unless the
1547 // user wants to print out timing details. summarize() will do all
1548 // the work even if it's passed a "black hole" output stream.
1549 if (verbosity_ & TimingDetails)
1550 Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
1551#endif
1552
1553 // get iteration information for this solve
1554 numIters_ = maxIterTest_->getNumIters();
1555
1556 // Save the convergence test value ("achieved tolerance") for this
1557 // solve. For this solver, convTest_ may either be a single
1558 // residual norm test, or a combination of two residual norm tests.
1559 // In the latter case, the master convergence test convTest_ is a
1560 // SEQ combo of the implicit resp. explicit tests. If the implicit
1561 // test never passes, then the explicit test won't ever be executed.
1562 // This manifests as expConvTest_->getTestValue()->size() < 1. We
1563 // deal with this case by using the values returned by
1564 // impConvTest_->getTestValue().
1565 {
1566 // We'll fetch the vector of residual norms one way or the other.
1567 const std::vector<MagnitudeType>* pTestValues = NULL;
1568 if (expResTest_) {
1569 pTestValues = expConvTest_->getTestValue();
1570 if (pTestValues == NULL || pTestValues->size() < 1) {
1571 pTestValues = impConvTest_->getTestValue();
1572 }
1573 }
1574 else {
1575 // Only the implicit residual norm test is being used.
1576 pTestValues = impConvTest_->getTestValue();
1577 }
1578 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1579 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1580 "getTestValue() method returned NULL. Please report this bug to the "
1581 "Belos developers.");
1582 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1583 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1584 "getTestValue() method returned a vector of length zero. Please report "
1585 "this bug to the Belos developers.");
1586
1587 // FIXME (mfh 12 Dec 2011) Does pTestValues really contain the
1588 // achieved tolerances for all vectors in the current solve(), or
1589 // just for the vectors from the last deflation?
1590 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1591 }
1592
1593 if (!isConverged || loaDetected_) {
1594 return retType; // return from PseudoBlockGmresSolMgr::solve()
1595 }
1596 return Converged; // return from PseudoBlockGmresSolMgr::solve()
1597}
1598
1599
1600template<class ScalarType, class MV, class OP, class DM>
1602{
1603 std::ostringstream out;
1604
1605 out << "\"Belos::PseudoBlockGmresSolMgr\": {";
1606 if (this->getObjectLabel () != "") {
1607 out << "Label: " << this->getObjectLabel () << ", ";
1608 }
1609 out << "Num Blocks: " << numBlocks_
1610 << ", Maximum Iterations: " << maxIters_
1611 << ", Maximum Restarts: " << maxRestarts_
1612 << ", Convergence Tolerance: " << convtol_
1613 << "}";
1614 return out.str ();
1615}
1616
1617
1618template<class ScalarType, class MV, class OP, class DM>
1620describe (Teuchos::FancyOStream &out,
1621 const Teuchos::EVerbosityLevel verbLevel) const
1622{
1623 using Teuchos::TypeNameTraits;
1624 using Teuchos::VERB_DEFAULT;
1625 using Teuchos::VERB_NONE;
1626 using Teuchos::VERB_LOW;
1627 // using Teuchos::VERB_MEDIUM;
1628 // using Teuchos::VERB_HIGH;
1629 // using Teuchos::VERB_EXTREME;
1630 using std::endl;
1631
1632 // Set default verbosity if applicable.
1633 const Teuchos::EVerbosityLevel vl =
1635
1636 if (vl != VERB_NONE) {
1637 Teuchos::OSTab tab0 (out);
1638
1639 out << "\"Belos::PseudoBlockGmresSolMgr\":" << endl;
1640 Teuchos::OSTab tab1 (out);
1641 out << "Template parameters:" << endl;
1642 {
1643 Teuchos::OSTab tab2 (out);
1644 out << "ScalarType: " << TypeNameTraits<ScalarType>::name () << endl
1645 << "MV: " << TypeNameTraits<MV>::name () << endl
1646 << "OP: " << TypeNameTraits<OP>::name () << endl;
1647 }
1648 if (this->getObjectLabel () != "") {
1649 out << "Label: " << this->getObjectLabel () << endl;
1650 }
1651 out << "Num Blocks: " << numBlocks_ << endl
1652 << "Maximum Iterations: " << maxIters_ << endl
1653 << "Maximum Restarts: " << maxRestarts_ << endl
1654 << "Convergence Tolerance: " << convtol_ << endl;
1655 }
1656}
1657
1658} // end Belos namespace
1659
1660#ifdef HAVE_BELOS_TPETRA
1662
1663#define BELOS_TPETRA_PSEUDOBLOCKGMRESSOLMGR_NOEXTERN_CALL(SC, LO, GO, NT) \
1664 BELOS_TPETRA_CALL(Belos::PseudoBlockGmresSolMgr, SC, LO, GO, NT)
1665
1666#define BELOS_TPETRA_PSEUDOBLOCKGMRESSOLMGR_EXTERN_CALL(SC, LO, GO, NT) \
1667 BELOS_TPETRA_EXTERN_CALL(Belos::PseudoBlockGmresSolMgr, SC, LO, GO, NT)
1668
1669TPETRA_INSTANTIATE_SLGN_NO_ORDINAL_SCALAR(BELOS_TPETRA_PSEUDOBLOCKGMRESSOLMGR_EXTERN_CALL)
1670#endif
1671
1672
1673#endif /* BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP */
Belos header file which uses auto-configuration information to include necessary C++ headers.
Class which describes the linear problem to be solved by the iterative solver.
Class which manages the output and verbosity of the Belos solvers.
Belos concrete class for performing the pseudo-block GMRES iteration.
Pure virtual base class which describes the basic interface for a solver manager.
A factory class for generating StatusTestOutput objects.
Collection of types and exceptions used within the Belos solvers.
Parent class to all Belos exceptions.
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).
PseudoBlockGmresIterOrthoFailure is thrown when the orthogonalization manager is unable to generate o...
Interface to standard and "pseudoblock" GMRES.
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const override
Return a reference to the linear problem being solved by this solver manager.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
Teuchos::RCP< SolverManager< ScalarType, MV, OP, DM > > clone() const override
clone for Inverted Injection (DII)
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
The current parameters for this solver.
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
virtual void setUserConvStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &userConvStatusTest, const typename StatusTestCombo< ScalarType, MV, OP, DM >::ComboType &comboType=StatusTestCombo< ScalarType, MV, OP, DM >::SEQ) override
Set a custom status test.
void setDebugStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &debugStatusTest) override
Set a debug status test that will be checked at the same time as the top-level status test.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
A list of valid default parameters for this solver.
const StatusTestResNorm< ScalarType, MV, OP, DM > * getResidualStatusTest() const
Return the residual status test.
bool isLOADetected() const override
Whether a "loss of accuracy" was detected during the last solve().
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &problem) override
Set the linear problem to solve.
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > &params) override
Set the parameters the solver manager should use to solve the linear problem.
std::string description() const override
Return a one-line description of this object.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const override
Print the object with the given verbosity level to a FancyOStream.
ReturnType solve() override
This method performs possibly repeated calls to the underlying linear solver's iterate() routine unti...
int getNumIters() const override
Iteration count for the most recent call to solve().
PseudoBlockGmresSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i....
PseudoBlockGmresSolMgrOrthoFailure is thrown when the orthogonalization manager is unable to generate...
PseudoBlockGmresSolMgrOrthoFailure(const std::string &what_arg)
The Belos::SolverManager is a templated virtual base class that defines the basic interface that any ...
A class for extending the status testing capabilities of Belos via logical combinations.
ComboType
The test can be either the AND of all the component tests, or the OR of all the component tests,...
ScaleType convertStringToScaleType(const std::string &scaleType)
Convert the given string to its ScaleType enum value.
@ StatusTestDetails
@ FinalSummary
@ TimingDetails
ReturnType
Whether the Belos solve converged for all linear systems.
@ NaNDetected
@ Unconverged
@ MaxItersReached
@ NonspecificException
@ MaxRestartsReached
@ LossOfAccuracyDetected
@ InconsistentState
@ Undetermined
ScaleType
The type of scaling to use on the residual norm value.
@ UserProvided
ResetType
How to reset the solver.
Default parameters common to most Belos solvers.
static const double resScaleFactor
User-defined residual scaling factor.
static const double convTol
Default convergence tolerance.
static const double orthoKappa
DGKS orthogonalization constant.

Generated for Belos by doxygen 1.9.8