Belos  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BelosGmresPolySolMgr.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Belos: Block Linear Solvers Package
4 //
5 // Copyright 2004-2016 NTESS and the Belos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 //
10 
11 #ifndef BELOS_GMRES_POLY_SOLMGR_HPP
12 #define BELOS_GMRES_POLY_SOLMGR_HPP
13 
17 
18 #include "BelosConfigDefs.hpp"
19 #include "BelosTypes.hpp"
20 
21 #include "BelosLinearProblem.hpp"
22 #include "BelosSolverManager.hpp"
23 #include "BelosGmresPolyOp.hpp"
26 #include "Teuchos_as.hpp"
27 #ifdef BELOS_TEUCHOS_TIME_MONITOR
28 #include "Teuchos_TimeMonitor.hpp"
29 #endif
30 
35 namespace Belos {
36 
38 
39 
47  GmresPolySolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
48  {}};
49 
57  GmresPolySolMgrPolynomialFailure(const std::string& what_arg) : BelosError(what_arg)
58  {}};
59 
73 //
108 //
120 
121 template<class ScalarType, class MV, class OP>
122 class GmresPolySolMgr : public SolverManager<ScalarType,MV,OP> {
123 private:
124 
125  typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
126 
130 
131 public:
132 
134 
135 
141  GmresPolySolMgr();
142 
163 
165  virtual ~GmresPolySolMgr() {};
166 
170  }
172 
174 
175 
178  const LinearProblem<ScalarType,MV,OP>& getProblem() const override {
179  return *problem_;
180  }
181 
185 
189 
206  MagnitudeType achievedTol() const override {
207  return achievedTol_;
208  }
209 
216  return Teuchos::tuple(timerPoly_);
217  }
218 
220  int getNumIters() const override {
221  return numIters_;
222  }
223 
227  bool isLOADetected() const override { return loaDetected_; }
228 
230 
232 
233 
235  void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) override { problem_ = problem; }
236 
238  void setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params ) override;
239 
241 
243 
252  void reset( const ResetType type ) override {
253  if ((type & Belos::Problem) && ! problem_.is_null ()) {
254  problem_->setProblem ();
255  poly_Op_ = Teuchos::null;
256  poly_dim_ = 0; // Rebuild the GMRES polynomial
257  }
258  }
259 
261 
263 
281  ReturnType solve() override;
282 
284 
287 
289  std::string description() const override;
290 
292 
293 private:
294 
295  // Linear problem.
297 
298  // Output manager.
299  Teuchos::RCP<std::ostream> outputStream_;
300 
301  // Current parameter list.
304 
305  // Default solver values.
306  static constexpr int maxDegree_default_ = 25;
307  static constexpr int verbosity_default_ = Belos::Errors;
308  static constexpr const char * label_default_ = "Belos";
309  static constexpr const char * outerSolverType_default_ = "";
310  static constexpr const char * polyType_default_ = "Arnoldi";
311  static constexpr const char * orthoType_default_ = "ICGS";
312  static constexpr bool addRoots_default_ = true;
313  static constexpr bool dampPoly_default_ = false;
314  static constexpr bool randomRHS_default_ = true;
315 
316  // Current solver values.
317  MagnitudeType polyTol_, achievedTol_;
318  int maxDegree_, numIters_;
319  int verbosity_;
320  bool hasOuterSolver_;
321  bool randomRHS_;
322  bool damp_;
323  bool addRoots_;
324  std::string polyType_;
325  std::string outerSolverType_;
326  std::string orthoType_;
327 
328  // Polynomial storage
329  int poly_dim_;
331 
332  // Timers.
333  std::string label_;
334  Teuchos::RCP<Teuchos::Time> timerPoly_;
335 
336  // Internal state variables.
337  bool isSet_;
338  bool loaDetected_;
339 
342 };
343 
344 
345 template<class ScalarType, class MV, class OP>
347  outputStream_ (Teuchos::rcpFromRef(std::cout)),
348  polyTol_ (DefaultSolverParameters::polyTol),
349  achievedTol_(MTS::zero()),
350  maxDegree_ (maxDegree_default_),
351  numIters_ (0),
352  verbosity_ (verbosity_default_),
353  hasOuterSolver_ (false),
354  randomRHS_ (randomRHS_default_),
355  damp_ (dampPoly_default_),
356  addRoots_ (addRoots_default_),
357  polyType_ (polyType_default_),
358  outerSolverType_ (outerSolverType_default_),
359  orthoType_ (orthoType_default_),
360  poly_dim_ (0),
361  label_ (label_default_),
362  isSet_ (false),
363  loaDetected_ (false)
364 {}
365 
366 
367 template<class ScalarType, class MV, class OP>
371  problem_ (problem),
372  outputStream_ (Teuchos::rcpFromRef(std::cout)),
373  polyTol_ (DefaultSolverParameters::polyTol),
374  maxDegree_ (maxDegree_default_),
375  numIters_ (0),
376  verbosity_ (verbosity_default_),
377  hasOuterSolver_ (false),
378  randomRHS_ (randomRHS_default_),
379  damp_ (dampPoly_default_),
380  addRoots_ (addRoots_default_),
381  polyType_ (polyType_default_),
382  outerSolverType_ (outerSolverType_default_),
383  orthoType_ (orthoType_default_),
384  poly_dim_ (0),
385  label_ (label_default_),
386  isSet_ (false),
387  loaDetected_ (false)
388 {
390  problem_.is_null (), std::invalid_argument,
391  "Belos::GmresPolySolMgr: The given linear problem is null. "
392  "Please call this constructor with a nonnull LinearProblem argument, "
393  "or call the constructor that does not take a LinearProblem.");
394 
395  // If the input parameter list is null, then the parameters take
396  // default values.
397  if (! pl.is_null ()) {
398  setParameters (pl);
399  }
400 }
401 
402 
403 template<class ScalarType, class MV, class OP>
406 {
407  if (validPL_.is_null ()) {
408  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList ();
409 
410  // The static_cast is to resolve an issue with older clang versions which
411  // would cause the constexpr to link fail. With c++17 the problem is resolved.
412  pl->set("Polynomial Type", static_cast<const char *>(polyType_default_),
413  "The type of GMRES polynomial that is used as a preconditioner: Roots, Arnoldi, or Gmres.");
414  pl->set("Polynomial Tolerance", static_cast<MagnitudeType>(DefaultSolverParameters::polyTol),
415  "The relative residual tolerance that used to construct the GMRES polynomial.");
416  pl->set("Maximum Degree", static_cast<int>(maxDegree_default_),
417  "The maximum degree allowed for any GMRES polynomial.");
418  pl->set("Outer Solver", static_cast<const char *>(outerSolverType_default_),
419  "The outer solver that this polynomial is used to precondition.");
420  pl->set("Outer Solver Params", Teuchos::ParameterList(),
421  "Parameter list for the outer solver.");
422  pl->set("Verbosity", static_cast<int>(verbosity_default_),
423  "What type(s) of solver information should be outputted\n"
424  "to the output stream.");
425  pl->set("Output Stream", Teuchos::rcpFromRef(std::cout),
426  "A reference-counted pointer to the output stream where all\n"
427  "solver output is sent.");
428  pl->set("Timer Label", static_cast<const char *>(label_default_),
429  "The string to use as a prefix for the timer labels.");
430  pl->set("Orthogonalization", static_cast<const char *>(orthoType_default_),
431  "The type of orthogonalization to use to generate polynomial: DGKS, ICGS, or IMGS.");
432  pl->set("Random RHS", static_cast<bool>(randomRHS_default_),
433  "Add roots to polynomial for stability.");
434  pl->set("Add Roots", static_cast<bool>(addRoots_default_),
435  "Add roots to polynomial for stability.");
436  pl->set("Damp Poly", static_cast<bool>(dampPoly_default_),
437  "Damp polynomial for ill-conditioned problems.");
438  validPL_ = pl;
439  }
440  return validPL_;
441 }
442 
443 
444 template<class ScalarType, class MV, class OP>
447 {
448  // Create the internal parameter list if ones doesn't already exist.
449  if (params_.is_null ()) {
450  params_ = Teuchos::parameterList (*getValidParameters ());
451  }
452  else {
453  params->validateParameters (*getValidParameters (),0);
454  }
455 
456  // Check which Gmres polynomial to use
457  if (params->isParameter("Polynomial Type")) {
458  polyType_ = params->get("Polynomial Type", polyType_default_);
459  }
460 
461  // Update the outer solver in our list.
462  params_->set("Polynomial Type", polyType_);
463 
464  // Check if there is an outer solver for this Gmres Polynomial
465  if (params->isParameter("Outer Solver")) {
466  outerSolverType_ = params->get("Outer Solver", outerSolverType_default_);
467  }
468 
469  // Update the outer solver in our list.
470  params_->set("Outer Solver", outerSolverType_);
471 
472  // Check if there is a parameter list for the outer solver
473  if (params->isSublist("Outer Solver Params")) {
474  outerParams_ = Teuchos::parameterList( params->get<Teuchos::ParameterList>("Outer Solver Params") );
475  }
476 
477  // Check for maximum polynomial degree
478  if (params->isParameter("Maximum Degree")) {
479  maxDegree_ = params->get("Maximum Degree",maxDegree_default_);
480  }
481 
482  // Update parameter in our list.
483  params_->set("Maximum Degree", maxDegree_);
484 
485  // Check to see if the timer label changed.
486  if (params->isParameter("Timer Label")) {
487  std::string tempLabel = params->get("Timer Label", label_default_);
488 
489  // Update parameter in our list and solver timer
490  if (tempLabel != label_) {
491  label_ = tempLabel;
492 #ifdef BELOS_TEUCHOS_TIME_MONITOR
493  std::string polyLabel = label_ + ": GmresPolyOp creation time";
494  timerPoly_ = Teuchos::TimeMonitor::getNewCounter(polyLabel);
495 #endif
496  }
497  }
498 
499  // Update timer label
500  params_->set("Timer Label", label_);
501 
502  // Check if the orthogonalization changed.
503  if (params->isParameter("Orthogonalization")) {
504  std::string tempOrthoType = params->get("Orthogonalization",orthoType_default_);
506  // Ensure that the specified orthogonalization type is valid.
507  if (! factory.isValidName (tempOrthoType)) {
508  std::ostringstream os;
509  os << "Belos::GCRODRSolMgr: Invalid orthogonalization name \""
510  << tempOrthoType << "\". The following are valid options "
511  << "for the \"Orthogonalization\" name parameter: ";
512  factory.printValidNames (os);
513  throw std::invalid_argument (os.str());
514  }
515  if (tempOrthoType != orthoType_) {
516  orthoType_ = tempOrthoType;
517  }
518  }
519 
520  params_->set("Orthogonalization", orthoType_);
521 
522  // Check for a change in verbosity level
523  if (params->isParameter("Verbosity")) {
524  if (Teuchos::isParameterType<int>(*params,"Verbosity")) {
525  verbosity_ = params->get("Verbosity", verbosity_default_);
526  } else {
527  verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,"Verbosity");
528  }
529  }
530 
531  // Update parameter in our list.
532  params_->set("Verbosity", verbosity_);
533 
534  // output stream
535  if (params->isParameter("Output Stream")) {
536  outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,"Output Stream");
537  }
538 
539  // Update parameter in our list.
540  params_->set("Output Stream", outputStream_);
541 
542  // Convergence
543  // Check for polynomial convergence tolerance
544  if (params->isParameter("Polynomial Tolerance")) {
545  if (params->isType<MagnitudeType> ("Polynomial Tolerance")) {
546  polyTol_ = params->get ("Polynomial Tolerance",
547  static_cast<MagnitudeType> (DefaultSolverParameters::polyTol));
548  }
549  else {
550  polyTol_ = params->get ("Polynomial Tolerance", DefaultSolverParameters::polyTol);
551  }
552  }
553 
554  // Update parameter in our list and residual tests.
555  params_->set("Polynomial Tolerance", polyTol_);
556 
557  // Check for maximum polynomial degree
558  if (params->isParameter("Random RHS")) {
559  randomRHS_ = params->get("Random RHS",randomRHS_default_);
560  }
561 
562  // Update parameter in our list.
563  params_->set("Random RHS", randomRHS_);
564 
565 
566  // Check for polynomial damping
567  if (params->isParameter("Damped Poly")) {
568  damp_ = params->get("Damped Poly",dampPoly_default_);
569  }
570  // Update parameter in our list.
571  params_->set("Damped Poly", damp_);
572 
573  // Check: Should we add roots for stability if needed?
574  if (params->isParameter("Add Roots")) {
575  addRoots_ = params->get("Add Roots",addRoots_default_);
576  }
577 
578  // Update parameter in our list.
579  params_->set("Add Roots", addRoots_);
580 
581  // Create the timers if we need to.
582 #ifdef BELOS_TEUCHOS_TIME_MONITOR
583  if (timerPoly_ == Teuchos::null) {
584  std::string polyLabel = label_ + ": GmresPolyOp creation time";
585  timerPoly_ = Teuchos::TimeMonitor::getNewCounter(polyLabel);
586  }
587 #endif
588 
589  // Check if we are going to perform an outer solve.
590  if (outerSolverType_ != "") {
591  hasOuterSolver_ = true;
592  }
593 
594  // Inform the solver manager that the current parameters were set.
595  isSet_ = true;
596 }
597 
598 
599 template<class ScalarType, class MV, class OP>
601 {
602  using Teuchos::RCP;
603  using Teuchos::rcp;
604  using Teuchos::rcp_const_cast;
605 
606  // Assume convergence is achieved if user does not require strict convergence.
608 
609  // Set the current parameters if they were not set before. NOTE:
610  // This may occur if the user generated the solver manager with the
611  // default constructor and then didn't set any parameters using
612  // setParameters().
613  if (! isSet_) {
614  setParameters (Teuchos::parameterList (*getValidParameters ()));
615  }
616 
618  problem_.is_null (), GmresPolySolMgrLinearProblemFailure,
619  "Belos::GmresPolySolMgr::solve: The linear problem has not been set yet, "
620  "or was set to null. Please call setProblem() with a nonnull input before "
621  "calling solve().");
622 
624  ! problem_->isProblemSet (), GmresPolySolMgrLinearProblemFailure,
625  "Belos::GmresPolySolMgr::solve: The linear problem is not ready. Please "
626  "call setProblem() on the LinearProblem object before calling solve().");
627 
628  // If the GMRES polynomial has not been constructed for this
629  // (nmatrix, preconditioner) pair, generate it.
630  if (!poly_dim_ && maxDegree_) {
631 #ifdef BELOS_TEUCHOS_TIME_MONITOR
632  Teuchos::TimeMonitor slvtimer(*timerPoly_);
633 #endif
634  poly_Op_ = Teuchos::rcp( new gmres_poly_t( problem_, params_ ) );
635  poly_dim_ = poly_Op_->polyDegree();
636 
638  "Belos::GmresPolyOp: Failed to generate polynomial that satisfied requirements.");
639  }
640 
641 
642  // Solve the linear system using the polynomial
643  if (hasOuterSolver_ && maxDegree_) {
644 
645  // Then the polynomial will be used as an operator for an outer solver.
646  // Use outer solver parameter list passed in a sublist.
648  RCP<SolverManager<ScalarType, MultiVec<ScalarType>, Operator<ScalarType> > > solver = factory.create( outerSolverType_, outerParams_ );
649  TEUCHOS_TEST_FOR_EXCEPTION( solver == Teuchos::null, std::invalid_argument,
650  "Belos::GmresPolySolMgr::solve(): Selected solver is not valid.");
651 
652  // Create a copy of the linear problem that uses the polynomial as a preconditioner.
653  // The original initial solution and right-hand side are thinly wrapped in the gmres_poly_mv_t
654  RCP<gmres_poly_mv_t> new_lhs = rcp( new gmres_poly_mv_t( problem_->getLHS() ) );
655  RCP<gmres_poly_mv_t> new_rhs = rcp( new gmres_poly_mv_t( rcp_const_cast<MV>( problem_->getRHS() ) ) );
656  RCP<gmres_poly_t> A = rcp( new gmres_poly_t( problem_ ) ); // This just performs problem_->applyOp
657  RCP<LinearProblem<ScalarType,MultiVec<ScalarType>,Operator<ScalarType> > > newProblem =
658  rcp( new LinearProblem<ScalarType,MultiVec<ScalarType>,Operator<ScalarType> >( A, new_lhs, new_rhs ) );
659  std::string solverLabel = label_ + ": Hybrid Gmres";
660  newProblem->setLabel(solverLabel);
661 
662  // If the preconditioner is left preconditioner, use Gmres poly as a left preconditioner.
663  if (problem_->getLeftPrec() != Teuchos::null)
664  newProblem->setLeftPrec( poly_Op_ );
665  else
666  newProblem->setRightPrec( poly_Op_ );
667  // Set the initial residual vector, if it has already been set in the original problem.
668  // Don't set the preconditioned residual vector, because it is not the GmresPoly preconditioned residual vector.
669  if (problem_->getInitResVec() != Teuchos::null)
670  newProblem->setInitResVec( rcp( new gmres_poly_mv_t( rcp_const_cast<MV>( problem_->getInitResVec() ) ) ) );
671  newProblem->setProblem();
672 
673  solver->setProblem( newProblem );
674 
675  ret = solver->solve();
676  numIters_ = solver->getNumIters();
677  loaDetected_ = solver->isLOADetected();
678  achievedTol_ = solver->achievedTol();
679 
680  } // if (hasOuterSolver_ && maxDegree_)
681  else if (hasOuterSolver_) {
682 
683  // There is no polynomial, just create the outer solver with the outerSolverType_ and outerParams_.
685  RCP<SolverManager<ScalarType, MV, OP> > solver = factory.create( outerSolverType_, outerParams_ );
686  TEUCHOS_TEST_FOR_EXCEPTION( solver == Teuchos::null, std::invalid_argument,
687  "Belos::GmresPolySolMgr::solve(): Selected solver is not valid.");
688 
689  solver->setProblem( problem_ );
690 
691  ret = solver->solve();
692  numIters_ = solver->getNumIters();
693  loaDetected_ = solver->isLOADetected();
694  achievedTol_ = solver->achievedTol();
695 
696  }
697  else if (maxDegree_) {
698 
699  // Apply the polynomial to the current linear system
700  poly_Op_->ApplyPoly( *problem_->getRHS(), *problem_->getLHS() );
701  achievedTol_ = MTS::one();
702 
703  }
704 
705  return ret;
706 }
707 
708 
709 template<class ScalarType, class MV, class OP>
711 {
712  std::ostringstream out;
713 
714  out << "\"Belos::GmresPolySolMgr\": {"
715  << "ScalarType: " << Teuchos::TypeNameTraits<ScalarType>::name ()
716  << ", Poly Degree: " << poly_dim_
717  << ", Poly Max Degree: " << maxDegree_
718  << ", Poly Tol: " << polyTol_;
719  out << "}";
720  return out.str ();
721 }
722 
723 } // namespace Belos
724 
725 #endif // BELOS_GMRES_POLY_SOLMGR_HPP
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
Get a parameter list containing the current parameters for this object.
Collection of types and exceptions used within the Belos solvers.
ReturnType solve() override
This method performs possibly repeated calls to the underlying linear solver&#39;s iterate() routine unti...
virtual ~GmresPolySolMgr()
Destructor.
Defines the GMRES polynomial operator hybrid-GMRES iterative linear solver.
bool isLOADetected() const override
Return whether a loss of accuracy was detected by this solver during the most current solve...
T & get(const std::string &name, T def_value)
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
static RCP< Time > getNewCounter(const std::string &name)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
static const double polyTol
Relative residual tolerance for matrix polynomial construction.
Definition: BelosTypes.hpp:264
bool isParameter(const std::string &name) const
ResetType
How to reset the solver.
Definition: BelosTypes.hpp:174
Alternative run-time polymorphic interface for operators.
GmresPolySolMgrLinearProblemFailure is thrown when the linear problem is not setup (i...
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. ...
bool isValidName(const std::string &name) const
Whether this factory recognizes the MatOrthoManager with the given name.
bool isSublist(const std::string &name) const
std::ostream & printValidNames(std::ostream &out) const
Print all recognized MatOrthoManager names to the given ostream.
const LinearProblem< ScalarType, MV, OP > & getProblem() const override
Get current linear problem being solved for in this object.
A linear system to solve, and its associated information.
Class which describes the linear problem to be solved by the iterative solver.
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) override
Set the linear problem that needs to be solved.
The GMRES polynomial can be created in conjunction with any standard preconditioner.
int getNumIters() const override
Get the iteration count for the most recent call to solve().
ReturnType
Whether the Belos solve converged for all linear systems.
Definition: BelosTypes.hpp:123
The Belos::SolverManager is a templated virtual base class that defines the basic interface that any ...
Belos&#39;s class for applying the GMRES polynomial operator that is used by the hybrid-GMRES linear solv...
void reset(const ResetType type) override
Reset the solver.
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
std::string description() const override
Method to return description of the hybrid block GMRES solver manager.
GmresPolySolMgrPolynomialFailure is thrown when their is a problem generating the GMRES polynomial fo...
virtual Teuchos::RCP< solver_base_type > create(const std::string &solverName, const Teuchos::RCP< Teuchos::ParameterList > &solverParams)
Create, configure, and return the specified solver.
GmresPolySolMgrPolynomialFailure(const std::string &what_arg)
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > &params) override
Set the parameters the solver manager should use to solve the linear problem.
bool isType(const std::string &name) const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
Get a parameter list containing the valid parameters for this object.
Interface for multivectors used by Belos&#39; linear solvers.
Parent class to all Belos exceptions.
Definition: BelosTypes.hpp:28
Default parameters common to most Belos solvers.
Definition: BelosTypes.hpp:251
GmresPolySolMgr()
Empty constructor for GmresPolySolMgr. This constructor takes no arguments and sets the default value...
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
Belos header file which uses auto-configuration information to include necessary C++ headers...
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
typename::Belos::Impl::SolverFactorySelector< SC, MV, OP >::type SolverFactory
GmresPolySolMgrLinearProblemFailure(const std::string &what_arg)
static std::string name()
bool is_null() const

Generated on Fri Dec 20 2024 09:24:48 for Belos by doxygen 1.8.5