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
22
28#ifdef BELOS_TEUCHOS_TIME_MONITOR
29#include "Teuchos_TimeMonitor.hpp"
30#endif
31
42namespace Belos {
43
45
46
56
66
90 template<class ScalarType, class MV, class OP>
91 class PseudoBlockGmresSolMgr : public SolverManager<ScalarType,MV,OP> {
92
93 private:
96 typedef Teuchos::ScalarTraits<ScalarType> SCT;
97 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
98 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
99
100 public:
101
103
104
113
225 const Teuchos::RCP<Teuchos::ParameterList> &pl );
226
229
231 Teuchos::RCP<SolverManager<ScalarType, MV, OP> > clone () const override {
232 return Teuchos::rcp(new PseudoBlockGmresSolMgr<ScalarType,MV,OP>);
233 }
235
237
238
240 return *problem_;
241 }
242
244 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const override;
245
247 Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const override { return params_; }
248
254 Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
255 return Teuchos::tuple(timerSolve_);
256 }
257
268 MagnitudeType achievedTol() const override {
269 return achievedTol_;
270 }
271
273 int getNumIters() const override {
274 return numIters_;
275 }
276
332 bool isLOADetected() const override { return loaDetected_; }
333
336 getResidualStatusTest() const { return impConvTest_.getRawPtr(); }
338
340
341
343 void setProblem (const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem) override {
344 problem_ = problem;
345 }
346
348 void setParameters (const Teuchos::RCP<Teuchos::ParameterList> &params) override;
349
356 virtual void setUserConvStatusTest(
360 ) override;
361
363 void setDebugStatusTest( const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &debugStatusTest ) override;
364
366
368
369
373 void reset( const ResetType type ) override { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
375
377
378
396 ReturnType solve() override;
397
399
402
409 void
410 describe (Teuchos::FancyOStream& out,
411 const Teuchos::EVerbosityLevel verbLevel =
412 Teuchos::Describable::verbLevel_default) const override;
413
415 std::string description () const override;
416
418
419 private:
420
435 bool checkStatusTest();
436
438 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
439
440 // Output manager.
441 Teuchos::RCP<OutputManager<ScalarType> > printer_;
442 Teuchos::RCP<std::ostream> outputStream_;
443
444 // Status tests.
445 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > userConvStatusTest_;
446 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > debugStatusTest_;
447 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
448 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
449 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
450 Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > impConvTest_, expConvTest_;
451 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
453 Teuchos::RCP<std::map<std::string, Teuchos::RCP<StatusTest<ScalarType, MV, OP> > > > taggedTests_;
454
455 // Orthogonalization manager.
456 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
457
458 // Current parameter list.
459 Teuchos::RCP<Teuchos::ParameterList> params_;
460
461 // Default solver values.
462 static constexpr int maxRestarts_default_ = 20;
463 static constexpr int maxIters_default_ = 1000;
464 static constexpr bool showMaxResNormOnly_default_ = false;
465 static constexpr int blockSize_default_ = 1;
466 static constexpr int numBlocks_default_ = 300;
467 static constexpr int verbosity_default_ = Belos::Errors;
468 static constexpr int outputStyle_default_ = Belos::General;
469 static constexpr int outputFreq_default_ = -1;
470 static constexpr int defQuorum_default_ = 1;
471 static constexpr const char * impResScale_default_ = "Norm of Preconditioned Initial Residual";
472 static constexpr const char * expResScale_default_ = "Norm of Initial Residual";
473 static constexpr const char * label_default_ = "Belos";
474 static constexpr const char * orthoType_default_ = "ICGS";
475
476 // Current solver values.
477 MagnitudeType convtol_, orthoKappa_, achievedTol_;
478 int maxRestarts_, maxIters_, numIters_;
479 int blockSize_, numBlocks_, verbosity_, outputStyle_, outputFreq_, defQuorum_;
480 bool showMaxResNormOnly_;
481 std::string orthoType_;
482 std::string impResScale_, expResScale_;
483 MagnitudeType resScaleFactor_;
484
485 // Timers.
486 std::string label_;
487 Teuchos::RCP<Teuchos::Time> timerSolve_;
488
489 // Internal state variables.
490 bool isSet_, isSTSet_, expResTest_;
491 bool loaDetected_;
492 };
493
494
495// Empty Constructor
496template<class ScalarType, class MV, class OP>
498 outputStream_(Teuchos::rcpFromRef(std::cout)),
499 taggedTests_(Teuchos::null),
500 convtol_(DefaultSolverParameters::convTol),
501 orthoKappa_(DefaultSolverParameters::orthoKappa),
502 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
503 maxRestarts_(maxRestarts_default_),
504 maxIters_(maxIters_default_),
505 numIters_(0),
506 blockSize_(blockSize_default_),
507 numBlocks_(numBlocks_default_),
508 verbosity_(verbosity_default_),
509 outputStyle_(outputStyle_default_),
510 outputFreq_(outputFreq_default_),
511 defQuorum_(defQuorum_default_),
512 showMaxResNormOnly_(showMaxResNormOnly_default_),
513 orthoType_(orthoType_default_),
514 impResScale_(impResScale_default_),
515 expResScale_(expResScale_default_),
516 resScaleFactor_(DefaultSolverParameters::resScaleFactor),
517 label_(label_default_),
518 isSet_(false),
519 isSTSet_(false),
520 expResTest_(false),
521 loaDetected_(false)
522{}
523
524// Basic Constructor
525template<class ScalarType, class MV, class OP>
528 const Teuchos::RCP<Teuchos::ParameterList> &pl) :
529 problem_(problem),
530 outputStream_(Teuchos::rcpFromRef(std::cout)),
531 taggedTests_(Teuchos::null),
532 convtol_(DefaultSolverParameters::convTol),
533 orthoKappa_(DefaultSolverParameters::orthoKappa),
534 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
535 maxRestarts_(maxRestarts_default_),
536 maxIters_(maxIters_default_),
537 numIters_(0),
538 blockSize_(blockSize_default_),
539 numBlocks_(numBlocks_default_),
540 verbosity_(verbosity_default_),
541 outputStyle_(outputStyle_default_),
542 outputFreq_(outputFreq_default_),
543 defQuorum_(defQuorum_default_),
544 showMaxResNormOnly_(showMaxResNormOnly_default_),
545 orthoType_(orthoType_default_),
546 impResScale_(impResScale_default_),
547 expResScale_(expResScale_default_),
548 resScaleFactor_(DefaultSolverParameters::resScaleFactor),
549 label_(label_default_),
550 isSet_(false),
551 isSTSet_(false),
552 expResTest_(false),
553 loaDetected_(false)
554{
555 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
556
557 // If the parameter list pointer is null, then set the current parameters to the default parameter list.
558 if (!is_null(pl)) {
559 // Set the parameters using the list that was passed in.
560 setParameters( pl );
561 }
562}
563
564template<class ScalarType, class MV, class OP>
565void
567setParameters (const Teuchos::RCP<Teuchos::ParameterList>& params)
568{
569 using Teuchos::ParameterList;
570 using Teuchos::parameterList;
571 using Teuchos::rcp;
572 using Teuchos::rcp_dynamic_cast;
573
574 // Create the internal parameter list if one doesn't already exist.
575 if (params_ == Teuchos::null) {
576 params_ = parameterList (*getValidParameters ());
577 } else {
578 // TAW: 3/8/2016: do not validate sub parameter lists as they
579 // might not have a pre-defined structure
580 // e.g. user-specified status tests
581 // The Belos Pseudo Block GMRES parameters on the first level are
582 // not affected and verified.
583 params->validateParameters (*getValidParameters (), 0);
584 }
585
586 // Check for maximum number of restarts
587 if (params->isParameter ("Maximum Restarts")) {
588 maxRestarts_ = params->get ("Maximum Restarts", maxRestarts_default_);
589
590 // Update parameter in our list.
591 params_->set ("Maximum Restarts", maxRestarts_);
592 }
593
594 // Check for maximum number of iterations
595 if (params->isParameter ("Maximum Iterations")) {
596 maxIters_ = params->get ("Maximum Iterations", maxIters_default_);
597
598 // Update parameter in our list and in status test.
599 params_->set ("Maximum Iterations", maxIters_);
600 if (! maxIterTest_.is_null ()) {
601 maxIterTest_->setMaxIters (maxIters_);
602 }
603 }
604
605 // Check for blocksize
606 if (params->isParameter ("Block Size")) {
607 blockSize_ = params->get ("Block Size", blockSize_default_);
609 blockSize_ <= 0, std::invalid_argument,
610 "Belos::PseudoBlockGmresSolMgr::setParameters: "
611 "The \"Block Size\" parameter must be strictly positive, "
612 "but you specified a value of " << blockSize_ << ".");
613
614 // Update parameter in our list.
615 params_->set ("Block Size", blockSize_);
616 }
617
618 // Check for the maximum number of blocks.
619 if (params->isParameter ("Num Blocks")) {
620 numBlocks_ = params->get ("Num Blocks", numBlocks_default_);
622 numBlocks_ <= 0, std::invalid_argument,
623 "Belos::PseudoBlockGmresSolMgr::setParameters: "
624 "The \"Num Blocks\" parameter must be strictly positive, "
625 "but you specified a value of " << numBlocks_ << ".");
626
627 // Update parameter in our list.
628 params_->set ("Num Blocks", numBlocks_);
629 }
630
631 // Check to see if the timer label changed.
632 if (params->isParameter ("Timer Label")) {
633 const std::string tempLabel = params->get ("Timer Label", label_default_);
634
635 // Update parameter in our list and solver timer
636 if (tempLabel != label_) {
637 label_ = tempLabel;
638 params_->set ("Timer Label", label_);
639 const std::string solveLabel =
640 label_ + ": PseudoBlockGmresSolMgr total solve time";
641#ifdef BELOS_TEUCHOS_TIME_MONITOR
642 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
643#endif // BELOS_TEUCHOS_TIME_MONITOR
644 if (ortho_ != Teuchos::null) {
645 ortho_->setLabel( label_ );
646 }
647 }
648 }
649
650
651 // Check for a change in verbosity level
652 if (params->isParameter ("Verbosity")) {
653 if (Teuchos::isParameterType<int> (*params, "Verbosity")) {
654 verbosity_ = params->get ("Verbosity", verbosity_default_);
655 } else {
656 verbosity_ = (int) Teuchos::getParameter<Belos::MsgType> (*params, "Verbosity");
657 }
658
659 // Update parameter in our list.
660 params_->set ("Verbosity", verbosity_);
661 if (! printer_.is_null ()) {
662 printer_->setVerbosity (verbosity_);
663 }
664 }
665
666 // Check for a change in output style.
667 if (params->isParameter ("Output Style")) {
668 if (Teuchos::isParameterType<int> (*params, "Output Style")) {
669 outputStyle_ = params->get ("Output Style", outputStyle_default_);
670 } else {
671 outputStyle_ = (int) Teuchos::getParameter<Belos::OutputType> (*params, "Output Style");
672 }
673
674 // Update parameter in our list.
675 params_->set ("Output Style", outputStyle_);
676 if (! outputTest_.is_null ()) {
677 isSTSet_ = false;
678 }
679
680 }
681
682 // Check if user has specified his own status tests
683 if (params->isSublist ("User Status Tests")) {
684 Teuchos::ParameterList userStatusTestsList = params->sublist("User Status Tests",true);
685 if ( userStatusTestsList.numParams() > 0 ) {
686 std::string userCombo_string = params->get<std::string>("User Status Tests Combo Type", "SEQ");
687 Teuchos::RCP<StatusTestFactory<ScalarType,MV,OP> > testFactory = Teuchos::rcp(new StatusTestFactory<ScalarType,MV,OP>());
688 setUserConvStatusTest( testFactory->buildStatusTests(userStatusTestsList), testFactory->stringToComboType(userCombo_string) );
689 taggedTests_ = testFactory->getTaggedTests();
690 isSTSet_ = false;
691 }
692 }
693
694 // output stream
695 if (params->isParameter ("Output Stream")) {
696 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> > (*params, "Output Stream");
697
698 // Update parameter in our list.
699 params_->set("Output Stream", outputStream_);
700 if (! printer_.is_null ()) {
701 printer_->setOStream (outputStream_);
702 }
703 }
704
705 // frequency level
706 if (verbosity_ & Belos::StatusTestDetails) {
707 if (params->isParameter ("Output Frequency")) {
708 outputFreq_ = params->get ("Output Frequency", outputFreq_default_);
709 }
710
711 // Update parameter in out list and output status test.
712 params_->set ("Output Frequency", outputFreq_);
713 if (! outputTest_.is_null ()) {
714 outputTest_->setOutputFrequency (outputFreq_);
715 }
716 }
717
718 // Create output manager if we need to.
719 if (printer_.is_null ()) {
720 printer_ = rcp (new OutputManager<ScalarType> (verbosity_, outputStream_));
721 }
722
723 // Check if the orthogonalization changed.
724 bool changedOrthoType = false;
725 if (params->isParameter ("Orthogonalization")) {
726 std::string tempOrthoType = params->get ("Orthogonalization", orthoType_default_);
727 if (tempOrthoType != orthoType_) {
728 orthoType_ = tempOrthoType;
729 changedOrthoType = true;
730 }
731 }
732 params_->set("Orthogonalization", orthoType_);
733
734 // Check which orthogonalization constant to use.
735 if (params->isParameter ("Orthogonalization Constant")) {
736 if (params->isType<MagnitudeType> ("Orthogonalization Constant")) {
737 orthoKappa_ = params->get ("Orthogonalization Constant",
738 static_cast<MagnitudeType> (DefaultSolverParameters::orthoKappa));
739 }
740 else {
741 orthoKappa_ = params->get ("Orthogonalization Constant",
743 }
744
745 // Update parameter in our list.
746 params_->set ("Orthogonalization Constant", orthoKappa_);
747 if (orthoType_ == "DGKS") {
748 if (orthoKappa_ > 0 && ! ortho_.is_null() && !changedOrthoType) {
750 rcp_dynamic_cast<ortho_type> (ortho_)->setDepTol (orthoKappa_);
751 }
752 }
753 }
754
755 // Create orthogonalization manager if we need to.
756 if (ortho_.is_null() || changedOrthoType) {
758 Teuchos::RCP<Teuchos::ParameterList> paramsOrtho; // can be null
759 if (orthoType_=="DGKS" && orthoKappa_ > 0) {
760 paramsOrtho = Teuchos::rcp(new Teuchos::ParameterList());
761 paramsOrtho->set ("depTol", orthoKappa_ );
762 }
763
764 ortho_ = factory.makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_, paramsOrtho);
765 }
766
767 // Convergence
768
769 // Check for convergence tolerance
770 if (params->isParameter ("Convergence Tolerance")) {
771 if (params->isType<MagnitudeType> ("Convergence Tolerance")) {
772 convtol_ = params->get ("Convergence Tolerance",
773 static_cast<MagnitudeType> (DefaultSolverParameters::convTol));
774 }
775 else {
776 convtol_ = params->get ("Convergence Tolerance", DefaultSolverParameters::convTol);
777 }
778
779 // Update parameter in our list and residual tests.
780 params_->set ("Convergence Tolerance", convtol_);
781 if (! impConvTest_.is_null ()) {
782 impConvTest_->setTolerance (convtol_);
783 }
784 if (! expConvTest_.is_null ()) {
785 expConvTest_->setTolerance (convtol_);
786 }
787 }
788
789 // Grab the user defined residual scaling
791 if (params->isParameter ("User Defined Residual Scaling")) {
793 if (params->isType<MagnitudeType> ("User Defined Residual Scaling")) {
794 tempResScaleFactor = params->get ("User Defined Residual Scaling",
795 static_cast<MagnitudeType> (DefaultSolverParameters::resScaleFactor));
796 }
797 else {
798 tempResScaleFactor = params->get ("User Defined Residual Scaling",
800 }
801
802 // Only update the scaling if it's different.
803 if (resScaleFactor_ != tempResScaleFactor) {
804 resScaleFactor_ = tempResScaleFactor;
806 }
807
809 {
810 if (! params->isParameter ("Implicit Residual Scaling") && ! impConvTest_.is_null ()) {
811 try {
812 if(impResScale_ == "User Provided")
813 impConvTest_->defineScaleForm (Belos::UserProvided, Belos::TwoNorm, resScaleFactor_);
814 }
815 catch (std::exception& e) {
816 // Make sure the convergence test gets constructed again.
817 isSTSet_ = false;
818 }
819 }
820 if (! params->isParameter ("Explicit Residual Scaling") && ! expConvTest_.is_null ()) {
821 try {
822 if(expResScale_ == "User Provided")
823 expConvTest_->defineScaleForm (Belos::UserProvided, Belos::TwoNorm, resScaleFactor_);
824 }
825 catch (std::exception& e) {
826 // Make sure the convergence test gets constructed again.
827 isSTSet_ = false;
828 }
829 }
830 }
831 }
832
833 // Check for a change in scaling, if so we need to build new residual tests.
834 if (params->isParameter ("Implicit Residual Scaling")) {
835 const std::string tempImpResScale =
836 Teuchos::getParameter<std::string> (*params, "Implicit Residual Scaling");
837
838 // Only update the scaling if it's different.
839 if (impResScale_ != tempImpResScale) {
841 impResScale_ = tempImpResScale;
842
843 // Update parameter in our list and residual tests
844 params_->set ("Implicit Residual Scaling", impResScale_);
845 if (! impConvTest_.is_null ()) {
846 try {
847 if(impResScale_ == "User Provided")
848 impConvTest_->defineScaleForm (impResScaleType, Belos::TwoNorm, resScaleFactor_);
849 else
850 impConvTest_->defineScaleForm (impResScaleType, Belos::TwoNorm);
851 }
852 catch (std::exception& e) {
853 // Make sure the convergence test gets constructed again.
854 isSTSet_ = false;
855 }
856 }
857 }
860
861 if (! impConvTest_.is_null ()) {
862 try {
863 if(impResScale_ == "User Provided")
864 impConvTest_->defineScaleForm (impResScaleType, Belos::TwoNorm, resScaleFactor_);
865 }
866 catch (std::exception& e) {
867 // Make sure the convergence test gets constructed again.
868 isSTSet_ = false;
869 }
870 }
871 }
872 }
873
874 if (params->isParameter ("Explicit Residual Scaling")) {
875 const std::string tempExpResScale =
876 Teuchos::getParameter<std::string> (*params, "Explicit Residual Scaling");
877
878 // Only update the scaling if it's different.
879 if (expResScale_ != tempExpResScale) {
881 expResScale_ = tempExpResScale;
882
883 // Update parameter in our list and residual tests
884 params_->set ("Explicit Residual Scaling", expResScale_);
885 if (! expConvTest_.is_null ()) {
886 try {
887 if(expResScale_ == "User Provided")
888 expConvTest_->defineScaleForm (expResScaleType, Belos::TwoNorm, resScaleFactor_);
889 else
890 expConvTest_->defineScaleForm (expResScaleType, Belos::TwoNorm);
891 }
892 catch (std::exception& e) {
893 // Make sure the convergence test gets constructed again.
894 isSTSet_ = false;
895 }
896 }
897 }
900
901 if (! expConvTest_.is_null ()) {
902 try {
903 if(expResScale_ == "User Provided")
904 expConvTest_->defineScaleForm (expResScaleType, Belos::TwoNorm, resScaleFactor_);
905 }
906 catch (std::exception& e) {
907 // Make sure the convergence test gets constructed again.
908 isSTSet_ = false;
909 }
910 }
911 }
912 }
913
914
915 if (params->isParameter ("Show Maximum Residual Norm Only")) {
916 showMaxResNormOnly_ =
917 Teuchos::getParameter<bool> (*params, "Show Maximum Residual Norm Only");
918
919 // Update parameter in our list and residual tests
920 params_->set ("Show Maximum Residual Norm Only", showMaxResNormOnly_);
921 if (! impConvTest_.is_null ()) {
922 impConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
923 }
924 if (! expConvTest_.is_null ()) {
925 expConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
926 }
927 }
928
929 // Create status tests if we need to.
930
931 // Get the deflation quorum, or number of converged systems before deflation is allowed
932 if (params->isParameter("Deflation Quorum")) {
933 defQuorum_ = params->get("Deflation Quorum", defQuorum_);
935 defQuorum_ > blockSize_, std::invalid_argument,
936 "Belos::PseudoBlockGmresSolMgr::setParameters: "
937 "The \"Deflation Quorum\" parameter (= " << defQuorum_ << ") must not be "
938 "larger than \"Block Size\" (= " << blockSize_ << ").");
939 params_->set ("Deflation Quorum", defQuorum_);
940 if (! impConvTest_.is_null ()) {
941 impConvTest_->setQuorum (defQuorum_);
942 }
943 if (! expConvTest_.is_null ()) {
944 expConvTest_->setQuorum (defQuorum_);
945 }
946 }
947
948 // Create the timer if we need to.
949 if (timerSolve_ == Teuchos::null) {
950 std::string solveLabel = label_ + ": PseudoBlockGmresSolMgr total solve time";
951#ifdef BELOS_TEUCHOS_TIME_MONITOR
952 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
953#endif
954 }
955
956 // Inform the solver manager that the current parameters were set.
957 isSet_ = true;
958}
959
960
961template<class ScalarType, class MV, class OP>
962void
971
972template<class ScalarType, class MV, class OP>
973void
980
981
982
983template<class ScalarType, class MV, class OP>
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>
1050
1051 typedef Belos::StatusTestCombo<ScalarType,MV,OP> StatusTestCombo_t;
1054
1055 // Basic test checks maximum iterations and native residual.
1056 maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>( 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> > > 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> 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>
1163
1164 // Set the current parameters if they were not set before.
1165 // NOTE: This may occur if the user generated the solver manager with the default constructor and
1166 // then didn't set any parameters using setParameters().
1167 if (!isSet_) { setParameters( params_ ); }
1168
1170 "Belos::PseudoBlockGmresSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1171
1172 // Check if we have to create the status tests.
1173 if (!isSTSet_ || (!expResTest_ && !Teuchos::is_null(problem_->getLeftPrec())) ) {
1175 "Belos::BlockGmresSolMgr::solve(): Linear problem and requested status tests are incompatible.");
1176 }
1177
1178 // Create indices for the linear systems to be solved.
1179 int startPtr = 0;
1180 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1181 int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1182
1183 std::vector<int> currIdx( numCurrRHS );
1184 blockSize_ = numCurrRHS;
1185 for (int i=0; i<numCurrRHS; ++i)
1186 { currIdx[i] = startPtr+i; }
1187
1188 // Inform the linear problem of the current linear system to solve.
1189 problem_->setLSIndex( currIdx );
1190
1192 // Parameter list
1193 Teuchos::ParameterList plist;
1194 plist.set("Num Blocks",numBlocks_);
1195
1196 // Reset the status test.
1197 outputTest_->reset();
1198 loaDetected_ = false;
1199
1200 // Assume convergence is achieved, then let any failed convergence set this to false.
1201 bool isConverged = true;
1202
1204 // BlockGmres solver
1205
1206 Teuchos::RCP<PseudoBlockGmresIter<ScalarType,MV,OP> > block_gmres_iter
1207 = Teuchos::rcp( new PseudoBlockGmresIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,ortho_,plist) );
1208
1209 // Enter solve() iterations
1210 {
1211#ifdef BELOS_TEUCHOS_TIME_MONITOR
1212 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1213#endif
1214
1215 while ( numRHS2Solve > 0 ) {
1216
1217 // Reset the active / converged vectors from this block
1218 std::vector<int> convRHSIdx;
1219 std::vector<int> currRHSIdx( currIdx );
1220 currRHSIdx.resize(numCurrRHS);
1221
1222 // Set the current number of blocks with the pseudo Gmres iteration.
1223 block_gmres_iter->setNumBlocks( numBlocks_ );
1224
1225 // Reset the number of iterations.
1226 block_gmres_iter->resetNumIters();
1227
1228 // Reset the number of calls that the status test output knows about.
1229 outputTest_->resetNumCalls();
1230
1231 // Get a new state struct and initialize the solver.
1233
1234 // Create the first block in the current Krylov basis for each right-hand side.
1235 std::vector<int> index(1);
1236 Teuchos::RCP<MV> tmpV, R_0 = MVT::CloneCopy( *(problem_->getInitPrecResVec()), currIdx );
1237 newState.V.resize( blockSize_ );
1238 newState.Z.resize( blockSize_ );
1239 for (int i=0; i<blockSize_; ++i) {
1240 index[0]=i;
1241 tmpV = MVT::CloneViewNonConst( *R_0, index );
1242
1243 // Get a matrix to hold the orthonormalization coefficients.
1244 Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > tmpZ
1245 = Teuchos::rcp( new Teuchos::SerialDenseVector<int,ScalarType>( 1 ));
1246
1247 // Orthonormalize the new V_0
1248 int rank = ortho_->normalize( *tmpV, tmpZ );
1250 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors.");
1251
1252 newState.V[i] = tmpV;
1253 newState.Z[i] = tmpZ;
1254 }
1255
1256 newState.curDim = 0;
1257 block_gmres_iter->initialize(newState);
1258 int numRestarts = 0;
1259
1260 while(1) {
1261
1262 // tell block_gmres_iter to iterate
1263 try {
1264 block_gmres_iter->iterate();
1265
1267 //
1268 // check convergence first
1269 //
1271 if ( convTest_->getStatus() == Passed ) {
1272
1273 if ( expConvTest_->getLOADetected() ) {
1274 // Oops! There was a loss of accuracy (LOA) for one or
1275 // more right-hand sides. That means the implicit
1276 // (a.k.a. "native") residuals claim convergence,
1277 // whereas the explicit (hence expConvTest_, i.e.,
1278 // "explicit convergence test") residuals have not
1279 // converged.
1280 //
1281 // We choose to deal with this situation by deflating
1282 // out the affected right-hand sides and moving on.
1284 loaDetected_ = true;
1285 printer_->stream(Warnings) <<
1286 "Belos::PseudoBlockGmresSolMgr::solve(): Warning! Solver has experienced a loss of accuracy!" << std::endl;
1287 isConverged = false;
1288 }
1289
1290 // Figure out which linear systems converged.
1291 std::vector<int> convIdx = expConvTest_->convIndices();
1292
1293 // If the number of converged linear systems is equal to the
1294 // number of current linear systems, then we are done with this block.
1295 if (convIdx.size() == currRHSIdx.size())
1296 break; // break from while(1){block_gmres_iter->iterate()}
1297
1298 // Get a new state struct and initialize the solver.
1300
1301 // Inform the linear problem that we are finished with this current linear system.
1302 problem_->setCurrLS();
1303
1304 // Get the state.
1306 int curDim = oldState.curDim;
1307
1308 // Get a new state struct and reset currRHSIdx to have the right-hand sides that
1309 // are left to converge for this block.
1310 int have = 0;
1311 std::vector<int> oldRHSIdx( currRHSIdx );
1312 std::vector<int> defRHSIdx;
1313 for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
1314 bool found = false;
1315 for (unsigned int j=0; j<convIdx.size(); ++j) {
1316 if (currRHSIdx[i] == convIdx[j]) {
1317 found = true;
1318 break;
1319 }
1320 }
1321 if (found) {
1322 defRHSIdx.push_back( i );
1323 }
1324 else {
1325 defState.V.push_back( Teuchos::rcp_const_cast<MV>( oldState.V[i] ) );
1326 defState.Z.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,ScalarType> >( oldState.Z[i] ) );
1327 defState.H.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseMatrix<int,ScalarType> >( oldState.H[i] ) );
1328 defState.sn.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,ScalarType> >( oldState.sn[i] ) );
1329 defState.cs.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,MagnitudeType> >(oldState.cs[i] ) );
1331 have++;
1332 }
1333 }
1334 defRHSIdx.resize(currRHSIdx.size()-have);
1335 currRHSIdx.resize(have);
1336
1337 // Compute the current solution that needs to be deflated if this solver has taken any steps.
1338 if (curDim) {
1339 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1340 Teuchos::RCP<MV> defUpdate = MVT::CloneViewNonConst( *update, defRHSIdx );
1341
1342 // Set the deflated indices so we can update the solution.
1343 problem_->setLSIndex( convIdx );
1344
1345 // Update the linear problem.
1346 problem_->updateSolution( defUpdate, true );
1347 }
1348
1349 // Set the remaining indices after deflation.
1350 problem_->setLSIndex( currRHSIdx );
1351
1352 // Set the dimension of the subspace, which is the same as the old subspace size.
1353 defState.curDim = curDim;
1354
1355 // Initialize the solver with the deflated system.
1356 block_gmres_iter->initialize(defState);
1357 }
1359 //
1360 // check for maximum iterations
1361 //
1363 else if ( maxIterTest_->getStatus() == Passed ) {
1364 // we don't have convergence
1366 isConverged = false;
1367 break; // break from while(1){block_gmres_iter->iterate()}
1368 }
1370 //
1371 // check for restarting, i.e. the subspace is full
1372 //
1374 else if ( block_gmres_iter->getCurSubspaceDim() == block_gmres_iter->getMaxSubspaceDim() ) {
1375
1376 if ( numRestarts >= maxRestarts_ ) {
1378 isConverged = false;
1379 break; // break from while(1){block_gmres_iter->iterate()}
1380 }
1381 numRestarts++;
1382
1383 printer_->stream(Debug) << " Performing restart number " << numRestarts << " of " << maxRestarts_ << std::endl << std::endl;
1384
1385 // Update the linear problem.
1386 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1387 problem_->updateSolution( update, true );
1388
1389 // Get the state.
1391
1392 // Set the new state.
1394 newstate.V.resize(currRHSIdx.size());
1395 newstate.Z.resize(currRHSIdx.size());
1396
1397 // Compute the restart vectors
1398 // NOTE: Force the linear problem to update the current residual since the solution was updated.
1399 R_0 = MVT::Clone( *(problem_->getInitPrecResVec()), currRHSIdx.size() );
1400 problem_->computeCurrPrecResVec( &*R_0 );
1401 for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
1402 index[0] = i; // index(1) vector declared on line 891
1403
1404 tmpV = MVT::CloneViewNonConst( *R_0, index );
1405
1406 // Get a matrix to hold the orthonormalization coefficients.
1407 Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > tmpZ
1408 = Teuchos::rcp( new Teuchos::SerialDenseVector<int,ScalarType>( 1 ));
1409
1410 // Orthonormalize the new V_0
1411 int rank = ortho_->normalize( *tmpV, tmpZ );
1413 "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors after the restart.");
1414
1415 newstate.V[i] = tmpV;
1416 newstate.Z[i] = tmpZ;
1417 }
1418
1419 // Initialize the solver.
1420 newstate.curDim = 0;
1421 block_gmres_iter->initialize(newstate);
1422
1423 } // end of restarting
1424
1426 //
1427 // we returned from iterate(), but none of our status tests Passed.
1428 // something is wrong, and it is probably our fault.
1429 //
1431
1432 else {
1434 TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
1435 "Belos::PseudoBlockGmresSolMgr::solve(): Invalid return from PseudoBlockGmresIter::iterate().");
1436 }
1437 }
1438 catch (const PseudoBlockGmresIterOrthoFailure &e) {
1439
1440 // Try to recover the most recent least-squares solution
1441 block_gmres_iter->updateLSQR( block_gmres_iter->getCurSubspaceDim() );
1442
1443 // Check to see if the most recent least-squares solution yielded convergence.
1444 sTest_->checkStatus( &*block_gmres_iter );
1445 if (convTest_->getStatus() != Passed) {
1447 isConverged = false;
1448 }
1449 break;
1450 }
1451 catch (const StatusTestNaNError& e) {
1452 // A NaN was detected in the solver. Set the solution to zero and return unconverged.
1454 achievedTol_ = MT::one();
1455 Teuchos::RCP<MV> X = problem_->getLHS();
1456 MVT::MvInit( *X, SCT::zero() );
1457 printer_->stream(Warnings) << "Belos::PseudoBlockGmresSolMgr::solve(): Warning! NaN has been detected!"
1458 << std::endl;
1459 return retType;
1460 }
1461 catch (const std::exception &e) {
1463 printer_->stream(Errors) << "Error! Caught std::exception in PseudoBlockGmresIter::iterate() at iteration "
1464 << block_gmres_iter->getNumIters() << std::endl
1465 << e.what() << std::endl;
1466 throw;
1467 }
1468 }
1469
1470 // Compute the current solution.
1471 // Update the linear problem.
1472 if (nonnull(userConvStatusTest_)) {
1473 //std::cout << "\nnonnull(userConvStatusTest_)\n";
1474 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1475 problem_->updateSolution( update, true );
1476 }
1477 else if (nonnull(expConvTest_->getSolution())) {
1478 //std::cout << "\nexpConvTest_->getSolution()\n";
1479 Teuchos::RCP<MV> newX = expConvTest_->getSolution();
1480 Teuchos::RCP<MV> curX = problem_->getCurrLHSVec();
1481 MVT::MvAddMv( 0.0, *newX, 1.0, *newX, *curX );
1482 }
1483 else {
1484 //std::cout << "\nblock_gmres_iter->getCurrentUpdate()\n";
1485 Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1486 problem_->updateSolution( update, true );
1487 }
1488
1489 // Inform the linear problem that we are finished with this block linear system.
1490 problem_->setCurrLS();
1491
1492 // Update indices for the linear systems to be solved.
1495 if ( numRHS2Solve > 0 ) {
1496 numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1497
1498 blockSize_ = numCurrRHS;
1499 currIdx.resize( numCurrRHS );
1500 for (int i=0; i<numCurrRHS; ++i)
1501 { currIdx[i] = startPtr+i; }
1502
1503 // Adapt the status test quorum if we need to.
1504 if (defQuorum_ > blockSize_) {
1505 if (impConvTest_ != Teuchos::null)
1506 impConvTest_->setQuorum( blockSize_ );
1507 if (expConvTest_ != Teuchos::null)
1508 expConvTest_->setQuorum( blockSize_ );
1509 }
1510
1511 // Set the next indices.
1512 problem_->setLSIndex( currIdx );
1513 }
1514 else {
1515 currIdx.resize( numRHS2Solve );
1516 }
1517
1518 }// while ( numRHS2Solve > 0 )
1519
1520 }
1521
1522 // print final summary
1523 sTest_->print( printer_->stream(FinalSummary) );
1524
1525 // print timing information
1526#ifdef BELOS_TEUCHOS_TIME_MONITOR
1527 // Calling summarize() can be expensive, so don't call unless the
1528 // user wants to print out timing details. summarize() will do all
1529 // the work even if it's passed a "black hole" output stream.
1530 if (verbosity_ & TimingDetails)
1531 Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
1532#endif
1533
1534 // get iteration information for this solve
1535 numIters_ = maxIterTest_->getNumIters();
1536
1537 // Save the convergence test value ("achieved tolerance") for this
1538 // solve. For this solver, convTest_ may either be a single
1539 // residual norm test, or a combination of two residual norm tests.
1540 // In the latter case, the master convergence test convTest_ is a
1541 // SEQ combo of the implicit resp. explicit tests. If the implicit
1542 // test never passes, then the explicit test won't ever be executed.
1543 // This manifests as expConvTest_->getTestValue()->size() < 1. We
1544 // deal with this case by using the values returned by
1545 // impConvTest_->getTestValue().
1546 {
1547 // We'll fetch the vector of residual norms one way or the other.
1548 const std::vector<MagnitudeType>* pTestValues = NULL;
1549 if (expResTest_) {
1550 pTestValues = expConvTest_->getTestValue();
1551 if (pTestValues == NULL || pTestValues->size() < 1) {
1552 pTestValues = impConvTest_->getTestValue();
1553 }
1554 }
1555 else {
1556 // Only the implicit residual norm test is being used.
1557 pTestValues = impConvTest_->getTestValue();
1558 }
1559 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1560 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1561 "getTestValue() method returned NULL. Please report this bug to the "
1562 "Belos developers.");
1563 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1564 "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1565 "getTestValue() method returned a vector of length zero. Please report "
1566 "this bug to the Belos developers.");
1567
1568 // FIXME (mfh 12 Dec 2011) Does pTestValues really contain the
1569 // achieved tolerances for all vectors in the current solve(), or
1570 // just for the vectors from the last deflation?
1571 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1572 }
1573
1574 if (!isConverged || loaDetected_) {
1575 return retType; // return from PseudoBlockGmresSolMgr::solve()
1576 }
1577 return Converged; // return from PseudoBlockGmresSolMgr::solve()
1578}
1579
1580
1581template<class ScalarType, class MV, class OP>
1583{
1584 std::ostringstream out;
1585
1586 out << "\"Belos::PseudoBlockGmresSolMgr\": {";
1587 if (this->getObjectLabel () != "") {
1588 out << "Label: " << this->getObjectLabel () << ", ";
1589 }
1590 out << "Num Blocks: " << numBlocks_
1591 << ", Maximum Iterations: " << maxIters_
1592 << ", Maximum Restarts: " << maxRestarts_
1593 << ", Convergence Tolerance: " << convtol_
1594 << "}";
1595 return out.str ();
1596}
1597
1598
1599template<class ScalarType, class MV, class OP>
1600void
1602describe (Teuchos::FancyOStream &out,
1603 const Teuchos::EVerbosityLevel verbLevel) const
1604{
1605 using Teuchos::TypeNameTraits;
1606 using Teuchos::VERB_DEFAULT;
1607 using Teuchos::VERB_NONE;
1608 using Teuchos::VERB_LOW;
1609 // using Teuchos::VERB_MEDIUM;
1610 // using Teuchos::VERB_HIGH;
1611 // using Teuchos::VERB_EXTREME;
1612 using std::endl;
1613
1614 // Set default verbosity if applicable.
1615 const Teuchos::EVerbosityLevel vl =
1617
1618 if (vl != VERB_NONE) {
1619 Teuchos::OSTab tab0 (out);
1620
1621 out << "\"Belos::PseudoBlockGmresSolMgr\":" << endl;
1622 Teuchos::OSTab tab1 (out);
1623 out << "Template parameters:" << endl;
1624 {
1625 Teuchos::OSTab tab2 (out);
1626 out << "ScalarType: " << TypeNameTraits<ScalarType>::name () << endl
1627 << "MV: " << TypeNameTraits<MV>::name () << endl
1628 << "OP: " << TypeNameTraits<OP>::name () << endl;
1629 }
1630 if (this->getObjectLabel () != "") {
1631 out << "Label: " << this->getObjectLabel () << endl;
1632 }
1633 out << "Num Blocks: " << numBlocks_ << endl
1634 << "Maximum Iterations: " << maxIters_ << endl
1635 << "Maximum Restarts: " << maxRestarts_ << endl
1636 << "Convergence Tolerance: " << convtol_ << endl;
1637 }
1638}
1639
1640} // end Belos namespace
1641
1642#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.
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
bool isLOADetected() const override
Whether a "loss of accuracy" was detected during the last solve().
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.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
A list of valid default parameters for this solver.
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > &params) override
Set the parameters the solver manager should use to solve the linear problem.
ReturnType solve() override
This method performs possibly repeated calls to the underlying linear solver's iterate() routine unti...
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
const StatusTestResNorm< ScalarType, MV, OP > * getResidualStatusTest() const
Return the residual status test.
void setDebugStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &debugStatusTest) override
Set a debug status test that will be checked at the same time as the top-level status test.
std::string description() const override
Return a one-line description of this object.
virtual void setUserConvStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &userConvStatusTest, const typename StatusTestCombo< ScalarType, MV, OP >::ComboType &comboType=StatusTestCombo< ScalarType, MV, OP >::SEQ) override
Set a custom status test.
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
const LinearProblem< ScalarType, MV, OP > & getProblem() const override
Return a reference to the linear problem being solved by this solver manager.
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
The current parameters for this solver.
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) override
Set the linear problem to solve.
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