Belos  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BelosPseudoBlockGmresSolMgr.hpp
Go to the documentation of this file.
1 //@HEADER
2 // ************************************************************************
3 //
4 // Belos: Block Linear Solvers Package
5 // Copyright 2004 Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 //@HEADER
41 
42 #ifndef BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
43 #define BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP
44 
49 #include "BelosConfigDefs.hpp"
50 #include "BelosTypes.hpp"
51 
52 #include "BelosLinearProblem.hpp"
53 #include "BelosSolverManager.hpp"
54 
59 #include "BelosOutputManager.hpp"
60 #ifdef BELOS_TEUCHOS_TIME_MONITOR
61 #include "Teuchos_TimeMonitor.hpp"
62 #endif
63 
71 namespace Belos {
72 
74 
75 
83  PseudoBlockGmresSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
84  {}};
85 
93  PseudoBlockGmresSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg)
94  {}};
95 
119  template<class ScalarType, class MV, class OP>
120  class PseudoBlockGmresSolMgr : public SolverManager<ScalarType,MV,OP> {
121 
122  private:
126  typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
128 
129  public:
130 
132 
133 
142 
255 
258 
262  }
264 
266 
267 
268  const LinearProblem<ScalarType,MV,OP>& getProblem() const override {
269  return *problem_;
270  }
271 
274 
277 
284  return Teuchos::tuple(timerSolve_);
285  }
286 
297  MagnitudeType achievedTol() const override {
298  return achievedTol_;
299  }
300 
302  int getNumIters() const override {
303  return numIters_;
304  }
305 
361  bool isLOADetected() const override { return loaDetected_; }
362 
365  getResidualStatusTest() const { return impConvTest_.getRawPtr(); }
367 
369 
370 
372  void setProblem (const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem) override {
373  problem_ = problem;
374  }
375 
377  void setParameters (const Teuchos::RCP<Teuchos::ParameterList> &params) override;
378 
385  virtual void setUserConvStatusTest(
386  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &userConvStatusTest,
387  const typename StatusTestCombo<ScalarType,MV,OP>::ComboType &comboType =
389  ) override;
390 
392  void setDebugStatusTest( const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &debugStatusTest ) override;
393 
395 
397 
398 
402  void reset( const ResetType type ) override { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
404 
406 
407 
425  ReturnType solve() override;
426 
428 
431 
438  void
440  const Teuchos::EVerbosityLevel verbLevel =
442 
444  std::string description () const override;
445 
447 
448  private:
449 
464  bool checkStatusTest();
465 
468 
469  // Output manager.
471  Teuchos::RCP<std::ostream> outputStream_;
472 
473  // Status tests.
474  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > userConvStatusTest_;
479  Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > impConvTest_, expConvTest_;
483 
484  // Orthogonalization manager.
486 
487  // Current parameter list.
489 
490  // Default solver values.
491  static constexpr int maxRestarts_default_ = 20;
492  static constexpr int maxIters_default_ = 1000;
493  static constexpr bool showMaxResNormOnly_default_ = false;
494  static constexpr int blockSize_default_ = 1;
495  static constexpr int numBlocks_default_ = 300;
496  static constexpr int verbosity_default_ = Belos::Errors;
497  static constexpr int outputStyle_default_ = Belos::General;
498  static constexpr int outputFreq_default_ = -1;
499  static constexpr int defQuorum_default_ = 1;
500  static constexpr const char * impResScale_default_ = "Norm of Preconditioned Initial Residual";
501  static constexpr const char * expResScale_default_ = "Norm of Initial Residual";
502  static constexpr const char * label_default_ = "Belos";
503  static constexpr const char * orthoType_default_ = "ICGS";
504 
505  // Current solver values.
506  MagnitudeType convtol_, orthoKappa_, achievedTol_;
507  int maxRestarts_, maxIters_, numIters_;
508  int blockSize_, numBlocks_, verbosity_, outputStyle_, outputFreq_, defQuorum_;
509  bool showMaxResNormOnly_;
510  std::string orthoType_;
511  std::string impResScale_, expResScale_;
512  MagnitudeType resScaleFactor_;
513 
514  // Timers.
515  std::string label_;
516  Teuchos::RCP<Teuchos::Time> timerSolve_;
517 
518  // Internal state variables.
519  bool isSet_, isSTSet_, expResTest_;
520  bool loaDetected_;
521  };
522 
523 
524 // Empty Constructor
525 template<class ScalarType, class MV, class OP>
527  outputStream_(Teuchos::rcpFromRef(std::cout)),
528  taggedTests_(Teuchos::null),
529  convtol_(DefaultSolverParameters::convTol),
530  orthoKappa_(DefaultSolverParameters::orthoKappa),
531  achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
532  maxRestarts_(maxRestarts_default_),
533  maxIters_(maxIters_default_),
534  numIters_(0),
535  blockSize_(blockSize_default_),
536  numBlocks_(numBlocks_default_),
537  verbosity_(verbosity_default_),
538  outputStyle_(outputStyle_default_),
539  outputFreq_(outputFreq_default_),
540  defQuorum_(defQuorum_default_),
541  showMaxResNormOnly_(showMaxResNormOnly_default_),
542  orthoType_(orthoType_default_),
543  impResScale_(impResScale_default_),
544  expResScale_(expResScale_default_),
545  resScaleFactor_(DefaultSolverParameters::resScaleFactor),
546  label_(label_default_),
547  isSet_(false),
548  isSTSet_(false),
549  expResTest_(false),
550  loaDetected_(false)
551 {}
552 
553 // Basic Constructor
554 template<class ScalarType, class MV, class OP>
558  problem_(problem),
559  outputStream_(Teuchos::rcpFromRef(std::cout)),
560  taggedTests_(Teuchos::null),
561  convtol_(DefaultSolverParameters::convTol),
562  orthoKappa_(DefaultSolverParameters::orthoKappa),
563  achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
564  maxRestarts_(maxRestarts_default_),
565  maxIters_(maxIters_default_),
566  numIters_(0),
567  blockSize_(blockSize_default_),
568  numBlocks_(numBlocks_default_),
569  verbosity_(verbosity_default_),
570  outputStyle_(outputStyle_default_),
571  outputFreq_(outputFreq_default_),
572  defQuorum_(defQuorum_default_),
573  showMaxResNormOnly_(showMaxResNormOnly_default_),
574  orthoType_(orthoType_default_),
575  impResScale_(impResScale_default_),
576  expResScale_(expResScale_default_),
577  resScaleFactor_(DefaultSolverParameters::resScaleFactor),
578  label_(label_default_),
579  isSet_(false),
580  isSTSet_(false),
581  expResTest_(false),
582  loaDetected_(false)
583 {
584  TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
585 
586  // If the parameter list pointer is null, then set the current parameters to the default parameter list.
587  if (!is_null(pl)) {
588  // Set the parameters using the list that was passed in.
589  setParameters( pl );
590  }
591 }
592 
593 template<class ScalarType, class MV, class OP>
594 void
597 {
599  using Teuchos::parameterList;
600  using Teuchos::rcp;
601  using Teuchos::rcp_dynamic_cast;
602 
603  // Create the internal parameter list if one doesn't already exist.
604  if (params_ == Teuchos::null) {
605  params_ = parameterList (*getValidParameters ());
606  } else {
607  // TAW: 3/8/2016: do not validate sub parameter lists as they
608  // might not have a pre-defined structure
609  // e.g. user-specified status tests
610  // The Belos Pseudo Block GMRES parameters on the first level are
611  // not affected and verified.
612  params->validateParameters (*getValidParameters (), 0);
613  }
614 
615  // Check for maximum number of restarts
616  if (params->isParameter ("Maximum Restarts")) {
617  maxRestarts_ = params->get ("Maximum Restarts", maxRestarts_default_);
618 
619  // Update parameter in our list.
620  params_->set ("Maximum Restarts", maxRestarts_);
621  }
622 
623  // Check for maximum number of iterations
624  if (params->isParameter ("Maximum Iterations")) {
625  maxIters_ = params->get ("Maximum Iterations", maxIters_default_);
626 
627  // Update parameter in our list and in status test.
628  params_->set ("Maximum Iterations", maxIters_);
629  if (! maxIterTest_.is_null ()) {
630  maxIterTest_->setMaxIters (maxIters_);
631  }
632  }
633 
634  // Check for blocksize
635  if (params->isParameter ("Block Size")) {
636  blockSize_ = params->get ("Block Size", blockSize_default_);
638  blockSize_ <= 0, std::invalid_argument,
639  "Belos::PseudoBlockGmresSolMgr::setParameters: "
640  "The \"Block Size\" parameter must be strictly positive, "
641  "but you specified a value of " << blockSize_ << ".");
642 
643  // Update parameter in our list.
644  params_->set ("Block Size", blockSize_);
645  }
646 
647  // Check for the maximum number of blocks.
648  if (params->isParameter ("Num Blocks")) {
649  numBlocks_ = params->get ("Num Blocks", numBlocks_default_);
651  numBlocks_ <= 0, std::invalid_argument,
652  "Belos::PseudoBlockGmresSolMgr::setParameters: "
653  "The \"Num Blocks\" parameter must be strictly positive, "
654  "but you specified a value of " << numBlocks_ << ".");
655 
656  // Update parameter in our list.
657  params_->set ("Num Blocks", numBlocks_);
658  }
659 
660  // Check to see if the timer label changed.
661  if (params->isParameter ("Timer Label")) {
662  const std::string tempLabel = params->get ("Timer Label", label_default_);
663 
664  // Update parameter in our list and solver timer
665  if (tempLabel != label_) {
666  label_ = tempLabel;
667  params_->set ("Timer Label", label_);
668  const std::string solveLabel =
669  label_ + ": PseudoBlockGmresSolMgr total solve time";
670 #ifdef BELOS_TEUCHOS_TIME_MONITOR
671  timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
672 #endif // BELOS_TEUCHOS_TIME_MONITOR
673  if (ortho_ != Teuchos::null) {
674  ortho_->setLabel( label_ );
675  }
676  }
677  }
678 
679 
680  // Check for a change in verbosity level
681  if (params->isParameter ("Verbosity")) {
682  if (Teuchos::isParameterType<int> (*params, "Verbosity")) {
683  verbosity_ = params->get ("Verbosity", verbosity_default_);
684  } else {
685  verbosity_ = (int) Teuchos::getParameter<Belos::MsgType> (*params, "Verbosity");
686  }
687 
688  // Update parameter in our list.
689  params_->set ("Verbosity", verbosity_);
690  if (! printer_.is_null ()) {
691  printer_->setVerbosity (verbosity_);
692  }
693  }
694 
695  // Check for a change in output style.
696  if (params->isParameter ("Output Style")) {
697  if (Teuchos::isParameterType<int> (*params, "Output Style")) {
698  outputStyle_ = params->get ("Output Style", outputStyle_default_);
699  } else {
700  outputStyle_ = (int) Teuchos::getParameter<Belos::OutputType> (*params, "Output Style");
701  }
702 
703  // Update parameter in our list.
704  params_->set ("Output Style", outputStyle_);
705  if (! outputTest_.is_null ()) {
706  isSTSet_ = false;
707  }
708 
709  }
710 
711  // Check if user has specified his own status tests
712  if (params->isSublist ("User Status Tests")) {
713  Teuchos::ParameterList userStatusTestsList = params->sublist("User Status Tests",true);
714  if ( userStatusTestsList.numParams() > 0 ) {
715  std::string userCombo_string = params->get<std::string>("User Status Tests Combo Type", "SEQ");
717  setUserConvStatusTest( testFactory->buildStatusTests(userStatusTestsList), testFactory->stringToComboType(userCombo_string) );
718  taggedTests_ = testFactory->getTaggedTests();
719  isSTSet_ = false;
720  }
721  }
722 
723  // output stream
724  if (params->isParameter ("Output Stream")) {
725  outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> > (*params, "Output Stream");
726 
727  // Update parameter in our list.
728  params_->set("Output Stream", outputStream_);
729  if (! printer_.is_null ()) {
730  printer_->setOStream (outputStream_);
731  }
732  }
733 
734  // frequency level
735  if (verbosity_ & Belos::StatusTestDetails) {
736  if (params->isParameter ("Output Frequency")) {
737  outputFreq_ = params->get ("Output Frequency", outputFreq_default_);
738  }
739 
740  // Update parameter in out list and output status test.
741  params_->set ("Output Frequency", outputFreq_);
742  if (! outputTest_.is_null ()) {
743  outputTest_->setOutputFrequency (outputFreq_);
744  }
745  }
746 
747  // Create output manager if we need to.
748  if (printer_.is_null ()) {
749  printer_ = rcp (new OutputManager<ScalarType> (verbosity_, outputStream_));
750  }
751 
752  // Check if the orthogonalization changed.
753  bool changedOrthoType = false;
754  if (params->isParameter ("Orthogonalization")) {
755  std::string tempOrthoType = params->get ("Orthogonalization", orthoType_default_);
756  if (tempOrthoType != orthoType_) {
757  orthoType_ = tempOrthoType;
758  changedOrthoType = true;
759  }
760  }
761  params_->set("Orthogonalization", orthoType_);
762 
763  // Check which orthogonalization constant to use.
764  if (params->isParameter ("Orthogonalization Constant")) {
765  if (params->isType<MagnitudeType> ("Orthogonalization Constant")) {
766  orthoKappa_ = params->get ("Orthogonalization Constant",
767  static_cast<MagnitudeType> (DefaultSolverParameters::orthoKappa));
768  }
769  else {
770  orthoKappa_ = params->get ("Orthogonalization Constant",
772  }
773 
774  // Update parameter in our list.
775  params_->set ("Orthogonalization Constant", orthoKappa_);
776  if (orthoType_ == "DGKS") {
777  if (orthoKappa_ > 0 && ! ortho_.is_null() && !changedOrthoType) {
778  typedef DGKSOrthoManager<ScalarType, MV, OP> ortho_type;
779  rcp_dynamic_cast<ortho_type> (ortho_)->setDepTol (orthoKappa_);
780  }
781  }
782  }
783 
784  // Create orthogonalization manager if we need to.
785  if (ortho_.is_null() || changedOrthoType) {
787  Teuchos::RCP<Teuchos::ParameterList> paramsOrtho; // can be null
788  if (orthoType_=="DGKS" && orthoKappa_ > 0) {
789  paramsOrtho = Teuchos::rcp(new Teuchos::ParameterList());
790  paramsOrtho->set ("depTol", orthoKappa_ );
791  }
792 
793  ortho_ = factory.makeMatOrthoManager (orthoType_, Teuchos::null, printer_, label_, paramsOrtho);
794  }
795 
796  // Convergence
797 
798  // Check for convergence tolerance
799  if (params->isParameter ("Convergence Tolerance")) {
800  if (params->isType<MagnitudeType> ("Convergence Tolerance")) {
801  convtol_ = params->get ("Convergence Tolerance",
802  static_cast<MagnitudeType> (DefaultSolverParameters::convTol));
803  }
804  else {
805  convtol_ = params->get ("Convergence Tolerance", DefaultSolverParameters::convTol);
806  }
807 
808  // Update parameter in our list and residual tests.
809  params_->set ("Convergence Tolerance", convtol_);
810  if (! impConvTest_.is_null ()) {
811  impConvTest_->setTolerance (convtol_);
812  }
813  if (! expConvTest_.is_null ()) {
814  expConvTest_->setTolerance (convtol_);
815  }
816  }
817 
818  // Grab the user defined residual scaling
819  bool userDefinedResidualScalingUpdated = false;
820  if (params->isParameter ("User Defined Residual Scaling")) {
821  MagnitudeType tempResScaleFactor = DefaultSolverParameters::resScaleFactor;
822  if (params->isType<MagnitudeType> ("User Defined Residual Scaling")) {
823  tempResScaleFactor = params->get ("User Defined Residual Scaling",
824  static_cast<MagnitudeType> (DefaultSolverParameters::resScaleFactor));
825  }
826  else {
827  tempResScaleFactor = params->get ("User Defined Residual Scaling",
829  }
830 
831  // Only update the scaling if it's different.
832  if (resScaleFactor_ != tempResScaleFactor) {
833  resScaleFactor_ = tempResScaleFactor;
834  userDefinedResidualScalingUpdated = true;
835  }
836 
837  if(userDefinedResidualScalingUpdated)
838  {
839  if (! params->isParameter ("Implicit Residual Scaling") && ! impConvTest_.is_null ()) {
840  try {
841  if(impResScale_ == "User Provided")
842  impConvTest_->defineScaleForm (Belos::UserProvided, Belos::TwoNorm, resScaleFactor_);
843  }
844  catch (std::exception& e) {
845  // Make sure the convergence test gets constructed again.
846  isSTSet_ = false;
847  }
848  }
849  if (! params->isParameter ("Explicit Residual Scaling") && ! expConvTest_.is_null ()) {
850  try {
851  if(expResScale_ == "User Provided")
852  expConvTest_->defineScaleForm (Belos::UserProvided, Belos::TwoNorm, resScaleFactor_);
853  }
854  catch (std::exception& e) {
855  // Make sure the convergence test gets constructed again.
856  isSTSet_ = false;
857  }
858  }
859  }
860  }
861 
862  // Check for a change in scaling, if so we need to build new residual tests.
863  if (params->isParameter ("Implicit Residual Scaling")) {
864  const std::string tempImpResScale =
865  Teuchos::getParameter<std::string> (*params, "Implicit Residual Scaling");
866 
867  // Only update the scaling if it's different.
868  if (impResScale_ != tempImpResScale) {
869  Belos::ScaleType impResScaleType = convertStringToScaleType (tempImpResScale);
870  impResScale_ = tempImpResScale;
871 
872  // Update parameter in our list and residual tests
873  params_->set ("Implicit Residual Scaling", impResScale_);
874  if (! impConvTest_.is_null ()) {
875  try {
876  if(impResScale_ == "User Provided")
877  impConvTest_->defineScaleForm (impResScaleType, Belos::TwoNorm, resScaleFactor_);
878  else
879  impConvTest_->defineScaleForm (impResScaleType, Belos::TwoNorm);
880  }
881  catch (std::exception& e) {
882  // Make sure the convergence test gets constructed again.
883  isSTSet_ = false;
884  }
885  }
886  }
887  else if (userDefinedResidualScalingUpdated) {
888  Belos::ScaleType impResScaleType = convertStringToScaleType (impResScale_);
889 
890  if (! impConvTest_.is_null ()) {
891  try {
892  if(impResScale_ == "User Provided")
893  impConvTest_->defineScaleForm (impResScaleType, Belos::TwoNorm, resScaleFactor_);
894  }
895  catch (std::exception& e) {
896  // Make sure the convergence test gets constructed again.
897  isSTSet_ = false;
898  }
899  }
900  }
901  }
902 
903  if (params->isParameter ("Explicit Residual Scaling")) {
904  const std::string tempExpResScale =
905  Teuchos::getParameter<std::string> (*params, "Explicit Residual Scaling");
906 
907  // Only update the scaling if it's different.
908  if (expResScale_ != tempExpResScale) {
909  Belos::ScaleType expResScaleType = convertStringToScaleType (tempExpResScale);
910  expResScale_ = tempExpResScale;
911 
912  // Update parameter in our list and residual tests
913  params_->set ("Explicit Residual Scaling", expResScale_);
914  if (! expConvTest_.is_null ()) {
915  try {
916  if(expResScale_ == "User Provided")
917  expConvTest_->defineScaleForm (expResScaleType, Belos::TwoNorm, resScaleFactor_);
918  else
919  expConvTest_->defineScaleForm (expResScaleType, Belos::TwoNorm);
920  }
921  catch (std::exception& e) {
922  // Make sure the convergence test gets constructed again.
923  isSTSet_ = false;
924  }
925  }
926  }
927  else if (userDefinedResidualScalingUpdated) {
928  Belos::ScaleType expResScaleType = convertStringToScaleType (expResScale_);
929 
930  if (! expConvTest_.is_null ()) {
931  try {
932  if(expResScale_ == "User Provided")
933  expConvTest_->defineScaleForm (expResScaleType, Belos::TwoNorm, resScaleFactor_);
934  }
935  catch (std::exception& e) {
936  // Make sure the convergence test gets constructed again.
937  isSTSet_ = false;
938  }
939  }
940  }
941  }
942 
943 
944  if (params->isParameter ("Show Maximum Residual Norm Only")) {
945  showMaxResNormOnly_ =
946  Teuchos::getParameter<bool> (*params, "Show Maximum Residual Norm Only");
947 
948  // Update parameter in our list and residual tests
949  params_->set ("Show Maximum Residual Norm Only", showMaxResNormOnly_);
950  if (! impConvTest_.is_null ()) {
951  impConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
952  }
953  if (! expConvTest_.is_null ()) {
954  expConvTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
955  }
956  }
957 
958  // Create status tests if we need to.
959 
960  // Get the deflation quorum, or number of converged systems before deflation is allowed
961  if (params->isParameter("Deflation Quorum")) {
962  defQuorum_ = params->get("Deflation Quorum", defQuorum_);
964  defQuorum_ > blockSize_, std::invalid_argument,
965  "Belos::PseudoBlockGmresSolMgr::setParameters: "
966  "The \"Deflation Quorum\" parameter (= " << defQuorum_ << ") must not be "
967  "larger than \"Block Size\" (= " << blockSize_ << ").");
968  params_->set ("Deflation Quorum", defQuorum_);
969  if (! impConvTest_.is_null ()) {
970  impConvTest_->setQuorum (defQuorum_);
971  }
972  if (! expConvTest_.is_null ()) {
973  expConvTest_->setQuorum (defQuorum_);
974  }
975  }
976 
977  // Create the timer if we need to.
978  if (timerSolve_ == Teuchos::null) {
979  std::string solveLabel = label_ + ": PseudoBlockGmresSolMgr total solve time";
980 #ifdef BELOS_TEUCHOS_TIME_MONITOR
981  timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
982 #endif
983  }
984 
985  // Inform the solver manager that the current parameters were set.
986  isSet_ = true;
987 }
988 
989 
990 template<class ScalarType, class MV, class OP>
991 void
993  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &userConvStatusTest,
994  const typename StatusTestCombo<ScalarType,MV,OP>::ComboType &comboType
995  )
996 {
997  userConvStatusTest_ = userConvStatusTest;
998  comboType_ = comboType;
999 }
1000 
1001 template<class ScalarType, class MV, class OP>
1002 void
1004  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &debugStatusTest
1005  )
1006 {
1007  debugStatusTest_ = debugStatusTest;
1008 }
1009 
1010 
1011 
1012 template<class ScalarType, class MV, class OP>
1015 {
1017  if (is_null(validPL)) {
1018  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
1019  // Set all the valid parameters and their default values.
1020 
1021  // The static_cast is to resolve an issue with older clang versions which
1022  // would cause the constexpr to link fail. With c++17 the problem is resolved.
1023  pl= Teuchos::rcp( new Teuchos::ParameterList() );
1024  pl->set("Convergence Tolerance", static_cast<MagnitudeType>(DefaultSolverParameters::convTol),
1025  "The relative residual tolerance that needs to be achieved by the\n"
1026  "iterative solver in order for the linear system to be declared converged.");
1027  pl->set("Maximum Restarts", static_cast<int>(maxRestarts_default_),
1028  "The maximum number of restarts allowed for each\n"
1029  "set of RHS solved.");
1030  pl->set("Maximum Iterations", static_cast<int>(maxIters_default_),
1031  "The maximum number of block iterations allowed for each\n"
1032  "set of RHS solved.");
1033  pl->set("Num Blocks", static_cast<int>(numBlocks_default_),
1034  "The maximum number of vectors allowed in the Krylov subspace\n"
1035  "for each set of RHS solved.");
1036  pl->set("Block Size", static_cast<int>(blockSize_default_),
1037  "The number of RHS solved simultaneously.");
1038  pl->set("Verbosity", static_cast<int>(verbosity_default_),
1039  "What type(s) of solver information should be outputted\n"
1040  "to the output stream.");
1041  pl->set("Output Style", static_cast<int>(outputStyle_default_),
1042  "What style is used for the solver information outputted\n"
1043  "to the output stream.");
1044  pl->set("Output Frequency", static_cast<int>(outputFreq_default_),
1045  "How often convergence information should be outputted\n"
1046  "to the output stream.");
1047  pl->set("Deflation Quorum", static_cast<int>(defQuorum_default_),
1048  "The number of linear systems that need to converge before\n"
1049  "they are deflated. This number should be <= block size.");
1050  pl->set("Output Stream", Teuchos::rcpFromRef(std::cout),
1051  "A reference-counted pointer to the output stream where all\n"
1052  "solver output is sent.");
1053  pl->set("Show Maximum Residual Norm Only", static_cast<bool>(showMaxResNormOnly_default_),
1054  "When convergence information is printed, only show the maximum\n"
1055  "relative residual norm when the block size is greater than one.");
1056  pl->set("Implicit Residual Scaling", static_cast<const char *>(impResScale_default_),
1057  "The type of scaling used in the implicit residual convergence test.");
1058  pl->set("Explicit Residual Scaling", static_cast<const char *>(expResScale_default_),
1059  "The type of scaling used in the explicit residual convergence test.");
1060  pl->set("Timer Label", static_cast<const char *>(label_default_),
1061  "The string to use as a prefix for the timer labels.");
1062  pl->set("Orthogonalization", static_cast<const char *>(orthoType_default_),
1063  "The type of orthogonalization to use.");
1064  pl->set("Orthogonalization Constant",static_cast<MagnitudeType>(DefaultSolverParameters::orthoKappa),
1065  "The constant used by DGKS orthogonalization to determine\n"
1066  "whether another step of classical Gram-Schmidt is necessary.");
1067  pl->sublist("User Status Tests");
1068  pl->set("User Status Tests Combo Type", "SEQ",
1069  "Type of logical combination operation of user-defined\n"
1070  "and/or solver-specific status tests.");
1071  validPL = pl;
1072  }
1073  return validPL;
1074 }
1075 
1076 // Check the status test versus the defined linear problem
1077 template<class ScalarType, class MV, class OP>
1079 
1080  typedef Belos::StatusTestCombo<ScalarType,MV,OP> StatusTestCombo_t;
1081  typedef Belos::StatusTestGenResNorm<ScalarType,MV,OP> StatusTestGenResNorm_t;
1082  typedef Belos::StatusTestImpResNorm<ScalarType,MV,OP> StatusTestImpResNorm_t;
1083 
1084  // Basic test checks maximum iterations and native residual.
1085  maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>( maxIters_ ) );
1086 
1087  // If there is a left preconditioner, we create a combined status test that checks the implicit
1088  // and then explicit residual norm to see if we have convergence.
1089  if ( !Teuchos::is_null(problem_->getLeftPrec()) ) {
1090  expResTest_ = true;
1091  }
1092 
1093  if (expResTest_) {
1094 
1095  // Implicit residual test, using the native residual to determine if convergence was achieved.
1096  Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
1097  Teuchos::rcp( new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1098  if(impResScale_ == "User Provided")
1099  tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm, resScaleFactor_ );
1100  else
1101  tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm );
1102 
1103  tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1104  impConvTest_ = tmpImpConvTest;
1105 
1106  // Explicit residual test once the native residual is below the tolerance
1107  Teuchos::RCP<StatusTestGenResNorm_t> tmpExpConvTest =
1108  Teuchos::rcp( new StatusTestGenResNorm_t( convtol_, defQuorum_ ) );
1109  tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit, Belos::TwoNorm );
1110  if(expResScale_ == "User Provided")
1111  tmpExpConvTest->defineScaleForm( convertStringToScaleType(expResScale_), Belos::TwoNorm, resScaleFactor_ );
1112  else
1113  tmpExpConvTest->defineScaleForm( convertStringToScaleType(expResScale_), Belos::TwoNorm );
1114  tmpExpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1115  expConvTest_ = tmpExpConvTest;
1116 
1117  // The convergence test is a combination of the "cheap" implicit test and explicit test.
1118  convTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) );
1119  }
1120  else {
1121 
1122  // Implicit residual test, using the native residual to determine if convergence was achieved.
1123  // Use test that checks for loss of accuracy.
1124  Teuchos::RCP<StatusTestImpResNorm_t> tmpImpConvTest =
1125  Teuchos::rcp( new StatusTestImpResNorm_t( convtol_, defQuorum_ ) );
1126  if(impResScale_ == "User Provided")
1127  tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm, resScaleFactor_ );
1128  else
1129  tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm );
1130  tmpImpConvTest->setShowMaxResNormOnly( showMaxResNormOnly_ );
1131  impConvTest_ = tmpImpConvTest;
1132 
1133  // Set the explicit and total convergence test to this implicit test that checks for accuracy loss.
1134  expConvTest_ = impConvTest_;
1135  convTest_ = impConvTest_;
1136  }
1137 
1138  if (nonnull(userConvStatusTest_) ) {
1139  // Check if this is a combination of several StatusTestResNorm objects
1140  Teuchos::RCP<StatusTestCombo_t> tmpComboTest = Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(userConvStatusTest_);
1141  if (tmpComboTest != Teuchos::null) {
1142  std::vector<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > tmpVec = tmpComboTest->getStatusTests();
1143  comboType_ = tmpComboTest->getComboType();
1144  const int numResTests = static_cast<int>(tmpVec.size());
1145  auto newConvTest = Teuchos::rcp(new StatusTestCombo_t(comboType_));
1146  newConvTest->addStatusTest(convTest_);
1147  for (int j = 0; j < numResTests; ++j) {
1148  newConvTest->addStatusTest(tmpVec[j]);
1149  }
1150  convTest_ = newConvTest;
1151  }
1152  else{
1153  // Override the overall convergence test with the users convergence test
1154  convTest_ = Teuchos::rcp(
1155  new StatusTestCombo_t( comboType_, convTest_, userConvStatusTest_ ) );
1156  // brief output style not compatible with more general combinations
1157  //outputStyle_ = Belos::General;
1158  // NOTE: Above, you have to run the other convergence tests also because
1159  // the logic in this class depends on it. This is very unfortunate.
1160  }
1161  }
1162 
1163  sTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
1164 
1165  // Add debug status test, if one is provided by the user
1166  if (nonnull(debugStatusTest_) ) {
1167  // Add debug convergence test
1168  Teuchos::rcp_dynamic_cast<StatusTestCombo_t>(sTest_)->addStatusTest( debugStatusTest_ );
1169  }
1170 
1171  // Create the status test output class.
1172  // This class manages and formats the output from the status test.
1173  StatusTestOutputFactory<ScalarType,MV,OP> stoFactory( outputStyle_, taggedTests_ );
1174  outputTest_ = stoFactory.create( printer_, sTest_, outputFreq_, Passed+Failed+Undefined );
1175 
1176  // Set the solver string for the output test
1177  std::string solverDesc = " Pseudo Block Gmres ";
1178  outputTest_->setSolverDesc( solverDesc );
1179 
1180 
1181  // The status test is now set.
1182  isSTSet_ = true;
1183 
1184  return false;
1185 }
1186 
1187 
1188 // solve()
1189 template<class ScalarType, class MV, class OP>
1191 
1192  // Set the current parameters if they were not set before.
1193  // NOTE: This may occur if the user generated the solver manager with the default constructor and
1194  // then didn't set any parameters using setParameters().
1195  if (!isSet_) { setParameters( params_ ); }
1196 
1198  "Belos::PseudoBlockGmresSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1199 
1200  // Check if we have to create the status tests.
1201  if (!isSTSet_ || (!expResTest_ && !Teuchos::is_null(problem_->getLeftPrec())) ) {
1203  "Belos::BlockGmresSolMgr::solve(): Linear problem and requested status tests are incompatible.");
1204  }
1205 
1206  // Create indices for the linear systems to be solved.
1207  int startPtr = 0;
1208  int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
1209  int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1210 
1211  std::vector<int> currIdx( numCurrRHS );
1212  blockSize_ = numCurrRHS;
1213  for (int i=0; i<numCurrRHS; ++i)
1214  { currIdx[i] = startPtr+i; }
1215 
1216  // Inform the linear problem of the current linear system to solve.
1217  problem_->setLSIndex( currIdx );
1218 
1220  // Parameter list
1221  Teuchos::ParameterList plist;
1222  plist.set("Num Blocks",numBlocks_);
1223 
1224  // Reset the status test.
1225  outputTest_->reset();
1226  loaDetected_ = false;
1227 
1228  // Assume convergence is achieved, then let any failed convergence set this to false.
1229  bool isConverged = true;
1230 
1232  // BlockGmres solver
1233 
1235  = Teuchos::rcp( new PseudoBlockGmresIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,ortho_,plist) );
1236 
1237  // Enter solve() iterations
1238  {
1239 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1240  Teuchos::TimeMonitor slvtimer(*timerSolve_);
1241 #endif
1242 
1243  while ( numRHS2Solve > 0 ) {
1244 
1245  // Reset the active / converged vectors from this block
1246  std::vector<int> convRHSIdx;
1247  std::vector<int> currRHSIdx( currIdx );
1248  currRHSIdx.resize(numCurrRHS);
1249 
1250  // Set the current number of blocks with the pseudo Gmres iteration.
1251  block_gmres_iter->setNumBlocks( numBlocks_ );
1252 
1253  // Reset the number of iterations.
1254  block_gmres_iter->resetNumIters();
1255 
1256  // Reset the number of calls that the status test output knows about.
1257  outputTest_->resetNumCalls();
1258 
1259  // Get a new state struct and initialize the solver.
1261 
1262  // Create the first block in the current Krylov basis for each right-hand side.
1263  std::vector<int> index(1);
1264  Teuchos::RCP<MV> tmpV, R_0 = MVT::CloneCopy( *(problem_->getInitPrecResVec()), currIdx );
1265  newState.V.resize( blockSize_ );
1266  newState.Z.resize( blockSize_ );
1267  for (int i=0; i<blockSize_; ++i) {
1268  index[0]=i;
1269  tmpV = MVT::CloneViewNonConst( *R_0, index );
1270 
1271  // Get a matrix to hold the orthonormalization coefficients.
1274 
1275  // Orthonormalize the new V_0
1276  int rank = ortho_->normalize( *tmpV, tmpZ );
1278  "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors.");
1279 
1280  newState.V[i] = tmpV;
1281  newState.Z[i] = tmpZ;
1282  }
1283 
1284  newState.curDim = 0;
1285  block_gmres_iter->initialize(newState);
1286  int numRestarts = 0;
1287 
1288  while(1) {
1289 
1290  // tell block_gmres_iter to iterate
1291  try {
1292  block_gmres_iter->iterate();
1293 
1295  //
1296  // check convergence first
1297  //
1299  if ( convTest_->getStatus() == Passed ) {
1300 
1301  if ( expConvTest_->getLOADetected() ) {
1302  // Oops! There was a loss of accuracy (LOA) for one or
1303  // more right-hand sides. That means the implicit
1304  // (a.k.a. "native") residuals claim convergence,
1305  // whereas the explicit (hence expConvTest_, i.e.,
1306  // "explicit convergence test") residuals have not
1307  // converged.
1308  //
1309  // We choose to deal with this situation by deflating
1310  // out the affected right-hand sides and moving on.
1311  loaDetected_ = true;
1312  printer_->stream(Warnings) <<
1313  "Belos::PseudoBlockGmresSolMgr::solve(): Warning! Solver has experienced a loss of accuracy!" << std::endl;
1314  isConverged = false;
1315  }
1316 
1317  // Figure out which linear systems converged.
1318  std::vector<int> convIdx = expConvTest_->convIndices();
1319 
1320  // If the number of converged linear systems is equal to the
1321  // number of current linear systems, then we are done with this block.
1322  if (convIdx.size() == currRHSIdx.size())
1323  break; // break from while(1){block_gmres_iter->iterate()}
1324 
1325  // Get a new state struct and initialize the solver.
1327 
1328  // Inform the linear problem that we are finished with this current linear system.
1329  problem_->setCurrLS();
1330 
1331  // Get the state.
1332  PseudoBlockGmresIterState<ScalarType,MV> oldState = block_gmres_iter->getState();
1333  int curDim = oldState.curDim;
1334 
1335  // Get a new state struct and reset currRHSIdx to have the right-hand sides that
1336  // are left to converge for this block.
1337  int have = 0;
1338  std::vector<int> oldRHSIdx( currRHSIdx );
1339  std::vector<int> defRHSIdx;
1340  for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
1341  bool found = false;
1342  for (unsigned int j=0; j<convIdx.size(); ++j) {
1343  if (currRHSIdx[i] == convIdx[j]) {
1344  found = true;
1345  break;
1346  }
1347  }
1348  if (found) {
1349  defRHSIdx.push_back( i );
1350  }
1351  else {
1352  defState.V.push_back( Teuchos::rcp_const_cast<MV>( oldState.V[i] ) );
1353  defState.Z.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,ScalarType> >( oldState.Z[i] ) );
1354  defState.H.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseMatrix<int,ScalarType> >( oldState.H[i] ) );
1355  defState.sn.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,ScalarType> >( oldState.sn[i] ) );
1356  defState.cs.push_back( Teuchos::rcp_const_cast<Teuchos::SerialDenseVector<int,MagnitudeType> >(oldState.cs[i] ) );
1357  currRHSIdx[have] = currRHSIdx[i];
1358  have++;
1359  }
1360  }
1361  defRHSIdx.resize(currRHSIdx.size()-have);
1362  currRHSIdx.resize(have);
1363 
1364  // Compute the current solution that needs to be deflated if this solver has taken any steps.
1365  if (curDim) {
1366  Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1367  Teuchos::RCP<MV> defUpdate = MVT::CloneViewNonConst( *update, defRHSIdx );
1368 
1369  // Set the deflated indices so we can update the solution.
1370  problem_->setLSIndex( convIdx );
1371 
1372  // Update the linear problem.
1373  problem_->updateSolution( defUpdate, true );
1374  }
1375 
1376  // Set the remaining indices after deflation.
1377  problem_->setLSIndex( currRHSIdx );
1378 
1379  // Set the dimension of the subspace, which is the same as the old subspace size.
1380  defState.curDim = curDim;
1381 
1382  // Initialize the solver with the deflated system.
1383  block_gmres_iter->initialize(defState);
1384  }
1386  //
1387  // check for maximum iterations
1388  //
1390  else if ( maxIterTest_->getStatus() == Passed ) {
1391  // we don't have convergence
1392  isConverged = false;
1393  break; // break from while(1){block_gmres_iter->iterate()}
1394  }
1396  //
1397  // check for restarting, i.e. the subspace is full
1398  //
1400  else if ( block_gmres_iter->getCurSubspaceDim() == block_gmres_iter->getMaxSubspaceDim() ) {
1401 
1402  if ( numRestarts >= maxRestarts_ ) {
1403  isConverged = false;
1404  break; // break from while(1){block_gmres_iter->iterate()}
1405  }
1406  numRestarts++;
1407 
1408  printer_->stream(Debug) << " Performing restart number " << numRestarts << " of " << maxRestarts_ << std::endl << std::endl;
1409 
1410  // Update the linear problem.
1411  Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1412  problem_->updateSolution( update, true );
1413 
1414  // Get the state.
1415  PseudoBlockGmresIterState<ScalarType,MV> oldState = block_gmres_iter->getState();
1416 
1417  // Set the new state.
1419  newstate.V.resize(currRHSIdx.size());
1420  newstate.Z.resize(currRHSIdx.size());
1421 
1422  // Compute the restart vectors
1423  // NOTE: Force the linear problem to update the current residual since the solution was updated.
1424  R_0 = MVT::Clone( *(problem_->getInitPrecResVec()), currRHSIdx.size() );
1425  problem_->computeCurrPrecResVec( &*R_0 );
1426  for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
1427  index[0] = i; // index(1) vector declared on line 891
1428 
1429  tmpV = MVT::CloneViewNonConst( *R_0, index );
1430 
1431  // Get a matrix to hold the orthonormalization coefficients.
1434 
1435  // Orthonormalize the new V_0
1436  int rank = ortho_->normalize( *tmpV, tmpZ );
1438  "Belos::PseudoBlockGmresSolMgr::solve(): Failed to compute initial block of orthonormal vectors after the restart.");
1439 
1440  newstate.V[i] = tmpV;
1441  newstate.Z[i] = tmpZ;
1442  }
1443 
1444  // Initialize the solver.
1445  newstate.curDim = 0;
1446  block_gmres_iter->initialize(newstate);
1447 
1448  } // end of restarting
1449 
1451  //
1452  // we returned from iterate(), but none of our status tests Passed.
1453  // something is wrong, and it is probably our fault.
1454  //
1456 
1457  else {
1458  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
1459  "Belos::PseudoBlockGmresSolMgr::solve(): Invalid return from PseudoBlockGmresIter::iterate().");
1460  }
1461  }
1462  catch (const PseudoBlockGmresIterOrthoFailure &e) {
1463 
1464  // Try to recover the most recent least-squares solution
1465  block_gmres_iter->updateLSQR( block_gmres_iter->getCurSubspaceDim() );
1466 
1467  // Check to see if the most recent least-squares solution yielded convergence.
1468  sTest_->checkStatus( &*block_gmres_iter );
1469  if (convTest_->getStatus() != Passed)
1470  isConverged = false;
1471  break;
1472  }
1473  catch (const StatusTestNaNError& e) {
1474  // A NaN was detected in the solver. Set the solution to zero and return unconverged.
1475  achievedTol_ = MT::one();
1476  Teuchos::RCP<MV> X = problem_->getLHS();
1477  MVT::MvInit( *X, SCT::zero() );
1478  printer_->stream(Warnings) << "Belos::PseudoBlockGmresSolMgr::solve(): Warning! NaN has been detected!"
1479  << std::endl;
1480  return Unconverged;
1481  }
1482  catch (const std::exception &e) {
1483  printer_->stream(Errors) << "Error! Caught std::exception in PseudoBlockGmresIter::iterate() at iteration "
1484  << block_gmres_iter->getNumIters() << std::endl
1485  << e.what() << std::endl;
1486  throw;
1487  }
1488  }
1489 
1490  // Compute the current solution.
1491  // Update the linear problem.
1492  if (nonnull(userConvStatusTest_)) {
1493  //std::cout << "\nnonnull(userConvStatusTest_)\n";
1494  Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1495  problem_->updateSolution( update, true );
1496  }
1497  else if (nonnull(expConvTest_->getSolution())) {
1498  //std::cout << "\nexpConvTest_->getSolution()\n";
1499  Teuchos::RCP<MV> newX = expConvTest_->getSolution();
1500  Teuchos::RCP<MV> curX = problem_->getCurrLHSVec();
1501  MVT::MvAddMv( 0.0, *newX, 1.0, *newX, *curX );
1502  }
1503  else {
1504  //std::cout << "\nblock_gmres_iter->getCurrentUpdate()\n";
1505  Teuchos::RCP<MV> update = block_gmres_iter->getCurrentUpdate();
1506  problem_->updateSolution( update, true );
1507  }
1508 
1509  // Inform the linear problem that we are finished with this block linear system.
1510  problem_->setCurrLS();
1511 
1512  // Update indices for the linear systems to be solved.
1513  startPtr += numCurrRHS;
1514  numRHS2Solve -= numCurrRHS;
1515  if ( numRHS2Solve > 0 ) {
1516  numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
1517 
1518  blockSize_ = numCurrRHS;
1519  currIdx.resize( numCurrRHS );
1520  for (int i=0; i<numCurrRHS; ++i)
1521  { currIdx[i] = startPtr+i; }
1522 
1523  // Adapt the status test quorum if we need to.
1524  if (defQuorum_ > blockSize_) {
1525  if (impConvTest_ != Teuchos::null)
1526  impConvTest_->setQuorum( blockSize_ );
1527  if (expConvTest_ != Teuchos::null)
1528  expConvTest_->setQuorum( blockSize_ );
1529  }
1530 
1531  // Set the next indices.
1532  problem_->setLSIndex( currIdx );
1533  }
1534  else {
1535  currIdx.resize( numRHS2Solve );
1536  }
1537 
1538  }// while ( numRHS2Solve > 0 )
1539 
1540  }
1541 
1542  // print final summary
1543  sTest_->print( printer_->stream(FinalSummary) );
1544 
1545  // print timing information
1546 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1547  // Calling summarize() can be expensive, so don't call unless the
1548  // user wants to print out timing details. summarize() will do all
1549  // the work even if it's passed a "black hole" output stream.
1550  if (verbosity_ & TimingDetails)
1551  Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
1552 #endif
1553 
1554  // get iteration information for this solve
1555  numIters_ = maxIterTest_->getNumIters();
1556 
1557  // Save the convergence test value ("achieved tolerance") for this
1558  // solve. For this solver, convTest_ may either be a single
1559  // residual norm test, or a combination of two residual norm tests.
1560  // In the latter case, the master convergence test convTest_ is a
1561  // SEQ combo of the implicit resp. explicit tests. If the implicit
1562  // test never passes, then the explicit test won't ever be executed.
1563  // This manifests as expConvTest_->getTestValue()->size() < 1. We
1564  // deal with this case by using the values returned by
1565  // impConvTest_->getTestValue().
1566  {
1567  // We'll fetch the vector of residual norms one way or the other.
1568  const std::vector<MagnitudeType>* pTestValues = NULL;
1569  if (expResTest_) {
1570  pTestValues = expConvTest_->getTestValue();
1571  if (pTestValues == NULL || pTestValues->size() < 1) {
1572  pTestValues = impConvTest_->getTestValue();
1573  }
1574  }
1575  else {
1576  // Only the implicit residual norm test is being used.
1577  pTestValues = impConvTest_->getTestValue();
1578  }
1579  TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1580  "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1581  "getTestValue() method returned NULL. Please report this bug to the "
1582  "Belos developers.");
1583  TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1584  "Belos::PseudoBlockGmresSolMgr::solve(): The implicit convergence test's "
1585  "getTestValue() method returned a vector of length zero. Please report "
1586  "this bug to the Belos developers.");
1587 
1588  // FIXME (mfh 12 Dec 2011) Does pTestValues really contain the
1589  // achieved tolerances for all vectors in the current solve(), or
1590  // just for the vectors from the last deflation?
1591  achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1592  }
1593 
1594  if (!isConverged || loaDetected_) {
1595  return Unconverged; // return from PseudoBlockGmresSolMgr::solve()
1596  }
1597  return Converged; // return from PseudoBlockGmresSolMgr::solve()
1598 }
1599 
1600 
1601 template<class ScalarType, class MV, class OP>
1603 {
1604  std::ostringstream out;
1605 
1606  out << "\"Belos::PseudoBlockGmresSolMgr\": {";
1607  if (this->getObjectLabel () != "") {
1608  out << "Label: " << this->getObjectLabel () << ", ";
1609  }
1610  out << "Num Blocks: " << numBlocks_
1611  << ", Maximum Iterations: " << maxIters_
1612  << ", Maximum Restarts: " << maxRestarts_
1613  << ", Convergence Tolerance: " << convtol_
1614  << "}";
1615  return out.str ();
1616 }
1617 
1618 
1619 template<class ScalarType, class MV, class OP>
1620 void
1623  const Teuchos::EVerbosityLevel verbLevel) const
1624 {
1626  using Teuchos::VERB_DEFAULT;
1627  using Teuchos::VERB_NONE;
1628  using Teuchos::VERB_LOW;
1629  // using Teuchos::VERB_MEDIUM;
1630  // using Teuchos::VERB_HIGH;
1631  // using Teuchos::VERB_EXTREME;
1632  using std::endl;
1633 
1634  // Set default verbosity if applicable.
1635  const Teuchos::EVerbosityLevel vl =
1636  (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
1637 
1638  if (vl != VERB_NONE) {
1639  Teuchos::OSTab tab0 (out);
1640 
1641  out << "\"Belos::PseudoBlockGmresSolMgr\":" << endl;
1642  Teuchos::OSTab tab1 (out);
1643  out << "Template parameters:" << endl;
1644  {
1645  Teuchos::OSTab tab2 (out);
1646  out << "ScalarType: " << TypeNameTraits<ScalarType>::name () << endl
1647  << "MV: " << TypeNameTraits<MV>::name () << endl
1648  << "OP: " << TypeNameTraits<OP>::name () << endl;
1649  }
1650  if (this->getObjectLabel () != "") {
1651  out << "Label: " << this->getObjectLabel () << endl;
1652  }
1653  out << "Num Blocks: " << numBlocks_ << endl
1654  << "Maximum Iterations: " << maxIters_ << endl
1655  << "Maximum Restarts: " << maxRestarts_ << endl
1656  << "Convergence Tolerance: " << convtol_ << endl;
1657  }
1658 }
1659 
1660 } // end Belos namespace
1661 
1662 #endif /* BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP */
static const double orthoKappa
DGKS orthogonalization constant.
Definition: BelosTypes.hpp:299
ScaleType convertStringToScaleType(const std::string &scaleType)
Convert the given string to its ScaleType enum value.
Definition: BelosTypes.cpp:106
std::vector< Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > > H
The current Hessenberg matrix.
Collection of types and exceptions used within the Belos solvers.
ComboType
The test can be either the AND of all the component tests, or the OR of all the component tests...
Belos&#39;s basic output manager for sending information of select verbosity levels to the appropriate ou...
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > &params) override
Set the parameters the solver manager should use to solve the linear problem.
Class which manages the output and verbosity of the Belos solvers.
bool is_null(const boost::shared_ptr< T > &p)
ScaleType
The type of scaling to use on the residual norm value.
Definition: BelosTypes.hpp:120
Convergence test using the implicit residual norm(s), with an explicit residual norm(s) check for los...
T & get(const std::string &name, T def_value)
PseudoBlockGmresSolMgrOrthoFailure(const std::string &what_arg)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
static RCP< Time > getNewCounter(const std::string &name)
bool is_null(const std::shared_ptr< T > &p)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
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...
An abstract class of StatusTest for stopping criteria using residual norms.
std::vector< Teuchos::RCP< const MV > > V
The current Krylov basis.
An implementation of StatusTestResNorm using a family of residual norms.
Ordinal numParams() const
static const double convTol
Default convergence tolerance.
Definition: BelosTypes.hpp:293
A pure virtual class for defining the status tests for the Belos iterative solvers.
Structure to contain pointers to PseudoBlockGmresIter state variables.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
A factory class for generating StatusTestOutput objects.
Traits class which defines basic operations on multivectors.
bool isParameter(const std::string &name) const
A Belos::StatusTest class for specifying a maximum number of iterations.
ResetType
How to reset the solver.
Definition: BelosTypes.hpp:206
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Pure virtual base class which describes the basic interface for a solver manager. ...
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.
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
bool isSublist(const std::string &name) const
PseudoBlockGmresSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i...
std::vector< Teuchos::RCP< const Teuchos::SerialDenseVector< int, MagnitudeType > > > cs
A linear system to solve, and its associated information.
Class which describes the linear problem to be solved by the iterative solver.
void reset(const ResetType type) override
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
Interface to standard and &quot;pseudoblock&quot; GMRES.
int getNumIters() const override
Iteration count for the most recent call to solve().
ReturnType
Whether the Belos solve converged for all linear systems.
Definition: BelosTypes.hpp:155
The Belos::SolverManager is a templated virtual base class that defines the basic interface that any ...
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
A list of valid default parameters for this solver.
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
static const EVerbosityLevel verbLevel_default
bool isLOADetected() const override
Whether a &quot;loss of accuracy&quot; was detected during the last solve().
bool nonnull(const boost::shared_ptr< T > &p)
std::vector< Teuchos::RCP< const Teuchos::SerialDenseVector< int, ScalarType > > > Z
The current right-hand side of the least squares system RY = Z.
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) override
Set the linear problem to solve.
Belos concrete class for performing the pseudo-block GMRES iteration.
bool isType(const std::string &name) const
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
An implementation of the Belos::MatOrthoManager that performs orthogonalization using (potentially) m...
A class for extending the status testing capabilities of Belos via logical combinations.
std::string description() const override
Return a one-line description of this object.
const StatusTestResNorm< ScalarType, MV, OP > * getResidualStatusTest() const
Return the residual status test.
Class which defines basic traits for the operator type.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
int curDim
The current dimension of the reduction.
Parent class to all Belos exceptions.
Definition: BelosTypes.hpp:60
ReturnType solve() override
This method performs possibly repeated calls to the underlying linear solver&#39;s iterate() routine unti...
Default parameters common to most Belos solvers.
Definition: BelosTypes.hpp:283
std::vector< Teuchos::RCP< const Teuchos::SerialDenseVector< int, ScalarType > > > sn
The current Given&#39;s rotation coefficients.
static const double resScaleFactor
User-defined residual scaling factor.
Definition: BelosTypes.hpp:302
Belos header file which uses auto-configuration information to include necessary C++ headers...
This class implements the pseudo-block GMRES iteration, where a block Krylov subspace is constructed ...
Factory to build a set of status tests from a parameter list.
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
The current parameters for this solver.
PseudoBlockGmresIterOrthoFailure is thrown when the orthogonalization manager is unable to generate o...
const LinearProblem< ScalarType, MV, OP > & getProblem() const override
Return a reference to the linear problem being solved by this solver manager.
PseudoBlockGmresSolMgrOrthoFailure is thrown when the orthogonalization manager is unable to generate...
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.
Teuchos::RCP< Belos::MatOrthoManager< Scalar, MV, OP > > makeMatOrthoManager(const std::string &ortho, const Teuchos::RCP< const OP > &M, const Teuchos::RCP< OutputManager< Scalar > > &, const std::string &label, const Teuchos::RCP< Teuchos::ParameterList > &params)
Return an instance of the specified MatOrthoManager subclass.

Generated on Fri May 17 2024 09:25:12 for Belos by doxygen 1.8.5