Belos  Version of the Day
BelosCGSingleRedIter.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_CG_SINGLE_RED_ITER_HPP
43 #define BELOS_CG_SINGLE_RED_ITER_HPP
44 
49 #include "BelosConfigDefs.hpp"
50 #include "BelosTypes.hpp"
51 #include "BelosCGIteration.hpp"
52 
53 #include "BelosLinearProblem.hpp"
54 #include "BelosOutputManager.hpp"
55 #include "BelosStatusTest.hpp"
56 #include "BelosOperatorTraits.hpp"
57 #include "BelosMultiVecTraits.hpp"
58 
59 #include "Teuchos_SerialDenseMatrix.hpp"
60 #include "Teuchos_SerialDenseVector.hpp"
61 #include "Teuchos_ScalarTraits.hpp"
62 #include "Teuchos_ParameterList.hpp"
63 #include "Teuchos_TimeMonitor.hpp"
64 
75 namespace Belos {
76 
77 template<class ScalarType, class MV, class OP>
78 class CGSingleRedIter : virtual public CGIteration<ScalarType,MV,OP> {
79 
80  public:
81 
82  //
83  // Convenience typedefs
84  //
87  typedef Teuchos::ScalarTraits<ScalarType> SCT;
88  typedef typename SCT::magnitudeType MagnitudeType;
89 
91 
92 
98  CGSingleRedIter( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
99  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
100  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
101  Teuchos::ParameterList &params );
102 
104  virtual ~CGSingleRedIter() {};
106 
107 
109 
110 
123  void iterate();
124 
140 
144  void initialize()
145  {
147  initializeCG(empty);
148  }
149 
158  state.R = R_;
159  state.P = P_;
160  state.AP = AP_;
161  state.Z = Z_;
162  return state;
163  }
164 
166 
167 
169 
170 
172  int getNumIters() const { return iter_; }
173 
175  void resetNumIters( int iter = 0 ) { iter_ = iter; }
176 
179  Teuchos::RCP<const MV> getNativeResiduals( std::vector<MagnitudeType> *norms ) const { return R_; }
180 
182 
184  Teuchos::RCP<MV> getCurrentUpdate() const { return Teuchos::null; }
185 
187 
189 
190 
192  const LinearProblem<ScalarType,MV,OP>& getProblem() const { return *lp_; }
193 
195  int getBlockSize() const { return 1; }
196 
198  void setBlockSize(int blockSize) {
199  TEUCHOS_TEST_FOR_EXCEPTION(blockSize!=1,std::invalid_argument,
200  "Belos::CGSingleRedIter::setBlockSize(): Cannot use a block size that is not one.");
201  }
202 
204  bool isInitialized() { return initialized_; }
205 
207 
208  private:
209 
210  //
211  // Internal methods
212  //
214  void setStateSize();
215 
216  //
217  // Classes inputed through constructor that define the linear problem to be solved.
218  //
219  const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > lp_;
220  const Teuchos::RCP<OutputManager<ScalarType> > om_;
221  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > stest_;
222 
223  //
224  // Current solver state
225  //
226  // initialized_ specifies that the basis vectors have been initialized and the iterate() routine
227  // is capable of running; _initialize is controlled by the initialize() member method
228  // For the implications of the state of initialized_, please see documentation for initialize()
229  bool initialized_;
230 
231  // stateStorageInitialized_ specifies that the state storage has been initialized.
232  // This initialization may be postponed if the linear problem was generated without
233  // the right-hand side or solution vectors.
234  bool stateStorageInitialized_;
235 
236  // Current number of iterations performed.
237  int iter_;
238 
239  //
240  // State Storage
241  //
242  // Residual
243  Teuchos::RCP<MV> R_;
244  //
245  // Preconditioned residual
246  Teuchos::RCP<MV> Z_;
247  //
248  // Operator applied to preconditioned residual
249  Teuchos::RCP<MV> AZ_;
250  //
251  // This is the additional storage needed for single-reduction CG (Chronopoulos/Gear)
252  // R_ views the first vector and AZ_ views the second vector
253  Teuchos::RCP<MV> S_;
254  //
255  // Direction vector
256  Teuchos::RCP<MV> P_;
257  //
258  // Operator applied to direction vector (S)
259  Teuchos::RCP<MV> AP_;
260 
261 };
262 
264  // Constructor.
265  template<class ScalarType, class MV, class OP>
267  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
268  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
269  Teuchos::ParameterList &params ):
270  lp_(problem),
271  om_(printer),
272  stest_(tester),
273  initialized_(false),
274  stateStorageInitialized_(false),
275  iter_(0)
276  {
277  }
278 
280  // Setup the state storage.
281  template <class ScalarType, class MV, class OP>
283  {
284  if (!stateStorageInitialized_) {
285 
286  // Check if there is any multivector to clone from.
287  Teuchos::RCP<const MV> lhsMV = lp_->getLHS();
288  Teuchos::RCP<const MV> rhsMV = lp_->getRHS();
289  if (lhsMV == Teuchos::null && rhsMV == Teuchos::null) {
290  stateStorageInitialized_ = false;
291  return;
292  }
293  else {
294 
295  // Initialize the state storage
296  // If the subspace has not be initialized before, generate it using the LHS or RHS from lp_.
297  if (R_ == Teuchos::null) {
298  // Get the multivector that is not null.
299  Teuchos::RCP<const MV> tmp = ( (rhsMV!=Teuchos::null)? rhsMV: lhsMV );
300  TEUCHOS_TEST_FOR_EXCEPTION(tmp == Teuchos::null,std::invalid_argument,
301  "Belos::CGSingleRedIter::setStateSize(): linear problem does not specify multivectors to clone from.");
302  S_ = MVT::Clone( *tmp, 2 );
303  Z_ = MVT::Clone( *tmp, 1 );
304  P_ = MVT::Clone( *tmp, 1 );
305  AP_ = MVT::Clone( *tmp, 1 );
306 
307  // R_ will view the first column of S_, AZ_ will view the second.
308  std::vector<int> index(1,0);
309  R_ = MVT::CloneViewNonConst( *S_, index );
310  index[0] = 1;
311  AZ_ = MVT::CloneViewNonConst( *S_, index );
312  }
313 
314  // State storage has now been initialized.
315  stateStorageInitialized_ = true;
316  }
317  }
318  }
319 
320 
322  // Initialize this iteration object
323  template <class ScalarType, class MV, class OP>
325  {
326  // Initialize the state storage if it isn't already.
327  if (!stateStorageInitialized_)
328  setStateSize();
329 
330  TEUCHOS_TEST_FOR_EXCEPTION(!stateStorageInitialized_,std::invalid_argument,
331  "Belos::CGSingleRedIter::initialize(): Cannot initialize state storage!");
332 
333  // NOTE: In CGSingleRedIter R_, the initial residual, is required!!!
334  //
335  std::string errstr("Belos::CGSingleRedIter::initialize(): Specified multivectors must have a consistent length and width.");
336 
337  if (newstate.R != Teuchos::null) {
338 
339  TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.R) != MVT::GetGlobalLength(*R_),
340  std::invalid_argument, errstr );
341  TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.R) != 1,
342  std::invalid_argument, errstr );
343 
344  // Copy basis vectors from newstate into V
345  if (newstate.R != R_) {
346  // copy over the initial residual (unpreconditioned).
347  MVT::Assign( *newstate.R, *R_ );
348  }
349 
350  // Compute initial direction vectors
351  // Initially, they are set to the preconditioned residuals
352  //
353  if ( lp_->getLeftPrec() != Teuchos::null ) {
354  lp_->applyLeftPrec( *R_, *Z_ );
355  if ( lp_->getRightPrec() != Teuchos::null ) {
356  Teuchos::RCP<MV> tmp = MVT::Clone( *Z_, 1 );
357  lp_->applyRightPrec( *Z_, *tmp );
358  Z_ = tmp;
359  }
360  }
361  else if ( lp_->getRightPrec() != Teuchos::null ) {
362  lp_->applyRightPrec( *R_, *Z_ );
363  }
364  else {
365  Z_ = R_;
366  }
367  MVT::Assign( *Z_, *P_ );
368 
369  // Multiply the current preconditioned residual vector by A and store in AZ_
370  lp_->applyOp( *Z_, *AZ_ );
371 
372  // Logically, AP_ = AZ_
373  MVT::Assign( *AZ_, *AP_ );
374  }
375  else {
376 
377  TEUCHOS_TEST_FOR_EXCEPTION(newstate.R == Teuchos::null,std::invalid_argument,
378  "Belos::CGSingleRedIter::initialize(): CGIterationState does not have initial residual.");
379  }
380 
381  // The solver is initialized
382  initialized_ = true;
383  }
384 
385 
387  // Iterate until the status test informs us we should stop.
388  template <class ScalarType, class MV, class OP>
390  {
391  //
392  // Allocate/initialize data structures
393  //
394  if (initialized_ == false) {
395  initialize();
396  }
397 
398  // Allocate memory for scalars.
399  Teuchos::SerialDenseMatrix<int,ScalarType> sHz( 2, 1 );
400  ScalarType rHz, rHz_old, alpha, beta, delta;
401 
402  // Create convenience variables for zero and one.
403  const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
404  const MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
405 
406  // Get the current solution vector.
407  Teuchos::RCP<MV> cur_soln_vec = lp_->getCurrLHSVec();
408 
409  // Check that the current solution vector only has one column.
410  TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*cur_soln_vec) != 1, CGIterateFailure,
411  "Belos::CGSingleRedIter::iterate(): current linear system has more than one vector!" );
412 
413  // Compute first <s,z> a.k.a. <r,z> and <Az,z> combined
414  MVT::MvTransMv( one, *S_, *Z_, sHz );
415  rHz = sHz(0,0);
416  delta = sHz(1,0);
417  alpha = rHz / delta;
418 
419  // Check that alpha is a positive number!
420  TEUCHOS_TEST_FOR_EXCEPTION( SCT::real(alpha) <= zero, CGIterateFailure,
421  "Belos::CGSingleRedIter::iterate(): non-positive value for p^H*A*p encountered!" );
422 
424  // Iterate until the status test tells us to stop.
425  //
426  while (1) {
427 
428  // Update the solution vector x := x + alpha * P_
429  //
430  MVT::MvAddMv( one, *cur_soln_vec, alpha, *P_, *cur_soln_vec );
431  lp_->updateSolution();
432  //
433  // Compute the new residual R_ := R_ - alpha * AP_
434  //
435  MVT::MvAddMv( one, *R_, -alpha, *AP_, *R_ );
436  //
437  // Check the status test, now that the solution and residual have been updated
438  //
439  if (stest_->checkStatus(this) == Passed) {
440  break;
441  }
442  // Increment the iteration
443  iter_++;
444  //
445  // Apply preconditioner to new residual to update Z_
446  //
447  if ( lp_->getLeftPrec() != Teuchos::null ) {
448  lp_->applyLeftPrec( *R_, *Z_ );
449  if ( lp_->getRightPrec() != Teuchos::null ) {
450  Teuchos::RCP<MV> tmp = MVT::Clone( *Z_, 1 );
451  lp_->applyRightPrec( *Z_, *tmp );
452  Z_ = tmp;
453  }
454  }
455  else if ( lp_->getRightPrec() != Teuchos::null ) {
456  lp_->applyRightPrec( *R_, *Z_ );
457  }
458  else {
459  Z_ = R_;
460  }
461  //
462  // Multiply the current preconditioned residual vector by A and store in AZ_
463  lp_->applyOp( *Z_, *AZ_ );
464  //
465  // Compute <S_,Z_> a.k.a. <R_,Z_> and <AZ_,Z_> combined
466  MVT::MvTransMv( one, *S_, *Z_, sHz );
467  //
468  // Update scalars.
469  rHz_old = rHz;
470  rHz = sHz(0,0);
471  delta = sHz(1,0);
472  //
473  beta = rHz / rHz_old;
474  alpha = rHz / (delta - (beta*rHz / alpha));
475  //
476  // Check that alpha is a positive number!
477  TEUCHOS_TEST_FOR_EXCEPTION( SCT::real(alpha) <= zero, CGIterateFailure,
478  "Belos::CGSingleRedIter::iterate(): non-positive value for p^H*A*p encountered!" );
479  //
480  // Update the direction vector P_ := Z_ + beta * P_
481  //
482  MVT::MvAddMv( one, *Z_, beta, *P_, *P_ );
483  //
484  // Update AP_ through recurrence relation AP_ := AZ_ + beta * AP_
485  // NOTE: This increases the number of vector updates by 1, in exchange for
486  // reducing the collectives from 2 to 1.
487  //
488  MVT::MvAddMv( one, *AZ_, beta, *AP_, *AP_ );
489  //
490  } // end while (sTest_->checkStatus(this) != Passed)
491  }
492 
493 } // end Belos namespace
494 
495 #endif /* BELOS_CG_SINGLE_RED_ITER_HPP */
Teuchos::RCP< const MV > R
The current residual.
int getNumIters() const
Get the current iteration count.
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...
Class which manages the output and verbosity of the Belos solvers.
Structure to contain pointers to CGIteration state variables.
Pure virtual base class which augments the basic interface for a conjugate gradient linear solver ite...
Pure virtual base class for defining the status testing capabilities of Belos.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *norms) const
Get the norms of the residuals native to the solver.
Declaration of basic traits for the multivector type.
void iterate()
This method performs CG iterations until the status test indicates the need to stop or an error occur...
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.
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
static void Assign(const MV &A, MV &mv)
mv := A
static void MvAddMv(const ScalarType alpha, const MV &A, const ScalarType beta, const MV &B, MV &mv)
Replace mv with .
MultiVecTraits< ScalarType, MV > MVT
Traits class which defines basic operations on multivectors.
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
static Teuchos::RCP< MV > CloneViewNonConst(MV &mv, const std::vector< int > &index)
Creates a new MV that shares the selected contents of mv (shallow copy).
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
void setBlockSize(int blockSize)
Set the blocksize to be used by the iterative solver in solving this linear problem.
A linear system to solve, and its associated information.
Class which describes the linear problem to be solved by the iterative solver.
bool isInitialized()
States whether the solver has been initialized or not.
CGIterationState< ScalarType, MV > getState() const
Get the current state of the linear solver.
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
virtual ~CGSingleRedIter()
Destructor.
SCT::magnitudeType MagnitudeType
void initializeCG(CGIterationState< ScalarType, MV > &newstate)
Initialize the solver to an iterate, providing a complete state.
Teuchos::RCP< const MV > Z
The current preconditioned residual.
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
static ptrdiff_t GetGlobalLength(const MV &mv)
Return the number of rows in the given multivector mv.
CGSingleRedIter(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)
CGSingleRedIter constructor with linear problem, solver utilities, and parameter list of solver optio...
Class which defines basic traits for the operator type.
This class implements the preconditioned single-reduction Conjugate Gradient (CG) iteration...
Teuchos::ScalarTraits< ScalarType > SCT
Belos header file which uses auto-configuration information to include necessary C++ headers...
void resetNumIters(int iter=0)
Reset the iteration count.
OperatorTraits< ScalarType, MV, OP > OPT
Teuchos::RCP< const MV > P
The current decent direction vector.

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