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