Belos Version of the Day
Loading...
Searching...
No Matches
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
23#include "BelosGmresPolyOp.hpp"
26#include "Teuchos_as.hpp"
27#ifdef BELOS_TEUCHOS_TIME_MONITOR
28#include "Teuchos_TimeMonitor.hpp"
29#endif
30
35namespace Belos {
36
38
39
49
59
73//
108//
120
121template<class ScalarType, class MV, class OP>
122class GmresPolySolMgr : public SolverManager<ScalarType,MV,OP> {
123private:
124
125 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
126
127 typedef Teuchos::ScalarTraits<MagnitudeType> MTS;
130
131public:
132
134
135
142
162 const Teuchos::RCP<Teuchos::ParameterList> &pl );
163
165 virtual ~GmresPolySolMgr() {};
166
168 Teuchos::RCP<SolverManager<ScalarType, MV, OP> > clone () const override {
169 return Teuchos::rcp(new GmresPolySolMgr<ScalarType,MV,OP>);
170 }
172
174
175
179 return *problem_;
180 }
181
184 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const override;
185
188 Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const override { return params_; }
189
206 MagnitudeType achievedTol() const override {
207 return achievedTol_;
208 }
209
215 Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
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
293private:
294
295 // Linear problem.
296 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
297
298 // Output manager.
299 Teuchos::RCP<std::ostream> outputStream_;
300
301 // Current parameter list.
302 Teuchos::RCP<Teuchos::ParameterList> params_;
303 Teuchos::RCP<Teuchos::ParameterList> outerParams_;
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_;
330 Teuchos::RCP<gmres_poly_t> poly_Op_;
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
341 mutable Teuchos::RCP<const Teuchos::ParameterList> validPL_;
342};
343
344
345template<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
367template<class ScalarType, class MV, class OP>
370 const Teuchos::RCP<Teuchos::ParameterList> &pl) :
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 ()) {
399 }
400}
401
402
403template<class ScalarType, class MV, class OP>
404Teuchos::RCP<const Teuchos::ParameterList>
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
444template<class ScalarType, class MV, class OP>
446setParameters (const Teuchos::RCP<Teuchos::ParameterList>& params)
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
599template<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
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
709template<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
Belos header file which uses auto-configuration information to include necessary C++ headers.
Defines the GMRES polynomial operator hybrid-GMRES iterative linear solver.
Class which describes the linear problem to be solved by the iterative solver.
Pure virtual base class which describes the basic interface for a solver manager.
Collection of types and exceptions used within the Belos solvers.
Parent class to all Belos exceptions.
GmresPolySolMgrLinearProblemFailure is thrown when the linear problem is not setup (i....
GmresPolySolMgrLinearProblemFailure(const std::string &what_arg)
GmresPolySolMgrPolynomialFailure is thrown when their is a problem generating the GMRES polynomial fo...
GmresPolySolMgrPolynomialFailure(const std::string &what_arg)
The GMRES polynomial can be created in conjunction with any standard preconditioner.
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
Get a parameter list containing the current parameters for this object.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
int getNumIters() const override
Get the iteration count for the most recent call to solve().
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
std::string description() const override
Method to return description of the hybrid block GMRES solver manager.
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
bool isLOADetected() const override
Return whether a loss of accuracy was detected by this solver during the most current solve.
const LinearProblem< ScalarType, MV, OP > & getProblem() const override
Get current linear problem being solved for in this object.
virtual ~GmresPolySolMgr()
Destructor.
GmresPolySolMgr()
Empty constructor for GmresPolySolMgr. This constructor takes no arguments and sets the default value...
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) override
Set the linear problem that needs to be solved.
void reset(const ResetType type) override
Reset the solver.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
Get a parameter list containing the valid parameters for this object.
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > &params) override
Set the parameters the solver manager should use to solve the linear problem.
ReturnType solve() override
This method performs possibly repeated calls to the underlying linear solver's iterate() routine unti...
A linear system to solve, and its associated information.
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).
The Belos::SolverManager is a templated virtual base class that defines the basic interface that any ...
ReturnType
Whether the Belos solve converged for all linear systems.
ResetType
How to reset the solver.
Default parameters common to most Belos solvers.
static const double polyTol
Relative residual tolerance for matrix polynomial construction.

Generated for Belos by doxygen 1.9.8