Belos Version of the Day
Loading...
Searching...
No Matches
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
24#include "BelosStatusTest.hpp"
28
29#include "Teuchos_ScalarTraits.hpp"
30#include "Teuchos_ParameterList.hpp"
31#include "Teuchos_TimeMonitor.hpp"
32
33namespace Belos {
34
36
37
42 template <class ScalarType, class MV, class DM>
43 class BlockCGIterationState : public CGIterationStateBase<ScalarType, MV, DM> {
44
45 public:
47
48 BlockCGIterationState(Teuchos::RCP<const MV> tmp) {
50 }
51
52 virtual ~BlockCGIterationState() = default;
53
54 void initialize(Teuchos::RCP<const MV> tmp, int _numVectors) {
56 this->R = MVT::Clone( *tmp, _numVectors );
57 this->Z = MVT::Clone( *tmp, _numVectors );
58 this->P = MVT::Clone( *tmp, _numVectors );
59 this->AP = MVT::Clone(*tmp, _numVectors );
60
62 }
63
64 bool matches(Teuchos::RCP<const MV> tmp, int _numVectors=1) const {
66 }
67
68};
69
75
78template<class ScalarType, class MV, class OP, class DM,
79 const bool lapackSupportsScalarType =
81class BlockCGIter : virtual public CGIteration<ScalarType, MV, OP, DM> {
82public:
85 typedef Teuchos::ScalarTraits<ScalarType> SCT;
86 typedef typename SCT::magnitudeType MagnitudeType;
87
88 BlockCGIter( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > & /* problem */,
89 const Teuchos::RCP<OutputManager<ScalarType> > & /* printer */,
90 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > & /* tester */,
91 const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > & /* ortho */,
92 Teuchos::ParameterList & /* params */ )
93 {
94 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
95 }
96
97 virtual ~BlockCGIter() {}
98
99 void iterate () {
100 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
101 }
102
103 void initializeCG (Teuchos::RCP<BlockCGIterationState<ScalarType,MV, DM> > /* newstate */, Teuchos::RCP<MV> /* R_0 */) {
104 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
105 }
106
107 void initialize () {
108 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
109 }
110
111 Teuchos::RCP<CGIterationStateBase<ScalarType,MV, DM> > getState () const {
112 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
113 }
114
116 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
117 }
118
119 int getNumIters() const {
120 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
121 }
122
123 void resetNumIters( int iter=0 ) {
124 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
125 }
126
127 Teuchos::RCP<const MV>
128 getNativeResiduals (std::vector<MagnitudeType>* /* norms */) const {
129 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
130 }
131
132 Teuchos::RCP<MV> getCurrentUpdate() 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
140 int getBlockSize() const {
141 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
142 }
143
145 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
146 }
147
149 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
150 }
151
152 void setDoCondEst(bool val){
153 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Stub");
154 }
155
156};
157
162template<class ScalarType, class MV, class OP, class DM>
163class BlockCGIter<ScalarType, MV, OP, DM, true> :
164 virtual public CGIteration<ScalarType,MV,OP,DM>
165{
166public:
167 //
168 // Convenience typedefs
169 //
172 using SCT = Teuchos::ScalarTraits<ScalarType>;
173 using MagnitudeType = typename SCT::magnitudeType;
174
176
177
184 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
185 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > &tester,
186 const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > &ortho,
187 Teuchos::ParameterList &params );
188
190 virtual ~BlockCGIter() = default;
192
193
195
196
209 void iterate();
210
225 void initializeCG(Teuchos::RCP<CGIterationStateBase<ScalarType,MV, DM> > newstate, Teuchos::RCP<MV> R_0);
226
231 {
232 initializeCG(Teuchos::null, Teuchos::null);
233 }
234
241 Teuchos::RCP<CGIterationStateBase<ScalarType,MV, DM> > getState() const {
242 auto state = Teuchos::rcp(new BlockCGIterationState<ScalarType,MV, DM>());
243 state->R = R_;
244 state->P = P_;
245 state->AP = AP_;
246 state->Z = Z_;
247 return state;
248 }
249
251 auto s = Teuchos::rcp_dynamic_cast<BlockCGIterationState<ScalarType,MV, DM> >(state, true);
252 R_ = s->R;
253 Z_ = s->Z;
254 P_ = s->P;
255 AP_ = s->AP;
256 }
257
259
260
262
263
265 int getNumIters() const { return iter_; }
266
268 void resetNumIters( int iter=0 ) { iter_ = iter; }
269
272 Teuchos::RCP<const MV> getNativeResiduals( std::vector<MagnitudeType> * /* norms */ ) const { return R_; }
273
275
277 Teuchos::RCP<MV> getCurrentUpdate() const { return Teuchos::null; }
278
280
282
283
285 const LinearProblem<ScalarType,MV,OP,DM>& getProblem() const { return *lp_; }
286
288 int getBlockSize() const { return blockSize_; }
289
291 void setBlockSize(int blockSize);
292
294 bool isInitialized() { return initialized_; }
295
297 void setDoCondEst(bool /* val */){/*ignored*/}
298
300 Teuchos::ArrayView<MagnitudeType> getDiag() {
301 Teuchos::ArrayView<MagnitudeType> temp;
302 return temp;
303 }
304
306 Teuchos::ArrayView<MagnitudeType> getOffDiag() {
307 Teuchos::ArrayView<MagnitudeType> temp;
308 return temp;
309 }
311
312 private:
313
314 //
315 // Internal methods
316
317 //
318 // Classes inputed through constructor that define the linear problem to be solved.
319 //
320 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > lp_;
321 const Teuchos::RCP<OutputManager<ScalarType> > om_;
322 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > stest_;
323 const Teuchos::RCP<OrthoManager<ScalarType,MV,DM> > ortho_;
324
325 //
326 // Algorithmic parameters
327 //
328 // blockSize_ is the solver block size.
329 int blockSize_;
330
331 //
332 // Current solver state
333 //
334 // initialized_ specifies that the basis vectors have been initialized and the iterate() routine
335 // is capable of running; _initialize is controlled by the initialize() member method
336 // For the implications of the state of initialized_, please see documentation for initialize()
337 bool initialized_;
338
339 // Current subspace dimension, and number of iterations performed.
340 int iter_;
341
342 //
343 // State Storage
344 //
345 // Residual
346 Teuchos::RCP<MV> R_;
347 //
348 // Preconditioned residual
349 Teuchos::RCP<MV> Z_;
350 //
351 // Direction std::vector
352 Teuchos::RCP<MV> P_;
353 //
354 // Operator applied to direction std::vector
355 Teuchos::RCP<MV> AP_;
356
357};
358
359 template<class ScalarType, class MV, class OP, class DM>
362 const Teuchos::RCP<OutputManager<ScalarType> >& printer,
363 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> >& tester,
364 const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> >& ortho,
365 Teuchos::ParameterList& params) :
366 lp_(problem),
367 om_(printer),
368 stest_(tester),
369 ortho_(ortho),
370 blockSize_(0),
371 initialized_(false),
372 iter_(0)
373 {
374 // Set the block size and allocate data
375 int bs = params.get("Block Size", 1);
376 setBlockSize( bs );
377 }
378
379 template<class ScalarType, class MV, class OP, class DM>
381 {
382 // This routine only allocates space; it doesn't not perform any computation
383 // any change in size will invalidate the state of the solver.
385 (blockSize <= 0, std::invalid_argument, "Belos::BlockGmresIter::"
386 "setBlockSize: blockSize = " << blockSize << " <= 0.");
387 if (blockSize == blockSize_) {
388 return; // do nothing
389 }
390 blockSize_ = blockSize;
391 initialized_ = false;
392 }
393
394 template <class ScalarType, class MV, class OP, class DM>
396 initializeCG (Teuchos::RCP<CGIterationStateBase<ScalarType,MV, DM> > newstate, Teuchos::RCP<MV> R_0)
397 {
398 const char prefix[] = "Belos::BlockCGIter::initialize: ";
399
400 // Initialize the state storage if it isn't already.
401 Teuchos::RCP<const MV> lhsMV = lp_->getLHS();
402 Teuchos::RCP<const MV> rhsMV = lp_->getRHS();
403 Teuchos::RCP<const MV> tmp = ( (rhsMV!=Teuchos::null)? rhsMV: lhsMV );
404 TEUCHOS_ASSERT(!newstate.is_null());
405 if (!Teuchos::rcp_dynamic_cast<BlockCGIterationState<ScalarType,MV, DM> >(newstate, true)->matches(tmp, blockSize_))
406 newstate->initialize(tmp, blockSize_);
407 setState(newstate);
408
409 // NOTE: In BlockCGIter R_, the initial residual, is required!!!
410 const char errstr[] = "Specified multivectors must have a consistent "
411 "length and width.";
412
413 {
414
416 (MVT::GetGlobalLength(*R_0) != MVT::GetGlobalLength(*R_),
417 std::invalid_argument, prefix << errstr );
419 (MVT::GetNumberVecs(*R_0) != blockSize_,
420 std::invalid_argument, prefix << errstr );
421
422 // Copy basis vectors from newstate into V
423 if (R_0 != R_) {
424 // copy over the initial residual (unpreconditioned).
425 MVT::Assign( *R_0, *R_ );
426 }
427 // Compute initial direction vectors
428 // Initially, they are set to the preconditioned residuals
429 //
430 if ( lp_->getLeftPrec() != Teuchos::null ) {
431 lp_->applyLeftPrec( *R_, *Z_ );
432 if ( lp_->getRightPrec() != Teuchos::null ) {
433 Teuchos::RCP<MV> tmp2 = MVT::Clone( *Z_, blockSize_ );
434 lp_->applyRightPrec( *Z_, *tmp2 );
435 Z_ = tmp2;
436 }
437 }
438 else if ( lp_->getRightPrec() != Teuchos::null ) {
439 lp_->applyRightPrec( *R_, *Z_ );
440 }
441 else {
442 Z_ = R_;
443 }
444 MVT::Assign( *Z_, *P_ );
445 }
446
447 // The solver is initialized
448 initialized_ = true;
449 }
450
451 template<class ScalarType, class MV, class OP, class DM>
453 {
454 const char prefix[] = "Belos::BlockCGIter::iterate: ";
456
457 //
458 // Allocate/initialize data structures
459 //
460 if (initialized_ == false) {
461 initialize();
462 }
463
464 // Allocate memory for scalars.
465 Teuchos::RCP<DM> alpha = DMT::Create( blockSize_, blockSize_ );
466 Teuchos::RCP<DM> beta = DMT::Create( blockSize_, blockSize_ );
467 Teuchos::RCP<DM> pAp = DMT::Create( blockSize_, blockSize_ );
468
469 // Create dense spd solver.
470 Teuchos::RCP<DenseSolver<ScalarType,DM>> lltSolver = DMT::createDenseSolver();
471 lltSolver->setSPD( true );
472
473 // Create convenience variable for one.
474 const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
475
476 // Get the current solution std::vector.
477 Teuchos::RCP<MV> cur_soln_vec = lp_->getCurrLHSVec();
478
479 // Check that the current solution std::vector has blockSize_ columns.
481 (MVT::GetNumberVecs(*cur_soln_vec) != blockSize_, CGIterateFailure,
482 prefix << "Current linear system does not have the right number of vectors!" );
483 int rank = ortho_->normalize( *P_, Teuchos::null );
485 (rank != blockSize_, CGIterationOrthoFailure,
486 prefix << "Failed to compute initial block of orthonormal direction vectors.");
487
488 //
489 // Iterate until the status test tells us to stop.
490 //
491 while (stest_->checkStatus(this) != Passed) {
492 // Increment the iteration
493 iter_++;
494
495 // Multiply the current direction std::vector by A and store in Ap_
496 lp_->applyOp( *P_, *AP_ );
497
498 // Compute alpha := <P_,R_> / <P_,AP_>
499 // 1) Compute P^T * A * P = pAp and P^T * R
500 // 2) Compute the Cholesky Factorization of pAp
501 // 3) Back and forward solves to compute alpha
502 //
503 MVT::MvTransMv( one, *P_, *R_, *alpha );
504 MVT::MvTransMv( one, *P_, *AP_, *pAp );
505
506 // Compute Cholesky factorization of pAp
507 lltSolver->setMatrix( pAp );
508 lltSolver->factorWithEquilibration( true );
509 int info = lltSolver->factor();
512 prefix << "Failed to compute Cholesky factorization using LAPACK routine POTRF.");
513
514 // Compute alpha by performing a back and forward solve with the
515 // Cholesky factorization in pAp.
516 lltSolver->setVectors (alpha, alpha);
517 info = lltSolver->solve();
520 prefix << "Failed to compute alpha using Cholesky factorization (POTRS).");
521
522 // Update the solution std::vector X := X + alpha * P_
523 MVT::MvTimesMatAddMv( one, *P_, *alpha, one, *cur_soln_vec );
524 lp_->updateSolution();
525
526 // Compute the new residual R_ := R_ - alpha * AP_
527 MVT::MvTimesMatAddMv( -one, *AP_, *alpha, one, *R_ );
528
529 // Compute the new preconditioned residual, Z_.
530 if ( lp_->getLeftPrec() != Teuchos::null ) {
531 lp_->applyLeftPrec( *R_, *Z_ );
532 if ( lp_->getRightPrec() != Teuchos::null ) {
533 Teuchos::RCP<MV> tmp = MVT::Clone( *Z_, blockSize_ );
534 lp_->applyRightPrec( *Z_, *tmp );
535 Z_ = tmp;
536 }
537 }
538 else if ( lp_->getRightPrec() != Teuchos::null ) {
539 lp_->applyRightPrec( *R_, *Z_ );
540 }
541 else {
542 Z_ = R_;
543 }
544
545 // Compute beta := <AP_,Z_> / <P_,AP_>
546 // 1) Compute AP_^T * Z_
547 // 2) Compute the Cholesky Factorization of pAp (already have)
548 // 3) Back and forward solves to compute beta
549
550 // Compute <AP_,Z>
551 MVT::MvTransMv( -one, *AP_, *Z_, *beta );
552
553 lltSolver->setVectors( beta, beta );
554 info = lltSolver->solve();
557 prefix << "Failed to compute beta using Cholesky factorization (POTRS).");
558
559 // Compute the new direction vectors P_ = Z_ + P_ * beta
560 Teuchos::RCP<MV> Pnew = MVT::CloneCopy( *Z_ );
561 MVT::MvTimesMatAddMv(one, *P_, *beta, one, *Pnew);
562 P_ = Pnew;
563
564 // Compute orthonormal block of new direction vectors.
565 rank = ortho_->normalize( *P_, Teuchos::null );
567 (rank != blockSize_, CGIterationOrthoFailure,
568 prefix << "Failed to compute block of orthonormal direction vectors.");
569
570 } // end while (sTest_->checkStatus(this) != Passed)
571 }
572
573} // namespace Belos
574
575#endif /* BELOS_BLOCK_CG_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.
int getNumIters() const
Get the current iteration count.
void setState(Teuchos::RCP< CGIterationStateBase< ScalarType, MV, DM > > state)
void resetNumIters(int iter=0)
Reset the iteration count.
Teuchos::ArrayView< MagnitudeType > getDiag()
Gets the diagonal for condition estimation (NOT_IMPLEMENTED)
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
int getBlockSize() const
Get the block size to be used by the iterative solver in solving this linear problem.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *) const
Get the norms of the residuals native to the solver.
Teuchos::ArrayView< MagnitudeType > getOffDiag()
Gets the off-diagonal for condition estimation (NOT_IMPLEMENTED)
Teuchos::RCP< CGIterationStateBase< ScalarType, MV, DM > > getState() const
Get the current state of the linear solver.
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
bool isInitialized()
States whether the solver has been initialized or not.
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const
Get a constant reference to the linear problem.
void setDoCondEst(bool)
Sets whether or not to store the diagonal for condition estimation.
Stub implementation of BlockCGIter, for ScalarType types for which Teuchos::LAPACK does NOT have a va...
void setBlockSize(int blockSize)
Set 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.
void resetNumIters(int iter=0)
Reset the iteration count to iter.
BlockCGIter(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &, const Teuchos::RCP< OutputManager< ScalarType > > &, const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &, const Teuchos::RCP< MatOrthoManager< ScalarType, MV, OP, DM > > &, Teuchos::ParameterList &)
Teuchos::RCP< CGIterationStateBase< ScalarType, MV, DM > > getState() const
Get the current state of the linear solver.
void iterate()
This method performs linear solver iterations until the status test indicates the need to stop or an ...
void setDoCondEst(bool val)
Sets whether or not to store the diagonal for condition estimation.
Teuchos::ScalarTraits< ScalarType > SCT
SCT::magnitudeType MagnitudeType
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const
Get a constant reference to the linear problem.
void setState(Teuchos::RCP< CGIterationStateBase< ScalarType, MV, DM > > state)
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
MultiVecTraits< ScalarType, MV, DM > MVT
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *) const
void initializeCG(Teuchos::RCP< BlockCGIterationState< ScalarType, MV, DM > >, Teuchos::RCP< MV >)
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
int getNumIters() const
Get the current iteration count.
bool isInitialized()
States whether the solver has been initialized or not.
OperatorTraits< ScalarType, MV, OP > OPT
Structure to contain pointers to BlockCGIteration state variables.
bool matches(Teuchos::RCP< const MV > tmp, int _numVectors=1) const
BlockCGIterationState(Teuchos::RCP< const MV > tmp)
void initialize(Teuchos::RCP< const MV > tmp, int _numVectors)
virtual ~BlockCGIterationState()=default
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.
CGIterationOrthoFailure is thrown when the CGIteration object is unable to compute independent direct...
Structure to contain pointers to CGIteration state variables.
Teuchos::RCP< MV > AP
The matrix A applied to current decent direction vector.
virtual bool matches(Teuchos::RCP< const MV > tmp, int _numVectors=1) const
Teuchos::RCP< MV > P
The current decent direction vector.
Teuchos::RCP< MV > R
The current residual.
virtual void initialize(Teuchos::RCP< const MV > tmp, int _numVectors)
Teuchos::RCP< MV > Z
The current preconditioned residual.
Type traits class that says whether Teuchos::LAPACK has a valid implementation for the given ScalarTy...
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).

Generated for Belos by doxygen 1.9.8