Belos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BelosRCGIter.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_RCG_ITER_HPP
11 #define BELOS_RCG_ITER_HPP
12 
17 #include "BelosConfigDefs.hpp"
18 #include "BelosTypes.hpp"
19 
20 #include "BelosLinearProblem.hpp"
21 #include "BelosMatOrthoManager.hpp"
22 #include "BelosOutputManager.hpp"
23 #include "BelosStatusTest.hpp"
24 #include "BelosOperatorTraits.hpp"
25 #include "BelosMultiVecTraits.hpp"
26 #include "BelosCGIteration.hpp"
27 
28 #include "Teuchos_LAPACK.hpp"
31 #include "Teuchos_ScalarTraits.hpp"
33 #include "Teuchos_TimeMonitor.hpp"
34 
35 // MLP Remove after debugging
36 #include <fstream>
37 #include <iomanip>
38 
50 namespace Belos {
51 
53 
54 
59  template <class ScalarType, class MV>
60  struct RCGIterState {
65  int curDim;
66 
69 
72 
75 
78 
80  bool existU;
81 
84 
91 
94 
99 
100 
101  RCGIterState() : curDim(0), P(Teuchos::null), Ap(Teuchos::null), r(Teuchos::null),
102  z(Teuchos::null),
103  existU(false),
104  U(Teuchos::null), AU(Teuchos::null),
105  Alpha(Teuchos::null), Beta(Teuchos::null), D(Teuchos::null), rTz_old(Teuchos::null),
106  Delta(Teuchos::null), LUUTAU(Teuchos::null), ipiv(Teuchos::null)
107  {}
108  };
109 
111 
112  template<class ScalarType, class MV, class OP>
113  class RCGIter : virtual public Iteration<ScalarType,MV,OP> {
114 
115  public:
116 
117  //
118  // Convenience typedefs
119  //
124 
126 
127 
136  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
138  Teuchos::ParameterList &params );
139 
141  virtual ~RCGIter() {};
143 
144 
146 
147 
160  void iterate();
161 
176  void initialize(RCGIterState<ScalarType,MV> &newstate);
177 
181  void initialize()
182  {
184  initialize(empty);
185  }
186 
188 
190 
191 
193  int getNumIters() const { return iter_; }
194 
196  void resetNumIters( int iter = 0 ) { iter_ = iter; }
197 
200  Teuchos::RCP<const MV> getNativeResiduals( std::vector<MagnitudeType> * /* norms */ ) const { return r_; }
201 
203 
209 
211  int getCurSubspaceDim() const {
212  if (!initialized_) return 0;
213  return curDim_;
214  };
215 
217  int getMaxSubspaceDim() const { return numBlocks_+1; }
218 
220 
221 
223 
224 
226  const LinearProblem<ScalarType,MV,OP>& getProblem() const { return *lp_; }
227 
229  int getNumBlocks() const { return numBlocks_; }
230 
232  void setNumBlocks(int numBlocks) { setSize( recycleBlocks_, numBlocks ); };
233 
235  int getRecycledBlocks() const { return recycleBlocks_; }
236 
238  void setRecycledBlocks(int recycleBlocks) { setSize( recycleBlocks, numBlocks_ ); };
239 
241  int getBlockSize() const { return 1; }
242 
244  void setBlockSize(int blockSize) {
245  TEUCHOS_TEST_FOR_EXCEPTION(blockSize!=1,std::invalid_argument,
246  "Belos::RCGIter::setBlockSize(): Cannot use a block size that is not one.");
247  }
248 
250  void setSize( int recycleBlocks, int numBlocks );
251 
253  bool isInitialized() { return initialized_; }
254 
256 
257  private:
258 
259  //
260  // Internal methods
261  //
262 
263  //
264  // Classes input through constructor that define the linear problem to be solved.
265  //
269 
270  //
271  // Algorithmic parameters
272  //
273  // numBlocks_ is the size of the allocated space for the Krylov basis, in blocks.
275 
276  // recycleBlocks_ is the size of the allocated space for the recycled subspace, in blocks.
278 
279  //
280  // Current solver state
281  //
282  // initialized_ specifies that the basis vectors have been initialized and the iterate() routine
283  // is capable of running; _initialize is controlled by the initialize() member method
284  // For the implications of the state of initialized_, please see documentation for initialize()
286 
287  // Current subspace dimension, and number of iterations performed.
289 
290  //
291  // State Storage
292  //
293  // Search vectors
295  //
296  // A times current search vector
298  //
299  // Residual vector
301  //
302  // Preconditioned residual
304  //
305  // Flag to indicate that the recycle space should be used
306  bool existU_;
307  // Recycled subspace and its image
309  //
310  // Coefficients arising in RCG iteration
312  //
313  // Solutions to local least-squares problems
315  //
316  // The LU factorization of the matrix U^T A U
318  //
319  // Data from LU factorization of UTAU
321  //
322  // The scalar r'*z
324  };
325 
327  // Constructor.
328  template<class ScalarType, class MV, class OP>
330  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
332  Teuchos::ParameterList &params ):
333  lp_(problem),
334  om_(printer),
335  stest_(tester),
336  numBlocks_(0),
337  recycleBlocks_(0),
338  initialized_(false),
339  curDim_(0),
340  iter_(0),
341  existU_(false)
342  {
343  // Get the maximum number of blocks allowed for this Krylov subspace
344  TEUCHOS_TEST_FOR_EXCEPTION(!params.isParameter("Num Blocks"), std::invalid_argument,
345  "Belos::RCGIter::constructor: mandatory parameter \"Num Blocks\" is not specified.");
346  int nb = Teuchos::getParameter<int>(params, "Num Blocks");
347 
348  TEUCHOS_TEST_FOR_EXCEPTION(!params.isParameter("Recycled Blocks"), std::invalid_argument,
349  "Belos::RCGIter::constructor: mandatory parameter \"Recycled Blocks\" is not specified.");
350  int rb = Teuchos::getParameter<int>(params, "Recycled Blocks");
351 
352  // Set the number of blocks and allocate data
353  setSize( rb, nb );
354  }
355 
357  // Set the block size and make necessary adjustments.
358  template <class ScalarType, class MV, class OP>
359  void RCGIter<ScalarType,MV,OP>::setSize( int recycleBlocks, int numBlocks )
360  {
361 
362  TEUCHOS_TEST_FOR_EXCEPTION(numBlocks <= 0, std::invalid_argument, "Belos::RCGIter::setSize() was passed a non-positive argument for \"Num Blocks\".");
363  TEUCHOS_TEST_FOR_EXCEPTION(recycleBlocks <= 0, std::invalid_argument, "Belos::RCGIter::setSize() was passed a non-positive argument for \"Recycled Blocks\".");
364  TEUCHOS_TEST_FOR_EXCEPTION(recycleBlocks >= numBlocks, std::invalid_argument, "Belos::RCGIter::setSize() the number of recycled blocks is larger than the allowable subspace.");
365 
366  numBlocks_ = numBlocks;
367  recycleBlocks_ = recycleBlocks;
368 
369  }
370 
372  // Initialize this iteration object
373  template <class ScalarType, class MV, class OP>
375  {
376 
377  if (newstate.P != Teuchos::null &&
378  newstate.Ap != Teuchos::null &&
379  newstate.r != Teuchos::null &&
380  newstate.z != Teuchos::null &&
381  newstate.U != Teuchos::null &&
382  newstate.AU != Teuchos::null &&
383  newstate.Alpha != Teuchos::null &&
384  newstate.Beta != Teuchos::null &&
385  newstate.D != Teuchos::null &&
386  newstate.Delta != Teuchos::null &&
387  newstate.LUUTAU != Teuchos::null &&
388  newstate.ipiv != Teuchos::null &&
389  newstate.rTz_old != Teuchos::null) {
390 
391  curDim_ = newstate.curDim;
392  P_ = newstate.P;
393  Ap_ = newstate.Ap;
394  r_ = newstate.r;
395  z_ = newstate.z;
396  existU_ = newstate.existU;
397  U_ = newstate.U;
398  AU_ = newstate.AU;
399  Alpha_ = newstate.Alpha;
400  Beta_ = newstate.Beta;
401  D_ = newstate.D;
402  Delta_ = newstate.Delta;
403  LUUTAU_ = newstate.LUUTAU;
404  ipiv_ = newstate.ipiv;
405  rTz_old_ = newstate.rTz_old;
406  }
407  else {
408 
409  TEUCHOS_TEST_FOR_EXCEPTION(newstate.P == Teuchos::null,std::invalid_argument,
410  "Belos::RCGIter::initialize(): RCGIterState does not have P initialized.");
411 
412  TEUCHOS_TEST_FOR_EXCEPTION(newstate.Ap == Teuchos::null,std::invalid_argument,
413  "Belos::RCGIter::initialize(): RCGIterState does not have Ap initialized.");
414 
415  TEUCHOS_TEST_FOR_EXCEPTION(newstate.r == Teuchos::null,std::invalid_argument,
416  "Belos::RCGIter::initialize(): RCGIterState does not have r initialized.");
417 
418  TEUCHOS_TEST_FOR_EXCEPTION(newstate.z == Teuchos::null,std::invalid_argument,
419  "Belos::RCGIter::initialize(): RCGIterState does not have z initialized.");
420 
421  TEUCHOS_TEST_FOR_EXCEPTION(newstate.U == Teuchos::null,std::invalid_argument,
422  "Belos::RCGIter::initialize(): RCGIterState does not have U initialized.");
423 
424  TEUCHOS_TEST_FOR_EXCEPTION(newstate.AU == Teuchos::null,std::invalid_argument,
425  "Belos::RCGIter::initialize(): RCGIterState does not have AU initialized.");
426 
427  TEUCHOS_TEST_FOR_EXCEPTION(newstate.Alpha == Teuchos::null,std::invalid_argument,
428  "Belos::RCGIter::initialize(): RCGIterState does not have Alpha initialized.");
429 
430  TEUCHOS_TEST_FOR_EXCEPTION(newstate.Beta == Teuchos::null,std::invalid_argument,
431  "Belos::RCGIter::initialize(): RCGIterState does not have Beta initialized.");
432 
433  TEUCHOS_TEST_FOR_EXCEPTION(newstate.D == Teuchos::null,std::invalid_argument,
434  "Belos::RCGIter::initialize(): RCGIterState does not have D initialized.");
435 
436  TEUCHOS_TEST_FOR_EXCEPTION(newstate.Delta == Teuchos::null,std::invalid_argument,
437  "Belos::RCGIter::initialize(): RCGIterState does not have Delta initialized.");
438 
439  TEUCHOS_TEST_FOR_EXCEPTION(newstate.LUUTAU == Teuchos::null,std::invalid_argument,
440  "Belos::RCGIter::initialize(): RCGIterState does not have LUUTAU initialized.");
441 
442  TEUCHOS_TEST_FOR_EXCEPTION(newstate.ipiv == Teuchos::null,std::invalid_argument,
443  "Belos::RCGIter::initialize(): RCGIterState does not have ipiv initialized.");
444 
445  TEUCHOS_TEST_FOR_EXCEPTION(newstate.rTz_old == Teuchos::null,std::invalid_argument,
446  "Belos::RCGIter::initialize(): RCGIterState does not have rTz_old initialized.");
447 
448  }
449 
450  // the solver is initialized
451  initialized_ = true;
452 
453  }
454 
456  // Iterate until the status test informs us we should stop.
457  template <class ScalarType, class MV, class OP>
459  {
460  TEUCHOS_TEST_FOR_EXCEPTION( initialized_ == false, CGIterateFailure,
461  "Belos::RCGIter::iterate(): RCGIter class not initialized." );
462 
463  // We'll need LAPACK
465 
466  // Create convenience variables for zero and one.
467  ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
468  ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
469 
470  // Allocate memory for scalars
471  std::vector<int> index(1);
473 
474  // Get the current solution std::vector.
475  Teuchos::RCP<MV> cur_soln_vec = lp_->getCurrLHSVec();
476 
477  // Check that the current solution std::vector only has one column.
478  TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*cur_soln_vec) != 1, CGIterateFailure,
479  "Belos::RCGIter::iterate(): current linear system has more than one std::vector!" );
480 
481  // Compute the current search dimension.
482  int searchDim = numBlocks_+1;
483 
484  // index of iteration within current cycle
485  int i_ = 0;
486 
488  // iterate until the status test tells us to stop.
489  //
490  // also break if our basis is full
491  //
494  while (stest_->checkStatus(this) != Passed && curDim_+1 <= searchDim) {
495 
496  // Ap = A*p;
497  index.resize( 1 );
498  index[0] = i_;
499  p_ = MVT::CloneView( *P_, index );
500  lp_->applyOp( *p_, *Ap_ );
501 
502  // d = p'*Ap;
503  MVT::MvTransMv( one, *p_, *Ap_, pAp );
504  (*D_)(i_,0) = pAp(0,0);
505 
506  // alpha = rTz_old / pAp
507  (*Alpha_)(i_,0) = (*rTz_old_)(0,0) / pAp(0,0);
508 
509  // Check that alpha is a positive number
510  TEUCHOS_TEST_FOR_EXCEPTION( SCT::real(pAp(0,0)) <= zero, CGPositiveDefiniteFailure,
511  "Belos::RCGIter::iterate(): non-positive value for p^H*A*p encountered!" );
512 
513  // x = x + (alpha * p);
514  MVT::MvAddMv( one, *cur_soln_vec, (*Alpha_)(i_,0), *p_, *cur_soln_vec );
515  lp_->updateSolution();
516 
517  // r = r - (alpha * Ap);
518  MVT::MvAddMv( one, *r_, -(*Alpha_)(i_,0), *Ap_, *r_ );
519 
520  std::vector<MagnitudeType> norm(1);
521  MVT::MvNorm( *r_, norm );
522 //printf("i = %i\tnorm(r) = %e\n",i_,norm[0]);
523 
524  // z = M\r
525  if ( lp_->getLeftPrec() != Teuchos::null ) {
526  lp_->applyLeftPrec( *r_, *z_ );
527  }
528  else if ( lp_->getRightPrec() != Teuchos::null ) {
529  lp_->applyRightPrec( *r_, *z_ );
530  }
531  else {
532  z_ = r_;
533  }
534 
535  // rTz_new = r'*z;
536  MVT::MvTransMv( one, *r_, *z_, rTz );
537 
538  // beta = rTz_new/rTz_old;
539  (*Beta_)(i_,0) = rTz(0,0) / (*rTz_old_)(0,0);
540 
541  // rTz_old = rTz_new;
542  (*rTz_old_)(0,0) = rTz(0,0);
543 
544  // get pointer for next p
545  index.resize( 1 );
546  index[0] = i_+1;
547  pnext_ = MVT::CloneViewNonConst( *P_, index );
548 
549  if (existU_) {
550  // mu = UTAU \ (AU'*z);
551  Teuchos::SerialDenseMatrix<int,ScalarType> mu( Teuchos::View, *Delta_, recycleBlocks_, 1, 0, i_ );
552  MVT::MvTransMv( one, *AU_, *z_, mu );
553  char TRANS = 'N';
554  int info;
555  lapack.GETRS( TRANS, recycleBlocks_, 1, LUUTAU_->values(), LUUTAU_->stride(), &(*ipiv_)[0], mu.values(), mu.stride(), &info );
557  "Belos::RCGIter::solve(): LAPACK GETRS failed to compute a solution.");
558  // p = -(U*mu) + (beta*p) + z (in two steps)
559  // p = (beta*p) + z;
560  MVT::MvAddMv( (*Beta_)(i_,0), *p_, one, *z_, *pnext_ );
561  // pnext = -(U*mu) + (one)*pnext;
562  MVT::MvTimesMatAddMv( -one, *U_, mu, one, *pnext_ );
563  }
564  else {
565  // p = (beta*p) + z;
566  MVT::MvAddMv( (*Beta_)(i_,0), *p_, one, *z_, *pnext_ );
567  }
568 
569  // Done with this view; release pointer
570  p_ = Teuchos::null;
571  pnext_ = Teuchos::null;
572 
573  // increment iteration count and dimension index
574  i_++;
575  iter_++;
576  curDim_++;
577 
578  } // end while (statusTest == false)
579 
580  }
581 
582 } // end Belos namespace
583 
584 #endif /* BELOS_RCG_ITER_HPP */
const Teuchos::RCP< OutputManager< ScalarType > > om_
ScalarType * values() const
Teuchos::RCP< MV > r
The current residual.
Collection of types and exceptions used within the Belos solvers.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > rTz_old
Belos&#39;s basic output manager for sending information of select verbosity levels to the appropriate ou...
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Alpha_
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > rTz_old_
Teuchos::RCP< MV > P
The current Krylov basis.
Teuchos::RCP< std::vector< int > > ipiv
Data from LU factorization of U^T A U.
Class which manages the output and verbosity of the Belos solvers.
void setNumBlocks(int numBlocks)
Set the maximum number of blocks used by the iterative solver.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Beta_
Teuchos::RCP< MV > AU
int getNumBlocks() const
Get the maximum number of blocks used by the iterative solver in solving this linear problem...
Pure virtual base class which augments the basic interface for a conjugate gradient linear solver ite...
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
Pure virtual base class for defining the status testing capabilities of Belos.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > D_
Teuchos::RCP< MV > U
The recycled subspace and its image.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > LUUTAU
The LU factorization of the matrix U^T A U.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Beta
Declaration of basic traits for the multivector type.
This class implements the RCG iteration, where a single-std::vector Krylov subspace is constructed...
int getRecycledBlocks() const
Get the maximum number of recycled blocks used by the iterative solver in solving this linear problem...
const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > lp_
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace.
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
OperatorTraits< ScalarType, MV, OP > OPT
int getNumIters() const
Get the current iteration count.
A pure virtual class for defining the status tests for the Belos iterative solvers.
Class which defines basic traits for the operator type.
CGIterateFailure is thrown when the CGIteration object is unable to compute the next iterate in the C...
MultiVecTraits< ScalarType, MV > MVT
virtual ~RCGIter()
Destructor.
Traits class which defines basic operations on multivectors.
void setSize(int recycleBlocks, int numBlocks)
Set the maximum number of blocks used by the iterative solver and the number of recycled vectors...
CGPositiveDefiniteFailure is thrown when the the CG &#39;alpha = p^H*A*P&#39; value is less than zero...
bool isParameter(const std::string &name) const
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > stest_
Structure to contain pointers to RCGIter state variables.
CGIterationLAPACKFailure is thrown when a nonzero return value is passed back from an LAPACK routine...
bool existU
Flag to indicate the recycle space should be used.
Teuchos::RCP< MV > z
The current preconditioned residual.
Teuchos::RCP< MV > Ap
A times current search vector.
RCGIter(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< OutputManager< ScalarType > > &printer, const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &tester, Teuchos::ParameterList &params)
RCGIter constructor with linear problem, solver utilities, and parameter list of solver options...
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
Teuchos::RCP< MV > U_
A linear system to solve, and its associated information.
Class which describes the linear problem to be solved by the iterative solver.
Teuchos::RCP< MV > P_
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Alpha
Coefficients arising in RCG iteration.
TransListIter iter
Teuchos::RCP< MV > Ap_
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > LUUTAU_
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Delta_
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current solution to the linear problem...
void GETRS(const char &TRANS, const OrdinalType &n, const OrdinalType &nrhs, const ScalarType *A, const OrdinalType &lda, const OrdinalType *IPIV, ScalarType *B, const OrdinalType &ldb, OrdinalType *info) const
int curDim
The current dimension of the reduction.
void setRecycledBlocks(int recycleBlocks)
Set the maximum number of recycled blocks used by the iterative solver.
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
Teuchos::RCP< MV > AU_
Class which defines basic traits for the operator type.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > D
void iterate()
This method performs RCG iterations until the status test indicates the need to stop or an error occu...
void resetNumIters(int iter=0)
Reset the iteration count.
Teuchos::RCP< std::vector< int > > ipiv_
void setBlockSize(int blockSize)
Set the blocksize.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *) const
Get the norms of the residuals native to the solver.
Belos header file which uses auto-configuration information to include necessary C++ headers...
Teuchos::ScalarTraits< ScalarType > SCT
Teuchos::RCP< MV > r_
bool isInitialized()
States whether the solver has been initialized or not.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Delta
Solutions to local least-squares problems.
OrdinalType stride() const
Teuchos::RCP< MV > z_
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
SCT::magnitudeType MagnitudeType