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 //
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_GMRES_POLY_SOLMGR_HPP
43 #define BELOS_GMRES_POLY_SOLMGR_HPP
44 
48 
49 #include "BelosConfigDefs.hpp"
50 #include "BelosTypes.hpp"
51 
52 #include "BelosLinearProblem.hpp"
53 #include "BelosSolverManager.hpp"
54 #include "BelosGmresPolyOp.hpp"
56 #include "Teuchos_as.hpp"
57 #ifdef BELOS_TEUCHOS_TIME_MONITOR
58 #include "Teuchos_TimeMonitor.hpp"
59 #endif
60 
61 
62 namespace Belos {
63 
65 
66 
74  GmresPolySolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
75  {}};
76 
84  GmresPolySolMgrPolynomialFailure(const std::string& what_arg) : BelosError(what_arg)
85  {}};
86 
132 
133 template<class ScalarType, class MV, class OP>
134 class GmresPolySolMgr : public SolverManager<ScalarType,MV,OP> {
135 private:
136 
139  typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
142 
143 public:
144 
146 
147 
153  GmresPolySolMgr();
154 
166 
168  virtual ~GmresPolySolMgr() {};
169 
173  }
175 
177 
178 
181  const LinearProblem<ScalarType,MV,OP>& getProblem() const override {
182  return *problem_;
183  }
184 
188 
192 
199  return Teuchos::tuple(timerPoly_);
200  }
201 
203  int getNumIters() const override {
204  return numIters_;
205  }
206 
210  bool isLOADetected() const override { return loaDetected_; }
211 
213 
215 
216 
218  void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) override { problem_ = problem; }
219 
221  void setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params ) override;
222 
224 
226 
235  void reset( const ResetType type ) override {
236  if ((type & Belos::Problem) && ! problem_.is_null ()) {
237  problem_->setProblem ();
238  poly_Op_ = Teuchos::null;
239  poly_dim_ = 0; // Rebuild the GMRES polynomial
240  }
241  }
242 
244 
246 
264  ReturnType solve() override;
265 
267 
270 
272  std::string description() const override;
273 
275 
276 private:
277 
278  // Linear problem.
280 
281  // Output manager.
282  Teuchos::RCP<std::ostream> outputStream_;
283 
284  // Current parameter list.
287 
288  // Default solver values.
289  static constexpr int maxDegree_default_ = 25;
290  static constexpr int verbosity_default_ = Belos::Errors;
291  static constexpr const char * label_default_ = "Belos";
292  static constexpr const char * outerSolverType_default_ = "";
293  static constexpr const char * polyType_default_ = "Arnoldi";
294  static constexpr const char * orthoType_default_ = "DGKS";
295  static constexpr std::ostream * outputStream_default_ = &std::cout;
296 
297  // Current solver values.
298  MagnitudeType polyTol_;
299  int maxDegree_, numIters_;
300  int verbosity_;
301  bool hasOuterSolver_;
302  bool randomRHS_;
303  std::string polyType_;
304  std::string outerSolverType_;
305  std::string orthoType_;
306 
307  // Polynomial storage
308  int poly_dim_;
310 
311  // Timers.
312  std::string label_;
313  Teuchos::RCP<Teuchos::Time> timerPoly_;
314 
315  // Internal state variables.
316  bool isSet_;
317  bool loaDetected_;
318 
321 };
322 
323 
324 template<class ScalarType, class MV, class OP>
326  outputStream_ (Teuchos::rcp(outputStream_default_,false)),
327  polyTol_ (DefaultSolverParameters::polyTol),
328  maxDegree_ (maxDegree_default_),
329  numIters_ (0),
330  verbosity_ (verbosity_default_),
331  hasOuterSolver_ (false),
332  randomRHS_ (true),
333  polyType_ (polyType_default_),
334  outerSolverType_ (outerSolverType_default_),
335  orthoType_ (orthoType_default_),
336  poly_dim_ (0),
337  label_ (label_default_),
338  isSet_ (false),
339  loaDetected_ (false)
340 {}
341 
342 
343 template<class ScalarType, class MV, class OP>
347  problem_ (problem),
348  outputStream_ (Teuchos::rcp(outputStream_default_,false)),
349  polyTol_ (DefaultSolverParameters::polyTol),
350  maxDegree_ (maxDegree_default_),
351  numIters_ (0),
352  verbosity_ (verbosity_default_),
353  hasOuterSolver_ (false),
354  randomRHS_ (true),
355  polyType_ (polyType_default_),
356  outerSolverType_ (outerSolverType_default_),
357  orthoType_ (orthoType_default_),
358  poly_dim_ (0),
359  label_ (label_default_),
360  isSet_ (false),
361  loaDetected_ (false)
362 {
364  problem_.is_null (), std::invalid_argument,
365  "Belos::GmresPolySolMgr: The given linear problem is null. "
366  "Please call this constructor with a nonnull LinearProblem argument, "
367  "or call the constructor that does not take a LinearProblem.");
368 
369  // If the input parameter list is null, then the parameters take
370  // default values.
371  if (! pl.is_null ()) {
372  setParameters (pl);
373  }
374 }
375 
376 
377 template<class ScalarType, class MV, class OP>
380 {
381  if (validPL_.is_null ()) {
382  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList ();
383 
384  // The static_cast is to resolve an issue with older clang versions which
385  // would cause the constexpr to link fail. With c++17 the problem is resolved.
386  pl->set("Polynomial Type", static_cast<const char *>(polyType_default_),
387  "The type of GMRES polynomial that is used as a preconditioner.");
388  pl->set("Polynomial Tolerance", static_cast<MagnitudeType>(DefaultSolverParameters::polyTol),
389  "The relative residual tolerance that used to construct the GMRES polynomial.");
390  pl->set("Maximum Degree", static_cast<int>(maxDegree_default_),
391  "The maximum degree allowed for any GMRES polynomial.");
392  pl->set("Outer Solver", static_cast<const char *>(outerSolverType_default_),
393  "The outer solver that this polynomial is used to precondition.");
394  pl->set("Verbosity", static_cast<int>(verbosity_default_),
395  "What type(s) of solver information should be outputted\n"
396  "to the output stream.");
397  pl->set("Output Stream", Teuchos::rcp(outputStream_default_,false),
398  "A reference-counted pointer to the output stream where all\n"
399  "solver output is sent.");
400  pl->set("Timer Label", static_cast<const char *>(label_default_),
401  "The string to use as a prefix for the timer labels.");
402  pl->set("Orthogonalization", static_cast<const char *>(orthoType_default_),
403  "The type of orthogonalization to use to generate polynomial: DGKS, ICGS, or IMGS.");
404  validPL_ = pl;
405  }
406  return validPL_;
407 }
408 
409 
410 template<class ScalarType, class MV, class OP>
413 {
414  // Create the internal parameter list if ones doesn't already exist.
415  if (params_.is_null ()) {
416  params_ = Teuchos::parameterList (*getValidParameters ());
417  }
418  else {
419  params->validateParameters (*getValidParameters ());
420  }
421 
422  // Check which Gmres polynomial to use
423  if (params->isParameter("Polynomial Type")) {
424  polyType_ = params->get("Polynomial Type", polyType_default_);
425  }
426 
427  // Update the outer solver in our list.
428  params_->set("Polynomial Type", polyType_);
429 
430  // Check if there is an outer solver for this Gmres Polynomial
431  if (params->isParameter("Outer Solver")) {
432  outerSolverType_ = params->get("Outer Solver", outerSolverType_default_);
433  }
434 
435  // Update the outer solver in our list.
436  params_->set("Outer Solver", outerSolverType_);
437 
438  // Check if there is a parameter list for the outer solver
439  if (params->isSublist("Outer Solver Params")) {
440  outerParams_ = Teuchos::parameterList( params->get<Teuchos::ParameterList>("Outer Solver Params") );
441  }
442 
443  // Check for maximum polynomial degree
444  if (params->isParameter("Maximum Degree")) {
445  maxDegree_ = params->get("Maximum Degree",maxDegree_default_);
446  }
447 
448  // Update parameter in our list.
449  params_->set("Maximum Degree", maxDegree_);
450 
451  // Check to see if the timer label changed.
452  if (params->isParameter("Timer Label")) {
453  std::string tempLabel = params->get("Timer Label", label_default_);
454 
455  // Update parameter in our list and solver timer
456  if (tempLabel != label_) {
457  label_ = tempLabel;
458 #ifdef BELOS_TEUCHOS_TIME_MONITOR
459  std::string polyLabel = label_ + ": GmresPolyOp creation time";
460  timerPoly_ = Teuchos::TimeMonitor::getNewCounter(polyLabel);
461 #endif
462  }
463  }
464 
465  // Update timer label
466  params_->set("Timer Label", label_);
467 
468  // Check if the orthogonalization changed.
469  if (params->isParameter("Orthogonalization")) {
470  std::string tempOrthoType = params->get("Orthogonalization",orthoType_default_);
471  TEUCHOS_TEST_FOR_EXCEPTION( tempOrthoType != "DGKS" && tempOrthoType != "ICGS" && tempOrthoType != "IMGS",
472  std::invalid_argument,
473  "Belos::GmresPolySolMgr: \"Orthogonalization\" must be either \"DGKS\", \"ICGS\", or \"IMGS\".");
474  if (tempOrthoType != orthoType_) {
475  orthoType_ = tempOrthoType;
476  }
477  }
478 
479  params_->set("Orthogonalization", orthoType_);
480 
481  // Check for a change in verbosity level
482  if (params->isParameter("Verbosity")) {
483  if (Teuchos::isParameterType<int>(*params,"Verbosity")) {
484  verbosity_ = params->get("Verbosity", verbosity_default_);
485  } else {
486  verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,"Verbosity");
487  }
488  }
489 
490  // Update parameter in our list.
491  params_->set("Verbosity", verbosity_);
492 
493  // output stream
494  if (params->isParameter("Output Stream")) {
495  outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,"Output Stream");
496  }
497 
498  // Update parameter in our list.
499  params_->set("Output Stream", outputStream_);
500 
501  // Convergence
502  // Check for polynomial convergence tolerance
503  if (params->isParameter("Polynomial Tolerance")) {
504  if (params->isType<MagnitudeType> ("Polynomial Tolerance")) {
505  polyTol_ = params->get ("Polynomial Tolerance",
506  static_cast<MagnitudeType> (DefaultSolverParameters::polyTol));
507  }
508  else {
509  polyTol_ = params->get ("Polynomial Tolerance", DefaultSolverParameters::polyTol);
510  }
511  }
512 
513  // Update parameter in our list and residual tests.
514  params_->set("Polynomial Tolerance", polyTol_);
515 
516  // Check for maximum polynomial degree
517  if (params->isParameter("Random RHS")) {
518  randomRHS_ = params->get("Random RHS",true);
519  }
520 
521  // Update parameter in our list.
522  params_->set("Random RHS", randomRHS_);
523 
524  // Create the timers if we need to.
525 #ifdef BELOS_TEUCHOS_TIME_MONITOR
526  if (timerPoly_ == Teuchos::null) {
527  std::string polyLabel = label_ + ": GmresPolyOp creation time";
528  timerPoly_ = Teuchos::TimeMonitor::getNewCounter(polyLabel);
529  }
530 #endif
531 
532  // Check if we are going to perform an outer solve.
533  if (outerSolverType_ != "") {
534  hasOuterSolver_ = true;
535  }
536 
537  // Inform the solver manager that the current parameters were set.
538  isSet_ = true;
539 }
540 
541 
542 template<class ScalarType, class MV, class OP>
544 {
545  using Teuchos::RCP;
546  using Teuchos::rcp;
547  using Teuchos::rcp_const_cast;
548 
549  // Assume convergence is achieved if user does not require strict convergence.
551 
552  // Set the current parameters if they were not set before. NOTE:
553  // This may occur if the user generated the solver manager with the
554  // default constructor and then didn't set any parameters using
555  // setParameters().
556  if (! isSet_) {
557  setParameters (Teuchos::parameterList (*getValidParameters ()));
558  }
559 
561  problem_.is_null (), GmresPolySolMgrLinearProblemFailure,
562  "Belos::GmresPolySolMgr::solve: The linear problem has not been set yet, "
563  "or was set to null. Please call setProblem() with a nonnull input before "
564  "calling solve().");
565 
567  ! problem_->isProblemSet (), GmresPolySolMgrLinearProblemFailure,
568  "Belos::GmresPolySolMgr::solve: The linear problem is not ready. Please "
569  "call setProblem() on the LinearProblem object before calling solve().");
570 
571  // If the GMRES polynomial has not been constructed for this
572  // (nmatrix, preconditioner) pair, generate it.
573  if (!poly_dim_ && maxDegree_) {
574 #ifdef BELOS_TEUCHOS_TIME_MONITOR
575  Teuchos::TimeMonitor slvtimer(*timerPoly_);
576 #endif
577  poly_Op_ = Teuchos::rcp( new gmres_poly_t( problem_, params_ ) );
578  poly_dim_ = poly_Op_->polyDegree();
579 
581  "Belos::GmresPolyOp: Failed to generate polynomial that satisfied requirements.");
582  }
583 
584 
585  // Solve the linear system using the polynomial
586  if (hasOuterSolver_ && maxDegree_) {
587 
588  // Then the polynomial will be used as an operator for an outer solver.
589  // Use outer solver parameter list passed in a sublist.
591  RCP<SolverManager<ScalarType, MultiVec<ScalarType>, Operator<ScalarType> > > solver = factory.create( outerSolverType_, outerParams_ );
592  TEUCHOS_TEST_FOR_EXCEPTION( solver == Teuchos::null, std::invalid_argument,
593  "Belos::GmresPolySolMgr::solve(): Selected solver is not valid.");
594 
595  // Create a copy of the linear problem that uses the polynomial as a preconditioner.
596  // The original initial solution and right-hand side are thinly wrapped in the gmres_poly_mv_t
597  RCP<gmres_poly_mv_t> new_lhs = rcp( new gmres_poly_mv_t( problem_->getLHS() ) );
598  RCP<gmres_poly_mv_t> new_rhs = rcp( new gmres_poly_mv_t( rcp_const_cast<MV>( problem_->getRHS() ) ) );
599  RCP<gmres_poly_t> A = rcp( new gmres_poly_t( problem_ ) ); // This just performs problem_->applyOp
600  RCP<LinearProblem<ScalarType,MultiVec<ScalarType>,Operator<ScalarType> > > newProblem =
601  rcp( new LinearProblem<ScalarType,MultiVec<ScalarType>,Operator<ScalarType> >( A, new_lhs, new_rhs ) );
602  std::string solverLabel = label_ + ": Hybrid Gmres";
603  newProblem->setLabel(solverLabel);
604 
605  // If the preconditioner is left preconditioner, use Gmres poly as a left preconditioner.
606  if (problem_->getLeftPrec() != Teuchos::null)
607  newProblem->setLeftPrec( poly_Op_ );
608  else
609  newProblem->setRightPrec( poly_Op_ );
610  // Set the initial residual vector, if it has already been set in the original problem.
611  // Don't set the preconditioned residual vector, because it is not the GmresPoly preconditioned residual vector.
612  if (problem_->getInitResVec() != Teuchos::null)
613  newProblem->setInitResVec( rcp( new gmres_poly_mv_t( rcp_const_cast<MV>( problem_->getInitResVec() ) ) ) );
614  newProblem->setProblem();
615 
616  solver->setProblem( newProblem );
617 
618  ret = solver->solve();
619  numIters_ = solver->getNumIters();
620  loaDetected_ = solver->isLOADetected();
621 
622  } // if (hasOuterSolver_ && maxDegree_)
623  else if (hasOuterSolver_) {
624 
625  // There is no polynomial, just create the outer solver with the outerSolverType_ and outerParams_.
627  RCP<SolverManager<ScalarType, MV, OP> > solver = factory.create( outerSolverType_, outerParams_ );
628  TEUCHOS_TEST_FOR_EXCEPTION( solver == Teuchos::null, std::invalid_argument,
629  "Belos::GmresPolySolMgr::solve(): Selected solver is not valid.");
630 
631  solver->setProblem( problem_ );
632 
633  ret = solver->solve();
634  numIters_ = solver->getNumIters();
635  loaDetected_ = solver->isLOADetected();
636 
637  }
638  else if (maxDegree_) {
639 
640  // Apply the polynomial to the current linear system
641  poly_Op_->ApplyPoly( *problem_->getRHS(), *problem_->getLHS() );
642 
643  }
644 
645  return ret;
646 }
647 
648 
649 template<class ScalarType, class MV, class OP>
651 {
652  std::ostringstream out;
653 
654  out << "\"Belos::GmresPolySolMgr\": {"
655  << "ScalarType: " << Teuchos::TypeNameTraits<ScalarType>::name ()
656  << ", Poly Degree: " << poly_dim_
657  << ", Poly Max Degree: " << maxDegree_
658  << ", Poly Tol: " << polyTol_;
659  out << "}";
660  return out.str ();
661 }
662 
663 } // namespace Belos
664 
665 #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)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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)
static const double polyTol
Relative residual tolerance for matrix polynomial construction.
Definition: BelosTypes.hpp:304
Traits class which defines basic operations on multivectors.
bool isParameter(const std::string &name) const
ResetType
How to reset the solver.
Definition: BelosTypes.hpp:206
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 isSublist(const std::string &name) const
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.
Hybrid block GMRES iterative linear solver.
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:155
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:60
Default parameters common to most Belos solvers.
Definition: BelosTypes.hpp:291
GmresPolySolMgr()
Empty constructor for GmresPolySolMgr. This constructor takes no arguments and sets the default value...
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 Jun 5 2020 10:20:40 for Belos by doxygen 1.8.5