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 
44 
47 template<class ScalarType, class MV, class OP,
48  const bool lapackSupportsScalarType =
50 class BlockCGIter : virtual public CGIteration<ScalarType, MV, OP> {
51 public:
56 
58  const Teuchos::RCP<OutputManager<ScalarType> > & /* printer */,
59  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > & /* tester */,
60  const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > & /* ortho */,
61  Teuchos::ParameterList & /* params */ )
62  {
63  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
64  }
65 
66  virtual ~BlockCGIter() {}
67 
68  void iterate () {
69  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
70  }
71 
73  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
74  }
75 
76  void initialize () {
77  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
78  }
79 
81  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
82  }
83 
84  int getNumIters() const {
85  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
86  }
87 
88  void resetNumIters( int iter=0 ) {
89  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
90  }
91 
93  getNativeResiduals (std::vector<MagnitudeType>* /* norms */) const {
94  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
95  }
96 
98  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
99  }
100 
102  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
103  }
104 
105  int getBlockSize() const {
106  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
107  }
108 
109  void setBlockSize(int blockSize) {
110  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
111  }
112 
113  bool isInitialized() {
114  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
115  }
116 
117  void setDoCondEst(bool val){
118  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
119  }
120 
121 
122 private:
123  void setStateSize() {
124  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
125  }
126 };
127 
132 template<class ScalarType, class MV, class OP>
133 class BlockCGIter<ScalarType, MV, OP, true> :
134  virtual public CGIteration<ScalarType,MV,OP>
135 {
136 public:
137  //
138  // Convenience typedefs
139  //
144 
146 
147 
154  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
157  Teuchos::ParameterList &params );
158 
160  virtual ~BlockCGIter() {};
162 
163 
165 
166 
179  void iterate();
180 
196 
200  void initialize()
201  {
203  initializeCG(empty);
204  }
205 
214  state.R = R_;
215  state.P = P_;
216  state.AP = AP_;
217  state.Z = Z_;
218  return state;
219  }
220 
222 
223 
225 
226 
228  int getNumIters() const { return iter_; }
229 
231  void resetNumIters( int iter=0 ) { iter_ = iter; }
232 
235  Teuchos::RCP<const MV> getNativeResiduals( std::vector<MagnitudeType> * /* norms */ ) const { return R_; }
236 
238 
241 
243 
245 
246 
248  const LinearProblem<ScalarType,MV,OP>& getProblem() const { return *lp_; }
249 
251  int getBlockSize() const { return blockSize_; }
252 
254  void setBlockSize(int blockSize);
255 
257  bool isInitialized() { return initialized_; }
258 
260  void setDoCondEst(bool /* val */){/*ignored*/}
261 
265  return temp;
266  }
267 
271  return temp;
272  }
274 
275  private:
276 
277  //
278  // Internal methods
279  //
281  void setStateSize();
282 
283  //
284  // Classes inputed through constructor that define the linear problem to be solved.
285  //
290 
291  //
292  // Algorithmic parameters
293  //
294  // blockSize_ is the solver block size.
296 
297  //
298  // Current solver state
299  //
300  // initialized_ specifies that the basis vectors have been initialized and the iterate() routine
301  // is capable of running; _initialize is controlled by the initialize() member method
302  // For the implications of the state of initialized_, please see documentation for initialize()
304 
305  // stateStorageInitialized_ specified that the state storage has be initialized.
306  // This initialization may be postponed if the linear problem was generated without
307  // the right-hand side or solution vectors.
309 
310  // Current subspace dimension, and number of iterations performed.
311  int iter_;
312 
313  //
314  // State Storage
315  //
316  // Residual
318  //
319  // Preconditioned residual
321  //
322  // Direction std::vector
324  //
325  // Operator applied to direction std::vector
327 
328 };
329 
330  template<class ScalarType, class MV, class OP>
333  const Teuchos::RCP<OutputManager<ScalarType> >& printer,
336  Teuchos::ParameterList& params) :
337  lp_(problem),
338  om_(printer),
339  stest_(tester),
340  ortho_(ortho),
341  blockSize_(0),
342  initialized_(false),
343  stateStorageInitialized_(false),
344  iter_(0)
345  {
346  // Set the block size and allocate data
347  int bs = params.get("Block Size", 1);
348  setBlockSize( bs );
349  }
350 
351  template <class ScalarType, class MV, class OP>
353  {
354  if (! stateStorageInitialized_) {
355  // Check if there is any multivector to clone from.
356  Teuchos::RCP<const MV> lhsMV = lp_->getLHS();
357  Teuchos::RCP<const MV> rhsMV = lp_->getRHS();
358  if (lhsMV == Teuchos::null && rhsMV == Teuchos::null) {
359  stateStorageInitialized_ = false;
360  return;
361  }
362  else {
363  // Initialize the state storage If the subspace has not be
364  // initialized before, generate it using the LHS or RHS from
365  // lp_.
366  if (R_ == Teuchos::null || MVT::GetNumberVecs(*R_)!=blockSize_) {
367  // Get the multivector that is not null.
368  Teuchos::RCP<const MV> tmp = ( (rhsMV!=Teuchos::null)? rhsMV: lhsMV );
370  (tmp == Teuchos::null,std:: invalid_argument,
371  "Belos::BlockCGIter::setStateSize: LinearProblem lacks "
372  "multivectors from which to clone.");
373  R_ = MVT::Clone (*tmp, blockSize_);
374  Z_ = MVT::Clone (*tmp, blockSize_);
375  P_ = MVT::Clone (*tmp, blockSize_);
376  AP_ = MVT::Clone (*tmp, blockSize_);
377  }
378 
379  // State storage has now been initialized.
380  stateStorageInitialized_ = true;
381  }
382  }
383  }
384 
385  template <class ScalarType, class MV, class OP>
387  {
388  // This routine only allocates space; it doesn't not perform any computation
389  // any change in size will invalidate the state of the solver.
391  (blockSize <= 0, std::invalid_argument, "Belos::BlockGmresIter::"
392  "setBlockSize: blockSize = " << blockSize << " <= 0.");
393  if (blockSize == blockSize_) {
394  return; // do nothing
395  }
396  if (blockSize!=blockSize_) {
397  stateStorageInitialized_ = false;
398  }
399  blockSize_ = blockSize;
400  initialized_ = false;
401  // Use the current blockSize_ to initialize the state storage.
402  setStateSize ();
403  }
404 
405  template <class ScalarType, class MV, class OP>
408  {
409  const char prefix[] = "Belos::BlockCGIter::initialize: ";
410 
411  // Initialize the state storage if it isn't already.
412  if (! stateStorageInitialized_) {
413  setStateSize();
414  }
415 
417  (! stateStorageInitialized_, std::invalid_argument,
418  prefix << "Cannot initialize state storage!");
419 
420  // NOTE: In BlockCGIter R_, the initial residual, is required!!!
421  const char errstr[] = "Specified multivectors must have a consistent "
422  "length and width.";
423 
424  // Create convenience variables for zero and one.
425  //const MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero(); // unused
426 
427  if (newstate.R != Teuchos::null) {
428 
430  (MVT::GetGlobalLength(*newstate.R) != MVT::GetGlobalLength(*R_),
431  std::invalid_argument, prefix << errstr );
433  (MVT::GetNumberVecs(*newstate.R) != blockSize_,
434  std::invalid_argument, prefix << errstr );
435 
436  // Copy basis vectors from newstate into V
437  if (newstate.R != R_) {
438  // copy over the initial residual (unpreconditioned).
439  MVT::Assign( *newstate.R, *R_ );
440  }
441  // Compute initial direction vectors
442  // Initially, they are set to the preconditioned residuals
443  //
444  if ( lp_->getLeftPrec() != Teuchos::null ) {
445  lp_->applyLeftPrec( *R_, *Z_ );
446  if ( lp_->getRightPrec() != Teuchos::null ) {
447  Teuchos::RCP<MV> tmp = MVT::Clone( *Z_, blockSize_ );
448  lp_->applyRightPrec( *Z_, *tmp );
449  Z_ = tmp;
450  }
451  }
452  else if ( lp_->getRightPrec() != Teuchos::null ) {
453  lp_->applyRightPrec( *R_, *Z_ );
454  }
455  else {
456  Z_ = R_;
457  }
458  MVT::Assign( *Z_, *P_ );
459  }
460  else {
462  (newstate.R == Teuchos::null, std::invalid_argument,
463  prefix << "BlockCGStateIterState does not have initial residual.");
464  }
465 
466  // The solver is initialized
467  initialized_ = true;
468  }
469 
470  template <class ScalarType, class MV, class OP>
472  {
473  const char prefix[] = "Belos::BlockCGIter::iterate: ";
474 
475  //
476  // Allocate/initialize data structures
477  //
478  if (initialized_ == false) {
479  initialize();
480  }
481  // Allocate data needed for LAPACK work.
482  int info = 0;
483  //char UPLO = 'U';
484  //(void) UPLO; // silence "unused variable" compiler warnings
485  bool uplo = true;
487 
488  // Allocate memory for scalars.
489  Teuchos::SerialDenseMatrix<int,ScalarType> alpha( blockSize_, blockSize_ );
490  Teuchos::SerialDenseMatrix<int,ScalarType> beta( blockSize_, blockSize_ );
491  Teuchos::SerialDenseMatrix<int,ScalarType> rHz( blockSize_, blockSize_ ),
492  rHz_old( blockSize_, blockSize_ ), pAp( blockSize_, blockSize_ );
493  Teuchos::SerialSymDenseMatrix<int,ScalarType> pApHerm(Teuchos::View, uplo, pAp.values(), blockSize_, blockSize_);
494 
495  // Create dense spd solver.
497 
498  // Create convenience variable for one.
499  const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
500 
501  // Get the current solution std::vector.
502  Teuchos::RCP<MV> cur_soln_vec = lp_->getCurrLHSVec();
503 
504  // Check that the current solution std::vector has blockSize_ columns.
506  (MVT::GetNumberVecs(*cur_soln_vec) != blockSize_, CGIterateFailure,
507  prefix << "Current linear system does not have the right number of vectors!" );
508  int rank = ortho_->normalize( *P_, Teuchos::null );
510  (rank != blockSize_, CGIterationOrthoFailure,
511  prefix << "Failed to compute initial block of orthonormal direction vectors.");
512 
513  //
514  // Iterate until the status test tells us to stop.
515  //
516  while (stest_->checkStatus(this) != Passed) {
517  // Increment the iteration
518  iter_++;
519 
520  // Multiply the current direction std::vector by A and store in Ap_
521  lp_->applyOp( *P_, *AP_ );
522 
523  // Compute alpha := <P_,R_> / <P_,AP_>
524  // 1) Compute P^T * A * P = pAp and P^T * R
525  // 2) Compute the Cholesky Factorization of pAp
526  // 3) Back and forward solves to compute alpha
527  //
528  MVT::MvTransMv( one, *P_, *R_, alpha );
529  MVT::MvTransMv( one, *P_, *AP_, pAp );
530 
531  // Compute Cholesky factorization of pAp
532  lltSolver.setMatrix( Teuchos::rcp(&pApHerm, false) );
533  lltSolver.factorWithEquilibration( true );
534  info = lltSolver.factor();
536  (info != 0, CGIterationLAPACKFailure,
537  prefix << "Failed to compute Cholesky factorization using LAPACK routine POTRF.");
538 
539  // Compute alpha by performing a back and forward solve with the
540  // Cholesky factorization in pAp.
541  lltSolver.setVectors (Teuchos::rcpFromRef (alpha), Teuchos::rcpFromRef (alpha));
542  info = lltSolver.solve();
544  (info != 0, CGIterationLAPACKFailure,
545  prefix << "Failed to compute alpha using Cholesky factorization (POTRS).");
546 
547  // Update the solution std::vector X := X + alpha * P_
548  MVT::MvTimesMatAddMv( one, *P_, alpha, one, *cur_soln_vec );
549  lp_->updateSolution();
550 
551  // Compute the new residual R_ := R_ - alpha * AP_
552  MVT::MvTimesMatAddMv( -one, *AP_, alpha, one, *R_ );
553 
554  // Compute the new preconditioned residual, Z_.
555  if ( lp_->getLeftPrec() != Teuchos::null ) {
556  lp_->applyLeftPrec( *R_, *Z_ );
557  if ( lp_->getRightPrec() != Teuchos::null ) {
558  Teuchos::RCP<MV> tmp = MVT::Clone( *Z_, blockSize_ );
559  lp_->applyRightPrec( *Z_, *tmp );
560  Z_ = tmp;
561  }
562  }
563  else if ( lp_->getRightPrec() != Teuchos::null ) {
564  lp_->applyRightPrec( *R_, *Z_ );
565  }
566  else {
567  Z_ = R_;
568  }
569 
570  // Compute beta := <AP_,Z_> / <P_,AP_>
571  // 1) Compute AP_^T * Z_
572  // 2) Compute the Cholesky Factorization of pAp (already have)
573  // 3) Back and forward solves to compute beta
574 
575  // Compute <AP_,Z>
576  MVT::MvTransMv( -one, *AP_, *Z_, beta );
577 
578  lltSolver.setVectors( Teuchos::rcp( &beta, false ), Teuchos::rcp( &beta, false ) );
579  info = lltSolver.solve();
581  (info != 0, CGIterationLAPACKFailure,
582  prefix << "Failed to compute beta using Cholesky factorization (POTRS).");
583 
584  // Compute the new direction vectors P_ = Z_ + P_ * beta
585  Teuchos::RCP<MV> Pnew = MVT::CloneCopy( *Z_ );
586  MVT::MvTimesMatAddMv(one, *P_, beta, one, *Pnew);
587  P_ = Pnew;
588 
589  // Compute orthonormal block of new direction vectors.
590  rank = ortho_->normalize( *P_, Teuchos::null );
592  (rank != blockSize_, CGIterationOrthoFailure,
593  prefix << "Failed to compute block of orthonormal direction vectors.");
594 
595  } // end while (sTest_->checkStatus(this) != Passed)
596  }
597 
598 } // namespace Belos
599 
600 #endif /* BELOS_BLOCK_CG_ITER_HPP */
ScalarType * values() const
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...
CGIterationState< ScalarType, MV > getState() const
Get the current state of the linear solver.
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)
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.
Teuchos::ScalarTraits< ScalarType > SCT
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
int getNumIters() const
Get the current iteration count.
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)
Structure to contain pointers to CGIteration state variables.
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.
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.
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...
Teuchos::RCP< const MV > AP
The matrix A applied to current decent direction vector.
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
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.
OperatorTraits< ScalarType, MV, OP > OPT
void initializeCG(CGIterationState< ScalarType, MV > &)
Initialize the solver to an iterate, providing a complete state.
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)
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.
bool isInitialized()
States whether the solver has been initialized or not.
void resetNumIters(int iter=0)
Reset the iteration count to iter.
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > stest_
const Teuchos::RCP< OrthoManager< ScalarType, MV > > ortho_
Teuchos::RCP< const MV > Z
The current preconditioned residual.
Teuchos::ArrayView< MagnitudeType > getDiag()
Gets the diagonal for condition estimation (NOT_IMPLEMENTED)
TransListIter iter
OperatorTraits< ScalarType, MV, OP > OPT
static ptrdiff_t GetGlobalLength(const MV &mv)
Return the number of rows in the given multivector mv.
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...
Belos header file which uses auto-configuration information to include necessary C++ headers...
CGIterationState< ScalarType, MV > getState() const
Get the current state of the linear solver.
Teuchos::RCP< const MV > P
The current decent direction vector.
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...