Belos Version of the Day
Loading...
Searching...
No Matches
BelosPseudoBlockCGSolMgr.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#ifndef BELOS_PSEUDO_BLOCK_CG_SOLMGR_HPP
11#define BELOS_PSEUDO_BLOCK_CG_SOLMGR_HPP
12
17#include "BelosCGIteration.hpp"
18#include "BelosConfigDefs.hpp"
19#include "BelosTypes.hpp"
20
23
25#include "BelosCGIter.hpp"
31#include "Teuchos_LAPACK.hpp"
32#ifdef BELOS_TEUCHOS_TIME_MONITOR
33#include "Teuchos_TimeMonitor.hpp"
34#endif
35
55namespace Belos {
56
58
59
69
70
71 // Partial specialization for unsupported ScalarType types.
72 // This contains a stub implementation.
73 template<class ScalarType, class MV, class OP,
74 const bool supportsScalarType =
77 public Details::SolverManagerRequiresLapack<ScalarType, MV, OP,
78 Belos::Details::LapackSupportsScalar<ScalarType>::value>
79 {
80 static const bool scalarTypeIsSupported =
83
84 public:
89 const Teuchos::RCP<Teuchos::ParameterList> &pl) :
90 base_type ()
91 {}
92 virtual ~PseudoBlockCGSolMgr () = default;
93
94 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> >
95 getResidualStatusTest() const { return Teuchos::null; }
96 };
97
98
99 template<class ScalarType, class MV, class OP>
101 public Details::SolverManagerRequiresLapack<ScalarType, MV, OP, true>
102 {
103 private:
106 using SCT = Teuchos::ScalarTraits<ScalarType>;
107 using MagnitudeType = typename Teuchos::ScalarTraits<ScalarType>::magnitudeType;
108 using MT = Teuchos::ScalarTraits<MagnitudeType>;
109
110 public:
111
113
114
121
138 const Teuchos::RCP<Teuchos::ParameterList> &pl );
139
141 virtual ~PseudoBlockCGSolMgr() = default;
142
144 Teuchos::RCP<SolverManager<ScalarType, MV, OP> > clone () const override {
145 return Teuchos::rcp(new PseudoBlockCGSolMgr<ScalarType,MV,OP>);
146 }
148
150
151
153 return *problem_;
154 }
155
158 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const override;
159
162 Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const override { return params_; }
163
169 Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
170 return Teuchos::tuple(timerSolve_);
171 }
172
173
184 MagnitudeType achievedTol() const override {
185 return achievedTol_;
186 }
187
189 int getNumIters() const override {
190 return numIters_;
191 }
192
196 bool isLOADetected() const override { return false; }
197
201 ScalarType getConditionEstimate() const {return condEstimate_;}
202 Teuchos::ArrayRCP<MagnitudeType> getEigenEstimates() const {return eigenEstimates_;}
203
205 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> >
206 getResidualStatusTest() const { return convTest_; }
207
209
211
212
214 void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) override { problem_ = problem; }
215
217 void setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params ) override;
218
220
222
223
227 void reset( const ResetType type ) override { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
229
231
232
250 ReturnType solve() override;
251
253
256
258 std::string description() const override;
259
261 private:
262 // Compute the condition number estimate
263 void compute_condnum_tridiag_sym(Teuchos::ArrayView<MagnitudeType> diag,
264 Teuchos::ArrayView<MagnitudeType> offdiag,
265 Teuchos::ArrayRCP<MagnitudeType>& lambdas,
269
270 // Linear problem.
271 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
272
273 // Output manager.
274 Teuchos::RCP<OutputManager<ScalarType> > printer_;
275 Teuchos::RCP<std::ostream> outputStream_;
276
277 // Status test.
278 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
279 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
280 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
281 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
282
283 // Current parameter list.
284 Teuchos::RCP<Teuchos::ParameterList> params_;
285
291 mutable Teuchos::RCP<const Teuchos::ParameterList> validParams_;
292
293 // Default solver values.
294 static constexpr int maxIters_default_ = 1000;
295 static constexpr bool assertPositiveDefiniteness_default_ = true;
296 static constexpr bool showMaxResNormOnly_default_ = false;
297 static constexpr int verbosity_default_ = Belos::Errors;
298 static constexpr int outputStyle_default_ = Belos::General;
299 static constexpr int outputFreq_default_ = -1;
300 static constexpr int defQuorum_default_ = 1;
301 static constexpr bool foldConvergenceDetectionIntoAllreduce_default_ = false;
302 static constexpr const char * resScale_default_ = "Norm of Initial Residual";
303 static constexpr const char * label_default_ = "Belos";
304 static constexpr bool genCondEst_default_ = false;
305
306 // Current solver values.
307 MagnitudeType convtol_,achievedTol_;
308 int maxIters_, numIters_;
309 int verbosity_, outputStyle_, outputFreq_, defQuorum_;
310 bool assertPositiveDefiniteness_, showMaxResNormOnly_;
311 bool foldConvergenceDetectionIntoAllreduce_;
312 std::string resScale_;
313 bool genCondEst_;
314 ScalarType condEstimate_;
315 Teuchos::ArrayRCP<MagnitudeType> eigenEstimates_;
316
317 Teuchos::RCP<CGIterationStateBase<ScalarType, MV> > state_;
318
319 // Timers.
320 std::string label_;
321 Teuchos::RCP<Teuchos::Time> timerSolve_;
322
323 // Internal state variables.
324 bool isSet_;
325 };
326
327
328// Empty Constructor
329template<class ScalarType, class MV, class OP>
331 outputStream_(Teuchos::rcpFromRef(std::cout)),
332 convtol_(DefaultSolverParameters::convTol),
333 maxIters_(maxIters_default_),
334 numIters_(0),
335 verbosity_(verbosity_default_),
336 outputStyle_(outputStyle_default_),
337 outputFreq_(outputFreq_default_),
338 defQuorum_(defQuorum_default_),
339 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
340 showMaxResNormOnly_(showMaxResNormOnly_default_),
341 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
342 resScale_(resScale_default_),
343 genCondEst_(genCondEst_default_),
344 condEstimate_(-Teuchos::ScalarTraits<ScalarType>::one()),
345 label_(label_default_),
346 isSet_(false)
347{}
348
349// Basic Constructor
350template<class ScalarType, class MV, class OP>
353 const Teuchos::RCP<Teuchos::ParameterList> &pl ) :
354 problem_(problem),
355 outputStream_(Teuchos::rcpFromRef(std::cout)),
356 convtol_(DefaultSolverParameters::convTol),
357 maxIters_(maxIters_default_),
358 numIters_(0),
359 verbosity_(verbosity_default_),
360 outputStyle_(outputStyle_default_),
361 outputFreq_(outputFreq_default_),
362 defQuorum_(defQuorum_default_),
363 assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
364 showMaxResNormOnly_(showMaxResNormOnly_default_),
365 foldConvergenceDetectionIntoAllreduce_(foldConvergenceDetectionIntoAllreduce_default_),
366 resScale_(resScale_default_),
367 genCondEst_(genCondEst_default_),
368 condEstimate_(-Teuchos::ScalarTraits<ScalarType>::one()),
369 label_(label_default_),
370 isSet_(false)
371{
373 problem_.is_null (), std::invalid_argument,
374 "Belos::PseudoBlockCGSolMgr two-argument constructor: "
375 "'problem' is null. You must supply a non-null Belos::LinearProblem "
376 "instance when calling this constructor.");
377
378 if (! pl.is_null ()) {
379 // Set the parameters using the list that was passed in.
380 setParameters (pl);
381 }
382}
383
384template<class ScalarType, class MV, class OP>
385void
387setParameters (const Teuchos::RCP<Teuchos::ParameterList>& params)
388{
389 using Teuchos::ParameterList;
390 using Teuchos::parameterList;
391 using Teuchos::RCP;
392 using Teuchos::rcp;
393
394 RCP<const ParameterList> defaultParams = this->getValidParameters ();
395
396 // Create the internal parameter list if one doesn't already exist.
397 // Belos' solvers treat the input ParameterList to setParameters as
398 // a "delta" -- that is, a change from the current state -- so the
399 // default parameter list (if the input is null) should be empty.
400 // This explains also why Belos' solvers copy parameters one by one
401 // from the input list to the current list.
402 //
403 // Belos obfuscates the latter, because it takes the input parameter
404 // list by RCP, rather than by (nonconst) reference. The latter
405 // would make more sense, given that it doesn't actually keep the
406 // input parameter list.
407 //
408 // Note, however, that Belos still correctly triggers the "used"
409 // field of each parameter in the input list. While isParameter()
410 // doesn't (apparently) trigger the "used" flag, get() certainly
411 // does.
412
413 if (params_.is_null ()) {
414 // Create an empty list with the same name as the default list.
415 params_ = parameterList (defaultParams->name ());
416 } else {
417 params->validateParameters (*defaultParams);
418 }
419
420 // Check for maximum number of iterations
421 if (params->isParameter ("Maximum Iterations")) {
422 maxIters_ = params->get ("Maximum Iterations", maxIters_default_);
423
424 // Update parameter in our list and in status test.
425 params_->set ("Maximum Iterations", maxIters_);
426 if (! maxIterTest_.is_null ()) {
427 maxIterTest_->setMaxIters (maxIters_);
428 }
429 }
430
431 // Check if positive definiteness assertions are to be performed
432 if (params->isParameter ("Assert Positive Definiteness")) {
433 assertPositiveDefiniteness_ =
434 params->get ("Assert Positive Definiteness",
435 assertPositiveDefiniteness_default_);
436
437 // Update parameter in our list.
438 params_->set ("Assert Positive Definiteness", assertPositiveDefiniteness_);
439 }
440
441 if (params->isParameter("Fold Convergence Detection Into Allreduce")) {
442 foldConvergenceDetectionIntoAllreduce_ = params->get("Fold Convergence Detection Into Allreduce",
443 foldConvergenceDetectionIntoAllreduce_default_);
444 }
445
446 // Check to see if the timer label changed.
447 if (params->isParameter ("Timer Label")) {
448 const std::string tempLabel = params->get ("Timer Label", label_default_);
449
450 // Update parameter in our list and solver timer
451 if (tempLabel != label_) {
452 label_ = tempLabel;
453 params_->set ("Timer Label", label_);
454 const std::string solveLabel =
455 label_ + ": PseudoBlockCGSolMgr total solve time";
456#ifdef BELOS_TEUCHOS_TIME_MONITOR
457 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
458#endif
459 }
460 }
461
462 // Check for a change in verbosity level
463 if (params->isParameter ("Verbosity")) {
464 if (Teuchos::isParameterType<int> (*params, "Verbosity")) {
465 verbosity_ = params->get ("Verbosity", verbosity_default_);
466 } else {
467 verbosity_ = (int) Teuchos::getParameter<Belos::MsgType> (*params, "Verbosity");
468 }
469
470 // Update parameter in our list.
471 params_->set ("Verbosity", verbosity_);
472 if (! printer_.is_null ()) {
473 printer_->setVerbosity (verbosity_);
474 }
475 }
476
477 // Check for a change in output style
478 if (params->isParameter ("Output Style")) {
479 if (Teuchos::isParameterType<int> (*params, "Output Style")) {
480 outputStyle_ = params->get ("Output Style", outputStyle_default_);
481 } else {
482 // FIXME (mfh 29 Jul 2015) What if the type is wrong?
483 outputStyle_ = (int) Teuchos::getParameter<Belos::OutputType> (*params, "Output Style");
484 }
485
486 // Reconstruct the convergence test if the explicit residual test
487 // is not being used.
488 params_->set ("Output Style", outputStyle_);
489 outputTest_ = Teuchos::null;
490 }
491
492 // output stream
493 if (params->isParameter ("Output Stream")) {
494 outputStream_ = params->get<RCP<std::ostream> > ("Output Stream");
495
496 // Update parameter in our list.
497 params_->set ("Output Stream", outputStream_);
498 if (! printer_.is_null ()) {
499 printer_->setOStream (outputStream_);
500 }
501 }
502
503 // frequency level
504 if (verbosity_ & Belos::StatusTestDetails) {
505 if (params->isParameter ("Output Frequency")) {
506 outputFreq_ = params->get ("Output Frequency", outputFreq_default_);
507 }
508
509 // Update parameter in out list and output status test.
510 params_->set ("Output Frequency", outputFreq_);
511 if (! outputTest_.is_null ()) {
512 outputTest_->setOutputFrequency (outputFreq_);
513 }
514 }
515
516 // Condition estimate
517 if (params->isParameter ("Estimate Condition Number")) {
518 genCondEst_ = params->get ("Estimate Condition Number", genCondEst_default_);
519 }
520
521 // Create output manager if we need to.
522 if (printer_.is_null ()) {
523 printer_ = rcp (new OutputManager<ScalarType> (verbosity_, outputStream_));
524 }
525
526 // Convergence
527 using StatusTestCombo_t = Belos::StatusTestCombo<ScalarType, MV, OP>;
528 using StatusTestResNorm_t = Belos::StatusTestGenResNorm<ScalarType, MV, OP>;
529
530 // Check for convergence tolerance
531 if (params->isParameter ("Convergence Tolerance")) {
532 if (params->isType<MagnitudeType> ("Convergence Tolerance")) {
533 convtol_ = params->get ("Convergence Tolerance",
534 static_cast<MagnitudeType> (DefaultSolverParameters::convTol));
535 }
536 else {
537 convtol_ = params->get ("Convergence Tolerance", DefaultSolverParameters::convTol);
538 }
539
540 // Update parameter in our list and residual tests.
541 params_->set ("Convergence Tolerance", convtol_);
542 if (! convTest_.is_null ()) {
543 convTest_->setTolerance (convtol_);
544 }
545 }
546
547 if (params->isParameter ("Show Maximum Residual Norm Only")) {
548 showMaxResNormOnly_ = params->get<bool> ("Show Maximum Residual Norm Only");
549
550 // Update parameter in our list and residual tests
551 params_->set ("Show Maximum Residual Norm Only", showMaxResNormOnly_);
552 if (! convTest_.is_null ()) {
553 convTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
554 }
555 }
556
557 // Check for a change in scaling, if so we need to build new residual tests.
558 bool newResTest = false;
559 {
560 // "Residual Scaling" is the old parameter name; "Implicit
561 // Residual Scaling" is the new name. We support both options for
562 // backwards compatibility.
563 std::string tempResScale = resScale_;
564 bool implicitResidualScalingName = false;
565 if (params->isParameter ("Residual Scaling")) {
566 tempResScale = params->get<std::string> ("Residual Scaling");
567 }
568 else if (params->isParameter ("Implicit Residual Scaling")) {
569 tempResScale = params->get<std::string> ("Implicit Residual Scaling");
571 }
572
573 // Only update the scaling if it's different.
574 if (resScale_ != tempResScale) {
577 resScale_ = tempResScale;
578
579 // Update parameter in our list and residual tests, using the
580 // given parameter name.
582 params_->set ("Implicit Residual Scaling", resScale_);
583 }
584 else {
585 params_->set ("Residual Scaling", resScale_);
586 }
587
588 if (! convTest_.is_null ()) {
589 try {
590 convTest_->defineScaleForm (resScaleType, Belos::TwoNorm);
591 }
592 catch (std::exception& e) {
593 // Make sure the convergence test gets constructed again.
594 newResTest = true;
595 }
596 }
597 }
598 }
599
600 // Get the deflation quorum, or number of converged systems before deflation is allowed
601 if (params->isParameter ("Deflation Quorum")) {
602 defQuorum_ = params->get ("Deflation Quorum", defQuorum_);
603 params_->set ("Deflation Quorum", defQuorum_);
604 if (! convTest_.is_null ()) {
605 convTest_->setQuorum( defQuorum_ );
606 }
607 }
608
609 // Create status tests if we need to.
610
611 // Basic test checks maximum iterations and native residual.
612 if (maxIterTest_.is_null ()) {
613 maxIterTest_ = rcp (new StatusTestMaxIters<ScalarType,MV,OP> (maxIters_));
614 }
615
616 // Implicit residual test, using the native residual to determine if convergence was achieved.
617 if (convTest_.is_null () || newResTest) {
618 convTest_ = rcp (new StatusTestResNorm_t (convtol_, defQuorum_, showMaxResNormOnly_));
619 convTest_->defineScaleForm (convertStringToScaleType (resScale_), Belos::TwoNorm);
620 }
621
622 if (sTest_.is_null () || newResTest) {
623 sTest_ = rcp (new StatusTestCombo_t (StatusTestCombo_t::OR, maxIterTest_, convTest_));
624 }
625
626 if (outputTest_.is_null () || newResTest) {
627 // Create the status test output class.
628 // This class manages and formats the output from the status test.
630 outputTest_ = stoFactory.create (printer_, sTest_, outputFreq_,
632
633 // Set the solver string for the output test
634 const std::string solverDesc = " Pseudo Block CG ";
635 outputTest_->setSolverDesc (solverDesc);
636 }
637
638 // Create the timer if we need to.
639 if (timerSolve_.is_null ()) {
640 const std::string solveLabel =
641 label_ + ": PseudoBlockCGSolMgr total solve time";
642#ifdef BELOS_TEUCHOS_TIME_MONITOR
643 timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
644#endif
645 }
646
647 // Inform the solver manager that the current parameters were set.
648 isSet_ = true;
649}
650
651
652template<class ScalarType, class MV, class OP>
653Teuchos::RCP<const Teuchos::ParameterList>
655{
656 using Teuchos::ParameterList;
657 using Teuchos::parameterList;
658 using Teuchos::RCP;
659
660 if (validParams_.is_null()) {
661 // Set all the valid parameters and their default values.
663 pl->set("Convergence Tolerance", static_cast<MagnitudeType>(DefaultSolverParameters::convTol),
664 "The relative residual tolerance that needs to be achieved by the\n"
665 "iterative solver in order for the linear system to be declared converged.");
666 pl->set("Maximum Iterations", static_cast<int>(maxIters_default_),
667 "The maximum number of block iterations allowed for each\n"
668 "set of RHS solved.");
669 pl->set("Assert Positive Definiteness", static_cast<bool>(assertPositiveDefiniteness_default_),
670 "Whether or not to assert that the linear operator\n"
671 "and the preconditioner are indeed positive definite.");
672 pl->set("Verbosity", static_cast<int>(verbosity_default_),
673 "What type(s) of solver information should be outputted\n"
674 "to the output stream.");
675 pl->set("Output Style", static_cast<int>(outputStyle_default_),
676 "What style is used for the solver information outputted\n"
677 "to the output stream.");
678 pl->set("Output Frequency", static_cast<int>(outputFreq_default_),
679 "How often convergence information should be outputted\n"
680 "to the output stream.");
681 pl->set("Deflation Quorum", static_cast<int>(defQuorum_default_),
682 "The number of linear systems that need to converge before\n"
683 "they are deflated. This number should be <= block size.");
684 pl->set("Output Stream", Teuchos::rcpFromRef(std::cout),
685 "A reference-counted pointer to the output stream where all\n"
686 "solver output is sent.");
687 pl->set("Show Maximum Residual Norm Only", static_cast<bool>(showMaxResNormOnly_default_),
688 "When convergence information is printed, only show the maximum\n"
689 "relative residual norm when the block size is greater than one.");
690 pl->set("Implicit Residual Scaling", resScale_default_,
691 "The type of scaling used in the residual convergence test.");
692 pl->set("Estimate Condition Number", static_cast<bool>(genCondEst_default_),
693 "Whether or not to estimate the condition number of the preconditioned system.");
694 // We leave the old name as a valid parameter for backwards
695 // compatibility (so that validateParametersAndSetDefaults()
696 // doesn't raise an exception if it encounters "Residual
697 // Scaling"). The new name was added for compatibility with other
698 // solvers, none of which use "Residual Scaling".
699 pl->set("Residual Scaling", resScale_default_,
700 "The type of scaling used in the residual convergence test. This "
701 "name is deprecated; the new name is \"Implicit Residual Scaling\".");
702 pl->set("Timer Label", static_cast<const char *>(label_default_),
703 "The string to use as a prefix for the timer labels.");
704 pl->set("Fold Convergence Detection Into Allreduce",static_cast<bool>(foldConvergenceDetectionIntoAllreduce_default_),
705 "Merge the allreduce for convergence detection with the one for CG.\n"
706 "This saves one all-reduce, but incurs more computation.");
707 validParams_ = pl;
708 }
709 return validParams_;
710}
711
712
713// solve()
714template<class ScalarType, class MV, class OP>
716{
717 const char prefix[] = "Belos::PseudoBlockCGSolMgr::solve: ";
718
719 // Set the current parameters if they were not set before.
720 // NOTE: This may occur if the user generated the solver manager with the default constructor and
721 // then didn't set any parameters using setParameters().
722 if (!isSet_) { setParameters( params_ ); }
723
725 (! problem_->isProblemSet (), PseudoBlockCGSolMgrLinearProblemFailure,
726 prefix << "The linear problem to solve is not ready. You must call "
727 "setProblem() on the Belos::LinearProblem instance before telling the "
728 "Belos solver to solve it.");
729
730 // Create indices for the linear systems to be solved.
731 int startPtr = 0;
732 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
734
735 std::vector<int> currIdx( numRHS2Solve ), currIdx2( numRHS2Solve );
736 for (int i=0; i<numRHS2Solve; ++i) {
737 currIdx[i] = startPtr+i;
738 currIdx2[i]=i;
739 }
740
741 // Inform the linear problem of the current linear system to solve.
742 problem_->setLSIndex( currIdx );
743
745 // Parameter list (iteration)
746 Teuchos::ParameterList plist;
747
748 plist.set("Assert Positive Definiteness",assertPositiveDefiniteness_);
749 if(genCondEst_) plist.set("Max Size For Condest",maxIters_);
750
751 // Reset the status test.
752 outputTest_->reset();
753
754 // Assume convergence is achieved, then let any failed convergence set this to false.
755 bool isConverged = true;
756
758 // Pseudo-Block CG solver
759 Teuchos::RCP<CGIteration<ScalarType,MV,OP> > block_cg_iter;
760 if (numRHS2Solve == 1) {
761 plist.set("Fold Convergence Detection Into Allreduce",
762 foldConvergenceDetectionIntoAllreduce_);
764 Teuchos::rcp (new CGIter<ScalarType,MV,OP> (problem_, printer_, outputTest_, convTest_, plist));
765 if (state_.is_null() || Teuchos::rcp_dynamic_cast<CGIterationState<ScalarType, MV> >(state_).is_null())
766 state_ = Teuchos::rcp(new CGIterationState<ScalarType, MV>());
767 } else {
769 Teuchos::rcp (new PseudoBlockCGIter<ScalarType,MV,OP> (problem_, printer_, outputTest_, plist));
770 if (state_.is_null() || Teuchos::rcp_dynamic_cast<PseudoBlockCGIterationState<ScalarType, MV> >(state_).is_null())
771 state_ = Teuchos::rcp(new PseudoBlockCGIterationState<ScalarType, MV>());
772 }
773
774 // Setup condition estimate
775 block_cg_iter->setDoCondEst(genCondEst_);
776 bool condEstPerf = false;
777
778 // Enter solve() iterations
779 {
780#ifdef BELOS_TEUCHOS_TIME_MONITOR
781 Teuchos::TimeMonitor slvtimer(*timerSolve_);
782#endif
783
784 while ( numRHS2Solve > 0 ) {
785
786 // Reset the active / converged vectors from this block
787 std::vector<int> convRHSIdx;
788 std::vector<int> currRHSIdx( currIdx );
789 currRHSIdx.resize(numCurrRHS);
790
791 // Reset the number of iterations.
792 block_cg_iter->resetNumIters();
793
794 // Reset the number of calls that the status test output knows about.
795 outputTest_->resetNumCalls();
796
797 // Get the current residual for this block of linear systems.
798 Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
799
800 // Get a new state struct and initialize the solver.
801 block_cg_iter->initializeCG(state_, R_0);
802
803 while(true) {
804
805 // tell block_gmres_iter to iterate
806 try {
807
808 block_cg_iter->iterate();
809
811 //
812 // check convergence first
813 //
815 if ( convTest_->getStatus() == Passed ) {
816
817 // Figure out which linear systems converged.
818 std::vector<int> convIdx = Teuchos::rcp_dynamic_cast<StatusTestGenResNorm<ScalarType,MV,OP> >(convTest_)->convIndices();
819
820 // If the number of converged linear systems is equal to the
821 // number of current linear systems, then we are done with this block.
822 if (convIdx.size() == currRHSIdx.size())
823 break; // break from while(1){block_cg_iter->iterate()}
824
825 // Inform the linear problem that we are finished with this current linear system.
826 problem_->setCurrLS();
827
828 // Reset currRHSIdx to have the right-hand sides that are left to converge for this block.
829 int have = 0;
830 for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
831 bool found = false;
832 for (unsigned int j=0; j<convIdx.size(); ++j) {
833 if (currRHSIdx[i] == convIdx[j]) {
834 found = true;
835 break;
836 }
837 }
838 if (!found) {
841 }
842 }
843 currRHSIdx.resize(have);
844 currIdx2.resize(have);
845
846 // Compute condition estimate if the very first linear system in the block has converged.
847 if (currRHSIdx[0] != 0 && genCondEst_ && !condEstPerf)
848 {
849 // Compute the estimate.
851 Teuchos::ArrayView<MagnitudeType> diag = block_cg_iter->getDiag();
852 Teuchos::ArrayView<MagnitudeType> offdiag = block_cg_iter->getOffDiag();
853 compute_condnum_tridiag_sym(diag,offdiag,eigenEstimates_,l_min,l_max,condEstimate_);
854
855 // Make sure not to do more condition estimate computations for this solve.
856 block_cg_iter->setDoCondEst(false);
857 condEstPerf = true;
858 }
859
860 // Set the remaining indices after deflation.
861 problem_->setLSIndex( currRHSIdx );
862
863 // Get the current residual vector.
864 std::vector<MagnitudeType> norms;
865 R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
866 for (int i=0; i<have; ++i) { currIdx2[i] = i; }
867
868 // Set the new state and initialize the solver.
869 block_cg_iter->initializeCG(state_, R_0);
870 }
871
873 //
874 // check for maximum iterations
875 //
877 else if ( maxIterTest_->getStatus() == Passed ) {
878 // we don't have convergence
879 isConverged = false;
880 break; // break from while(1){block_cg_iter->iterate()}
881 }
882
884 //
885 // we returned from iterate(), but none of our status tests Passed.
886 // something is wrong, and it is probably our fault.
887 //
889
890 else {
891 TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
892 "Belos::PseudoBlockCGSolMgr::solve(): Invalid return from PseudoBlockCGIter::iterate().");
893 }
894 }
895 catch (const StatusTestNaNError& e) {
896 // A NaN was detected in the solver. Set the solution to zero and return unconverged.
897 achievedTol_ = MT::one();
898 Teuchos::RCP<MV> X = problem_->getLHS();
899 MVT::MvInit( *X, SCT::zero() );
900 printer_->stream(Warnings) << "Belos::PseudoBlockCGSolMgr::solve(): Warning! NaN has been detected!"
901 << std::endl;
902 return Unconverged;
903 }
904 catch (const std::exception &e) {
905 printer_->stream(Errors) << "Error! Caught std::exception in PseudoBlockCGIter::iterate() at iteration "
906 << block_cg_iter->getNumIters() << std::endl
907 << e.what() << std::endl;
908 throw;
909 }
910 }
911
912 // Inform the linear problem that we are finished with this block linear system.
913 problem_->setCurrLS();
914
915 // Update indices for the linear systems to be solved.
918
919 if ( numRHS2Solve > 0 ) {
920
922 currIdx.resize( numCurrRHS );
923 currIdx2.resize( numCurrRHS );
924 for (int i=0; i<numCurrRHS; ++i)
925 { currIdx[i] = startPtr+i; currIdx2[i] = i; }
926
927 // Set the next indices.
928 problem_->setLSIndex( currIdx );
929 }
930 else {
931 currIdx.resize( numRHS2Solve );
932 }
933
934 }// while ( numRHS2Solve > 0 )
935
936 }
937
938 // print final summary
939 sTest_->print( printer_->stream(FinalSummary) );
940
941 // print timing information
942#ifdef BELOS_TEUCHOS_TIME_MONITOR
943 // Calling summarize() can be expensive, so don't call unless the
944 // user wants to print out timing details. summarize() will do all
945 // the work even if it's passed a "black hole" output stream.
946 if (verbosity_ & TimingDetails)
947 Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
948#endif
949
950 // get iteration information for this solve
951 numIters_ = maxIterTest_->getNumIters();
952
953 // Save the convergence test value ("achieved tolerance") for this
954 // solve.
955 const std::vector<MagnitudeType>* pTestValues = convTest_->getTestValue();
956 if (pTestValues != NULL && pTestValues->size () > 0) {
957 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
958 }
959
960 // Do condition estimate, if needed
961 if (genCondEst_ && !condEstPerf) {
963 Teuchos::ArrayView<MagnitudeType> diag = block_cg_iter->getDiag();
964 Teuchos::ArrayView<MagnitudeType> offdiag = block_cg_iter->getOffDiag();
965 compute_condnum_tridiag_sym(diag,offdiag,eigenEstimates_,l_min,l_max,condEstimate_);
966 condEstPerf = true;
967 }
968
969 if (! isConverged) {
970 return Unconverged; // return from PseudoBlockCGSolMgr::solve()
971 }
972 return Converged; // return from PseudoBlockCGSolMgr::solve()
973}
974
975// This method requires the solver manager to return a std::string that describes itself.
976template<class ScalarType, class MV, class OP>
978{
979 std::ostringstream oss;
980 oss << "Belos::PseudoBlockCGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<">";
981 oss << "{";
982 oss << "}";
983 return oss.str();
984}
985
986
987template<class ScalarType, class MV, class OP>
988void
990compute_condnum_tridiag_sym (Teuchos::ArrayView<MagnitudeType> diag,
991 Teuchos::ArrayView<MagnitudeType> offdiag,
992 Teuchos::ArrayRCP<MagnitudeType>& lambdas,
996{
997 using STS = Teuchos::ScalarTraits<ScalarType>;
998
999 /* Copied from az_cg.c: compute_condnum_tridiag_sym */
1000 /* diag == ScalarType vector of size N, containing the diagonal
1001 elements of A
1002 offdiag == ScalarType vector of size N-1, containing the offdiagonal
1003 elements of A. Note that A is supposed to be symmatric
1004 */
1005 int info = 0;
1006 const int N = diag.size ();
1008 std::vector<MagnitudeType> mag_dummy(4*N);
1009 char char_N = 'N';
1010 Teuchos::LAPACK<int,ScalarType> lapack;
1011
1012 lambdas.resize(N, 0.0);
1013 lambda_min = STS::one ();
1014 lambda_max = STS::one ();
1015 if( N > 2 ) {
1016 lapack.PTEQR (char_N, N, diag.getRawPtr (), offdiag.getRawPtr (),
1017 &scalar_dummy, 1, &mag_dummy[0], &info);
1019 (info < 0, std::logic_error, "Belos::PseudoBlockCGSolMgr::"
1020 "compute_condnum_tridiag_sym: LAPACK's _PTEQR failed with info = "
1021 << info << " < 0. This suggests there might be a bug in the way Belos "
1022 "is calling LAPACK. Please report this to the Belos developers.");
1023 for (int k = 0; k < N; k++) {
1024 lambdas[k] = diag[N - 1 - k];
1025 }
1026 lambda_min = Teuchos::as<ScalarType> (diag[N-1]);
1027 lambda_max = Teuchos::as<ScalarType> (diag[0]);
1028 }
1029
1030 // info > 0 means that LAPACK's eigensolver didn't converge. This
1031 // is unlikely but may be possible. In that case, the best we can
1032 // do is use the eigenvalues that it computes, as long as lambda_max
1033 // >= lambda_min.
1034 if (STS::real (lambda_max) < STS::real (lambda_min)) {
1035 ConditionNumber = STS::one ();
1036 }
1037 else {
1038 // It's OK for the condition number to be Inf.
1040 }
1041
1042} /* compute_condnum_tridiag_sym */
1043
1044
1045
1046
1047
1048} // end Belos namespace
1049
1050#endif /* BELOS_PSEUDO_BLOCK_CG_SOLMGR_HPP */
Belos concrete class for performing the conjugate-gradient (CG) iteration.
Pure virtual base class which augments the basic interface for a conjugate gradient linear solver ite...
Belos header file which uses auto-configuration information to include necessary C++ headers.
Class which describes the linear problem to be solved by the iterative solver.
Class which manages the output and verbosity of the Belos solvers.
Belos concrete class for performing the pseudo-block CG iteration.
Pure virtual base class which describes the basic interface for a solver manager.
Belos::StatusTest for logically combining several status tests.
Belos::StatusTestResNorm for specifying general residual norm stopping criteria.
Belos::StatusTest class for specifying a maximum number of iterations.
A factory class for generating StatusTestOutput objects.
Collection of types and exceptions used within the Belos solvers.
Parent class to all Belos exceptions.
Type traits class that says whether Teuchos::LAPACK has a valid implementation for the given ScalarTy...
Base class for Belos::SolverManager subclasses which normally can only compile with ScalarType types ...
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).
PseudoBlockCGSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i....
PseudoBlockCGSolMgrLinearProblemFailure(const std::string &what_arg)
Teuchos::ArrayRCP< MagnitudeType > getEigenEstimates() const
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
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
const LinearProblem< ScalarType, MV, OP > & getProblem() const override
Return a reference to the linear problem being solved by this solver manager.
Teuchos::RCP< SolverManager< ScalarType, MV, OP > > clone() const override
clone for Inverted Injection (DII)
MagnitudeType achievedTol() const override
Tolerance achieved by the last solve() invocation.
Teuchos::RCP< StatusTestGenResNorm< ScalarType, MV, OP > > getResidualStatusTest() const
Return the residual status test.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
ScalarType getConditionEstimate() const
Gets the estimated condition number.
int getNumIters() const override
Get the iteration count for the most recent call to solve().
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const override
Get a parameter list containing the current parameters for this object.
bool isLOADetected() const override
Return whether a loss of accuracy was detected by this solver during the most current solve.
The Belos::PseudoBlockCGSolMgr provides a powerful and fully-featured solver manager over the pseudo-...
Teuchos::RCP< StatusTestGenResNorm< ScalarType, MV, OP > > getResidualStatusTest() const
virtual ~PseudoBlockCGSolMgr()=default
PseudoBlockCGSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< Teuchos::ParameterList > &pl)
ScaleType convertStringToScaleType(const std::string &scaleType)
Convert the given string to its ScaleType enum value.
@ StatusTestDetails
@ FinalSummary
@ TimingDetails
ReturnType
Whether the Belos solve converged for all linear systems.
@ Unconverged
ScaleType
The type of scaling to use on the residual norm value.
ResetType
How to reset the solver.
Default parameters common to most Belos solvers.
static const double convTol
Default convergence tolerance.

Generated for Belos by doxygen 1.9.8