10 #ifndef BELOS_BLOCK_GMRES_ITER_HPP 
   11 #define BELOS_BLOCK_GMRES_ITER_HPP 
   51 template<
class ScalarType, 
class MV, 
class OP>
 
  228   void setSize(
int blockSize, 
int numBlocks);
 
  249   std::string 
accuracyCheck(
const CheckList &chk, 
const std::string &where) 
const;
 
  319   template<
class ScalarType, 
class MV, 
class OP>
 
  332     stateStorageInitialized_(false),
 
  333     keepHessenberg_(false),
 
  334     initHessenberg_(false),
 
  349                        "Belos::BlockGmresIter::constructor: mandatory parameter 'Num Blocks' is not specified.");
 
  350     int nb = Teuchos::getParameter<int>(params, 
"Num Blocks");
 
  353     int bs = params.get(
"Block Size", 1);
 
  359   template <
class ScalarType, 
class MV, 
class OP>
 
  365     TEUCHOS_TEST_FOR_EXCEPTION(numBlocks <= 0 || blockSize <= 0, std::invalid_argument, 
"Belos::BlockGmresIter::setSize was passed a non-positive argument.");
 
  366     if (blockSize == blockSize_ && numBlocks == numBlocks_) {
 
  371     if (blockSize!=blockSize_ || numBlocks!=numBlocks_)
 
  372       stateStorageInitialized_ = 
false;
 
  374     blockSize_ = blockSize;
 
  375     numBlocks_ = numBlocks;
 
  377     initialized_ = 
false;
 
  387   template <
class ScalarType, 
class MV, 
class OP>
 
  390     if (!stateStorageInitialized_) {
 
  396         stateStorageInitialized_ = 
false;
 
  404         int newsd = blockSize_*(numBlocks_+1);
 
  411           beta.resize( newsd );
 
  415         TEUCHOS_TEST_FOR_EXCEPTION(blockSize_*static_cast<ptrdiff_t>(numBlocks_) > MVT::GetGlobalLength(*rhsMV),std::invalid_argument,
 
  416                            "Belos::BlockGmresIter::setStateSize(): Cannot generate a Krylov basis with dimension larger the operator!");
 
  423                                      "Belos::BlockGmresIter::setStateSize(): linear problem does not specify multivectors to clone from.");
 
  424           V_ = MVT::Clone( *tmp, newsd );
 
  428           if (MVT::GetNumberVecs(*V_) < newsd) {
 
  430             V_ = MVT::Clone( *tmp, newsd );
 
  438         if (initHessenberg_) {
 
  439           R_->shape( newsd, newsd-blockSize_ );
 
  442           if (R_->numRows() < newsd || R_->numCols() < newsd-blockSize_) {
 
  443             R_->shapeUninitialized( newsd, newsd-blockSize_ );
 
  448         if (keepHessenberg_) {
 
  452           if (initHessenberg_) {
 
  453             H_->shape( newsd, newsd-blockSize_ );
 
  456             if (H_->numRows() < newsd || H_->numCols() < newsd-blockSize_) {
 
  457               H_->shapeUninitialized( newsd, newsd-blockSize_ );
 
  470         if (z_-> numRows() < newsd || z_->numCols() < blockSize_) {
 
  471           z_->shapeUninitialized( newsd, blockSize_ );
 
  475         stateStorageInitialized_ = 
true;
 
  482   template <
class ScalarType, 
class MV, 
class OP>
 
  491       return currentUpdate;
 
  493       const ScalarType one  = SCT::one();
 
  494       const ScalarType zero = SCT::zero();
 
  496       currentUpdate = MVT::Clone( *V_, blockSize_ );
 
  510       std::vector<int> index(curDim_);
 
  511       for ( 
int i=0; i<curDim_; i++ ) {
 
  515       MVT::MvTimesMatAddMv( one, *Vjp1, y, zero, *currentUpdate );
 
  517     return currentUpdate;
 
  524   template <
class ScalarType, 
class MV, 
class OP>
 
  530     if ( norms && (
int)norms->size() < blockSize_ )
 
  531       norms->resize( blockSize_ );
 
  535       for (
int j=0; j<blockSize_; j++) {
 
  536         (*norms)[j] = blas.
NRM2( blockSize_, &(*z_)(curDim_, j), 1);
 
  546   template <
class ScalarType, 
class MV, 
class OP>
 
  550     if (!stateStorageInitialized_)
 
  554                                "Belos::BlockGmresIter::initialize(): Cannot initialize state storage!");
 
  556     const ScalarType zero = SCT::zero(), one = SCT::one();
 
  562     std::string errstr(
"Belos::BlockGmresIter::initialize(): Specified multivectors must have a consistent length and width.");
 
  569                           std::invalid_argument, errstr );
 
  571                           std::invalid_argument, errstr );
 
  573                           std::invalid_argument, errstr );
 
  575       curDim_ = newstate.
curDim;
 
  576       int lclDim = MVT::GetNumberVecs(*newstate.
V);
 
  583       if (newstate.
V != V_) {
 
  585         if (curDim_ == 0 && lclDim > blockSize_) {
 
  586           om_->stream(
Warnings) << 
"Belos::BlockGmresIter::initialize(): the solver was initialized with a kernel of " << lclDim << std::endl
 
  587                                                                          << 
"The block size however is only " << blockSize_ << std::endl
 
  588                                                                          << 
"The last " << lclDim - blockSize_ << 
" vectors will be discarded." << std::endl;
 
  590         std::vector<int> nevind(curDim_+blockSize_);
 
  591         for (
int i=0; i<curDim_+blockSize_; i++) nevind[i] = i;
 
  594         MVT::MvAddMv( one, *newV, zero, *newV, *lclV );
 
  601       if (newstate.
z != z_) {
 
  616                          "Belos::BlockGmresIter::initialize(): BlockGmresStateIterState does not have initial kernel V_0.");
 
  619                          "Belos::BlockGmresIter::initialize(): BlockGmresStateIterState does not have initial norms z_0.");
 
  625     if (om_->isVerbosity( 
Debug ) ) {
 
  630       om_->print( 
Debug, accuracyCheck(chk, 
": after initialize()") );
 
  638   template <
class ScalarType, 
class MV, 
class OP>
 
  644     if (initialized_ == 
false) {
 
  649     int searchDim = blockSize_*numBlocks_;
 
  656     while (stest_->checkStatus(
this) != 
Passed && curDim_+blockSize_ <= searchDim) {
 
  661       int lclDim = curDim_ + blockSize_;
 
  664       std::vector<int> curind(blockSize_);
 
  665       for (
int i=0; i<blockSize_; i++) { curind[i] = lclDim + i; }
 
  670       for (
int i=0; i<blockSize_; i++) { curind[i] = curDim_ + i; }
 
  674       lp_->apply(*Vprev,*Vnext);
 
  679       std::vector<int> prevind(lclDim);
 
  680       for (
int i=0; i<lclDim; i++) { prevind[i] = i; }
 
  681       Vprev = MVT::CloneView(*V_,prevind);
 
  694                               ( 
Teuchos::View,*H_,blockSize_,blockSize_,lclDim,curDim_ ) );
 
  696       int rank = ortho_->projectAndNormalize(*Vnext,AsubH,subH2,AVprev);
 
  700       if (keepHessenberg_) {
 
  710                             ( 
Teuchos::View,*R_,blockSize_,blockSize_,lclDim,curDim_ ) );
 
  711         subR2->assign(*subH2);
 
  715                                  "Belos::BlockGmresIter::iterate(): couldn't generate basis of full rank.");
 
  726       curDim_ += blockSize_;
 
  729       if (om_->isVerbosity( 
Debug ) ) {
 
  734         om_->print( 
Debug, accuracyCheck(chk, 
": after local update") );
 
  739         om_->print( 
OrthoDetails, accuracyCheck(chk, 
": after local update") );
 
  747   template<
class ScalarType, 
class MV, 
class OP>
 
  751     ScalarType sigma, mu, vscale, maxelem;
 
  752     const ScalarType zero = SCT::zero();
 
  757     int curDim = curDim_;
 
  758     if (dim >= curDim_ && dim < getMaxSubspaceDim()) {
 
  767     if (blockSize_ == 1) {
 
  771       for (i=0; i<curDim; i++) {
 
  775         blas.
ROT( 1, &(*R_)(i,curDim), 1, &(*R_)(i+1, curDim), 1, &cs[i], &sn[i] );
 
  780       blas.
ROTG( &(*R_)(curDim,curDim), &(*R_)(curDim+1,curDim), &cs[curDim], &sn[curDim] );
 
  781       (*R_)(curDim+1,curDim) = zero;
 
  785       blas.
ROT( 1, &(*z_)(curDim,0), 1, &(*z_)(curDim+1,0), 1, &cs[curDim], &sn[curDim] );
 
  791       for (j=0; j<blockSize_; j++) {
 
  795         for (i=0; i<curDim+j; i++) {
 
  796           sigma = blas.
DOT( blockSize_, &(*R_)(i+1,i), 1, &(*R_)(i+1,curDim+j), 1);
 
  797           sigma += (*R_)(i,curDim+j);
 
  798           sigma *= SCT::conjugate(beta[i]);
 
  799           blas.
AXPY(blockSize_, ScalarType(-sigma), &(*R_)(i+1,i), 1, &(*R_)(i+1,curDim+j), 1);
 
  800           (*R_)(i,curDim+j) -= sigma;
 
  805         maxidx = blas.
IAMAX( blockSize_+1, &(*R_)(curDim+j,curDim+j), 1 );
 
  806         maxelem = SCT::magnitude((*R_)(curDim+j+maxidx-1,curDim+j));
 
  807         for (i=0; i<blockSize_+1; i++)
 
  808           (*R_)(curDim+j+i,curDim+j) /= maxelem;
 
  809         sigma = blas.
DOT( blockSize_, &(*R_)(curDim+j+1,curDim+j), 1,
 
  810                           &(*R_)(curDim+j+1,curDim+j), 1 );
 
  811         MagnitudeType sign_Rjj = -SCT::real((*R_)(curDim+j,curDim+j)) /
 
  812                  SCT::magnitude(SCT::real(((*R_)(curDim+j,curDim+j))));
 
  814           beta[curDim + j] = zero;
 
  816           mu = SCT::squareroot(SCT::conjugate((*R_)(curDim+j,curDim+j))*(*R_)(curDim+j,curDim+j)+sigma);
 
  817           vscale = (*R_)(curDim+j,curDim+j) - Teuchos::as<ScalarType>(sign_Rjj)*mu;
 
  818           beta[curDim+j] = -Teuchos::as<ScalarType>(sign_Rjj) * vscale / mu;
 
  819           (*R_)(curDim+j,curDim+j) = Teuchos::as<ScalarType>(sign_Rjj)*maxelem*mu;
 
  820           for (i=0; i<blockSize_; i++)
 
  821             (*R_)(curDim+j+1+i,curDim+j) /= vscale;
 
  826         for (i=0; i<blockSize_; i++) {
 
  827           sigma = blas.
DOT( blockSize_, &(*R_)(curDim+j+1,curDim+j),
 
  828                             1, &(*z_)(curDim+j+1,i), 1);
 
  829           sigma += (*z_)(curDim+j,i);
 
  830           sigma *= SCT::conjugate(beta[curDim+j]);
 
  831           blas.
AXPY(blockSize_, ScalarType(-sigma), &(*R_)(curDim+j+1,curDim+j),
 
  832                     1, &(*z_)(curDim+j+1,i), 1);
 
  833           (*z_)(curDim+j,i) -= sigma;
 
  839     if (dim >= curDim_ && dim < getMaxSubspaceDim()) {
 
  840       curDim_ = dim + blockSize_;
 
  856   template <
class ScalarType, 
class MV, 
class OP>
 
  859     std::stringstream os;
 
  861     os.setf(std::ios::scientific, std::ios::floatfield);
 
  864     os << 
" Debugging checks: iteration " << iter_ << where << std::endl;
 
  867     std::vector<int> lclind(curDim_);
 
  868     for (
int i=0; i<curDim_; i++) lclind[i] = i;
 
  869     std::vector<int> bsind(blockSize_);
 
  870     for (
int i=0; i<blockSize_; i++) { bsind[i] = curDim_ + i; }
 
  875       lclV = MVT::CloneView(*V_,lclind);
 
  876     lclF = MVT::CloneView(*V_,bsind);
 
  880         tmp = ortho_->orthonormError(*lclV);
 
  881         os << 
" >> Error in V^H M V == I  : " << tmp << std::endl;
 
  883       tmp = ortho_->orthonormError(*lclF);
 
  884       os << 
" >> Error in F^H M F == I  : " << tmp << std::endl;
 
  886         tmp = ortho_->orthogError(*lclV,*lclF);
 
  887         os << 
" >> Error in V^H M F == 0  : " << tmp << std::endl;
 
  895         lclAV = MVT::Clone(*V_,curDim_);
 
  896         lp_->apply(*lclV,*lclAV);
 
  901         MVT::MvTimesMatAddMv( -one, *lclV, subH, one, *lclAV );
 
  905                                                         blockSize_,curDim_, curDim_ );
 
  906         MVT::MvTimesMatAddMv( -one, *lclF, curB, one, *lclAV );
 
  909         std::vector<MagnitudeType> arnNorms( curDim_ );
 
  910         ortho_->norm( *lclAV, arnNorms );
 
  912         for (
int i=0; i<curDim_; i++) {
 
  913         os << 
" >> Error in Krylov factorization (R = AV-VH-FB^H), ||R[" << i << 
"]|| : " << arnNorms[i] << std::endl;
 
ScalarType * values() const 
Collection of types and exceptions used within the Belos solvers. 
void TRSM(ESide side, EUplo uplo, ETransp transa, EDiag diag, const OrdinalType &m, const OrdinalType &n, const alpha_type alpha, const A_type *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb) const 
Belos's basic output manager for sending information of select verbosity levels to the appropriate ou...
void AXPY(const OrdinalType &n, const alpha_type alpha, const x_type *x, const OrdinalType &incx, ScalarType *y, const OrdinalType &incy) const 
const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > lp_
Array< T > & append(const T &x)
Class which manages the output and verbosity of the Belos solvers. 
int getMaxSubspaceDim() const 
Get the maximum dimension allocated for the search subspace. 
void ROT(const OrdinalType &n, ScalarType *dx, const OrdinalType &incx, ScalarType *dy, const OrdinalType &incy, MagnitudeType *c, ScalarType *s) const 
This class implements the block GMRES iteration, where a block Krylov subspace is constructed...
Teuchos::RCP< const MV > V
The current Krylov basis. 
T & get(ParameterList &l, const std::string &name)
std::string accuracyCheck(const CheckList &chk, const std::string &where) const 
Check accuracy of Arnoldi factorization. 
MultiVecTraits< ScalarType, MV > MVT
Pure virtual base class for defining the status testing capabilities of Belos. 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void updateLSQR(int dim=-1)
Method for updating QR factorization of upper Hessenberg matrix. 
Teuchos::RCP< MV > getCurrentUpdate() const 
Get the current update to the linear system. 
Declaration of basic traits for the multivector type. 
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > z
The current right-hand side of the least squares system RY = Z. 
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > stest_
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > R_
ScalarTraits< ScalarType >::magnitudeType NRM2(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx) const 
void iterate()
This method performs block Gmres iterations until the status test indicates the need to stop or an er...
OrdinalType IAMAX(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx) const 
Structure to contain pointers to GmresIteration state variables. 
void resetNumIters(int iter=0)
Reset the iteration count. 
const Teuchos::RCP< OutputManager< ScalarType > > om_
SCT::magnitudeType MagnitudeType
A pure virtual class for defining the status tests for the Belos iterative solvers. 
Class which defines basic traits for the operator type. 
const LinearProblem< ScalarType, MV, OP > & getProblem() const 
Get a constant reference to the linear problem. 
void setSize(int blockSize, int numBlocks)
Set the blocksize and number of blocks to be used by the iterative solver in solving this linear prob...
const Teuchos::RCP< OrthoManager< ScalarType, MV > > ortho_
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *norms) const 
Get the norms of the residuals native to the solver. 
virtual ~BlockGmresIter()
Destructor. 
Traits class which defines basic operations on multivectors. 
bool isParameter(const std::string &name) const 
bool isInitialized()
States whether the solver has been initialized or not. 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
int curDim
The current dimension of the reduction. 
OperatorTraits< ScalarType, MV, OP > OPT
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > R
The current upper-triangular matrix from the QR reduction of H. 
bool stateStorageInitialized_
A linear system to solve, and its associated information. 
Class which describes the linear problem to be solved by the iterative solver. 
int getBlockSize() const 
Get the blocksize to be used by the iterative solver in solving this linear problem. 
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > H_
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > z_
ScalarType DOT(const OrdinalType &n, const x_type *x, const OrdinalType &incx, const y_type *y, const OrdinalType &incy) const 
int getNumBlocks() const 
Get the maximum number of blocks used by the iterative solver in solving this linear problem...
Teuchos::ScalarTraits< ScalarType > SCT
Teuchos::SerialDenseVector< int, ScalarType > sn
GmresIterationState< ScalarType, MV > getState() const 
Get the current state of the linear solver. 
OrdinalType numCols() const 
void setNumBlocks(int numBlocks)
Set the maximum number of blocks used by the iterative solver. 
void ROTG(ScalarType *da, ScalarType *db, rotg_c_type *c, ScalarType *s) const 
Teuchos::SerialDenseVector< int, MagnitudeType > cs
Teuchos::SerialDenseVector< int, ScalarType > beta
Class which defines basic traits for the operator type. 
void initializeGmres(GmresIterationState< ScalarType, MV > &newstate)
Initialize the solver to an iterate, providing a complete state. 
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data. 
BlockGmresIter(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem, const Teuchos::RCP< OutputManager< ScalarType > > &printer, const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &tester, const Teuchos::RCP< MatOrthoManager< ScalarType, MV, OP > > &ortho, Teuchos::ParameterList ¶ms)
BlockGmresIter constructor with linear problem, solver utilities, and parameter list of solver option...
Belos's templated virtual class for providing routines for orthogonalization and orthonormzalition of...
Pure virtual base class which augments the basic interface for a Gmres linear solver iteration...
GmresIterationOrthoFailure is thrown when the GmresIteration object is unable to compute independent ...
Belos header file which uses auto-configuration information to include necessary C++ headers...
int getCurSubspaceDim() const 
Get the dimension of the search subspace used to generate the current solution to the linear problem...
void setBlockSize(int blockSize)
Set the blocksize. 
OrdinalType stride() const 
void setStateSize()
Method for initalizing the state storage needed by block GMRES. 
OrdinalType numRows() const 
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
int getNumIters() const 
Get the current iteration count. 
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > H
The current Hessenberg matrix.