10#ifndef BELOS_PCPG_ITER_HPP
11#define BELOS_PCPG_ITER_HPP
28#include "Teuchos_ScalarTraits.hpp"
29#include "Teuchos_ParameterList.hpp"
30#include "Teuchos_TimeMonitor.hpp"
54 template <
class ScalarType,
class MV,
class DM>
87 std::vector<ScalarType>
D;
100 template<
class ScalarType,
class MV,
class OP,
class DM>
111 typedef Teuchos::ScalarTraits<ScalarType>
SCT;
127 Teuchos::ParameterList &
params );
202 state.curDim = curDim_;
203 state.prevUdim = prevUdim_;
231 if (!initialized_)
return 0;
237 if (!initialized_)
return 0;
261 "Belos::PCPGIter::setBlockSize(): Cannot use a block size that is not one.");
286 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > lp_;
287 const Teuchos::RCP<OutputManager<ScalarType> > om_;
288 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > stest_;
306 bool stateStorageInitialized_;
336 Teuchos::RCP<MV> AP_;
346 std::vector<ScalarType> D_;
351 template<
class ScalarType,
class MV,
class OP,
class DM>
355 Teuchos::ParameterList &
params ):
361 stateStorageInitialized_(
false),
362 keepDiagonal_(
false),
363 initDiagonal_(
false),
371 "Belos::PCPGIter::constructor: mandatory parameter \"Saved Blocks\" is not specified.");
372 int rb = Teuchos::getParameter<int>(
params,
"Saved Blocks");
375 keepDiagonal_ =
params.get(
"Keep Diagonal",
false);
378 initDiagonal_ =
params.get(
"Initialize Diagonal",
false);
386 template<
class ScalarType,
class MV,
class OP,
class DM>
395 stateStorageInitialized_ =
false;
397 initialized_ =
false;
406 template<
class ScalarType,
class MV,
class OP,
class DM>
409 stateStorageInitialized_ =
false;
410 initialized_ =
false;
418 template<
class ScalarType,
class MV,
class OP,
class DM>
421 if (!stateStorageInitialized_) {
424 Teuchos::RCP<const MV>
lhsMV = lp_->getLHS();
425 Teuchos::RCP<const MV>
rhsMV = lp_->getRHS();
426 if (
lhsMV == Teuchos::null &&
rhsMV == Teuchos::null) {
433 int newsd = savedBlocks_ ;
438 if (Z_ == Teuchos::null) {
440 Z_ = MVT::Clone( *
tmp, 1 );
442 if (P_ == Teuchos::null) {
444 P_ = MVT::Clone( *
tmp, 1 );
446 if (AP_ == Teuchos::null) {
448 AP_ = MVT::Clone( *
tmp, 1 );
451 if (C_ == Teuchos::null) {
456 "Belos::PCPGIter::setStateSize(): linear problem does not specify multivectors to clone from.");
458 "Belos::PCPGIter::setStateSize(): prevUdim not zero and C is null.");
459 C_ = MVT::Clone( *
tmp, savedBlocks_ );
463 if (MVT::GetNumberVecs(*C_) < savedBlocks_ ) {
464 Teuchos::RCP<const MV>
tmp = C_;
465 C_ = MVT::Clone( *
tmp, savedBlocks_ );
468 if (U_ == Teuchos::null) {
471 "Belos::PCPGIter::setStateSize(): prevUdim not zero and U is null.");
472 U_ = MVT::Clone( *
tmp, savedBlocks_ );
476 if (MVT::GetNumberVecs(*U_) < savedBlocks_ ) {
477 Teuchos::RCP<const MV>
tmp = U_;
478 U_ = MVT::Clone( *
tmp, savedBlocks_ );
482 if (initDiagonal_ || ((
int)(D_.size()) <
newsd)) {
487 stateStorageInitialized_ =
true;
494 template<
class ScalarType,
class MV,
class OP,
class DM>
499 "Belos::PCPGIter::initialize(): Cannot initialize state storage!");
503 std::string
errstr(
"Belos::PCPGIter::initialize(): Specified multivectors must have a consistent length and width.");
516 std::vector<int> index(prevUdim_);
517 for (
int i=0;
i< prevUdim_; ++
i)
519 Teuchos::RCP<const MV>
Ukeff = MVT::CloneView( *
newstate.U, index );
521 Teuchos::RCP<MV>
Ckeff = MVT::CloneViewNonConst( *
newstate.C, index );
524 curDim_ = prevUdim_ ;
528 if (!stateStorageInitialized_)
541 if ( lp_->getLeftPrec() != Teuchos::null ) {
542 lp_->applyLeftPrec( *R_, *Z_ );
558 std::invalid_argument,
errstr );
564 std::invalid_argument,
errstr );
572 "Belos::PCPGIter::initialize(): PCPGStateIterState does not have initial kernel R_0.");
582 template<
class ScalarType,
class MV,
class OP,
class DM>
588 if (initialized_ ==
false) {
591 const bool debug =
false;
595 Teuchos::RCP<DM>
pAp = DMT::Create(1,1);
596 Teuchos::RCP<DM>
rHz = DMT::Create(1,1);
599 std::cout <<
" Iterate Warning: begin from nonzero iter_ ?" << std::endl;
603 Teuchos::RCP<const MV>
Uprev;
604 Teuchos::RCP<const MV>
Cprev;
610 CZ = DMT::Create( prevUdim_ , 1 );
620 "Belos::PCPGIter::iterate(): current linear system has more than one std::vector!" );
624 "Belos::PCPGIter::iterate(): mistake in initialization !" );
627 const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
628 const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
631 std::vector<int>
curind(1);
636 P = MVT::CloneViewNonConst(*U_,
curind);
640 if( curDim_ == savedBlocks_ ){
649 MVT::MvTransMv(
one, *R_, *Z_, *
rHz );
650 DMT::SyncDeviceToHost( *
rHz );
655 while (stest_->checkStatus(
this) !=
Passed ) {
656 Teuchos::RCP<const MV> P;
662 MVT::MvNorm(*R_,
rnorm);
663 std::cout << iter_ <<
" " << curDim_ <<
" " <<
rnorm[0] << std::endl;
665 if( prevUdim_ + iter_ < savedBlocks_ ){
666 P = MVT::CloneView(*U_,
curind);
667 AP = MVT::CloneViewNonConst(*C_,
curind);
668 lp_->applyOp( *P, *AP );
669 MVT::MvTransMv(
one, *P, *AP, *
pAp );
671 if( prevUdim_ + iter_ == savedBlocks_ ){
672 AP = MVT::CloneViewNonConst(*C_,
curind);
673 lp_->applyOp( *P_, *AP );
674 MVT::MvTransMv(
one, *P_, *AP, *
pAp );
676 lp_->applyOp( *P_, *AP_ );
677 MVT::MvTransMv(
one, *P_, *AP_, *
pAp );
680 DMT::SyncDeviceToHost( *
pAp );
682 if( keepDiagonal_ && prevUdim_ + iter_ <= savedBlocks_ )
683 D_[iter_-1] = DMT::ValueConst(*
pAp,0,0);
687 "Belos::PCPGIter::iterate(): non-positive value for p^H*A*p encountered!" );
690 alpha = DMT::ValueConst(*
rHz,0,0) / DMT::ValueConst(*
pAp,0,0);
694 "Belos::PCPGIter::iterate(): non-positive value for alpha encountered!" );
697 if( curDim_ < savedBlocks_ ){
709 if( prevUdim_ + iter_ <= savedBlocks_ ){
710 MVT::MvAddMv(
one, *R_, -alpha, *AP, *R_ );
713 MVT::MvAddMv(
one, *R_, -alpha, *AP_, *R_ );
718 if ( lp_->getLeftPrec() != Teuchos::null ) {
719 lp_->applyLeftPrec( *R_, *Z_ );
724 MVT::MvTransMv(
one, *R_, *Z_, *
rHz );
725 DMT::SyncDeviceToHost( *
rHz );
729 if( curDim_ < savedBlocks_ ){
732 Teuchos::RCP<MV>
Pnext = MVT::CloneViewNonConst(*U_,
curind);
733 MVT::MvAddMv(
one, *Z_, beta, *P, *
Pnext );
739 if( curDim_ == savedBlocks_ ){
744 Pnext = Teuchos::null;
746 MVT::MvAddMv(
one, *Z_, beta, *P_, *P_ );
757 TEUCHOS_TEST_FOR_EXCEPTION( AP != Teuchos::null || P != Teuchos::null, std::logic_error,
"Loop recurrence violated. Please contact Belos team.");
759 if( prevUdim_ + iter_ < savedBlocks_ ) --curDim_;
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.
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.
CGIterationInitFailure is thrown when the CGIteration object is unable to generate an initial iterate...
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 PCPG iteration, where a single-vector Krylov subspace is constructed....
int getBlockSize() const
Get the maximum number of blocks used by the iterative solver in solving this linear problem.
int getPrevSubspaceDim() const
Get the dimension of the search subspace used to solve the current solution to the linear problem.
void initialize()
Initialize the solver with the initial vectors from the linear problem. An exception is thrown if ini...
void resetState()
tell the Iterator to "reset" itself; delete and rebuild the seed space.
void iterate()
PCPGIter iterates CG until the status test either requests a stop or detects an error....
void setBlockSize(int blockSize)
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 solution?.
DenseMatTraits< ScalarType, DM > DMT
int getNumIters() const
Get the current iteration count.
int getNumRecycledBlocks() const
Get the maximum number of recycled blocks used by the iterative solver in solving this linear problem...
PCPGIterState< ScalarType, MV, DM > getState() const
Get the current state of the linear solver.
int getCurSubspaceDim() const
Get the current dimension of the whole seed subspace.
MultiVecTraits< ScalarType, MV, DM > MVT
OperatorTraits< ScalarType, MV, OP > OPT
PCPGIter(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 ¶ms)
PCPGIter constructor with linear problem, solver utilities, and parameter list of solver options.
bool isInitialized()
States whether the solver has been initialized or not.
void setSize(int savedBlocks)
Set the maximum number of saved or recycled blocks used by the iterative solver.
SCT::magnitudeType MagnitudeType
void resetNumIters(int iter=0)
Reset the iteration count.
Teuchos::ScalarTraits< ScalarType > SCT
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *) const
Get the norms of the residuals native to the solver.
virtual ~PCPGIter()
Destructor.
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const
Get a constant reference to the linear problem.
Structure to contain pointers to PCPGIter state variables.
Teuchos::RCP< MV > AP
The matrix A applied to current decent direction std::vector.
int curDim
The current dimension of the reduction.
int prevUdim
Number of block columns in matrices C and U before current iteration.
Teuchos::RCP< MV > C
C = AU, U spans recycled subspace.
Teuchos::RCP< MV > P
The current decent direction std::vector.
std::vector< ScalarType > D
The current diagonal matrix.
Teuchos::RCP< MV > R
The current residual.
Teuchos::RCP< MV > Z
The current preconditioned residual.
Teuchos::RCP< MV > U
The recycled subspace.