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"
27#include "BelosCGIteration.hpp"
28
29#include "Teuchos_LAPACK.hpp"
30#include "Teuchos_ScalarTraits.hpp"
31#include "Teuchos_ParameterList.hpp"
32#include "Teuchos_TimeMonitor.hpp"
33
45namespace Belos {
46
48
49
54 template <class ScalarType, class MV, class DM>
55 struct RCGIterState {
60 int curDim;
61
63 Teuchos::RCP<MV> P;
64
66 Teuchos::RCP<MV> Ap;
67
69 Teuchos::RCP<MV> r;
70
72 Teuchos::RCP<MV> z;
73
75 bool existU;
76
78 Teuchos::RCP<MV> U, AU;
79
82 Teuchos::RCP<std::vector<ScalarType> > Alpha;
83 Teuchos::RCP<std::vector<ScalarType> > Beta;
84 int Beta_i;
85 Teuchos::RCP<std::vector<ScalarType> > D;
86 Teuchos::RCP<std::vector<ScalarType> > rTz_old;
87
89 Teuchos::RCP<DM> Delta;
90
92 Teuchos::RCP<DM> LUUTAU;
94 Teuchos::RCP<std::vector<int> > ipiv;
95
96
97 RCGIterState() : curDim(0), P(Teuchos::null), Ap(Teuchos::null), r(Teuchos::null),
98 z(Teuchos::null),
100 U(Teuchos::null), AU(Teuchos::null),
101 Alpha(Teuchos::null), Beta(Teuchos::null), Beta_i(0),
102 D(Teuchos::null), rTz_old(Teuchos::null),
103 Delta(Teuchos::null), LUUTAU(Teuchos::null), ipiv(Teuchos::null)
104 {}
105 };
106
108
109 template<class ScalarType, class MV, class OP, class DM>
110 class RCGIter : virtual public Iteration<ScalarType,MV,OP,DM> {
111
112 public:
113
114 //
115 // Convenience typedefs
116 //
120 typedef Teuchos::ScalarTraits<ScalarType> SCT;
121 typedef typename SCT::magnitudeType MagnitudeType;
122
124
125
134 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
135 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > &tester,
136 Teuchos::ParameterList &params );
137
139 virtual ~RCGIter() {};
141
142
144
145
158 void iterate();
159
175
184
186
188
189
191 int getNumIters() const { return iter_; }
192
194 void resetNumIters( int iter = 0 ) { iter_ = iter; }
195
198 Teuchos::RCP<const MV> getNativeResiduals( std::vector<MagnitudeType> * /* norms */ ) const { return r_; }
199
201
206 Teuchos::RCP<MV> getCurrentUpdate() const { return Teuchos::null; }
207
209 int getCurSubspaceDim() const {
210 if (!initialized_) return 0;
211 return curDim_;
212 };
213
215 int getMaxSubspaceDim() const { return numBlocks_+1; }
216
218
219
221
222
224 const LinearProblem<ScalarType,MV,OP,DM>& getProblem() const { return *lp_; }
225
227 int getNumBlocks() const { return numBlocks_; }
228
230 void setNumBlocks(int numBlocks) { setSize( recycleBlocks_, numBlocks ); };
231
233 int getBlockSize() const { return 1; }
234
237 TEUCHOS_TEST_FOR_EXCEPTION(blockSize!=1,std::invalid_argument,
238 "Belos::RCGIter::setBlockSize(): Cannot use a block size that is not one.");
239 }
240
242 void setSize( int recycleBlocks, int numBlocks );
243
245 bool isInitialized() { return initialized_; }
246
248
249 private:
250
251 //
252 // Internal methods
253 //
254
255 //
256 // Classes input through constructor that define the linear problem to be solved.
257 //
258 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > lp_;
259 const Teuchos::RCP<OutputManager<ScalarType> > om_;
260 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > stest_;
261
262 //
263 // Algorithmic parameters
264 //
265 // numBlocks_ is the size of the allocated space for the Krylov basis, in blocks.
266 int numBlocks_;
267
268 // recycleBlocks_ is the size of the allocated space for the recycled subspace, in blocks.
269 int recycleBlocks_;
270
271 //
272 // Current solver state
273 //
274 // initialized_ specifies that the basis vectors have been initialized and the iterate() routine
275 // is capable of running; _initialize is controlled by the initialize() member method
276 // For the implications of the state of initialized_, please see documentation for initialize()
277 bool initialized_;
278
279 // Current subspace dimension, and number of iterations performed.
280 int curDim_, iter_;
281
282 //
283 // State Storage
284 //
285 // Search vectors
286 Teuchos::RCP<MV> P_;
287 //
288 // A times current search vector
289 Teuchos::RCP<MV> Ap_;
290 //
291 // Residual vector
292 Teuchos::RCP<MV> r_;
293 //
294 // Preconditioned residual
295 Teuchos::RCP<MV> z_;
296 //
297 // Flag to indicate that the recycle space should be used
298 bool existU_;
299 // Recycled subspace and its image
300 Teuchos::RCP<MV> U_, AU_;
301 //
302 // Coefficients arising in RCG iteration
303 Teuchos::RCP<std::vector<ScalarType> > Alpha_;
304 Teuchos::RCP<std::vector<ScalarType> > Beta_;
305 int Beta_i_;
306 Teuchos::RCP<std::vector<ScalarType> > D_;
307 //
308 // Solutions to local least-squares problems
309 Teuchos::RCP<DM> Delta_;
310 //
311 // The LU factorization of the matrix U^T A U
312 Teuchos::RCP<DM> LUUTAU_;
313 //
314 // Data from LU factorization of UTAU
315 Teuchos::RCP<std::vector<int> > ipiv_;
316 //
317 // The scalar r'*z
318 Teuchos::RCP<std::vector<ScalarType> > rTz_old_;
319 };
320
322 // Constructor.
323 template<class ScalarType, class MV, class OP, class DM>
325 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
326 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > &tester,
327 Teuchos::ParameterList &params ):
328 lp_(problem),
329 om_(printer),
330 stest_(tester),
331 numBlocks_(0),
332 recycleBlocks_(0),
333 initialized_(false),
334 curDim_(0),
335 iter_(0),
336 existU_(false)
337 {
338 // Get the maximum number of blocks allowed for this Krylov subspace
339 TEUCHOS_TEST_FOR_EXCEPTION(!params.isParameter("Num Blocks"), std::invalid_argument,
340 "Belos::RCGIter::constructor: mandatory parameter \"Num Blocks\" is not specified.");
341 int nb = Teuchos::getParameter<int>(params, "Num Blocks");
342
343 TEUCHOS_TEST_FOR_EXCEPTION(!params.isParameter("Recycled Blocks"), std::invalid_argument,
344 "Belos::RCGIter::constructor: mandatory parameter \"Recycled Blocks\" is not specified.");
345 int rb = Teuchos::getParameter<int>(params, "Recycled Blocks");
346
347 // Set the number of blocks and allocate data
348 setSize( rb, nb );
349 }
350
352 // Set the block size and make necessary adjustments.
353 template <class ScalarType, class MV, class OP, class DM>
355 {
356
357 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks <= 0, std::invalid_argument, "Belos::RCGIter::setSize() was passed a non-positive argument for \"Num Blocks\".");
358 TEUCHOS_TEST_FOR_EXCEPTION(recycleBlocks <= 0, std::invalid_argument, "Belos::RCGIter::setSize() was passed a non-positive argument for \"Recycled Blocks\".");
359 TEUCHOS_TEST_FOR_EXCEPTION(recycleBlocks >= numBlocks, std::invalid_argument, "Belos::RCGIter::setSize() the number of recycled blocks is larger than the allowable subspace.");
360
361 numBlocks_ = numBlocks;
362 recycleBlocks_ = recycleBlocks;
363
364 }
365
367 // Initialize this iteration object
368 template <class ScalarType, class MV, class OP, class DM>
370 {
371
372 if (newstate.P != Teuchos::null &&
373 newstate.Ap != Teuchos::null &&
374 newstate.r != Teuchos::null &&
375 newstate.z != Teuchos::null &&
376 newstate.U != Teuchos::null &&
377 newstate.AU != Teuchos::null &&
378 newstate.Alpha != Teuchos::null &&
379 newstate.Beta != Teuchos::null &&
380 newstate.D != Teuchos::null &&
381 newstate.Delta != Teuchos::null &&
382 newstate.LUUTAU != Teuchos::null &&
383 newstate.ipiv != Teuchos::null &&
384 newstate.rTz_old != Teuchos::null) {
385
386 curDim_ = newstate.curDim;
387 P_ = newstate.P;
388 Ap_ = newstate.Ap;
389 r_ = newstate.r;
390 z_ = newstate.z;
391 existU_ = newstate.existU;
392 U_ = newstate.U;
393 AU_ = newstate.AU;
394 Alpha_ = newstate.Alpha;
395 Beta_ = newstate.Beta;
396 Beta_i_ = newstate.Beta_i;
397 D_ = newstate.D;
398 Delta_ = newstate.Delta;
399 LUUTAU_ = newstate.LUUTAU;
400 ipiv_ = newstate.ipiv;
401 rTz_old_ = newstate.rTz_old;
402 }
403 else {
404
405 TEUCHOS_TEST_FOR_EXCEPTION(newstate.P == Teuchos::null,std::invalid_argument,
406 "Belos::RCGIter::initialize(): RCGIterState does not have P initialized.");
407
408 TEUCHOS_TEST_FOR_EXCEPTION(newstate.Ap == Teuchos::null,std::invalid_argument,
409 "Belos::RCGIter::initialize(): RCGIterState does not have Ap initialized.");
410
411 TEUCHOS_TEST_FOR_EXCEPTION(newstate.r == Teuchos::null,std::invalid_argument,
412 "Belos::RCGIter::initialize(): RCGIterState does not have r initialized.");
413
414 TEUCHOS_TEST_FOR_EXCEPTION(newstate.z == Teuchos::null,std::invalid_argument,
415 "Belos::RCGIter::initialize(): RCGIterState does not have z initialized.");
416
417 TEUCHOS_TEST_FOR_EXCEPTION(newstate.U == Teuchos::null,std::invalid_argument,
418 "Belos::RCGIter::initialize(): RCGIterState does not have U initialized.");
419
420 TEUCHOS_TEST_FOR_EXCEPTION(newstate.AU == Teuchos::null,std::invalid_argument,
421 "Belos::RCGIter::initialize(): RCGIterState does not have AU initialized.");
422
423 TEUCHOS_TEST_FOR_EXCEPTION(newstate.Alpha == Teuchos::null,std::invalid_argument,
424 "Belos::RCGIter::initialize(): RCGIterState does not have Alpha initialized.");
425
426 TEUCHOS_TEST_FOR_EXCEPTION(newstate.Beta == Teuchos::null,std::invalid_argument,
427 "Belos::RCGIter::initialize(): RCGIterState does not have Beta initialized.");
428
429 TEUCHOS_TEST_FOR_EXCEPTION(newstate.D == Teuchos::null,std::invalid_argument,
430 "Belos::RCGIter::initialize(): RCGIterState does not have D initialized.");
431
432 TEUCHOS_TEST_FOR_EXCEPTION(newstate.Delta == Teuchos::null,std::invalid_argument,
433 "Belos::RCGIter::initialize(): RCGIterState does not have Delta initialized.");
434
435 TEUCHOS_TEST_FOR_EXCEPTION(newstate.LUUTAU == Teuchos::null,std::invalid_argument,
436 "Belos::RCGIter::initialize(): RCGIterState does not have LUUTAU initialized.");
437
438 TEUCHOS_TEST_FOR_EXCEPTION(newstate.ipiv == Teuchos::null,std::invalid_argument,
439 "Belos::RCGIter::initialize(): RCGIterState does not have ipiv initialized.");
440
441 TEUCHOS_TEST_FOR_EXCEPTION(newstate.rTz_old == Teuchos::null,std::invalid_argument,
442 "Belos::RCGIter::initialize(): RCGIterState does not have rTz_old initialized.");
443
444 }
445
446 // the solver is initialized
447 initialized_ = true;
448
449 }
450
452 // Iterate until the status test informs us we should stop.
453 template <class ScalarType, class MV, class OP, class DM>
455 {
456 TEUCHOS_TEST_FOR_EXCEPTION( initialized_ == false, CGIterateFailure,
457 "Belos::RCGIter::iterate(): RCGIter class not initialized." );
458
459 // We'll need LAPACK
460 Teuchos::LAPACK<int,ScalarType> lapack;
461
462 // Create convenience variables for zero and one.
463 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
464 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
465
466 // Allocate memory for scalars
467 std::vector<int> index(1);
468 std::vector<ScalarType> pAp(1);
469 std::vector<ScalarType> rTz(1);
470
471 // Get the current solution std::vector.
472 Teuchos::RCP<MV> cur_soln_vec = lp_->getCurrLHSVec();
473
474 // Check that the current solution std::vector only has one column.
475 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*cur_soln_vec) != 1, CGIterateFailure,
476 "Belos::RCGIter::iterate(): current linear system has more than one std::vector!" );
477
478 // Compute the current search dimension.
479 int searchDim = numBlocks_+1;
480
481 // index of iteration within current cycle
482 int i_ = 0;
483
485 // iterate until the status test tells us to stop.
486 //
487 // also break if our basis is full
488 //
489 Teuchos::RCP<const MV> p_ = Teuchos::null;
490 Teuchos::RCP<MV> pnext_ = Teuchos::null;
491 while (stest_->checkStatus(this) != Passed && curDim_+1 <= searchDim) {
492
493 // Ap = A*p;
494 index.resize( 1 );
495 index[0] = i_;
496 p_ = MVT::CloneView( *P_, index );
497 lp_->applyOp( *p_, *Ap_ );
498
499 // d = p'*Ap;
500 MVT::MvDot( *p_, *Ap_, pAp );
501 (*D_)[i_] = pAp[0];
502
503 // alpha = rTz_old / pAp
504 (*Alpha_)[i_] = (*rTz_old_)[0] / pAp[0];
505
506 // Check that alpha is a positive number
508 "Belos::RCGIter::iterate(): non-positive value for p^H*A*p encountered!" );
509
510 // x = x + (alpha * p);
511 MVT::MvAddMv( one, *cur_soln_vec, (*Alpha_)[i_], *p_, *cur_soln_vec );
512 lp_->updateSolution();
513
514 // r = r - (alpha * Ap);
515 MVT::MvAddMv( one, *r_, -(*Alpha_)[i_], *Ap_, *r_ );
516
517 std::vector<MagnitudeType> norm(1);
518 MVT::MvNorm( *r_, norm );
519//printf("i = %i\tnorm(r) = %e\n",i_,norm[0]);
520
521 // z = M\r
522 if ( lp_->getLeftPrec() != Teuchos::null ) {
523 lp_->applyLeftPrec( *r_, *z_ );
524 }
525 else if ( lp_->getRightPrec() != Teuchos::null ) {
526 lp_->applyRightPrec( *r_, *z_ );
527 }
528 else {
529 z_ = r_;
530 }
531
532 // rTz_new = r'*z;
533 MVT::MvDot( *r_, *z_, rTz );
534
535 // beta = rTz_new/rTz_old;
536 (*Beta_)[Beta_i_] = rTz[0] / (*rTz_old_)[0];
537
538 // rTz_old = rTz_new;
539 (*rTz_old_) = rTz;
540
541 // get pointer for next p
542 index.resize( 1 );
543 index[0] = i_+1;
544 pnext_ = MVT::CloneViewNonConst( *P_, index );
545
546 if (existU_) {
547 // mu = UTAU \ (AU'*z);
548 Teuchos::RCP<DM> mu = DMT::Subview( *Delta_, recycleBlocks_, 1, 0, i_+1 );
549 MVT::MvTransMv( one, *AU_, *z_, *mu );
550
551 DMT::SyncDeviceToHost( *mu );
552 DMT::SyncDeviceToHost( *LUUTAU_ );
553 char TRANS = 'N';
554 int info;
555 lapack.GETRS( TRANS, recycleBlocks_, 1, DMT::GetConstRawHostPtr(*LUUTAU_), DMT::GetStride(*LUUTAU_),
556 &(*ipiv_)[0], DMT::GetRawHostPtr(*mu), DMT::GetStride(*mu), &info );
558 "Belos::RCGIter::solve(): LAPACK GETRS failed to compute a solution.");
559 DMT::SyncHostToDevice( *mu );
560 // p = -(U*mu) + (beta*p) + z (in two steps)
561 // p = (beta*p) + z;
562 MVT::MvAddMv( (*Beta_)[Beta_i_], *p_, one, *z_, *pnext_ );
563 // pnext = -(U*mu) + (one)*pnext;
564 MVT::MvTimesMatAddMv( -one, *U_, *mu, one, *pnext_ );
565 }
566 else {
567 // p = (beta*p) + z;
568 MVT::MvAddMv( (*Beta_)[Beta_i_], *p_, one, *z_, *pnext_ );
569 }
570
571 // Done with this view; release pointer
572 p_ = Teuchos::null;
573 pnext_ = Teuchos::null;
574
575 // increment iteration count and dimension index
576 i_++;
577 Beta_i_++;
578 iter_++;
579 curDim_++;
580
581 } // end while (statusTest == false)
582
583 }
584
585} // end Belos namespace
586
587#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.
RCGIter(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &problem, const Teuchos::RCP< OutputManager< ScalarType > > &printer, const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &tester, Teuchos::ParameterList &params)
RCGIter constructor with linear problem, solver utilities, and parameter list of solver options.
void setSize(int recycleBlocks, int numBlocks)
Set the maximum number of blocks used by the iterative solver and the number of recycled vectors.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
int getNumBlocks() const
Get the maximum number of blocks used by the iterative solver in solving this linear problem.
virtual ~RCGIter()
Destructor.
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current solution to the linear problem.
OperatorTraits< ScalarType, MV, OP > OPT
Teuchos::ScalarTraits< ScalarType > SCT
bool isInitialized()
States whether the solver has been initialized or not.
void setBlockSize(int blockSize)
Set the blocksize.
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *) const
Get the norms of the residuals native to the solver.
int getNumIters() const
Get the current iteration count.
MultiVecTraits< ScalarType, MV, DM > MVT
void resetNumIters(int iter=0)
Reset the iteration count.
void iterate()
This method performs RCG iterations until the status test indicates the need to stop or an error occu...
void setNumBlocks(int numBlocks)
Set the maximum number of blocks used by the iterative solver.
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const
Get a constant reference to the linear problem.
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace.
SCT::magnitudeType MagnitudeType
DenseMatTraits< ScalarType, DM > DMT
Structure to contain pointers to RCGIter state variables.
int curDim
The current dimension of the reduction.
Teuchos::RCP< MV > AU
Teuchos::RCP< MV > r
The current residual.
bool existU
Flag to indicate the recycle space should be used.
Teuchos::RCP< MV > P
The current Krylov basis.
Teuchos::RCP< MV > U
The recycled subspace and its image.
Teuchos::RCP< std::vector< ScalarType > > D
Teuchos::RCP< std::vector< ScalarType > > Beta
Teuchos::RCP< std::vector< ScalarType > > rTz_old
Teuchos::RCP< std::vector< ScalarType > > Alpha
Coefficients arising in RCG iteration.
Teuchos::RCP< DM > Delta
Solutions to local least-squares problems.
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< DM > LUUTAU
The LU factorization of the matrix U^T A U
Teuchos::RCP< MV > Ap
A times current search vector.

Generated for Belos by doxygen 1.9.8