42 #ifndef BELOS_PSEUDO_BLOCK_CG_ITER_MP_VECTOR_HPP 
   43 #define BELOS_PSEUDO_BLOCK_CG_ITER_MP_VECTOR_HPP 
   54 #include "BelosPseudoBlockCGIter.hpp" 
   73   template<
class Storage, 
class MV, 
class OP>
 
   75     virtual public CGIteration<Sacado::MP::Vector<Storage>, MV, OP> {
 
   83     typedef MultiVecTraits<ScalarType,MV> 
MVT;
 
   84     typedef OperatorTraits<ScalarType,MV,OP> 
OPT;
 
   99                           const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
 
  145     void initializeCG(CGIterationState<ScalarType,MV>& newstate);
 
  152       CGIterationState<ScalarType,MV> empty;
 
  164       CGIterationState<ScalarType,MV> state;
 
  199     const LinearProblem<ScalarType,MV,OP>& 
getProblem()
 const { 
return *lp_; }
 
  207                          "Belos::PseudoBlockCGIter::setBlockSize(): Cannot use a block size that is not one.");
 
  224       if (static_cast<size_type> (iter_) >= diag_.size ()) {
 
  227         return diag_ (0, iter_);
 
  239       if (static_cast<size_type> (iter_) >= offdiag_.size ()) {
 
  242         return offdiag_ (0, iter_);
 
  302   template<
class StorageType, 
class MV, 
class OP>
 
  305                                                                const Teuchos::RCP<OutputManager<ScalarType> > &printer,
 
  306                                                                const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
 
  314     assertPositiveDefiniteness_( params.get(
"Assert Positive Definiteness", 
true) ),
 
  315     numEntriesForCondEst_(params.get(
"Max Size For Condest",0) ),
 
  316     breakDownTol_(params.get(
"Ensemble Breakdown Tolerance", 0.0))
 
  323   template <
class StorageType, 
class MV, 
class OP>
 
  324   void PseudoBlockCGIter<Sacado::MP::Vector<StorageType>,MV,OP>::
 
  325   initializeCG(CGIterationState<ScalarType,MV>& newstate)
 
  331                        "Belos::PseudoBlockCGIter::initialize(): Cannot initialize state storage!");
 
  337     int numRHS = MVT::GetNumberVecs(*tmp);
 
  343       R_ = MVT::Clone( *tmp, numRHS_ );
 
  344       Z_ = MVT::Clone( *tmp, numRHS_ );
 
  345       P_ = MVT::Clone( *tmp, numRHS_ );
 
  346       AP_ = MVT::Clone( *tmp, numRHS_ );
 
  350     if(numEntriesForCondEst_ > 0) {
 
  351       diag_.resize(numEntriesForCondEst_);
 
  352       offdiag_.resize(numEntriesForCondEst_-1);
 
  357     std::string errstr(
"Belos::BlockPseudoCGIter::initialize(): Specified multivectors must have a consistent length and width.");
 
  366                           std::invalid_argument, errstr );
 
  368                           std::invalid_argument, errstr );
 
  371       if (newstate.R != R_) {
 
  373         MVT::MvAddMv( one, *newstate.R, zero, *newstate.R, *R_ );
 
  380         lp_->applyLeftPrec( *R_, *Z_ );
 
  383           lp_->applyRightPrec( *Z_, *tmp1 );
 
  388         lp_->applyRightPrec( *R_, *Z_ );
 
  393       MVT::MvAddMv( one, *Z_, zero, *Z_, *P_ );
 
  398                          "Belos::CGIter::initialize(): CGStateIterState does not have initial residual.");
 
  408   template <
