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.