42 #ifndef BELOS_CG_ITER_HPP
43 #define BELOS_CG_ITER_HPP
59 #include "Teuchos_SerialDenseMatrix.hpp"
60 #include "Teuchos_SerialDenseVector.hpp"
61 #include "Teuchos_ScalarTraits.hpp"
62 #include "Teuchos_ParameterList.hpp"
63 #include "Teuchos_TimeMonitor.hpp"
77 template<
class ScalarType,
class MV,
class OP>
87 typedef Teuchos::ScalarTraits<ScalarType>
SCT;
101 Teuchos::ParameterList ¶ms );
199 TEUCHOS_TEST_FOR_EXCEPTION(blockSize!=1,std::invalid_argument,
200 "Belos::CGIter::setBlockSize(): Cannot use a block size that is not one.");
209 if (numEntriesForCondEst_) doCondEst_=val;
217 typedef typename Teuchos::ArrayView<MagnitudeType>::size_type size_type;
218 if (
static_cast<size_type
> (iter_) >= diag_.size ()) {
221 return diag_ (0, iter_);
232 typedef typename Teuchos::ArrayView<MagnitudeType>::size_type size_type;
233 if (
static_cast<size_type
> (iter_) >= offdiag_.size ()) {
236 return offdiag_ (0, iter_);
253 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > lp_;
254 const Teuchos::RCP<OutputManager<ScalarType> > om_;
255 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > stest_;
268 bool stateStorageInitialized_;
274 bool assertPositiveDefiniteness_;
277 Teuchos::ArrayRCP<MagnitudeType> diag_, offdiag_;
278 int numEntriesForCondEst_;
296 Teuchos::RCP<MV> AP_;
302 template<
class ScalarType,
class MV,
class OP>
306 Teuchos::ParameterList ¶ms ):
311 stateStorageInitialized_(false),
313 assertPositiveDefiniteness_( params.get(
"Assert Positive Definiteness", true) ),
314 numEntriesForCondEst_(params.get(
"Max Size For Condest",0) ),
321 template <
class ScalarType,
class MV,
class OP>
324 if (!stateStorageInitialized_) {
327 Teuchos::RCP<const MV> lhsMV = lp_->getLHS();
328 Teuchos::RCP<const MV> rhsMV = lp_->getRHS();
329 if (lhsMV == Teuchos::null && rhsMV == Teuchos::null) {
330 stateStorageInitialized_ =
false;
337 if (R_ == Teuchos::null) {
339 Teuchos::RCP<const MV> tmp = ( (rhsMV!=Teuchos::null)? rhsMV: lhsMV );
340 TEUCHOS_TEST_FOR_EXCEPTION(tmp == Teuchos::null,std::invalid_argument,
341 "Belos::CGIter::setStateSize(): linear problem does not specify multivectors to clone from.");
342 R_ = MVT::Clone( *tmp, 1 );
343 Z_ = MVT::Clone( *tmp, 1 );
344 P_ = MVT::Clone( *tmp, 1 );
345 AP_ = MVT::Clone( *tmp, 1 );
349 if(numEntriesForCondEst_ > 0) {
350 diag_.resize(numEntriesForCondEst_);
351 offdiag_.resize(numEntriesForCondEst_-1);
355 stateStorageInitialized_ =
true;
363 template <
class ScalarType,
class MV,
class OP>
367 if (!stateStorageInitialized_)
370 TEUCHOS_TEST_FOR_EXCEPTION(!stateStorageInitialized_,std::invalid_argument,
371 "Belos::CGIter::initialize(): Cannot initialize state storage!");
375 std::string errstr(
"Belos::CGIter::initialize(): Specified multivectors must have a consistent length and width.");
378 const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
379 const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
381 if (newstate.
R != Teuchos::null) {
383 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.
R) != MVT::GetGlobalLength(*R_),
384 std::invalid_argument, errstr );
385 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.
R) != 1,
386 std::invalid_argument, errstr );
389 if (newstate.
R != R_) {
391 MVT::MvAddMv( one, *newstate.
R, zero, *newstate.
R, *R_ );
397 if ( lp_->getLeftPrec() != Teuchos::null ) {
398 lp_->applyLeftPrec( *R_, *Z_ );
399 if ( lp_->getRightPrec() != Teuchos::null ) {
400 Teuchos::RCP<MV> tmp = MVT::Clone( *Z_, 1 );
401 lp_->applyRightPrec( *Z_, *tmp );
405 else if ( lp_->getRightPrec() != Teuchos::null ) {
406 lp_->applyRightPrec( *R_, *Z_ );
411 MVT::MvAddMv( one, *Z_, zero, *Z_, *P_ );
415 TEUCHOS_TEST_FOR_EXCEPTION(newstate.
R == Teuchos::null,std::invalid_argument,
416 "Belos::CGIter::initialize(): CGIterationState does not have initial residual.");
426 template <
class ScalarType,
class MV,
class OP>
432 if (initialized_ ==
false) {
437 Teuchos::SerialDenseMatrix<int,ScalarType> alpha( 1, 1 );
438 Teuchos::SerialDenseMatrix<int,ScalarType> beta( 1, 1 );
439 Teuchos::SerialDenseMatrix<int,ScalarType> rHz( 1, 1 ), rHz_old( 1, 1 ), pAp( 1, 1 );
442 const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
443 const MagnitudeType zero = Teuchos::ScalarTraits<MagnitudeType>::zero();
446 ScalarType pAp_old = one, beta_old = one, rHz_old2 = one;
449 Teuchos::RCP<MV> cur_soln_vec = lp_->getCurrLHSVec();
452 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*cur_soln_vec) != 1,
CGIterateFailure,
453 "Belos::CGIter::iterate(): current linear system has more than one vector!" );
456 MVT::MvTransMv( one, *R_, *Z_, rHz );
461 while (stest_->checkStatus(
this) !=
Passed) {
467 lp_->applyOp( *P_, *AP_ );
470 MVT::MvTransMv( one, *P_, *AP_, pAp );
471 alpha(0,0) = rHz(0,0) / pAp(0,0);
474 if(assertPositiveDefiniteness_)
475 TEUCHOS_TEST_FOR_EXCEPTION( SCT::real(alpha(0,0)) <= zero,
CGIterateFailure,
476 "Belos::CGIter::iterate(): non-positive value for p^H*A*p encountered!" );
480 MVT::MvAddMv( one, *cur_soln_vec, alpha(0,0), *P_, *cur_soln_vec );
481 lp_->updateSolution();
485 rHz_old(0,0) = rHz(0,0);
489 MVT::MvAddMv( one, *R_, -alpha(0,0), *AP_, *R_ );
494 if ( lp_->getLeftPrec() != Teuchos::null ) {
495 lp_->applyLeftPrec( *R_, *Z_ );
496 if ( lp_->getRightPrec() != Teuchos::null ) {
497 Teuchos::RCP<MV> tmp = MVT::Clone( *Z_, 1 );
498 lp_->applyRightPrec( *Z_, *tmp );
502 else if ( lp_->getRightPrec() != Teuchos::null ) {
503 lp_->applyRightPrec( *R_, *Z_ );
509 MVT::MvTransMv( one, *R_, *Z_, rHz );
511 beta(0,0) = rHz(0,0) / rHz_old(0,0);
513 MVT::MvAddMv( one, *Z_, beta(0,0), *P_, *P_ );
518 diag_[iter_-1] = Teuchos::ScalarTraits<ScalarType>::real((beta_old * beta_old * pAp_old + pAp(0,0)) / rHz_old(0,0));
519 offdiag_[iter_-2] = -Teuchos::ScalarTraits<ScalarType>::real(beta_old * pAp_old / (sqrt( rHz_old(0,0) * rHz_old2)));
522 diag_[iter_-1] = Teuchos::ScalarTraits<ScalarType>::real(pAp(0,0) / rHz_old(0,0));
524 rHz_old2 = rHz_old(0,0);
525 beta_old = beta(0,0);