Belos  Version of the Day
BelosPseudoBlockCGSolMgr.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_PSEUDO_BLOCK_CG_SOLMGR_HPP
43 #define BELOS_PSEUDO_BLOCK_CG_SOLMGR_HPP
44 
49 #include "BelosConfigDefs.hpp"
50 #include "BelosTypes.hpp"
51 
52 #include "BelosLinearProblem.hpp"
53 #include "BelosSolverManager.hpp"
54 
58 #include "BelosStatusTestCombo.hpp"
60 #include "BelosOutputManager.hpp"
61 #include "Teuchos_BLAS.hpp"
62 #include "Teuchos_LAPACK.hpp"
63 #ifdef BELOS_TEUCHOS_TIME_MONITOR
64 #include "Teuchos_TimeMonitor.hpp"
65 #endif
66 
83 namespace Belos {
84 
86 
87 
95  PseudoBlockCGSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
96  {}};
97 
105  PseudoBlockCGSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg)
106  {}};
107 
108 
109  // Partial specialization for unsupported ScalarType types.
110  // This contains a stub implementation.
111  template<class ScalarType, class MV, class OP,
112  const bool supportsScalarType =
115  public Details::SolverManagerRequiresLapack<ScalarType, MV, OP,
116  Belos::Details::LapackSupportsScalar<ScalarType>::value>
117  {
118  static const bool scalarTypeIsSupported =
120  typedef Details::SolverManagerRequiresLapack<ScalarType, MV, OP,
121  scalarTypeIsSupported> base_type;
122 
123  public:
125  base_type ()
126  {}
127  PseudoBlockCGSolMgr (const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
128  const Teuchos::RCP<Teuchos::ParameterList> &pl) :
129  base_type ()
130  {}
131  virtual ~PseudoBlockCGSolMgr () {}
132 
133  Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> >
134  getResidualStatusTest() const { return Teuchos::null; }
135  };
136 
137 
138  template<class ScalarType, class MV, class OP>
139  class PseudoBlockCGSolMgr<ScalarType, MV, OP, true> :
140  public Details::SolverManagerRequiresLapack<ScalarType, MV, OP, true>
141  {
142  private:
145  typedef Teuchos::ScalarTraits<ScalarType> SCT;
146  typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
147  typedef Teuchos::ScalarTraits<MagnitudeType> MT;
148 
149  public:
150 
152 
153 
160 
176  PseudoBlockCGSolMgr( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
177  const Teuchos::RCP<Teuchos::ParameterList> &pl );
178 
180  virtual ~PseudoBlockCGSolMgr() {};
182 
184 
185 
187  return *problem_;
188  }
189 
192  Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
193 
196  Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const { return params_; }
197 
203  Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
204  return Teuchos::tuple(timerSolve_);
205  }
206 
207 
218  MagnitudeType achievedTol() const {
219  return achievedTol_;
220  }
221 
223  int getNumIters() const {
224  return numIters_;
225  }
226 
230  bool isLOADetected() const { return false; }
231 
235  ScalarType getConditionEstimate() const {return condEstimate_;}
236 
238  Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> >
239  getResidualStatusTest() const { return convTest_; }
240 
242 
244 
245 
247  void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) { problem_ = problem; }
248 
250  void setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params );
251 
253 
255 
256 
260  void reset( const ResetType type ) { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
262 
264 
265 
283  ReturnType solve();
284 
286 
289 
291  std::string description() const;
292 
294  private:
295  // Compute the condition number estimate
296  void compute_condnum_tridiag_sym(Teuchos::ArrayView<MagnitudeType> diag,
297  Teuchos::ArrayView<MagnitudeType> offdiag,
298  ScalarType & lambda_min,
299  ScalarType & lambda_max,
300  ScalarType & ConditionNumber );
301 
302  // Linear problem.
303  Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
304 
305  // Output manager.
306  Teuchos::RCP<OutputManager<ScalarType> > printer_;
307  Teuchos::RCP<std::ostream> outputStream_;
308 
309  // Status test.
310  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
311  Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
312  Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
313  Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
314 
315  // Current parameter list.
316  Teuchos::RCP<Teuchos::ParameterList> params_;
317 
323  mutable Teuchos::RCP<const Teuchos::ParameterList> validParams_;
324 
325  // Default solver values.
326  static const MagnitudeType convtol_default_;
327  static const int maxIters_default_;
328  static const bool assertPositiveDefiniteness_default_;
329  static const bool showMaxResNormOnly_default_;
330  static const int verbosity_default_;
331  static const int outputStyle_default_;
332  static const int outputFreq_default_;
333  static const int defQuorum_default_;
334  static const std::string resScale_default_;
335  static const std::string label_default_;
336  static const Teuchos::RCP<std::ostream> outputStream_default_;
337  static const bool genCondEst_default_;
338 
339  // Current solver values.
340  MagnitudeType convtol_,achievedTol_;
341  int maxIters_, numIters_;
342  int verbosity_, outputStyle_, outputFreq_, defQuorum_;
343  bool assertPositiveDefiniteness_, showMaxResNormOnly_;
344  std::string resScale_;
345  bool genCondEst_;
346  ScalarType condEstimate_;
347 
348  // Timers.
349  std::string label_;
350  Teuchos::RCP<Teuchos::Time> timerSolve_;
351 
352  // Internal state variables.
353  bool isSet_;
354  };
355 
356 
357 // Default solver values.
358 template<class ScalarType, class MV, class OP>
360 
361 template<class ScalarType, class MV, class OP>
363 
364 template<class ScalarType, class MV, class OP>
366 
367 template<class ScalarType, class MV, class OP>
369 
370 template<class ScalarType, class MV, class OP>
372 
373 template<class ScalarType, class MV, class OP>
375 
376 template<class ScalarType, class MV, class OP>
378 
379 template<class ScalarType, class MV, class OP>
381 
382 template<class ScalarType, class MV, class OP>
383 const std::string PseudoBlockCGSolMgr<ScalarType,MV,OP,true>::resScale_default_ = "Norm of Initial Residual";
384 
385 template<class ScalarType, class MV, class OP>
387 
388 template<class ScalarType, class MV, class OP>
389 const Teuchos::RCP<std::ostream> PseudoBlockCGSolMgr<ScalarType,MV,OP,true>::outputStream_default_ = Teuchos::rcp(&std::cout,false);
390 
391 template<class ScalarType, class MV, class OP>
393 
394 // Empty Constructor
395 template<class ScalarType, class MV, class OP>
397  outputStream_(outputStream_default_),
398  convtol_(convtol_default_),
399  maxIters_(maxIters_default_),
400  numIters_(0),
401  verbosity_(verbosity_default_),
402  outputStyle_(outputStyle_default_),
403  outputFreq_(outputFreq_default_),
404  defQuorum_(defQuorum_default_),
405  assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
406  showMaxResNormOnly_(showMaxResNormOnly_default_),
407  resScale_(resScale_default_),
408  genCondEst_(genCondEst_default_),
409  condEstimate_(-Teuchos::ScalarTraits<ScalarType>::one()),
410  label_(label_default_),
411  isSet_(false)
412 {}
413 
414 // Basic Constructor
415 template<class ScalarType, class MV, class OP>
418  const Teuchos::RCP<Teuchos::ParameterList> &pl ) :
419  problem_(problem),
420  outputStream_(outputStream_default_),
421  convtol_(convtol_default_),
422  maxIters_(maxIters_default_),
423  numIters_(0),
424  verbosity_(verbosity_default_),
425  outputStyle_(outputStyle_default_),
426  outputFreq_(outputFreq_default_),
427  defQuorum_(defQuorum_default_),
428  assertPositiveDefiniteness_(assertPositiveDefiniteness_default_),
429  showMaxResNormOnly_(showMaxResNormOnly_default_),
430  resScale_(resScale_default_),
431  genCondEst_(genCondEst_default_),
432  condEstimate_(-Teuchos::ScalarTraits<ScalarType>::one()),
433  label_(label_default_),
434  isSet_(false)
435 {
436  TEUCHOS_TEST_FOR_EXCEPTION(
437  problem_.is_null (), std::invalid_argument,
438  "Belos::PseudoBlockCGSolMgr two-argument constructor: "
439  "'problem' is null. You must supply a non-null Belos::LinearProblem "
440  "instance when calling this constructor.");
441 
442  if (! pl.is_null ()) {
443  // Set the parameters using the list that was passed in.
444  setParameters (pl);
445  }
446 }
447 
448 template<class ScalarType, class MV, class OP>
449 void
451 setParameters (const Teuchos::RCP<Teuchos::ParameterList>& params)
452 {
453  using Teuchos::ParameterList;
454  using Teuchos::parameterList;
455  using Teuchos::RCP;
456  using Teuchos::rcp;
457 
458  RCP<const ParameterList> defaultParams = this->getValidParameters ();
459 
460  // Create the internal parameter list if one doesn't already exist.
461  // Belos' solvers treat the input ParameterList to setParameters as
462  // a "delta" -- that is, a change from the current state -- so the
463  // default parameter list (if the input is null) should be empty.
464  // This explains also why Belos' solvers copy parameters one by one
465  // from the input list to the current list.
466  //
467  // Belos obfuscates the latter, because it takes the input parameter
468  // list by RCP, rather than by (nonconst) reference. The latter
469  // would make more sense, given that it doesn't actually keep the
470  // input parameter list.
471  //
472  // Note, however, that Belos still correctly triggers the "used"
473  // field of each parameter in the input list. While isParameter()
474  // doesn't (apparently) trigger the "used" flag, get() certainly
475  // does.
476 
477  if (params_.is_null ()) {
478  // Create an empty list with the same name as the default list.
479  params_ = parameterList (defaultParams->name ());
480  } else {
481  params->validateParameters (*defaultParams);
482  }
483 
484  // Check for maximum number of iterations
485  if (params->isParameter ("Maximum Iterations")) {
486  maxIters_ = params->get ("Maximum Iterations", maxIters_default_);
487 
488  // Update parameter in our list and in status test.
489  params_->set ("Maximum Iterations", maxIters_);
490  if (! maxIterTest_.is_null ()) {
491  maxIterTest_->setMaxIters (maxIters_);
492  }
493  }
494 
495  // Check if positive definiteness assertions are to be performed
496  if (params->isParameter ("Assert Positive Definiteness")) {
497  assertPositiveDefiniteness_ =
498  params->get ("Assert Positive Definiteness",
499  assertPositiveDefiniteness_default_);
500 
501  // Update parameter in our list.
502  params_->set ("Assert Positive Definiteness", assertPositiveDefiniteness_);
503  }
504 
505  // Check to see if the timer label changed.
506  if (params->isParameter ("Timer Label")) {
507  const std::string tempLabel = params->get ("Timer Label", label_default_);
508 
509  // Update parameter in our list and solver timer
510  if (tempLabel != label_) {
511  label_ = tempLabel;
512  params_->set ("Timer Label", label_);
513  const std::string solveLabel =
514  label_ + ": PseudoBlockCGSolMgr total solve time";
515 #ifdef BELOS_TEUCHOS_TIME_MONITOR
516  timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
517 #endif
518  }
519  }
520 
521  // Check for a change in verbosity level
522  if (params->isParameter ("Verbosity")) {
523  if (Teuchos::isParameterType<int> (*params, "Verbosity")) {
524  verbosity_ = params->get ("Verbosity", verbosity_default_);
525  } else {
526  verbosity_ = (int) Teuchos::getParameter<Belos::MsgType> (*params, "Verbosity");
527  }
528 
529  // Update parameter in our list.
530  params_->set ("Verbosity", verbosity_);
531  if (! printer_.is_null ()) {
532  printer_->setVerbosity (verbosity_);
533  }
534  }
535 
536  // Check for a change in output style
537  if (params->isParameter ("Output Style")) {
538  if (Teuchos::isParameterType<int> (*params, "Output Style")) {
539  outputStyle_ = params->get ("Output Style", outputStyle_default_);
540  } else {
541  // FIXME (mfh 29 Jul 2015) What if the type is wrong?
542  outputStyle_ = (int) Teuchos::getParameter<Belos::OutputType> (*params, "Output Style");
543  }
544 
545  // Reconstruct the convergence test if the explicit residual test
546  // is not being used.
547  params_->set ("Output Style", outputStyle_);
548  outputTest_ = Teuchos::null;
549  }
550 
551  // output stream
552  if (params->isParameter ("Output Stream")) {
553  outputStream_ = params->get<RCP<std::ostream> > ("Output Stream");
554 
555  // Update parameter in our list.
556  params_->set ("Output Stream", outputStream_);
557  if (! printer_.is_null ()) {
558  printer_->setOStream (outputStream_);
559  }
560  }
561 
562  // frequency level
563  if (verbosity_ & Belos::StatusTestDetails) {
564  if (params->isParameter ("Output Frequency")) {
565  outputFreq_ = params->get ("Output Frequency", outputFreq_default_);
566  }
567 
568  // Update parameter in out list and output status test.
569  params_->set ("Output Frequency", outputFreq_);
570  if (! outputTest_.is_null ()) {
571  outputTest_->setOutputFrequency (outputFreq_);
572  }
573  }
574 
575  // Condition estimate
576  if (params->isParameter ("Estimate Condition Number")) {
577  genCondEst_ = params->get ("Estimate Condition Number", genCondEst_default_);
578  }
579 
580  // Create output manager if we need to.
581  if (printer_.is_null ()) {
582  printer_ = rcp (new OutputManager<ScalarType> (verbosity_, outputStream_));
583  }
584 
585  // Convergence
586  typedef Belos::StatusTestCombo<ScalarType,MV,OP> StatusTestCombo_t;
587  typedef Belos::StatusTestGenResNorm<ScalarType,MV,OP> StatusTestResNorm_t;
588 
589  // Check for convergence tolerance
590  if (params->isParameter ("Convergence Tolerance")) {
591  convtol_ = params->get ("Convergence Tolerance", convtol_default_);
592 
593  // Update parameter in our list and residual tests.
594  params_->set ("Convergence Tolerance", convtol_);
595  if (! convTest_.is_null ()) {
596  convTest_->setTolerance (convtol_);
597  }
598  }
599 
600  if (params->isParameter ("Show Maximum Residual Norm Only")) {
601  showMaxResNormOnly_ = params->get<bool> ("Show Maximum Residual Norm Only");
602 
603  // Update parameter in our list and residual tests
604  params_->set ("Show Maximum Residual Norm Only", showMaxResNormOnly_);
605  if (! convTest_.is_null ()) {
606  convTest_->setShowMaxResNormOnly (showMaxResNormOnly_);
607  }
608  }
609 
610  // Check for a change in scaling, if so we need to build new residual tests.
611  bool newResTest = false;
612  {
613  // "Residual Scaling" is the old parameter name; "Implicit
614  // Residual Scaling" is the new name. We support both options for
615  // backwards compatibility.
616  std::string tempResScale = resScale_;
617  bool implicitResidualScalingName = false;
618  if (params->isParameter ("Residual Scaling")) {
619  tempResScale = params->get<std::string> ("Residual Scaling");
620  }
621  else if (params->isParameter ("Implicit Residual Scaling")) {
622  tempResScale = params->get<std::string> ("Implicit Residual Scaling");
623  implicitResidualScalingName = true;
624  }
625 
626  // Only update the scaling if it's different.
627  if (resScale_ != tempResScale) {
628  const Belos::ScaleType resScaleType =
629  convertStringToScaleType (tempResScale);
630  resScale_ = tempResScale;
631 
632  // Update parameter in our list and residual tests, using the
633  // given parameter name.
634  if (implicitResidualScalingName) {
635  params_->set ("Implicit Residual Scaling", resScale_);
636  }
637  else {
638  params_->set ("Residual Scaling", resScale_);
639  }
640 
641  if (! convTest_.is_null ()) {
642  try {
643  convTest_->defineScaleForm (resScaleType, Belos::TwoNorm);
644  }
645  catch (std::exception& e) {
646  // Make sure the convergence test gets constructed again.
647  newResTest = true;
648  }
649  }
650  }
651  }
652 
653  // Get the deflation quorum, or number of converged systems before deflation is allowed
654  if (params->isParameter ("Deflation Quorum")) {
655  defQuorum_ = params->get ("Deflation Quorum", defQuorum_);
656  params_->set ("Deflation Quorum", defQuorum_);
657  if (! convTest_.is_null ()) {
658  convTest_->setQuorum( defQuorum_ );
659  }
660  }
661 
662  // Create status tests if we need to.
663 
664  // Basic test checks maximum iterations and native residual.
665  if (maxIterTest_.is_null ()) {
666  maxIterTest_ = rcp (new StatusTestMaxIters<ScalarType,MV,OP> (maxIters_));
667  }
668 
669  // Implicit residual test, using the native residual to determine if convergence was achieved.
670  if (convTest_.is_null () || newResTest) {
671  convTest_ = rcp (new StatusTestResNorm_t (convtol_, defQuorum_, showMaxResNormOnly_));
672  convTest_->defineScaleForm (convertStringToScaleType (resScale_), Belos::TwoNorm);
673  }
674 
675  if (sTest_.is_null () || newResTest) {
676  sTest_ = rcp (new StatusTestCombo_t (StatusTestCombo_t::OR, maxIterTest_, convTest_));
677  }
678 
679  if (outputTest_.is_null () || newResTest) {
680  // Create the status test output class.
681  // This class manages and formats the output from the status test.
682  StatusTestOutputFactory<ScalarType,MV,OP> stoFactory (outputStyle_);
683  outputTest_ = stoFactory.create (printer_, sTest_, outputFreq_,
685 
686  // Set the solver string for the output test
687  const std::string solverDesc = " Pseudo Block CG ";
688  outputTest_->setSolverDesc (solverDesc);
689  }
690 
691  // Create the timer if we need to.
692  if (timerSolve_.is_null ()) {
693  const std::string solveLabel =
694  label_ + ": PseudoBlockCGSolMgr total solve time";
695 #ifdef BELOS_TEUCHOS_TIME_MONITOR
696  timerSolve_ = Teuchos::TimeMonitor::getNewCounter (solveLabel);
697 #endif
698  }
699 
700  // Inform the solver manager that the current parameters were set.
701  isSet_ = true;
702 }
703 
704 
705 template<class ScalarType, class MV, class OP>
706 Teuchos::RCP<const Teuchos::ParameterList>
708 {
709  using Teuchos::ParameterList;
710  using Teuchos::parameterList;
711  using Teuchos::RCP;
712 
713  if (validParams_.is_null()) {
714  // Set all the valid parameters and their default values.
715  RCP<ParameterList> pl = parameterList ();
716  pl->set("Convergence Tolerance", convtol_default_,
717  "The relative residual tolerance that needs to be achieved by the\n"
718  "iterative solver in order for the linera system to be declared converged.");
719  pl->set("Maximum Iterations", maxIters_default_,
720  "The maximum number of block iterations allowed for each\n"
721  "set of RHS solved.");
722  pl->set("Assert Positive Definiteness", assertPositiveDefiniteness_default_,
723  "Whether or not to assert that the linear operator\n"
724  "and the preconditioner are indeed positive definite.");
725  pl->set("Verbosity", verbosity_default_,
726  "What type(s) of solver information should be outputted\n"
727  "to the output stream.");
728  pl->set("Output Style", outputStyle_default_,
729  "What style is used for the solver information outputted\n"
730  "to the output stream.");
731  pl->set("Output Frequency", outputFreq_default_,
732  "How often convergence information should be outputted\n"
733  "to the output stream.");
734  pl->set("Deflation Quorum", defQuorum_default_,
735  "The number of linear systems that need to converge before\n"
736  "they are deflated. This number should be <= block size.");
737  pl->set("Output Stream", outputStream_default_,
738  "A reference-counted pointer to the output stream where all\n"
739  "solver output is sent.");
740  pl->set("Show Maximum Residual Norm Only", showMaxResNormOnly_default_,
741  "When convergence information is printed, only show the maximum\n"
742  "relative residual norm when the block size is greater than one.");
743  pl->set("Implicit Residual Scaling", resScale_default_,
744  "The type of scaling used in the residual convergence test.");
745  pl->set("Estimate Condition Number", genCondEst_default_,
746  "Whether or not to estimate the condition number of the preconditioned system.");
747  // We leave the old name as a valid parameter for backwards
748  // compatibility (so that validateParametersAndSetDefaults()
749  // doesn't raise an exception if it encounters "Residual
750  // Scaling"). The new name was added for compatibility with other
751  // solvers, none of which use "Residual Scaling".
752  pl->set("Residual Scaling", resScale_default_,
753  "The type of scaling used in the residual convergence test. This "
754  "name is deprecated; the new name is \"Implicit Residual Scaling\".");
755  pl->set("Timer Label", label_default_,
756  "The string to use as a prefix for the timer labels.");
757  validParams_ = pl;
758  }
759  return validParams_;
760 }
761 
762 
763 // solve()
764 template<class ScalarType, class MV, class OP>
766 {
767  const char prefix[] = "Belos::PseudoBlockCGSolMgr::solve: ";
768 
769  // Set the current parameters if they were not set before.
770  // NOTE: This may occur if the user generated the solver manager with the default constructor and
771  // then didn't set any parameters using setParameters().
772  if (!isSet_) { setParameters( params_ ); }
773 
774  Teuchos::BLAS<int,ScalarType> blas;
775 
776  TEUCHOS_TEST_FOR_EXCEPTION
777  (! problem_->isProblemSet (), PseudoBlockCGSolMgrLinearProblemFailure,
778  prefix << "The linear problem to solve is not ready. You must call "
779  "setProblem() on the Belos::LinearProblem instance before telling the "
780  "Belos solver to solve it.");
781 
782  // Create indices for the linear systems to be solved.
783  int startPtr = 0;
784  int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
785  int numCurrRHS = numRHS2Solve;
786 
787  std::vector<int> currIdx( numRHS2Solve ), currIdx2( numRHS2Solve );
788  for (int i=0; i<numRHS2Solve; ++i) {
789  currIdx[i] = startPtr+i;
790  currIdx2[i]=i;
791  }
792 
793  // Inform the linear problem of the current linear system to solve.
794  problem_->setLSIndex( currIdx );
795 
797  // Parameter list (iteration)
798  Teuchos::ParameterList plist;
799 
800  plist.set("Assert Positive Definiteness",assertPositiveDefiniteness_);
801  if(genCondEst_) plist.set("Max Size For Condest",maxIters_);
802 
803  // Reset the status test.
804  outputTest_->reset();
805 
806  // Assume convergence is achieved, then let any failed convergence set this to false.
807  bool isConverged = true;
808 
810  // Pseudo-Block CG solver
811 
812  Teuchos::RCP<PseudoBlockCGIter<ScalarType,MV,OP> > block_cg_iter
813  = Teuchos::rcp( new PseudoBlockCGIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,plist) );
814 
815  // Enter solve() iterations
816  {
817 #ifdef BELOS_TEUCHOS_TIME_MONITOR
818  Teuchos::TimeMonitor slvtimer(*timerSolve_);
819 #endif
820 
821  bool first_time=true;
822  while ( numRHS2Solve > 0 ) {
823  if(genCondEst_ && first_time) block_cg_iter->setDoCondEst(true);
824  else block_cg_iter->setDoCondEst(false);
825 
826  // Reset the active / converged vectors from this block
827  std::vector<int> convRHSIdx;
828  std::vector<int> currRHSIdx( currIdx );
829  currRHSIdx.resize(numCurrRHS);
830 
831  // Reset the number of iterations.
832  block_cg_iter->resetNumIters();
833 
834  // Reset the number of calls that the status test output knows about.
835  outputTest_->resetNumCalls();
836 
837  // Get the current residual for this block of linear systems.
838  Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
839 
840  // Get a new state struct and initialize the solver.
842  newState.R = R_0;
843  block_cg_iter->initializeCG(newState);
844 
845  while(1) {
846 
847  // tell block_gmres_iter to iterate
848  try {
849 
850  block_cg_iter->iterate();
851 
853  //
854  // check convergence first
855  //
857  if ( convTest_->getStatus() == Passed ) {
858 
859  // Figure out which linear systems converged.
860  std::vector<int> convIdx = Teuchos::rcp_dynamic_cast<StatusTestGenResNorm<ScalarType,MV,OP> >(convTest_)->convIndices();
861 
862  // If the number of converged linear systems is equal to the
863  // number of current linear systems, then we are done with this block.
864  if (convIdx.size() == currRHSIdx.size())
865  break; // break from while(1){block_cg_iter->iterate()}
866 
867  // Inform the linear problem that we are finished with this current linear system.
868  problem_->setCurrLS();
869 
870  // Reset currRHSIdx to have the right-hand sides that are left to converge for this block.
871  int have = 0;
872  std::vector<int> unconvIdx(currRHSIdx.size());
873  for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
874  bool found = false;
875  for (unsigned int j=0; j<convIdx.size(); ++j) {
876  if (currRHSIdx[i] == convIdx[j]) {
877  found = true;
878  break;
879  }
880  }
881  if (!found) {
882  currIdx2[have] = currIdx2[i];
883  currRHSIdx[have++] = currRHSIdx[i];
884  }
885  }
886  currRHSIdx.resize(have);
887  currIdx2.resize(have);
888 
889  // Set the remaining indices after deflation.
890  problem_->setLSIndex( currRHSIdx );
891 
892  // Get the current residual vector.
893  std::vector<MagnitudeType> norms;
894  R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
895  for (int i=0; i<have; ++i) { currIdx2[i] = i; }
896 
897  // Set the new state and initialize the solver.
899  defstate.R = R_0;
900  block_cg_iter->initializeCG(defstate);
901  }
902 
904  //
905  // check for maximum iterations
906  //
908  else if ( maxIterTest_->getStatus() == Passed ) {
909  // we don't have convergence
910  isConverged = false;
911  break; // break from while(1){block_cg_iter->iterate()}
912  }
913 
915  //
916  // we returned from iterate(), but none of our status tests Passed.
917  // something is wrong, and it is probably our fault.
918  //
920 
921  else {
922  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
923  "Belos::PseudoBlockCGSolMgr::solve(): Invalid return from PseudoBlockCGIter::iterate().");
924  }
925  }
926  catch (const std::exception &e) {
927  printer_->stream(Errors) << "Error! Caught std::exception in PseudoBlockCGIter::iterate() at iteration "
928  << block_cg_iter->getNumIters() << std::endl
929  << e.what() << std::endl;
930  throw;
931  }
932  }
933 
934  // Inform the linear problem that we are finished with this block linear system.
935  problem_->setCurrLS();
936 
937  // Update indices for the linear systems to be solved.
938  startPtr += numCurrRHS;
939  numRHS2Solve -= numCurrRHS;
940 
941  if ( numRHS2Solve > 0 ) {
942 
943  numCurrRHS = numRHS2Solve;
944  currIdx.resize( numCurrRHS );
945  currIdx2.resize( numCurrRHS );
946  for (int i=0; i<numCurrRHS; ++i)
947  { currIdx[i] = startPtr+i; currIdx2[i] = i; }
948 
949  // Set the next indices.
950  problem_->setLSIndex( currIdx );
951  }
952  else {
953  currIdx.resize( numRHS2Solve );
954  }
955 
956  first_time=false;
957  }// while ( numRHS2Solve > 0 )
958 
959  }
960 
961  // print final summary
962  sTest_->print( printer_->stream(FinalSummary) );
963 
964  // print timing information
965 #ifdef BELOS_TEUCHOS_TIME_MONITOR
966  // Calling summarize() can be expensive, so don't call unless the
967  // user wants to print out timing details. summarize() will do all
968  // the work even if it's passed a "black hole" output stream.
969  if (verbosity_ & TimingDetails)
970  Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
971 #endif
972 
973  // get iteration information for this solve
974  numIters_ = maxIterTest_->getNumIters();
975 
976  // Save the convergence test value ("achieved tolerance") for this
977  // solve.
978  const std::vector<MagnitudeType>* pTestValues = convTest_->getTestValue();
979  if (pTestValues != NULL && pTestValues->size () > 0) {
980  achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
981  }
982 
983  // Do condition estimate, if needed
984  if (genCondEst_) {
985  ScalarType l_min, l_max;
986  Teuchos::ArrayView<MagnitudeType> diag = block_cg_iter->getDiag();
987  Teuchos::ArrayView<MagnitudeType> offdiag = block_cg_iter->getOffDiag();
988  compute_condnum_tridiag_sym(diag,offdiag,l_min,l_max,condEstimate_);
989  }
990 
991  if (! isConverged) {
992  return Unconverged; // return from PseudoBlockCGSolMgr::solve()
993  }
994  return Converged; // return from PseudoBlockCGSolMgr::solve()
995 }
996 
997 // This method requires the solver manager to return a std::string that describes itself.
998 template<class ScalarType, class MV, class OP>
1000 {
1001  std::ostringstream oss;
1002  oss << "Belos::PseudoBlockCGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<">";
1003  oss << "{";
1004  oss << "}";
1005  return oss.str();
1006 }
1007 
1008 
1009 template<class ScalarType, class MV, class OP>
1010 void
1012 compute_condnum_tridiag_sym (Teuchos::ArrayView<MagnitudeType> diag,
1013  Teuchos::ArrayView<MagnitudeType> offdiag,
1014  ScalarType & lambda_min,
1015  ScalarType & lambda_max,
1016  ScalarType & ConditionNumber )
1017 {
1018  typedef Teuchos::ScalarTraits<ScalarType> STS;
1019 
1020  /* Copied from az_cg.c: compute_condnum_tridiag_sym */
1021  /* diag == ScalarType vector of size N, containing the diagonal
1022  elements of A
1023  offdiag == ScalarType vector of size N-1, containing the offdiagonal
1024  elements of A. Note that A is supposed to be symmatric
1025  */
1026  int info = 0;
1027  ScalarType scalar_dummy;
1028  MagnitudeType mag_dummy;
1029  char char_N = 'N';
1030  Teuchos::LAPACK<int,ScalarType> lapack;
1031  const int N = diag.size ();
1032 
1033  lambda_min = STS::one ();
1034  lambda_max = STS::one ();
1035  if( N > 2 ) {
1036  lapack.STEQR (char_N, N, diag.getRawPtr (), offdiag.getRawPtr (),
1037  &scalar_dummy, 1, &mag_dummy, &info);
1038  TEUCHOS_TEST_FOR_EXCEPTION
1039  (info < 0, std::logic_error, "Belos::PseudoBlockCGSolMgr::"
1040  "compute_condnum_tridiag_sym: LAPACK's _STEQR failed with info = "
1041  << info << " < 0. This suggests there might be a bug in the way Belos "
1042  "is calling LAPACK. Please report this to the Belos developers.");
1043  lambda_min = Teuchos::as<ScalarType> (diag[0]);
1044  lambda_max = Teuchos::as<ScalarType> (diag[N-1]);
1045  }
1046 
1047  // info > 0 means that LAPACK's eigensolver didn't converge. This
1048  // is unlikely but may be possible. In that case, the best we can
1049  // do is use the eigenvalues that it computes, as long as lambda_max
1050  // >= lambda_min.
1051  if (STS::real (lambda_max) < STS::real (lambda_min)) {
1052  ConditionNumber = STS::one ();
1053  }
1054  else {
1055  // It's OK for the condition number to be Inf.
1056  ConditionNumber = lambda_max / lambda_min;
1057  }
1058 
1059 } /* compute_condnum_tridiag_sym */
1060 
1061 
1062 
1063 
1064 
1065 } // end Belos namespace
1066 
1067 #endif /* BELOS_PSEUDO_BLOCK_CG_SOLMGR_HPP */
void reset(const ResetType type)
Performs a reset of the solver manager specified by the ResetType. This informs the solver manager th...
ScaleType convertStringToScaleType(const std::string &scaleType)
Convert the given string to its ScaleType enum value.
Definition: BelosTypes.cpp:87
Teuchos::RCP< const MV > R
The current residual.
Collection of types and exceptions used within the Belos solvers.
ScalarType getConditionEstimate() const
Gets the estimated condition number.
Belos&#39;s basic output manager for sending information of select verbosity levels to the appropriate ou...
Class which manages the output and verbosity of the Belos solvers.
void setProblem(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem)
Set the linear problem that needs to be solved.
ScaleType
The type of scaling to use on the residual norm value.
Definition: BelosTypes.hpp:119
PseudoBlockCGSolMgr(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< Teuchos::ParameterList > &pl)
Structure to contain pointers to CGIteration state variables.
Teuchos::RCP< StatusTestGenResNorm< ScalarType, MV, OP > > getResidualStatusTest() const
A factory class for generating StatusTestOutput objects.
PseudoBlockCGSolMgrLinearProblemFailure is thrown when the linear problem is not setup (i...
bool isLOADetected() const
Return whether a loss of accuracy was detected by this solver during the most current solve...
An implementation of StatusTestResNorm using a family of residual norms.
Belos::StatusTest class for specifying a maximum number of iterations.
A factory class for generating StatusTestOutput objects.
Traits class which defines basic operations on multivectors.
The Belos::PseudoBlockCGSolMgr provides a powerful and fully-featured solver manager over the pseudo-...
Belos::StatusTest for logically combining several status tests.
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Return a reference to the linear problem being solved by this solver manager.
This class implements the pseudo-block CG iteration, where the basic CG algorithm is performed on all...
A Belos::StatusTest class for specifying a maximum number of iterations.
ResetType
How to reset the solver.
Definition: BelosTypes.hpp:205
Pure virtual base class which describes the basic interface for a solver manager. ...
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
MagnitudeType achievedTol() const
Tolerance achieved by the last solve() invocation.
Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const
Get a parameter list containing the current parameters for this object.
A linear system to solve, and its associated information.
int getNumIters() const
Get the iteration count for the most recent call to solve().
Class which describes the linear problem to be solved by the iterative solver.
PseudoBlockCGSolMgrOrthoFailure(const std::string &what_arg)
Type traits class that says whether Teuchos::LAPACK has a valid implementation for the given ScalarTy...
ReturnType
Whether the Belos solve converged for all linear systems.
Definition: BelosTypes.hpp:154
Teuchos::RCP< StatusTestGenResNorm< ScalarType, MV, OP > > getResidualStatusTest() const
Return the residual status test.
int setTolerance(MagnitudeType tolerance)
Set the value of the tolerance.
Teuchos::RCP< StatusTestOutput< ScalarType, MV, OP > > create(const Teuchos::RCP< OutputManager< ScalarType > > &printer, Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test, int mod, int printStates)
Create the StatusTestOutput object specified by the outputStyle.
PseudoBlockCGSolMgrLinearProblemFailure(const std::string &what_arg)
Belos::StatusTestResNorm for specifying general residual norm stopping criteria.
A class for extending the status testing capabilities of Belos via logical combinations.
PseudoBlockCGSolMgrOrthoFailure is thrown when the orthogonalization manager is unable to generate or...
Class which defines basic traits for the operator type.
Belos concrete class for performing the pseudo-block CG iteration.
Parent class to all Belos exceptions.
Definition: BelosTypes.hpp:60
Base class for Belos::SolverManager subclasses which normally can only compile with ScalarType types ...
Belos header file which uses auto-configuration information to include necessary C++ headers...

Generated on Mon Feb 5 2018 15:01:51 for Belos by doxygen 1.8.13