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