Belos  Version of the Day
BelosBlockCGSolMgr.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_BLOCK_CG_SOLMGR_HPP
43 #define BELOS_BLOCK_CG_SOLMGR_HPP
44 
49 #include "BelosConfigDefs.hpp"
50 #include "BelosTypes.hpp"
51 
52 #include "BelosLinearProblem.hpp"
53 #include "BelosSolverManager.hpp"
54 
55 #include "BelosCGIter.hpp"
56 #include "BelosBlockCGIter.hpp"
62 #include "BelosStatusTestCombo.hpp"
64 #include "BelosOutputManager.hpp"
65 #include "Teuchos_BLAS.hpp"
66 #include "Teuchos_LAPACK.hpp"
67 #ifdef BELOS_TEUCHOS_TIME_MONITOR
68 # include "Teuchos_TimeMonitor.hpp"
69 #endif
70 #if defined(HAVE_TEUCHOSCORE_CXX11)
71 # include <type_traits>
72 #endif // defined(HAVE_TEUCHOSCORE_CXX11)
73 #include <algorithm>
74 
91 namespace Belos {
92 
94 
95 
103  BlockCGSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
104  {}};
105 
112  class BlockCGSolMgrOrthoFailure : public BelosError {public:
113  BlockCGSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg)
114  {}};
115 
116 
117  template<class ScalarType, class MV, class OP,
118  const bool lapackSupportsScalarType =
121  public Details::SolverManagerRequiresLapack<ScalarType,MV,OP>
122  {
123  static const bool requiresLapack =
125  typedef Details::SolverManagerRequiresLapack<ScalarType, MV, OP,
126  requiresLapack> base_type;
127 
128  public:
130  base_type ()
131  {}
132  BlockCGSolMgr (const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> >& problem,
133  const Teuchos::RCP<Teuchos::ParameterList>& pl) :
134  base_type ()
135  {}
136  virtual ~BlockCGSolMgr () {}
137  };
138 
139 
140  // Partial specialization for ScalarType types for which
141  // Teuchos::LAPACK has a valid implementation. This contains the
142  // actual working implementation of BlockCGSolMgr.
143  template<class ScalarType, class MV, class OP>
144  class BlockCGSolMgr<ScalarType, MV, OP, true> :
145  public Details::SolverManagerRequiresLapack<ScalarType, MV, OP, true>
146  {
147 #if defined(HAVE_TEUCHOSCORE_CXX11)
148 # if defined(HAVE_TEUCHOS_COMPLEX)
149  static_assert (std::is_same<ScalarType, std::complex<float> >::value ||
150  std::is_same<ScalarType, std::complex<double> >::value ||
151  std::is_same<ScalarType, float>::value ||
152  std::is_same<ScalarType, double>::value,
153  "Belos::GCRODRSolMgr: ScalarType must be one of the four "
154  "types (S,D,C,Z) supported by LAPACK.");
155 # else
156  static_assert (std::is_same<ScalarType, float>::value ||
157  std::is_same<ScalarType, double>::value,
158  "Belos::GCRODRSolMgr: ScalarType must be float or double. "
159  "Complex arithmetic support is currently disabled. To "
160  "enable it, set Teuchos_ENABLE_COMPLEX=ON.");
161 # endif // defined(HAVE_TEUCHOS_COMPLEX)
162 #endif // defined(HAVE_TEUCHOSCORE_CXX11)
163 
164  private:
167  typedef Teuchos::ScalarTraits<ScalarType> SCT;
168  typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
169  typedef Teuchos::ScalarTraits<MagnitudeType> MT;
170 
171  public:
172 
174 
175 
181  BlockCGSolMgr();
182 
211  BlockCGSolMgr( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
212  const Teuchos::RCP<Teuchos::ParameterList> &pl );
213 
215  virtual ~BlockCGSolMgr() {};
217 
219 
220 
222  return *problem_;
223  }
224 
227  Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
228 
231  Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const { return params_; }
232 
238  Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
239  return Teuchos::tuple(timerSolve_);
240  }
241 
247  MagnitudeType achievedTol() const {
248  return achievedTol_;
249  }
250 
252  int getNumIters() const {
253  return numIters_;
254  }
255 
258  bool isLOADetected() const { return false; }
259 
261 
263 
264 
266  void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) { problem_ = problem; }
267 
269  void setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params );
270 
272 
274 
275 
279  void reset( const ResetType type ) { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
281 
283 
284 
302  ReturnType solve();
303 
305 
308 
310  std::string description() const;
311 
313 
314  private:
315 
317  Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
318 
320  Teuchos::RCP<OutputManager<ScalarType> > printer_;
322  Teuchos::RCP<std::ostream> outputStream_;
323 
328  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
329 
331  Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
332 
334  Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
335 
337  Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
338 
340  Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
341 
343  Teuchos::RCP<Teuchos::ParameterList> params_;
344 
345  //
346  // Default solver parameters.
347  //
348  static const MagnitudeType convtol_default_;
349  static const MagnitudeType orthoKappa_default_;
350  static const int maxIters_default_;
351  static const bool adaptiveBlockSize_default_;
352  static const bool showMaxResNormOnly_default_;
353  static const int blockSize_default_;
354  static const int verbosity_default_;
355  static const int outputStyle_default_;
356  static const int outputFreq_default_;
357  static const std::string label_default_;
358  static const std::string orthoType_default_;
359  static const Teuchos::RCP<std::ostream> outputStream_default_;
360 
361  //
362  // Current solver parameters and other values.
363  //
364 
366  MagnitudeType convtol_;
367 
369  MagnitudeType orthoKappa_;
370 
376  MagnitudeType achievedTol_;
377 
379  int maxIters_;
380 
382  int numIters_;
383 
384  int blockSize_, verbosity_, outputStyle_, outputFreq_;
385  bool adaptiveBlockSize_, showMaxResNormOnly_;
386  std::string orthoType_;
387 
389  std::string label_;
390 
392  Teuchos::RCP<Teuchos::Time> timerSolve_;
393 
395  bool isSet_;
396  };
397 
398 
399 // Default solver values.
400 template<class ScalarType, class MV, class OP>
402 
403 template<class ScalarType, class MV, class OP>
405 
406 template<class ScalarType, class MV, class OP>
408 
409 template<class ScalarType, class MV, class OP>
411 
412 template<class ScalarType, class MV, class OP>
414 
415 template<class ScalarType, class MV, class OP>
417 
418 template<class ScalarType, class MV, class OP>
420 
421 template<class ScalarType, class MV, class OP>
423 
424 template<class ScalarType, class MV, class OP>
426 
427 template<class ScalarType, class MV, class OP>
428 const std::string BlockCGSolMgr<ScalarType,MV,OP,true>::label_default_ = "Belos";
429 
430 template<class ScalarType, class MV, class OP>
432 
433 template<class ScalarType, class MV, class OP>
434 const Teuchos::RCP<std::ostream> BlockCGSolMgr<ScalarType,MV,OP,true>::outputStream_default_ = Teuchos::rcp(&std::cout,false);
435 
436 
437 // Empty Constructor
438 template<class ScalarType, class MV, class OP>
440  outputStream_(outputStream_default_),
441  convtol_(convtol_default_),
442  orthoKappa_(orthoKappa_default_),
443  achievedTol_(Teuchos::ScalarTraits<MagnitudeType>::zero()),
444  maxIters_(maxIters_default_),
445  numIters_(0),
446  blockSize_(blockSize_default_),
447  verbosity_(verbosity_default_),
448  outputStyle_(outputStyle_default_),
449  outputFreq_(outputFreq_default_),
450  adaptiveBlockSize_(adaptiveBlockSize_default_),
451  showMaxResNormOnly_(showMaxResNormOnly_default_),
452  orthoType_(orthoType_default_),
453  label_(label_default_),
454  isSet_(false)
455 {}
456 
457 
458 // Basic Constructor
459 template<class ScalarType, class MV, class OP>
461 BlockCGSolMgr(const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
462  const Teuchos::RCP<Teuchos::ParameterList> &pl) :
463  problem_(problem),
464  outputStream_(outputStream_default_),
465  convtol_(convtol_default_),
466  orthoKappa_(orthoKappa_default_),
467  achievedTol_(Teuchos::ScalarTraits<MagnitudeType>::zero()),
468  maxIters_(maxIters_default_),
469  numIters_(0),
470  blockSize_(blockSize_default_),
471  verbosity_(verbosity_default_),
472  outputStyle_(outputStyle_default_),
473  outputFreq_(outputFreq_default_),
474  adaptiveBlockSize_(adaptiveBlockSize_default_),
475  showMaxResNormOnly_(showMaxResNormOnly_default_),
476  orthoType_(orthoType_default_),
477  label_(label_default_),
478  isSet_(false)
479 {
480  TEUCHOS_TEST_FOR_EXCEPTION(problem_.is_null(), std::invalid_argument,
481  "BlockCGSolMgr's constructor requires a nonnull LinearProblem instance.");
482 
483  // If the user passed in a nonnull parameter list, set parameters.
484  // Otherwise, the next solve() call will use default parameters,
485  // unless the user calls setParameters() first.
486  if (! pl.is_null()) {
487  setParameters (pl);
488  }
489 }
490 
491 template<class ScalarType, class MV, class OP>
492 void
494 setParameters (const Teuchos::RCP<Teuchos::ParameterList> &params)
495 {
496  // Create the internal parameter list if one doesn't already exist.
497  if (params_ == Teuchos::null) {
498  params_ = Teuchos::rcp( new Teuchos::ParameterList(*getValidParameters()) );
499  }
500  else {
501  params->validateParameters(*getValidParameters());
502  }
503 
504  // Check for maximum number of iterations
505  if (params->isParameter("Maximum Iterations")) {
506  maxIters_ = params->get("Maximum Iterations",maxIters_default_);
507 
508  // Update parameter in our list and in status test.
509  params_->set("Maximum Iterations", maxIters_);
510  if (maxIterTest_!=Teuchos::null)
511  maxIterTest_->setMaxIters( maxIters_ );
512  }
513 
514  // Check for blocksize
515  if (params->isParameter("Block Size")) {
516  blockSize_ = params->get("Block Size",blockSize_default_);
517  TEUCHOS_TEST_FOR_EXCEPTION(blockSize_ <= 0, std::invalid_argument,
518  "Belos::BlockCGSolMgr: \"Block Size\" must be strictly positive.");
519 
520  // Update parameter in our list.
521  params_->set("Block Size", blockSize_);
522  }
523 
524  // Check if the blocksize should be adaptive
525  if (params->isParameter("Adaptive Block Size")) {
526  adaptiveBlockSize_ = params->get("Adaptive Block Size",adaptiveBlockSize_default_);
527 
528  // Update parameter in our list.
529  params_->set("Adaptive Block Size", adaptiveBlockSize_);
530  }
531 
532  // Check to see if the timer label changed.
533  if (params->isParameter("Timer Label")) {
534  std::string tempLabel = params->get("Timer Label", label_default_);
535 
536  // Update parameter in our list and solver timer
537  if (tempLabel != label_) {
538  label_ = tempLabel;
539  params_->set("Timer Label", label_);
540  std::string solveLabel = label_ + ": BlockCGSolMgr total solve time";
541 #ifdef BELOS_TEUCHOS_TIME_MONITOR
542  timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
543 #endif
544  if (ortho_ != Teuchos::null) {
545  ortho_->setLabel( label_ );
546  }
547  }
548  }
549 
550  // Check if the orthogonalization changed.
551  if (params->isParameter("Orthogonalization")) {
552  std::string tempOrthoType = params->get("Orthogonalization",orthoType_default_);
553  TEUCHOS_TEST_FOR_EXCEPTION( tempOrthoType != "DGKS" && tempOrthoType != "ICGS" && tempOrthoType != "IMGS",
554  std::invalid_argument,
555  "Belos::BlockCGSolMgr: \"Orthogonalization\" must be either \"DGKS\", \"ICGS\", or \"IMGS\".");
556  if (tempOrthoType != orthoType_) {
557  orthoType_ = tempOrthoType;
558  // Create orthogonalization manager
559  if (orthoType_=="DGKS") {
560  if (orthoKappa_ <= 0) {
561  ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
562  }
563  else {
564  ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
565  Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
566  }
567  }
568  else if (orthoType_=="ICGS") {
569  ortho_ = Teuchos::rcp( new ICGSOrthoManager<ScalarType,MV,OP>( label_ ) );
570  }
571  else if (orthoType_=="IMGS") {
572  ortho_ = Teuchos::rcp( new IMGSOrthoManager<ScalarType,MV,OP>( label_ ) );
573  }
574  }
575  }
576 
577  // Check which orthogonalization constant to use.
578  if (params->isParameter("Orthogonalization Constant")) {
579  orthoKappa_ = params->get("Orthogonalization Constant",orthoKappa_default_);
580 
581  // Update parameter in our list.
582  params_->set("Orthogonalization Constant",orthoKappa_);
583  if (orthoType_=="DGKS") {
584  if (orthoKappa_ > 0 && ortho_ != Teuchos::null) {
585  Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
586  }
587  }
588  }
589 
590  // Check for a change in verbosity level
591  if (params->isParameter("Verbosity")) {
592  if (Teuchos::isParameterType<int>(*params,"Verbosity")) {
593  verbosity_ = params->get("Verbosity", verbosity_default_);
594  } else {
595  verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,"Verbosity");
596  }
597 
598  // Update parameter in our list.
599  params_->set("Verbosity", verbosity_);
600  if (printer_ != Teuchos::null)
601  printer_->setVerbosity(verbosity_);
602  }
603 
604  // Check for a change in output style
605  if (params->isParameter("Output Style")) {
606  if (Teuchos::isParameterType<int>(*params,"Output Style")) {
607  outputStyle_ = params->get("Output Style", outputStyle_default_);
608  } else {
609  outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,"Output Style");
610  }
611 
612  // Update parameter in our list.
613  params_->set("Output Style", outputStyle_);
614  outputTest_ = Teuchos::null;
615  }
616 
617  // output stream
618  if (params->isParameter("Output Stream")) {
619  outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,"Output Stream");
620 
621  // Update parameter in our list.
622  params_->set("Output Stream", outputStream_);
623  if (printer_ != Teuchos::null)
624  printer_->setOStream( outputStream_ );
625  }
626 
627  // frequency level
628  if (verbosity_ & Belos::StatusTestDetails) {
629  if (params->isParameter("Output Frequency")) {
630  outputFreq_ = params->get("Output Frequency", outputFreq_default_);
631  }
632 
633  // Update parameter in out list and output status test.
634  params_->set("Output Frequency", outputFreq_);
635  if (outputTest_ != Teuchos::null)
636  outputTest_->setOutputFrequency( outputFreq_ );
637  }
638 
639  // Create output manager if we need to.
640  if (printer_ == Teuchos::null) {
641  printer_ = Teuchos::rcp( new OutputManager<ScalarType>(verbosity_, outputStream_) );
642  }
643 
644  // Convergence
645  typedef Belos::StatusTestCombo<ScalarType,MV,OP> StatusTestCombo_t;
646  typedef Belos::StatusTestGenResNorm<ScalarType,MV,OP> StatusTestResNorm_t;
647 
648  // Check for convergence tolerance
649  if (params->isParameter("Convergence Tolerance")) {
650  convtol_ = params->get("Convergence Tolerance",convtol_default_);
651 
652  // Update parameter in our list and residual tests.
653  params_->set("Convergence Tolerance", convtol_);
654  if (convTest_ != Teuchos::null)
655  convTest_->setTolerance( convtol_ );
656  }
657 
658  if (params->isParameter("Show Maximum Residual Norm Only")) {
659  showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,"Show Maximum Residual Norm Only");
660 
661  // Update parameter in our list and residual tests
662  params_->set("Show Maximum Residual Norm Only", showMaxResNormOnly_);
663  if (convTest_ != Teuchos::null)
664  convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
665  }
666 
667  // Create status tests if we need to.
668 
669  // Basic test checks maximum iterations and native residual.
670  if (maxIterTest_ == Teuchos::null)
671  maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>( maxIters_ ) );
672 
673  // Implicit residual test, using the native residual to determine if convergence was achieved.
674  if (convTest_ == Teuchos::null)
675  convTest_ = Teuchos::rcp( new StatusTestResNorm_t( convtol_, 1 ) );
676 
677  if (sTest_ == Teuchos::null)
678  sTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
679 
680  if (outputTest_ == Teuchos::null) {
681 
682  // Create the status test output class.
683  // This class manages and formats the output from the status test.
684  StatusTestOutputFactory<ScalarType,MV,OP> stoFactory( outputStyle_ );
685  outputTest_ = stoFactory.create( printer_, sTest_, outputFreq_, Passed+Failed+Undefined );
686 
687  // Set the solver string for the output test
688  std::string solverDesc = " Block CG ";
689  outputTest_->setSolverDesc( solverDesc );
690 
691  }
692 
693  // Create orthogonalization manager if we need to.
694  if (ortho_ == Teuchos::null) {
695  if (orthoType_=="DGKS") {
696  if (orthoKappa_ <= 0) {
697  ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
698  }
699  else {
700  ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
701  Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
702  }
703  }
704  else if (orthoType_=="ICGS") {
705  ortho_ = Teuchos::rcp( new ICGSOrthoManager<ScalarType,MV,OP>( label_ ) );
706  }
707  else if (orthoType_=="IMGS") {
708  ortho_ = Teuchos::rcp( new IMGSOrthoManager<ScalarType,MV,OP>( label_ ) );
709  }
710  else {
711  TEUCHOS_TEST_FOR_EXCEPTION(orthoType_!="ICGS"&&orthoType_!="DGKS"&&orthoType_!="IMGS",std::logic_error,
712  "Belos::BlockCGSolMgr(): Invalid orthogonalization type.");
713  }
714  }
715 
716  // Create the timer if we need to.
717  if (timerSolve_ == Teuchos::null) {
718  std::string solveLabel = label_ + ": BlockCGSolMgr total solve time";
719 #ifdef BELOS_TEUCHOS_TIME_MONITOR
720  timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel);
721 #endif
722  }
723 
724  // Inform the solver manager that the current parameters were set.
725  isSet_ = true;
726 }
727 
728 
729 template<class ScalarType, class MV, class OP>
730 Teuchos::RCP<const Teuchos::ParameterList>
732 {
733  static Teuchos::RCP<const Teuchos::ParameterList> validPL;
734 
735  // Set all the valid parameters and their default values.
736  if(is_null(validPL)) {
737  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
738  pl->set("Convergence Tolerance", convtol_default_,
739  "The relative residual tolerance that needs to be achieved by the\n"
740  "iterative solver in order for the linear system to be declared converged.");
741  pl->set("Maximum Iterations", maxIters_default_,
742  "The maximum number of block iterations allowed for each\n"
743  "set of RHS solved.");
744  pl->set("Block Size", blockSize_default_,
745  "The number of vectors in each block.");
746  pl->set("Adaptive Block Size", adaptiveBlockSize_default_,
747  "Whether the solver manager should adapt to the block size\n"
748  "based on the number of RHS to solve.");
749  pl->set("Verbosity", verbosity_default_,
750  "What type(s) of solver information should be outputted\n"
751  "to the output stream.");
752  pl->set("Output Style", outputStyle_default_,
753  "What style is used for the solver information outputted\n"
754  "to the output stream.");
755  pl->set("Output Frequency", outputFreq_default_,
756  "How often convergence information should be outputted\n"
757  "to the output stream.");
758  pl->set("Output Stream", outputStream_default_,
759  "A reference-counted pointer to the output stream where all\n"
760  "solver output is sent.");
761  pl->set("Show Maximum Residual Norm Only", showMaxResNormOnly_default_,
762  "When convergence information is printed, only show the maximum\n"
763  "relative residual norm when the block size is greater than one.");
764  pl->set("Timer Label", label_default_,
765  "The string to use as a prefix for the timer labels.");
766  // pl->set("Restart Timers", restartTimers_);
767  pl->set("Orthogonalization", orthoType_default_,
768  "The type of orthogonalization to use: DGKS, ICGS, or IMGS.");
769  pl->set("Orthogonalization Constant",orthoKappa_default_,
770  "The constant used by DGKS orthogonalization to determine\n"
771  "whether another step of classical Gram-Schmidt is necessary.");
772  validPL = pl;
773  }
774  return validPL;
775 }
776 
777 
778 // solve()
779 template<class ScalarType, class MV, class OP>
781  using Teuchos::RCP;
782  using Teuchos::rcp;
783  using Teuchos::rcp_const_cast;
784  using Teuchos::rcp_dynamic_cast;
785 
786  // Set the current parameters if they were not set before. NOTE:
787  // This may occur if the user generated the solver manager with the
788  // default constructor and then didn't set any parameters using
789  // setParameters().
790  if (!isSet_) {
791  setParameters(Teuchos::parameterList(*getValidParameters()));
792  }
793 
794  Teuchos::BLAS<int,ScalarType> blas;
795  Teuchos::LAPACK<int,ScalarType> lapack;
796 
797  TEUCHOS_TEST_FOR_EXCEPTION( !problem_->isProblemSet(),
799  "Belos::BlockCGSolMgr::solve(): Linear problem is not ready, setProblem() "
800  "has not been called.");
801 
802  // Create indices for the linear systems to be solved.
803  int startPtr = 0;
804  int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
805  int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
806 
807  std::vector<int> currIdx, currIdx2;
808  // If an adaptive block size is allowed then only the linear
809  // systems that need to be solved are solved. Otherwise, the index
810  // set is generated that informs the linear problem that some
811  // linear systems are augmented.
812  if ( adaptiveBlockSize_ ) {
813  blockSize_ = numCurrRHS;
814  currIdx.resize( numCurrRHS );
815  currIdx2.resize( numCurrRHS );
816  for (int i=0; i<numCurrRHS; ++i)
817  { currIdx[i] = startPtr+i; currIdx2[i]=i; }
818 
819  }
820  else {
821  currIdx.resize( blockSize_ );
822  currIdx2.resize( blockSize_ );
823  for (int i=0; i<numCurrRHS; ++i)
824  { currIdx[i] = startPtr+i; currIdx2[i]=i; }
825  for (int i=numCurrRHS; i<blockSize_; ++i)
826  { currIdx[i] = -1; currIdx2[i] = i; }
827  }
828 
829  // Inform the linear problem of the current linear system to solve.
830  problem_->setLSIndex( currIdx );
831 
833  // Set up the parameter list for the Iteration subclass.
834  Teuchos::ParameterList plist;
835  plist.set("Block Size",blockSize_);
836 
837  // Reset the output status test (controls all the other status tests).
838  outputTest_->reset();
839 
840  // Assume convergence is achieved, then let any failed convergence
841  // set this to false. "Innocent until proven guilty."
842  bool isConverged = true;
843 
845  // Set up the BlockCG Iteration subclass.
846 
847  RCP<CGIteration<ScalarType,MV,OP> > block_cg_iter;
848  if (blockSize_ == 1) {
849  // Standard (nonblock) CG is faster for the special case of a
850  // block size of 1.
851  block_cg_iter =
852  rcp (new CGIter<ScalarType,MV,OP> (problem_, printer_,
853  outputTest_, plist));
854  } else {
855  block_cg_iter =
856  rcp (new BlockCGIter<ScalarType,MV,OP> (problem_, printer_, outputTest_,
857  ortho_, plist));
858  }
859 
860 
861  // Enter solve() iterations
862  {
863 #ifdef BELOS_TEUCHOS_TIME_MONITOR
864  Teuchos::TimeMonitor slvtimer(*timerSolve_);
865 #endif
866 
867  while ( numRHS2Solve > 0 ) {
868  //
869  // Reset the active / converged vectors from this block
870  std::vector<int> convRHSIdx;
871  std::vector<int> currRHSIdx( currIdx );
872  currRHSIdx.resize(numCurrRHS);
873 
874  // Reset the number of iterations.
875  block_cg_iter->resetNumIters();
876 
877  // Reset the number of calls that the status test output knows about.
878  outputTest_->resetNumCalls();
879 
880  // Get the current residual for this block of linear systems.
881  RCP<MV> R_0 = MVT::CloneViewNonConst( *(rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
882 
883  // Set the new state and initialize the solver.
885  newstate.R = R_0;
886  block_cg_iter->initializeCG(newstate);
887 
888  while(1) {
889 
890  // tell block_cg_iter to iterate
891  try {
892  block_cg_iter->iterate();
893  //
894  // Check whether any of the linear systems converged.
895  //
896  if (convTest_->getStatus() == Passed) {
897  // At least one of the linear system(s) converged.
898  //
899  // Get the column indices of the linear systems that converged.
900  typedef StatusTestGenResNorm<ScalarType,MV,OP> conv_test_type;
901  std::vector<int> convIdx =
902  rcp_dynamic_cast<conv_test_type>(convTest_)->convIndices();
903 
904  // If the number of converged linear systems equals the
905  // number of linear systems currently being solved, then
906  // we are done with this block.
907  if (convIdx.size() == currRHSIdx.size())
908  break; // break from while(1){block_cg_iter->iterate()}
909 
910  // Inform the linear problem that we are finished with
911  // this current linear system.
912  problem_->setCurrLS();
913 
914  // Reset currRHSIdx to contain the right-hand sides that
915  // are left to converge for this block.
916  int have = 0;
917  std::vector<int> unconvIdx(currRHSIdx.size());
918  for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
919  bool found = false;
920  for (unsigned int j=0; j<convIdx.size(); ++j) {
921  if (currRHSIdx[i] == convIdx[j]) {
922  found = true;
923  break;
924  }
925  }
926  if (!found) {
927  currIdx2[have] = currIdx2[i];
928  currRHSIdx[have++] = currRHSIdx[i];
929  }
930  else {
931  }
932  }
933  currRHSIdx.resize(have);
934  currIdx2.resize(have);
935 
936  // Set the remaining indices after deflation.
937  problem_->setLSIndex( currRHSIdx );
938 
939  // Get the current residual vector.
940  std::vector<MagnitudeType> norms;
941  R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
942  for (int i=0; i<have; ++i) { currIdx2[i] = i; }
943 
944  // Set the new blocksize for the solver.
945  block_cg_iter->setBlockSize( have );
946 
947  // Set the new state and initialize the solver.
949  defstate.R = R_0;
950  block_cg_iter->initializeCG(defstate);
951  }
952  //
953  // None of the linear systems converged. Check whether the
954  // maximum iteration count was reached.
955  //
956  else if (maxIterTest_->getStatus() == Passed) {
957  isConverged = false; // None of the linear systems converged.
958  break; // break from while(1){block_cg_iter->iterate()}
959  }
960  //
961  // iterate() returned, but none of our status tests Passed.
962  // This indicates a bug.
963  //
964  else {
965  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
966  "Belos::BlockCGSolMgr::solve(): Neither the convergence test nor "
967  "the maximum iteration count test passed. Please report this bug "
968  "to the Belos developers.");
969  }
970  }
971  catch (const std::exception &e) {
972  std::ostream& err = printer_->stream (Errors);
973  err << "Error! Caught std::exception in CGIteration::iterate() at "
974  << "iteration " << block_cg_iter->getNumIters() << std::endl
975  << e.what() << std::endl;
976  throw;
977  }
978  }
979 
980  // Inform the linear problem that we are finished with this
981  // block linear system.
982  problem_->setCurrLS();
983 
984  // Update indices for the linear systems to be solved.
985  startPtr += numCurrRHS;
986  numRHS2Solve -= numCurrRHS;
987  if ( numRHS2Solve > 0 ) {
988  numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
989 
990  if ( adaptiveBlockSize_ ) {
991  blockSize_ = numCurrRHS;
992  currIdx.resize( numCurrRHS );
993  currIdx2.resize( numCurrRHS );
994  for (int i=0; i<numCurrRHS; ++i)
995  { currIdx[i] = startPtr+i; currIdx2[i] = i; }
996  }
997  else {
998  currIdx.resize( blockSize_ );
999  currIdx2.resize( blockSize_ );
1000  for (int i=0; i<numCurrRHS; ++i)
1001  { currIdx[i] = startPtr+i; currIdx2[i] = i; }
1002  for (int i=numCurrRHS; i<blockSize_; ++i)
1003  { currIdx[i] = -1; currIdx2[i] = i; }
1004  }
1005  // Set the next indices.
1006  problem_->setLSIndex( currIdx );
1007 
1008  // Set the new blocksize for the solver.
1009  block_cg_iter->setBlockSize( blockSize_ );
1010  }
1011  else {
1012  currIdx.resize( numRHS2Solve );
1013  }
1014 
1015  }// while ( numRHS2Solve > 0 )
1016 
1017  }
1018 
1019  // print final summary
1020  sTest_->print( printer_->stream(FinalSummary) );
1021 
1022  // print timing information
1023 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1024  // Calling summarize() requires communication in general, so don't
1025  // call it unless the user wants to print out timing details.
1026  // summarize() will do all the work even if it's passed a "black
1027  // hole" output stream.
1028  if (verbosity_ & TimingDetails) {
1029  Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
1030  }
1031 #endif
1032 
1033  // Save the iteration count for this solve.
1034  numIters_ = maxIterTest_->getNumIters();
1035 
1036  // Save the convergence test value ("achieved tolerance") for this solve.
1037  {
1038  typedef StatusTestGenResNorm<ScalarType,MV,OP> conv_test_type;
1039  // testValues is nonnull and not persistent.
1040  const std::vector<MagnitudeType>* pTestValues =
1041  rcp_dynamic_cast<conv_test_type>(convTest_)->getTestValue();
1042 
1043  TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1044  "Belos::BlockCGSolMgr::solve(): The convergence test's getTestValue() "
1045  "method returned NULL. Please report this bug to the Belos developers.");
1046 
1047  TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1048  "Belos::BlockCGSolMgr::solve(): The convergence test's getTestValue() "
1049  "method returned a vector of length zero. Please report this bug to the "
1050  "Belos developers.");
1051 
1052  // FIXME (mfh 12 Dec 2011) Does pTestValues really contain the
1053  // achieved tolerances for all vectors in the current solve(), or
1054  // just for the vectors from the last deflation?
1055  achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
1056  }
1057 
1058  if (!isConverged) {
1059  return Unconverged; // return from BlockCGSolMgr::solve()
1060  }
1061  return Converged; // return from BlockCGSolMgr::solve()
1062 }
1063 
1064 // This method requires the solver manager to return a std::string that describes itself.
1065 template<class ScalarType, class MV, class OP>
1067 {
1068  std::ostringstream oss;
1069  oss << "Belos::BlockCGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<">";
1070  oss << "{";
1071  oss << "Ortho Type='"<<orthoType_<<"\', Block Size=" << blockSize_;
1072  oss << "}";
1073  return oss.str();
1074 }
1075 
1076 } // end Belos namespace
1077 
1078 #endif /* BELOS_BLOCK_CG_SOLMGR_HPP */
Teuchos::RCP< const MV > R
The current residual.
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem)
Set the linear problem that needs to be solved.
Collection of types and exceptions used within the Belos solvers.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
Belos&#39;s basic output manager for sending information of select verbosity levels to the appropriate ou...
Class which manages the output and verbosity of the Belos solvers.
int getNumIters() const
Get the iteration count for the most recent call to solve().
This class implements the preconditioned Conjugate Gradient (CG) iteration.
Definition: BelosCGIter.hpp:78
Structure to contain pointers to CGIteration state variables.
Belos concrete class for performing the conjugate-gradient (CG) iteration.
A factory class for generating StatusTestOutput objects.
Belos concrete class for performing the block conjugate-gradient (CG) iteration.
An implementation of StatusTestResNorm using a family of residual norms.
The Belos::BlockCGSolMgr provides a powerful and fully-featured solver manager over the CG and BlockC...
Belos::StatusTest class for specifying a maximum number of iterations.
BlockCGSolMgrLinearProblemFailure(const std::string &what_arg)
BlockCGSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i.e.
A factory class for generating StatusTestOutput objects.
Iterated Modified Gram-Schmidt (IMGS) implementation of the Belos::OrthoManager class.
BlockCGSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< Teuchos::ParameterList > &pl)
Traits class which defines basic operations on multivectors.
Belos::StatusTest for logically combining several status tests.
Classical Gram-Schmidt (with DGKS correction) implementation of the Belos::OrthoManager class...
A Belos::StatusTest class for specifying a maximum number of iterations.
ResetType
How to reset the solver.
Definition: BelosTypes.hpp:200
Pure virtual base class which describes the basic interface for a solver manager. ...
A linear system to solve, and its associated information.
Class which describes the linear problem to be solved by the iterative solver.
BlockCGSolMgrOrthoFailure is thrown when the orthogonalization manager is unable to generate orthonor...
Type traits class that says whether Teuchos::LAPACK has a valid implementation for the given ScalarTy...
ReturnType
Whether the Belos solve converged for all linear systems.
Definition: BelosTypes.hpp:149
Iterated Classical Gram-Schmidt (ICGS) implementation of the Belos::OrthoManager class.
MagnitudeType achievedTol() const
Tolerance achieved by the last solve() invocation.
An implementation of the Belos::MatOrthoManager that performs orthogonalization using multiple steps ...
BlockCGSolMgrOrthoFailure(const std::string &what_arg)
An implementation of the Belos::MatOrthoManager that performs orthogonalization using multiple steps ...
int setTolerance(MagnitudeType tolerance)
Set the value of the tolerance.
Teuchos::RCP< StatusTestOutput< ScalarType, MV, OP > > create(const Teuchos::RCP< OutputManager< ScalarType > > &printer, Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test, int mod, int printStates)
Create the StatusTestOutput object specified by the outputStyle.
bool isLOADetected() const
Return whether a loss of accuracy was detected by this solver during the most current solve...
Belos::StatusTestResNorm for specifying general residual norm stopping criteria.
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.
Class which defines basic traits for the operator type.
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const
Get a parameter list containing the current parameters for this object.
Parent class to all Belos exceptions.
Definition: BelosTypes.hpp:60
Base class for Belos::SolverManager subclasses which normally can only compile with ScalarType types ...
Belos header file which uses auto-configuration information to include necessary C++ headers...
void reset(const ResetType type)
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Return a reference to the linear problem being solved by this solver manager.
Stub implementation of BlockCGIter, for ScalarType types for which Teuchos::LAPACK does NOT have a va...