10 #ifndef BELOS_BLOCK_FGMRES_ITER_HPP
11 #define BELOS_BLOCK_FGMRES_ITER_HPP
50 template<
class ScalarType,
class MV,
class OP>
228 void setSize(
int blockSize,
int numBlocks);
300 template<
class ScalarType,
class MV,
class OP>
314 stateStorageInitialized_(false),
320 ! params.
isParameter (
"Num Blocks"), std::invalid_argument,
321 "Belos::BlockFGmresIter::constructor: mandatory parameter 'Num Blocks' is not specified.");
322 const int nb = params.
get<
int> (
"Num Blocks");
325 const int bs = params.
get (
"Block Size", 1);
331 template <
class ScalarType,
class MV,
class OP>
337 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks <= 0 || blockSize <= 0, std::invalid_argument,
"Belos::BlockFGmresIter::setSize was passed a non-positive argument.");
338 if (blockSize == blockSize_ && numBlocks == numBlocks_) {
343 if (blockSize!=blockSize_ || numBlocks!=numBlocks_)
344 stateStorageInitialized_ =
false;
346 blockSize_ = blockSize;
347 numBlocks_ = numBlocks;
349 initialized_ =
false;
359 template <
class ScalarType,
class MV,
class OP>
366 if (! stateStorageInitialized_) {
368 RCP<const MV> lhsMV = lp_->getLHS();
369 RCP<const MV> rhsMV = lp_->getRHS();
371 stateStorageInitialized_ =
false;
378 int newsd = blockSize_*(numBlocks_+1);
390 blockSize_ * static_cast<ptrdiff_t> (numBlocks_) > MVT::GetGlobalLength (*rhsMV),
391 std::invalid_argument,
"Belos::BlockFGmresIter::setStateSize(): "
392 "Cannot generate a Krylov basis with dimension larger the operator!");
397 RCP<const MV> tmp = (rhsMV !=
Teuchos::null) ? rhsMV : lhsMV;
400 "Belos::BlockFGmresIter::setStateSize(): "
401 "linear problem does not specify multivectors to clone from.");
402 V_ = MVT::Clone (*tmp, newsd);
406 if (MVT::GetNumberVecs (*V_) < newsd) {
407 RCP<const MV> tmp = V_;
408 V_ = MVT::Clone (*tmp, newsd);
414 RCP<const MV> tmp = (rhsMV !=
Teuchos::null) ? rhsMV : lhsMV;
417 "Belos::BlockFGmresIter::setStateSize(): "
418 "linear problem does not specify multivectors to clone from.");
419 Z_ = MVT::Clone (*tmp, newsd);
423 if (MVT::GetNumberVecs (*Z_) < newsd) {
424 RCP<const MV> tmp = Z_;
425 Z_ = MVT::Clone (*tmp, newsd);
431 H_ =
rcp (
new SDM (newsd, newsd-blockSize_));
434 H_->shapeUninitialized (newsd, newsd - blockSize_);
441 z_ =
rcp (
new SDM (newsd, blockSize_));
444 z_->shapeUninitialized (newsd, blockSize_);
448 stateStorageInitialized_ =
true;
454 template <
class ScalarType,
class MV,
class OP>
464 return currentUpdate;
471 currentUpdate = MVT::Clone (*Z_, blockSize_);
479 H_->values (), H_->stride (), y.values (), y.stride ());
482 std::vector<int> index (curDim_);
483 for (
int i = 0; i < curDim_; ++i) {
487 MVT::MvTimesMatAddMv (one, *Zjp1, y, zero, *currentUpdate);
489 return currentUpdate;
493 template <
class ScalarType,
class MV,
class OP>
499 if (norms != NULL && (
int)norms->size() < blockSize_) {
500 norms->resize (blockSize_);
505 for (
int j = 0; j < blockSize_; ++j) {
506 (*norms)[j] = blas.
NRM2 (blockSize_, &(*z_)(curDim_, j), 1);
515 template <
class ScalarType,
class MV,
class OP>
524 const ScalarType ZERO = STS::zero ();
525 const ScalarType ONE = STS::one ();
528 if (! stateStorageInitialized_) {
533 ! stateStorageInitialized_, std::invalid_argument,
534 "Belos::BlockFGmresIter::initialize(): Cannot initialize state storage!");
539 const char errstr[] =
"Belos::BlockFGmresIter::initialize(): The given "
540 "multivectors must have a consistent length and width.";
547 MVT::GetGlobalLength(*newstate.
V) != MVT::GetGlobalLength(*V_),
548 std::invalid_argument, errstr );
550 MVT::GetNumberVecs(*newstate.
V) < blockSize_,
551 std::invalid_argument, errstr );
553 newstate.
curDim > blockSize_*(numBlocks_+1),
554 std::invalid_argument, errstr );
556 curDim_ = newstate.
curDim;
557 const int lclDim = MVT::GetNumberVecs(*newstate.
V);
562 std::invalid_argument, errstr);
565 if (newstate.
V != V_) {
567 if (curDim_ == 0 && lclDim > blockSize_) {
568 std::ostream& warn = om_->stream (
Warnings);
569 warn <<
"Belos::BlockFGmresIter::initialize(): the solver was "
570 <<
"initialized with a kernel of " << lclDim << endl
571 <<
"The block size however is only " << blockSize_ << endl
572 <<
"The last " << lclDim - blockSize_
573 <<
" vectors will be discarded." << endl;
575 std::vector<int> nevind (curDim_ + blockSize_);
576 for (
int i = 0; i < curDim_ + blockSize_; ++i) {
579 RCP<const MV> newV = MVT::CloneView (*newstate.
V, nevind);
580 RCP<MV> lclV = MVT::CloneViewNonConst (*V_, nevind);
581 MVT::MvAddMv (ONE, *newV, ZERO, *newV, *lclV);
588 if (newstate.
z != z_) {
590 SDM newZ (
Teuchos::View, *newstate.
z, curDim_ + blockSize_, blockSize_);
592 lclz =
rcp (
new SDM (
Teuchos::View, *z_, curDim_ + blockSize_, blockSize_));
600 "Belos::BlockFGmresIter::initialize(): BlockFGmresStateIterState does not have initial kernel V_0.");
604 "Belos::BlockFGmresIter::initialize(): BlockFGmresStateIterState does not have initial norms z_0.");
612 template <
class ScalarType,
class MV,
class OP>
623 if (initialized_ ==
false) {
628 const int searchDim = blockSize_ * numBlocks_;
632 while (stest_->checkStatus (
this) !=
Passed && curDim_+blockSize_ <= searchDim) {
636 const int lclDim = curDim_ + blockSize_;
639 std::vector<int> curind (blockSize_);
640 for (
int i = 0; i < blockSize_; ++i) {
641 curind[i] = lclDim + i;
643 RCP<MV> Vnext = MVT::CloneViewNonConst (*V_, curind);
647 for (
int i = 0; i < blockSize_; ++i) {
648 curind[i] = curDim_ + i;
650 RCP<const MV> Vprev = MVT::CloneView (*V_, curind);
651 RCP<MV> Znext = MVT::CloneViewNonConst (*Z_, curind);
654 lp_->applyRightPrec (*Vprev, *Znext);
658 lp_->applyOp (*Znext, *Vnext);
663 std::vector<int> prevind (lclDim);
664 for (
int i = 0; i < lclDim; ++i) {
667 Vprev = MVT::CloneView (*V_, prevind);
668 Array<RCP<const MV> > AVprev (1, Vprev);
671 RCP<SDM> subH =
rcp (
new SDM (
View, *H_, lclDim, blockSize_, 0, curDim_));
672 Array<RCP<SDM> > AsubH;
676 RCP<SDM> subR =
rcp (
new SDM (
View, *H_, blockSize_, blockSize_, lclDim, curDim_));
677 const int rank = ortho_->projectAndNormalize (*Vnext, AsubH, subR, AVprev);
680 "Belos::BlockFGmresIter::iterate(): After orthogonalization, the new "
681 "basis block does not have full rank. It contains " << blockSize_
682 <<
" vector" << (blockSize_ != 1 ?
"s" :
"")
683 <<
", but its rank is " << rank <<
".");
695 curDim_ += blockSize_;
700 template<
class ScalarType,
class MV,
class OP>
706 const ScalarType zero = STS::zero ();
707 const ScalarType two = (STS::one () + STS::one());
708 ScalarType sigma, mu, vscale, maxelem;
715 int curDim = curDim_;
716 if (dim >= curDim_ && dim < getMaxSubspaceDim ()) {
725 if (blockSize_ == 1) {
727 for (
int i = 0; i < curDim; ++i) {
729 blas.
ROT (1, &(*H_)(i, curDim), 1, &(*H_)(i+1, curDim), 1, &cs[i], &sn[i]);
732 blas.
ROTG (&(*H_)(curDim, curDim), &(*H_)(curDim+1, curDim), &cs[curDim], &sn[curDim]);
733 (*H_)(curDim+1, curDim) = zero;
736 blas.
ROT (1, &(*z_)(curDim,0), 1, &(*z_)(curDim+1,0), 1, &cs[curDim], &sn[curDim]);
740 for (
int j = 0; j < blockSize_; ++j) {
742 for (
int i = 0; i < curDim + j; ++i) {
743 sigma = blas.
DOT (blockSize_, &(*H_)(i+1,i), 1, &(*H_)(i+1,curDim+j), 1);
744 sigma += (*H_)(i,curDim+j);
746 blas.
AXPY (blockSize_, ScalarType(-sigma), &(*H_)(i+1,i), 1, &(*H_)(i+1,curDim+j), 1);
747 (*H_)(i,curDim+j) -= sigma;
751 const int maxidx = blas.
IAMAX (blockSize_+1, &(*H_)(curDim+j,curDim+j), 1);
752 maxelem = (*H_)(curDim + j + maxidx - 1, curDim + j);
753 for (
int i = 0; i < blockSize_ + 1; ++i) {
754 (*H_)(curDim+j+i,curDim+j) /= maxelem;
756 sigma = blas.
DOT (blockSize_, &(*H_)(curDim + j + 1, curDim + j), 1,
757 &(*H_)(curDim + j + 1, curDim + j), 1);
759 beta[curDim + j] = zero;
761 mu = STS::squareroot ((*H_)(curDim+j,curDim+j)*(*H_)(curDim+j,curDim+j)+sigma);
762 if (STS::real ((*H_)(curDim + j, curDim + j)) < STM::zero ()) {
763 vscale = (*H_)(curDim+j,curDim+j) - mu;
765 vscale = -sigma / ((*H_)(curDim+j, curDim+j) + mu);
767 beta[curDim+j] = two * vscale * vscale / (sigma + vscale*vscale);
768 (*H_)(curDim+j, curDim+j) = maxelem*mu;
769 for (
int i = 0; i < blockSize_; ++i) {
770 (*H_)(curDim+j+1+i,curDim+j) /= vscale;
775 for (
int i = 0; i < blockSize_; ++i) {
776 sigma = blas.
DOT (blockSize_, &(*H_)(curDim+j+1,curDim+j),
777 1, &(*z_)(curDim+j+1,i), 1);
778 sigma += (*z_)(curDim+j,i);
779 sigma *= beta[curDim+j];
780 blas.
AXPY (blockSize_, ScalarType(-sigma), &(*H_)(curDim+j+1,curDim+j),
781 1, &(*z_)(curDim+j+1,i), 1);
782 (*z_)(curDim+j,i) -= sigma;
788 if (dim >= curDim_ && dim < getMaxSubspaceDim ()) {
789 curDim_ = dim + blockSize_;
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
void iterate()
This method performs block FGmres iterations until the status test indicates the need to stop or an e...
const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > lp_
bool stateStorageInitialized_
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
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
void setBlockSize(int blockSize)
Set the blocksize.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *norms) const
Get the norms of the residuals native to the solver.
Class which manages the output and verbosity of the Belos solvers.
BlockFGmresIter(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)
BlockFGmresIter constructor with linear problem, solver utilities, and parameter list of solver optio...
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > z_
Teuchos::SerialDenseVector< int, ScalarType > beta
OperatorTraits< ScalarType, MV, OP > OPT
Teuchos::ScalarTraits< ScalarType > SCT
void ROT(const OrdinalType &n, ScalarType *dx, const OrdinalType &incx, ScalarType *dy, const OrdinalType &incy, MagnitudeType *c, ScalarType *s) const
Teuchos::RCP< const MV > V
The current Krylov basis.
T & get(ParameterList &l, const std::string &name)
Pure virtual base class for defining the status testing capabilities of Belos.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::SerialDenseVector< int, ScalarType > sn
Teuchos::SerialDenseVector< int, MagnitudeType > cs
int getNumBlocks() const
Get the maximum number of blocks used by the iterative solver in solving this linear problem...
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.
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current solution to the linear problem...
ScalarTraits< ScalarType >::magnitudeType NRM2(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx) const
OrdinalType IAMAX(const OrdinalType &n, const ScalarType *x, const OrdinalType &incx) const
Structure to contain pointers to GmresIteration state variables.
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > H_
A pure virtual class for defining the status tests for the Belos iterative solvers.
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...
void resetNumIters(int iter=0)
Reset the iteration count.
Class which defines basic traits for the operator type.
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > stest_
int getNumIters() const
Get the current iteration count.
Traits class which defines basic operations on multivectors.
bool isParameter(const std::string &name) const
GmresIterationState< ScalarType, MV > getState() const
Get the current state of the linear solver.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< const MV > Z
The current preconditioned Krylov basis (only used in flexible GMRES).
int curDim
The current dimension of the reduction.
bool is_null(const RCP< T > &p)
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
const Teuchos::RCP< OutputManager< ScalarType > > om_
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > R
The current upper-triangular matrix from the QR reduction of H.
A linear system to solve, and its associated information.
Class which describes the linear problem to be solved by the iterative solver.
This class implements the block flexible GMRES iteration, where a block Krylov subspace is constructe...
ScalarType DOT(const OrdinalType &n, const x_type *x, const OrdinalType &incx, const y_type *y, const OrdinalType &incy) const
virtual ~BlockFGmresIter()
Destructor.
void initializeGmres(GmresIterationState< ScalarType, MV > &newstate)
Initialize the solver to an iterate, providing a complete state.
bool isInitialized()
States whether the solver has been initialized or not.
MultiVecTraits< ScalarType, MV > MVT
OrdinalType numCols() const
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace.
void setStateSize()
Method for initalizing the state storage needed by block flexible GMRES.
void ROTG(ScalarType *da, ScalarType *db, rotg_c_type *c, ScalarType *s) const
const Teuchos::RCP< OrthoManager< ScalarType, MV > > ortho_
Class which defines basic traits for the operator type.
SCT::magnitudeType MagnitudeType
void updateLSQR(int dim=-1)
Method for updating QR factorization of upper Hessenberg matrix.
void setNumBlocks(int numBlocks)
Set the maximum number of blocks used by the iterative solver.
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...
Teuchos::RCP< Teuchos::SerialDenseMatrix< int, ScalarType > > R_
OrdinalType numRows() const
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > H
The current Hessenberg matrix.