Belos Version of the Day
Loading...
Searching...
No Matches
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
23#include "BelosStatusTest.hpp"
26#include "BelosCGIteration.hpp"
27
28#include "Teuchos_LAPACK.hpp"
29#include "Teuchos_SerialDenseMatrix.hpp"
30#include "Teuchos_SerialDenseVector.hpp"
31#include "Teuchos_ScalarTraits.hpp"
32#include "Teuchos_ParameterList.hpp"
33#include "Teuchos_TimeMonitor.hpp"
34
35// MLP Remove after debugging
36#include <fstream>
37#include <iomanip>
38
50namespace Belos {
51
53
54
59 template <class ScalarType, class MV>
60 struct RCGIterState {
65 int curDim;
66
68 Teuchos::RCP<MV> P;
69
71 Teuchos::RCP<MV> Ap;
72
74 Teuchos::RCP<MV> r;
75
77 Teuchos::RCP<MV> z;
78
80 bool existU;
81
83 Teuchos::RCP<MV> U, AU;
84
87 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > Alpha;
88 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > Beta;
89 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > D;
90 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > rTz_old;
91
93 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > Delta;
94
96 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > LUUTAU;
98 Teuchos::RCP<std::vector<int> > ipiv;
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 //
122 typedef Teuchos::ScalarTraits<ScalarType> SCT;
123 typedef typename SCT::magnitudeType MagnitudeType;
124
126
127
135 RCGIter( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
136 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
137 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
138 Teuchos::ParameterList &params );
139
141 virtual ~RCGIter() {};
143
144
146
147
160 void iterate();
161
177
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
208 Teuchos::RCP<MV> getCurrentUpdate() const { return Teuchos::null; }
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
239
241 int getBlockSize() const { return 1; }
242
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 //
266 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > lp_;
267 const Teuchos::RCP<OutputManager<ScalarType> > om_;
268 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > stest_;
269
270 //
271 // Algorithmic parameters
272 //
273 // numBlocks_ is the size of the allocated space for the Krylov basis, in blocks.
274 int numBlocks_;
275
276 // recycleBlocks_ is the size of the allocated space for the recycled subspace, in blocks.
277 int recycleBlocks_;
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()
285 bool initialized_;
286
287 // Current subspace dimension, and number of iterations performed.
288 int curDim_, iter_;
289
290 //
291 // State Storage
292 //
293 // Search vectors
294 Teuchos::RCP<MV> P_;
295 //
296 // A times current search vector
297 Teuchos::RCP<MV> Ap_;
298 //
299 // Residual vector
300 Teuchos::RCP<MV> r_;
301 //
302 // Preconditioned residual
303 Teuchos::RCP<MV> z_;
304 //
305 // Flag to indicate that the recycle space should be used
306 bool existU_;
307 // Recycled subspace and its image
308 Teuchos::RCP<MV> U_, AU_;
309 //
310 // Coefficients arising in RCG iteration
311 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > Alpha_,Beta_,D_;
312 //
313 // Solutions to local least-squares problems
314 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > Delta_;
315 //
316 // The LU factorization of the matrix U^T A U
317 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > LUUTAU_;
318 //
319 // Data from LU factorization of UTAU
320 Teuchos::RCP<std::vector<int> > ipiv_;
321 //
322 // The scalar r'*z
323 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > rTz_old_;
324 };
325
327 // Constructor.
328 template<class ScalarType, class MV, class OP>
330 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
331 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
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>
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
464 Teuchos::LAPACK<int,ScalarType> 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);
472 Teuchos::SerialDenseMatrix<int,ScalarType> pAp(1,1), rTz(1,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 //
492 Teuchos::RCP<const MV> p_ = Teuchos::null;
493 Teuchos::RCP<MV> pnext_ = Teuchos::null;
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
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 */
Pure virtual base class which augments the basic interface for a conjugate gradient linear solver ite...
Belos header file which uses auto-configuration information to include necessary C++ headers.
Class which describes the linear problem to be solved by the iterative solver.
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Declaration of basic traits for the multivector type.
Class which defines basic traits for the operator type.
Class which manages the output and verbosity of the Belos solvers.
Pure virtual base class for defining the status testing capabilities of Belos.
Collection of types and exceptions used within the Belos solvers.
CGIterateFailure is thrown when the CGIteration object is unable to compute the next iterate in the C...
CGIterationLAPACKFailure is thrown when a nonzero return value is passed back from an LAPACK routine.
CGPositiveDefiniteFailure is thrown when the the CG 'alpha = p^H*A*P' value is less than zero,...
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).
This class implements the RCG iteration, where a single-std::vector Krylov subspace is constructed.
Teuchos::ScalarTraits< ScalarType > SCT
OperatorTraits< ScalarType, MV, OP > OPT
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
MultiVecTraits< ScalarType, MV > MVT
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace.
virtual ~RCGIter()
Destructor.
void resetNumIters(int iter=0)
Reset the iteration count.
void setSize(int recycleBlocks, int numBlocks)
Set the maximum number of blocks used by the iterative solver and the number of recycled vectors.
bool isInitialized()
States whether the solver has been initialized or not.
int getNumBlocks() const
Get the maximum number of blocks used by the iterative solver in solving this linear problem.
int getNumIters() const
Get the current iteration count.
void setBlockSize(int blockSize)
Set the blocksize.
void setRecycledBlocks(int recycleBlocks)
Set the maximum number of recycled blocks used by the iterative solver.
void setNumBlocks(int numBlocks)
Set the maximum number of blocks used by the iterative solver.
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current solution to the linear problem.
SCT::magnitudeType MagnitudeType
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
int getRecycledBlocks() const
Get the maximum number of recycled blocks used by the iterative solver in solving this linear problem...
void iterate()
This method performs RCG iterations until the status test indicates the need to stop or an error occu...
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.
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *) const
Get the norms of the residuals native to the solver.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
Structure to contain pointers to RCGIter state variables.
bool existU
Flag to indicate the recycle space should be used.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Beta
Teuchos::RCP< MV > U
The recycled subspace and its image.
Teuchos::RCP< MV > Ap
A times current search vector.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Delta
Solutions to local least-squares problems.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > D
int curDim
The current dimension of the reduction.
Teuchos::RCP< MV > r
The current residual.
Teuchos::RCP< std::vector< int > > ipiv
Data from LU factorization of U^T A U.
Teuchos::RCP< MV > z
The current preconditioned residual.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > LUUTAU
The LU factorization of the matrix U^T A U
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > rTz_old
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > Alpha
Coefficients arising in RCG iteration.
Teuchos::RCP< MV > P
The current Krylov basis.
Teuchos::RCP< MV > AU

Generated for Belos by doxygen 1.9.8