Belos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BelosBlockCGIter.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_BLOCK_CG_ITER_HPP
11 #define BELOS_BLOCK_CG_ITER_HPP
12 
17 #include "BelosConfigDefs.hpp"
18 #include "BelosTypes.hpp"
19 #include "BelosCGIteration.hpp"
20 
21 #include "BelosLinearProblem.hpp"
22 #include "BelosMatOrthoManager.hpp"
23 #include "BelosOutputManager.hpp"
24 #include "BelosStatusTest.hpp"
25 #include "BelosOperatorTraits.hpp"
26 #include "BelosMultiVecTraits.hpp"
27 
28 #include "Teuchos_LAPACK.hpp"
33 #include "Teuchos_ScalarTraits.hpp"
35 #include "Teuchos_TimeMonitor.hpp"
36 
37 namespace Belos {
38 
40 
41 
46  template <class ScalarType, class MV>
47  class BlockCGIterationState : public CGIterationStateBase<ScalarType, MV> {
48 
49  public:
50  BlockCGIterationState() = default;
51 
53  initialize(tmp);
54  }
55 
56  virtual ~BlockCGIterationState() = default;
57 
58  void initialize(Teuchos::RCP<const MV> tmp, int _numVectors) {
60  this->R = MVT::Clone( *tmp, _numVectors );
61  this->Z = MVT::Clone( *tmp, _numVectors );
62  this->P = MVT::Clone( *tmp, _numVectors );
63  this->AP = MVT::Clone(*tmp, _numVectors );
64 
66  }
67 
68  bool matches(Teuchos::RCP<const MV> tmp, int _numVectors=1) const {
69  return CGIterationStateBase<ScalarType, MV>::matches(tmp, _numVectors);
70  }
71 
72 };
73 
79 
82 template<class ScalarType, class MV, class OP,
83  const bool lapackSupportsScalarType =
85 class BlockCGIter : virtual public CGIteration<ScalarType, MV, OP> {
86 public:
91 
93  const Teuchos::RCP<OutputManager<ScalarType> > & /* printer */,
94  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > & /* tester */,
95  const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > & /* ortho */,
96  Teuchos::ParameterList & /* params */ )
97  {
98  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
99  }
100 
101  virtual ~BlockCGIter() {}
102 
103  void iterate () {
104  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
105  }
106 
108  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
109  }
110 
111  void initialize () {
112  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
113  }
114 
116  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
117  }
118 
120  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
121  }
122 
123  int getNumIters() const {
124  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
125  }
126 
127  void resetNumIters( int iter=0 ) {
128  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
129  }
130 
132  getNativeResiduals (std::vector<MagnitudeType>* /* norms */) const {
133  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
134  }
135 
137  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
138  }
139 
141  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
142  }
143 
144  int getBlockSize() const {
145  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
146  }
147 
148  void setBlockSize(int blockSize) {
149  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
150  }
151 
152  bool isInitialized() {
153  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
154  }
155 
156  void setDoCondEst(bool val){
157  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
158  }
159 
160 };
161 
166 template<class ScalarType, class MV, class OP>
167 class BlockCGIter<ScalarType, MV, OP, true> :
168  virtual public CGIteration<ScalarType,MV,OP>
169 {
170 public:
171  //
172  // Convenience typedefs
173  //
178 
180 
181 
188  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
191  Teuchos::ParameterList &params );
192 
194  virtual ~BlockCGIter() = default;
196 
197 
199 
200 
213  void iterate();
214 
230 
234  void initialize()
235  {
237  }
238 
247  state->R = R_;
248  state->P = P_;
249  state->AP = AP_;
250  state->Z = Z_;
251  return state;
252  }
253 
255  auto s = Teuchos::rcp_dynamic_cast<BlockCGIterationState<ScalarType,MV> >(state, true);
256  R_ = s->R;
257  Z_ = s->Z;
258  P_ = s->P;
259  AP_ = s->AP;
260  }
261 
263 
264 
266 
267 
269  int getNumIters() const { return iter_; }
270 
272  void resetNumIters( int iter=0 ) { iter_ = iter; }
273 
276  Teuchos::RCP<const MV> getNativeResiduals( std::vector<MagnitudeType> * /* norms */ ) const { return R_; }
277 
279 
282 
284 
286 
287 
289  const LinearProblem<ScalarType,MV,OP>& getProblem() const { return *lp_; }
290 
292  int getBlockSize() const { return blockSize_; }
293 
295  void setBlockSize(int blockSize);
296 
298  bool isInitialized() { return initialized_; }
299 
301  void setDoCondEst(bool /* val */){/*ignored*/}
302 
306  return temp;
307  }
308 
312  return temp;
313  }
315 
316  private:
317 
318  //
319  // Internal methods
320 
321  //
322  // Classes inputed through constructor that define the linear problem to be solved.
323  //
328 
329  //
330  // Algorithmic parameters
331  //
332  // blockSize_ is the solver block size.
334 
335  //
336  // Current solver state
337  //
338  // initialized_ specifies that the basis vectors have been initialized and the iterate() routine
339  // is capable of running; _initialize is controlled by the initialize() member method
340  // For the implications of the state of initialized_, please see documentation for initialize()
342 
343  // stateStorageInitialized_ specified that the state storage has be initialized.
344  // This initialization may be postponed if the linear problem was generated without
345  // the right-hand side or solution vectors.
347 
348  // Current subspace dimension, and number of iterations performed.
349  int iter_;
350 
351  //
352  // State Storage
353  //
354  // Residual
356  //
357  // Preconditioned residual
359  //
360  // Direction std::vector
362  //
363  // Operator applied to direction std::vector
365 
366 };
367 
368  template<class ScalarType, class MV, class OP>
371  const Teuchos::RCP<OutputManager<ScalarType> >& printer,
374  Teuchos::ParameterList& params) :
375  lp_(problem),
376  om_(printer),
377  stest_(tester),
378  ortho_(ortho),
379  blockSize_(0),
380  initialized_(false),
381  stateStorageInitialized_(false),
382  iter_(0)
383  {
384  // Set the block size and allocate data
385  int bs = params.get("Block Size", 1);
386  setBlockSize( bs );
387  }
388 
389  template <class ScalarType, class MV, class OP>
391  {
392  // This routine only allocates space; it doesn't not perform any computation
393  // any change in size will invalidate the state of the solver.
395  (blockSize <= 0, std::invalid_argument, "Belos::BlockGmresIter::"
396  "setBlockSize: blockSize = " << blockSize << " <= 0.");
397  if (blockSize == blockSize_) {
398  return; // do nothing
399  }
400  if (blockSize!=blockSize_) {
401  stateStorageInitialized_ = false;
402  }
403  blockSize_ = blockSize;
404  initialized_ = false;
405  }
406 
407  template <class ScalarType, class MV, class OP>
410  {
411  const char prefix[] = "Belos::BlockCGIter::initialize: ";
412 
413  // Initialize the state storage if it isn't already.
414  Teuchos::RCP<const MV> lhsMV = lp_->getLHS();
415  Teuchos::RCP<const MV> rhsMV = lp_->getRHS();
416  Teuchos::RCP<const MV> tmp = ( (rhsMV!=Teuchos::null)? rhsMV: lhsMV );
417  TEUCHOS_ASSERT(!newstate.is_null());
418  if (!Teuchos::rcp_dynamic_cast<BlockCGIterationState<ScalarType,MV> >(newstate, true)->matches(tmp, blockSize_))
419  newstate->initialize(tmp, blockSize_);
420  setState(newstate);
421 
422  // NOTE: In BlockCGIter R_, the initial residual, is required!!!
423  const char errstr[] = "Specified multivectors must have a consistent "
424  "length and width.";
425 
426  {
427 
430  std::invalid_argument, prefix << errstr );
432  (MVT::GetNumberVecs(*R_0) != blockSize_,
433  std::invalid_argument, prefix << errstr );
434 
435  // Copy basis vectors from newstate into V
436  if (R_0 != R_) {
437  // copy over the initial residual (unpreconditioned).
438  MVT::Assign( *R_0, *R_ );
439  }
440  // Compute initial direction vectors
441  // Initially, they are set to the preconditioned residuals
442  //
443  if ( lp_->getLeftPrec() != Teuchos::null ) {
444  lp_->applyLeftPrec( *R_, *Z_ );
445  if ( lp_->getRightPrec() != Teuchos::null ) {
446  Teuchos::RCP<MV> tmp2 = MVT::Clone( *Z_, blockSize_ );
447  lp_->applyRightPrec( *Z_, *tmp2 );
448  Z_ = tmp2;
449  }
450  }
451  else if ( lp_->getRightPrec() != Teuchos::null ) {
452  lp_->applyRightPrec( *R_, *Z_ );
453  }
454  else {
455  Z_ = R_;
456  }
457  MVT::Assign( *Z_, *P_ );
458  }
459 
460  // The solver is initialized
461  initialized_ = true;
462  }
463 
464  template <class ScalarType, class MV, class OP>
466  {
467  const char prefix[] = "Belos::BlockCGIter::iterate: ";
468 
469  //
470  // Allocate/initialize data structures
471  //
472  if (initialized_ == false) {
473  initialize();
474  }
475  // Allocate data needed for LAPACK work.
476  int info = 0;
477  //char UPLO = 'U';
478  //(void) UPLO; // silence "unused variable" compiler warnings
479  bool uplo = true;
481 
482  // Allocate memory for scalars.
483  Teuchos::SerialDenseMatrix<int,ScalarType> alpha( blockSize_, blockSize_ );
484  Teuchos::SerialDenseMatrix<int,ScalarType> beta( blockSize_, blockSize_ );
485  Teuchos::SerialDenseMatrix<int,ScalarType> rHz( blockSize_, blockSize_ ),
486  rHz_old( blockSize_, blockSize_ ), pAp( blockSize_, blockSize_ );
487  Teuchos::SerialSymDenseMatrix<int,ScalarType> pApHerm(Teuchos::View, uplo, pAp.values(), blockSize_, blockSize_);
488 
489  // Create dense spd solver.
491 
492  // Create convenience variable for one.
493  const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
494 
495  // Get the current solution std::vector.
496  Teuchos::RCP<MV> cur_soln_vec = lp_->getCurrLHSVec();
497 
498  // Check that the current solution std::vector has blockSize_ columns.
500  (MVT::GetNumberVecs(*cur_soln_vec) != blockSize_, CGIterateFailure,
501  prefix << "Current linear system does not have the right number of vectors!" );
502  int rank = ortho_->normalize( *P_, Teuchos::null );
504  (rank != blockSize_, CGIterationOrthoFailure,
505  prefix << "Failed to compute initial block of orthonormal direction vectors.");
506 
507  //
508  // Iterate until the status test tells us to stop.
509  //
510  while (stest_->checkStatus(this) != Passed) {
511  // Increment the iteration
512  iter_++;
513 
514  // Multiply the current direction std::vector by A and store in Ap_
515  lp_->applyOp( *P_, *AP_ );
516 
517  // Compute alpha := <P_,R_> / <P_,AP_>
518  // 1) Compute P^T * A * P = pAp and P^T * R
519  // 2) Compute the Cholesky Factorization of pAp
520  // 3) Back and forward solves to compute alpha
521  //
522  MVT::MvTransMv( one, *P_, *R_, alpha );
523  MVT::MvTransMv( one, *P_, *AP_, pAp );
524 
525  // Compute Cholesky factorization of pAp
526  lltSolver.setMatrix( Teuchos::rcp(&pApHerm, false) );
527  lltSolver.factorWithEquilibration( true );
528  info = lltSolver.factor();
530  (info != 0, CGIterationLAPACKFailure,
531  prefix << "Failed to compute Cholesky factorization using LAPACK routine POTRF.");
532 
533  // Compute alpha by performing a back and forward solve with the
534  // Cholesky factorization in pAp.
535  lltSolver.setVectors (Teuchos::rcpFromRef (alpha), Teuchos::rcpFromRef (alpha));
536  info = lltSolver.solve();
538  (info != 0, CGIterationLAPACKFailure,
539  prefix << "Failed to compute alpha using Cholesky factorization (POTRS).");
540 
541  // Update the solution std::vector X := X + alpha * P_
542  MVT::MvTimesMatAddMv( one, *P_, alpha, one, *cur_soln_vec );
543  lp_->updateSolution();
544 
545  // Compute the new residual R_ := R_ - alpha * AP_
546  MVT::MvTimesMatAddMv( -one, *AP_, alpha, one, *R_ );
547 
548  // Compute the new preconditioned residual, Z_.
549  if ( lp_->getLeftPrec() != Teuchos::null ) {
550  lp_->applyLeftPrec( *R_, *Z_ );
551  if ( lp_->getRightPrec() != Teuchos::null ) {
552  Teuchos::RCP<MV> tmp = MVT::Clone( *Z_, blockSize_ );
553  lp_->applyRightPrec( *Z_, *tmp );
554  Z_ = tmp;
555  }
556  }
557  else if ( lp_->getRightPrec() != Teuchos::null ) {
558  lp_->applyRightPrec( *R_, *Z_ );
559  }
560  else {
561  Z_ = R_;
562  }
563 
564  // Compute beta := <AP_,Z_> / <P_,AP_>
565  // 1) Compute AP_^T * Z_
566  // 2) Compute the Cholesky Factorization of pAp (already have)
567  // 3) Back and forward solves to compute beta
568 
569  // Compute <AP_,Z>
570  MVT::MvTransMv( -one, *AP_, *Z_, beta );
571 
572  lltSolver.setVectors( Teuchos::rcp( &beta, false ), Teuchos::rcp( &beta, false ) );
573  info = lltSolver.solve();
575  (info != 0, CGIterationLAPACKFailure,
576  prefix << "Failed to compute beta using Cholesky factorization (POTRS).");
577 
578  // Compute the new direction vectors P_ = Z_ + P_ * beta
579  Teuchos::RCP<MV> Pnew = MVT::CloneCopy( *Z_ );
580  MVT::MvTimesMatAddMv(one, *P_, beta, one, *Pnew);
581  P_ = Pnew;
582 
583  // Compute orthonormal block of new direction vectors.
584  rank = ortho_->normalize( *P_, Teuchos::null );
586  (rank != blockSize_, CGIterationOrthoFailure,
587  prefix << "Failed to compute block of orthonormal direction vectors.");
588 
589  } // end while (sTest_->checkStatus(this) != Passed)
590  }
591 
592 } // namespace Belos
593 
594 #endif /* BELOS_BLOCK_CG_ITER_HPP */
Structure to contain pointers to BlockCGIteration state variables.
ScalarType * values() const
Collection of types and exceptions used within the Belos solvers.
Teuchos::RCP< CGIterationStateBase< ScalarType, MV > > getState() const
Get the current state of the linear solver.
Belos&#39;s basic output manager for sending information of select verbosity levels to the appropriate ou...
void setDoCondEst(bool val)
Sets whether or not to store the diagonal for condition estimation.
Teuchos::ArrayView< MagnitudeType > getOffDiag()
Gets the off-diagonal for condition estimation (NOT_IMPLEMENTED)
void setState(Teuchos::RCP< CGIterationStateBase< ScalarType, MV > > state)
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
Class which manages the output and verbosity of the Belos solvers.
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
int getNumIters() const
Get the current iteration count.
Teuchos::RCP< CGIterationStateBase< ScalarType, MV > > getState() const
Get the current state of the linear solver.
const Teuchos::RCP< OutputManager< ScalarType > > om_
BlockCGIter(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &, const Teuchos::RCP< OutputManager< ScalarType > > &, const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &, const Teuchos::RCP< MatOrthoManager< ScalarType, MV, OP > > &, Teuchos::ParameterList &)
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
T & get(ParameterList &l, const std::string &name)
Pure virtual base class which augments the basic interface for a conjugate gradient linear solver ite...
void resetNumIters(int iter=0)
Reset the iteration count.
void setState(Teuchos::RCP< CGIterationStateBase< ScalarType, MV > > state)
Pure virtual base class for defining the status testing capabilities of Belos.
void setDoCondEst(bool)
Sets whether or not to store the diagonal for condition estimation.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
MultiVecTraits< ScalarType, MV > MVT
Declaration of basic traits for the multivector type.
bool matches(Teuchos::RCP< const MV > tmp, int _numVectors=1) const
Teuchos::ScalarTraits< ScalarType > SCT
static void MvTransMv(const ScalarType alpha, const MV &A, const MV &mv, Teuchos::SerialDenseMatrix< int, ScalarType > &B)
Compute a dense matrix B through the matrix-matrix multiply .
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...
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
Teuchos::RCP< MV > P
The current decent direction vector.
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
static void Assign(const MV &A, MV &mv)
mv := A
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
Traits class which defines basic operations on multivectors.
void initializeCG(Teuchos::RCP< BlockCGIterationState< ScalarType, MV > >, Teuchos::RCP< MV >)
CGIterationLAPACKFailure is thrown when a nonzero return value is passed back from an LAPACK routine...
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual void initialize(Teuchos::RCP< const MV > tmp, int _numVectors)
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *) const
Get the norms of the residuals native to the solver.
void iterate()
This method performs linear solver iterations until the status test indicates the need to stop or an ...
A linear system to solve, and its associated information.
int getNumIters() const
Get the current iteration count.
Class which describes the linear problem to be solved by the iterative solver.
SCT::magnitudeType MagnitudeType
Type traits class that says whether Teuchos::LAPACK has a valid implementation for the given ScalarTy...
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
Creates a new MV and copies contents of mv into the new vector (deep copy).
static void MvTimesMatAddMv(const ScalarType alpha, const MV &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta, MV &mv)
Update mv with .
const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > lp_
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
bool isInitialized()
States whether the solver has been initialized or not.
void initialize(Teuchos::RCP< const MV > tmp, int _numVectors)
bool isInitialized()
States whether the solver has been initialized or not.
BlockCGIterationState(Teuchos::RCP< const MV > tmp)
void resetNumIters(int iter=0)
Reset the iteration count to iter.
Structure to contain pointers to CGIteration state variables.
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > stest_
const Teuchos::RCP< OrthoManager< ScalarType, MV > > ortho_
Teuchos::ArrayView< MagnitudeType > getDiag()
Gets the diagonal for condition estimation (NOT_IMPLEMENTED)
Teuchos::RCP< MV > Z
The current preconditioned residual.
TransListIter iter
OperatorTraits< ScalarType, MV, OP > OPT
static ptrdiff_t GetGlobalLength(const MV &mv)
Return the number of rows in the given multivector mv.
Teuchos::RCP< MV > AP
The matrix A applied to current decent direction vector.
CGIterationOrthoFailure is thrown when the CGIteration object is unable to compute independent direct...
void setBlockSize(int blockSize)
Set the blocksize to be used by the iterative solver in solving this linear problem.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *) const
int getBlockSize() const
Get the block size to be used by the iterative solver in solving this linear problem.
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
Class which defines basic traits for the operator type.
Belos&#39;s templated virtual class for providing routines for orthogonalization and orthonormzalition of...
#define TEUCHOS_ASSERT(assertion_test)
Teuchos::RCP< MV > R
The current residual.
Belos header file which uses auto-configuration information to include necessary C++ headers...
virtual ~BlockCGIterationState()=default
virtual bool matches(Teuchos::RCP< const MV > tmp, int _numVectors=1) const
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Stub implementation of BlockCGIter, for ScalarType types for which Teuchos::LAPACK does NOT have a va...