42 #ifndef BELOS_PSEUDO_BLOCK_CG_ITER_HPP
43 #define BELOS_PSEUDO_BLOCK_CG_ITER_HPP
80 template<
class ScalarType,
class MV,
class OP>
211 "Belos::PseudoBlockCGIter::setBlockSize(): Cannot use a block size that is not one.");
303 template<
class ScalarType,
class MV,
class OP>
314 assertPositiveDefiniteness_( params.get(
"Assert Positive Definiteness", true) ),
315 numEntriesForCondEst_(params.get(
"Max Size For Condest",0) )
322 template <
class ScalarType,
class MV,
class OP>
329 "Belos::PseudoBlockCGIter::initialize(): Cannot initialize state storage!");
335 int numRHS = MVT::GetNumberVecs(*tmp);
341 R_ = MVT::Clone( *tmp, numRHS_ );
342 Z_ = MVT::Clone( *tmp, numRHS_ );
343 P_ = MVT::Clone( *tmp, numRHS_ );
344 AP_ = MVT::Clone( *tmp, numRHS_ );
348 if(numEntriesForCondEst_ > 0) {
349 diag_.resize(numEntriesForCondEst_);
350 offdiag_.resize(numEntriesForCondEst_-1);
355 std::string errstr(
"Belos::BlockPseudoCGIter::initialize(): Specified multivectors must have a consistent length and width.");
364 std::invalid_argument, errstr );
366 std::invalid_argument, errstr );
369 if (newstate.
R != R_) {
371 MVT::MvAddMv( one, *newstate.
R, zero, *newstate.
R, *R_ );
377 if ( lp_->getLeftPrec() != Teuchos::null ) {
378 lp_->applyLeftPrec( *R_, *Z_ );
379 if ( lp_->getRightPrec() != Teuchos::null ) {
381 lp_->applyRightPrec( *Z_, *tmp1 );
385 else if ( lp_->getRightPrec() != Teuchos::null ) {
386 lp_->applyRightPrec( *R_, *Z_ );
391 MVT::MvAddMv( one, *Z_, zero, *Z_, *P_ );
396 "Belos::CGIter::initialize(): CGStateIterState does not have initial residual.");
406 template <
class ScalarType,
class MV,
class OP>
412 if (initialized_ ==
false) {
418 std::vector<int> index(1);
419 std::vector<ScalarType> rHz( numRHS_ ), rHz_old( numRHS_ ), pAp( numRHS_ );
427 ScalarType pAp_old=one, beta_old=one ,rHz_old2=one;
433 MVT::MvDot( *R_, *Z_, rHz );
435 if ( assertPositiveDefiniteness_ )
436 for (i=0; i<numRHS_; ++i)
439 "Belos::PseudoBlockCGIter::iterate(): negative value for r^H*M*r encountered!" );
444 while (stest_->checkStatus(
this) !=
Passed) {
450 lp_->applyOp( *P_, *AP_ );
453 MVT::MvDot( *P_, *AP_, pAp );
455 for (i=0; i<numRHS_; ++i) {
456 if ( assertPositiveDefiniteness_ )
460 "Belos::PseudoBlockCGIter::iterate(): non-positive value for p^H*A*p encountered!" );
462 alpha(i,i) = rHz[i] / pAp[i];
468 MVT::MvTimesMatAddMv( one, *P_, alpha, one, *cur_soln_vec );
469 lp_->updateSolution();
473 for (i=0; i<numRHS_; ++i) {
479 MVT::MvTimesMatAddMv( -one, *AP_, alpha, one, *R_ );
484 if ( lp_->getLeftPrec() != Teuchos::null ) {
485 lp_->applyLeftPrec( *R_, *Z_ );
486 if ( lp_->getRightPrec() != Teuchos::null ) {
488 lp_->applyRightPrec( *Z_, *tmp );
492 else if ( lp_->getRightPrec() != Teuchos::null ) {
493 lp_->applyRightPrec( *R_, *Z_ );
499 MVT::MvDot( *R_, *Z_, rHz );
500 if ( assertPositiveDefiniteness_ )
501 for (i=0; i<numRHS_; ++i)
504 "Belos::PseudoBlockCGIter::iterate(): negative value for r^H*M*r encountered!" );
507 for (i=0; i<numRHS_; ++i) {
508 beta(i,i) = rHz[i] / rHz_old[i];
512 MVT::MvAddMv( one, *Z_i, beta(i,i), *P_i, *P_i );
524 rHz_old2 = rHz_old[0];
525 beta_old = beta(0,0);