class StorageType, 
class MV, 
class OP>
 
  409   void PseudoBlockCGIter<Sacado::MP::Vector<StorageType>,MV,OP>::
 
  415     if (initialized_ == 
false) {
 
  421     std::vector<int> index(1);
 
  422     std::vector<ScalarType> rHz( numRHS_ ), rHz_old( numRHS_ ), pAp( numRHS_ );
 
  430     ScalarType pAp_old=one, beta_old=one ,rHz_old2=one;
 
  436     MVT::MvDot( *R_, *Z_, rHz );
 
  438     if ( assertPositiveDefiniteness_ )
 
  439         for (i=0; i<numRHS_; ++i)
 
  442                                 "Belos::PseudoBlockCGIter::iterate(): negative value for r^H*M*r encountered!" );
 
  447     while (stest_->checkStatus(
this) != Passed) {
 
  453       lp_->applyOp( *P_, *AP_ );
 
  456       MVT::MvDot( *P_, *AP_, pAp );
 
  458       for (i=0; i<numRHS_; ++i) {
 
  459         if ( assertPositiveDefiniteness_ )
 
  463                                 "Belos::PseudoBlockCGIter::iterate(): non-positive value for p^H*A*p encountered!" );
 
  465         const int ensemble_size = pAp[i].size();
 
  466         for (
int k=0; k<ensemble_size; ++k) {
 
  467           if (SVT::magnitude(pAp[i].coeff(k)) <= breakDownTol_)
 
  468             alpha(i,i).fastAccessCoeff(k) = 0.0;
 
  470             alpha(i,i).fastAccessCoeff(k) = rHz[i].coeff(k) / pAp[i].coeff(k);
 
  477       MVT::MvTimesMatAddMv( one, *P_, alpha, one, *cur_soln_vec );
 
  478       lp_->updateSolution();
 
  482       for (i=0; i<numRHS_; ++i) {
 
  488       MVT::MvTimesMatAddMv( -one, *AP_, alpha, one, *R_ );
 
  494         lp_->applyLeftPrec( *R_, *Z_ );
 
  497           lp_->applyRightPrec( *Z_, *tmp );
 
  502         lp_->applyRightPrec( *R_, *Z_ );
 
  508       MVT::MvDot( *R_, *Z_, rHz );
 
  509       if ( assertPositiveDefiniteness_ )
 
  510           for (i=0; i<numRHS_; ++i)
 
  513                                   "Belos::PseudoBlockCGIter::iterate(): negative value for r^H*M*r encountered!" );
 
  516       for (i=0; i<numRHS_; ++i) {
 
  517         const int ensemble_size = rHz[i].size();
 
  518         for (
int k=0; k<ensemble_size; ++k) {
 
  519           if (SVT::magnitude(rHz[i].coeff(k)) <= breakDownTol_)
 
  520             beta(i,i).fastAccessCoeff(k) = 0.0;
 
  522             beta(i,i).fastAccessCoeff(k) = rHz[i].coeff(k) / rHz_old[i].coeff(k);
 
  527         MVT::MvAddMv( one, *Z_i, beta(i,i), *P_i, *P_i );
 
  539         rHz_old2 = rHz_old[0];
 
  540         beta_old = beta(0,0);
 
KOKKOS_INLINE_FUNCTION PCE< Storage > sqrt(const PCE< Storage > &a)
bool assertPositiveDefiniteness_
Teuchos::ScalarTraits< typename Storage::value_type > SVT
bool is_null(const std::shared_ptr< T > &p)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
static magnitudeType real(T a)
const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > lp_
OperatorTraits< ScalarType, MV, OP > OPT
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data. 
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *norms) const 
Teuchos::RCP< MV > getCurrentUpdate() const 
Get the current update to the linear system. 
virtual ~PseudoBlockCGIter()
Destructor. 
This class implements the pseudo-block CG iteration, where the basic CG algorithm is performed on all...
Teuchos::ScalarTraits< ScalarType > SCT
void setBlockSize(int blockSize)
Set the blocksize. 
int getNumIters() const 
Get the current iteration count. 
void resetNumIters(int iter=0)
Reset the iteration count. 
Teuchos::ArrayView< MagnitudeType > getDiag()
Gets the diagonal for condition estimation. 
MultiVecTraits< ScalarType, MV > MVT
int getBlockSize() const 
Get the blocksize to be used by the iterative solver in solving this linear problem. 
int numEntriesForCondEst_
Teuchos::ArrayView< MagnitudeType > getOffDiag()
Gets the off-diagonal for condition estimation. 
SCT::magnitudeType MagnitudeType
void setDoCondEst(bool val)
Sets whether or not to store the diagonal for condition estimation. 
Sacado::MP::Vector< Storage > ScalarType
CGIterationState< ScalarType, MV > getState() const 
Get the current state of the linear solver. 
bool isInitialized()
States whether the solver has been initialized or not. 
const LinearProblem< ScalarType, MV, OP > & getProblem() const 
Get a constant reference to the linear problem. 
SVT::magnitudeType breakDownTol_
const Teuchos::RCP< OutputManager< ScalarType > > om_
Teuchos::ArrayRCP< MagnitudeType > offdiag_
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > stest_