Belos  Version of the Day
BelosBlockGmresIter.hpp
Go to the documentation of this file.
1 //@HEADER
2 // ************************************************************************
3 //
4 // Belos: Block Linear Solvers Package
5 // Copyright 2004 Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 //@HEADER
41 
42 #ifndef BELOS_BLOCK_GMRES_ITER_HPP
43 #define BELOS_BLOCK_GMRES_ITER_HPP
44 
49 #include "BelosConfigDefs.hpp"
50 #include "BelosTypes.hpp"
51 #include "BelosGmresIteration.hpp"
52 
53 #include "BelosLinearProblem.hpp"
54 #include "BelosMatOrthoManager.hpp"
55 #include "BelosOutputManager.hpp"
56 #include "BelosStatusTest.hpp"
57 #include "BelosOperatorTraits.hpp"
58 #include "BelosMultiVecTraits.hpp"
59 
60 #include "Teuchos_BLAS.hpp"
61 #include "Teuchos_SerialDenseMatrix.hpp"
62 #include "Teuchos_SerialDenseVector.hpp"
63 #include "Teuchos_ScalarTraits.hpp"
64 #include "Teuchos_ParameterList.hpp"
65 #include "Teuchos_TimeMonitor.hpp"
66 
80 namespace Belos {
81 
82 template<class ScalarType, class MV, class OP>
83 class BlockGmresIter : virtual public GmresIteration<ScalarType,MV,OP> {
84 
85  public:
86 
87  //
88  // Convenience typedefs
89  //
92  typedef Teuchos::ScalarTraits<ScalarType> SCT;
93  typedef typename SCT::magnitudeType MagnitudeType;
94 
96 
97 
107  BlockGmresIter( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
108  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
109  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
110  const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > &ortho,
111  Teuchos::ParameterList &params );
112 
114  virtual ~BlockGmresIter() {};
116 
117 
119 
120 
142  void iterate();
143 
166 
170  void initialize()
171  {
173  initializeGmres(empty);
174  }
175 
185  state.curDim = curDim_;
186  state.V = V_;
187  state.H = H_;
188  state.R = R_;
189  state.z = z_;
190  return state;
191  }
192 
194 
195 
197 
198 
200  int getNumIters() const { return iter_; }
201 
203  void resetNumIters( int iter = 0 ) { iter_ = iter; }
204 
207  Teuchos::RCP<const MV> getNativeResiduals( std::vector<MagnitudeType> *norms ) const;
208 
210 
215  Teuchos::RCP<MV> getCurrentUpdate() const;
216 
218 
221  void updateLSQR( int dim = -1 );
222 
224  int getCurSubspaceDim() const {
225  if (!initialized_) return 0;
226  return curDim_;
227  };
228 
230  int getMaxSubspaceDim() const { return blockSize_*numBlocks_; }
231 
233 
234 
236 
237 
239  const LinearProblem<ScalarType,MV,OP>& getProblem() const { return *lp_; }
240 
242  int getBlockSize() const { return blockSize_; }
243 
245  void setBlockSize(int blockSize) { setSize( blockSize, numBlocks_ ); }
246 
248  int getNumBlocks() const { return numBlocks_; }
249 
251  void setNumBlocks(int numBlocks) { setSize( blockSize_, numBlocks ); }
252 
259  void setSize(int blockSize, int numBlocks);
260 
262  bool isInitialized() { return initialized_; }
263 
265 
266  private:
267 
268  //
269  // Internal methods
270  //
272  void setStateSize();
273 
274  //
275  // Classes inputed through constructor that define the linear problem to be solved.
276  //
277  const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > lp_;
278  const Teuchos::RCP<OutputManager<ScalarType> > om_;
279  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > stest_;
280  const Teuchos::RCP<OrthoManager<ScalarType,MV> > ortho_;
281 
282  //
283  // Algorithmic parameters
284  //
285  // blockSize_ is the solver block size.
286  // It controls the number of vectors added to the basis on each iteration.
287  int blockSize_;
288  // numBlocks_ is the size of the allocated space for the Krylov basis, in blocks.
289  int numBlocks_;
290 
291  // Storage for QR factorization of the least squares system.
292  Teuchos::SerialDenseVector<int,ScalarType> beta, sn;
293  Teuchos::SerialDenseVector<int,MagnitudeType> cs;
294 
295  //
296  // Current solver state
297  //
298  // initialized_ specifies that the basis vectors have been initialized and the iterate() routine
299  // is capable of running; _initialize is controlled by the initialize() member method
300  // For the implications of the state of initialized_, please see documentation for initialize()
301  bool initialized_;
302 
303  // stateStorageInitialized_ specifies that the state storage has be initialized to the current
304  // blockSize_ and numBlocks_. This initialization may be postponed if the linear problem was
305  // generated without the right-hand side or solution vectors.
306  bool stateStorageInitialized_;
307 
308  // keepHessenberg_ specifies that the iteration must keep the Hessenberg matrix formed via the
309  // Arnoldi factorization and the upper triangular matrix that is the Hessenberg matrix reduced via
310  // QR factorization separate.
311  bool keepHessenberg_;
312 
313  // initHessenberg_ specifies that the iteration should reinitialize the Hessenberg matrix by zeroing
314  // out all entries before an iteration is started.
315  bool initHessenberg_;
316 
317  // Current subspace dimension, and number of iterations performed.
318  int curDim_, iter_;
319 
320  //
321  // State Storage
322  //
323  Teuchos::RCP<MV> V_;
324  //
325  // Projected matrices
326  // H_ : Projected matrix from the Krylov factorization AV = VH + FE^T
327  //
328  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H_;
329  //
330  // QR decomposition of Projected matrices for solving the least squares system HY = B.
331  // R_: Upper triangular reduction of H
332  // z_: Q applied to right-hand side of the least squares system
333  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > R_;
334  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > z_;
335 };
336 
338  // Constructor.
339  template<class ScalarType, class MV, class OP>
341  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
342  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
343  const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > &ortho,
344  Teuchos::ParameterList &params ):
345  lp_(problem),
346  om_(printer),
347  stest_(tester),
348  ortho_(ortho),
349  blockSize_(0),
350  numBlocks_(0),
351  initialized_(false),
352  stateStorageInitialized_(false),
353  keepHessenberg_(false),
354  initHessenberg_(false),
355  curDim_(0),
356  iter_(0)
357  {
358  // Find out whether we are saving the Hessenberg matrix.
359  keepHessenberg_ = params.get("Keep Hessenberg", false);
360 
361  // Find out whether we are initializing the Hessenberg matrix.
362  initHessenberg_ = params.get("Initialize Hessenberg", false);
363 
364  // Get the maximum number of blocks allowed for this Krylov subspace
365  TEUCHOS_TEST_FOR_EXCEPTION(!params.isParameter("Num Blocks"), std::invalid_argument,
366  "Belos::BlockGmresIter::constructor: mandatory parameter 'Num Blocks' is not specified.");
367  int nb = Teuchos::getParameter<int>(params, "Num Blocks");
368 
369  // Set the block size and allocate data
370  int bs = params.get("Block Size", 1);
371  setSize( bs, nb );
372  }
373 
375  // Set the block size and make necessary adjustments.
376  template <class ScalarType, class MV, class OP>
377  void BlockGmresIter<ScalarType,MV,OP>::setSize (int blockSize, int numBlocks)
378  {
379  // This routine only allocates space; it doesn't not perform any computation
380  // any change in size will invalidate the state of the solver.
381 
382  TEUCHOS_TEST_FOR_EXCEPTION(numBlocks <= 0 || blockSize <= 0, std::invalid_argument, "Belos::BlockGmresIter::setSize was passed a non-positive argument.");
383  if (blockSize == blockSize_ && numBlocks == numBlocks_) {
384  // do nothing
385  return;
386  }
387 
388  if (blockSize!=blockSize_ || numBlocks!=numBlocks_)
389  stateStorageInitialized_ = false;
390 
391  blockSize_ = blockSize;
392  numBlocks_ = numBlocks;
393 
394  initialized_ = false;
395  curDim_ = 0;
396 
397  // Use the current blockSize_ and numBlocks_ to initialize the state storage.
398  setStateSize();
399 
400  }
401 
403  // Setup the state storage.
404  template <class ScalarType, class MV, class OP>
406  {
407  if (!stateStorageInitialized_) {
408 
409  // Check if there is any multivector to clone from.
410  Teuchos::RCP<const MV> lhsMV = lp_->getLHS();
411  Teuchos::RCP<const MV> rhsMV = lp_->getRHS();
412  if (lhsMV == Teuchos::null && rhsMV == Teuchos::null) {
413  stateStorageInitialized_ = false;
414  return;
415  }
416  else {
417 
419  // blockSize*numBlocks dependent
420  //
421  int newsd = blockSize_*(numBlocks_+1);
422 
423  if (blockSize_==1) {
424  cs.resize( newsd );
425  sn.resize( newsd );
426  }
427  else {
428  beta.resize( newsd );
429  }
430 
431  // Initialize the state storage
432  TEUCHOS_TEST_FOR_EXCEPTION(blockSize_*static_cast<ptrdiff_t>(numBlocks_) > MVT::GetGlobalLength(*rhsMV),std::invalid_argument,
433  "Belos::BlockGmresIter::setStateSize(): Cannot generate a Krylov basis with dimension larger the operator!");
434 
435  // If the subspace has not be initialized before, generate it using the LHS or RHS from lp_.
436  if (V_ == Teuchos::null) {
437  // Get the multivector that is not null.
438  Teuchos::RCP<const MV> tmp = ( (rhsMV!=Teuchos::null)? rhsMV: lhsMV );
439  TEUCHOS_TEST_FOR_EXCEPTION(tmp == Teuchos::null,std::invalid_argument,
440  "Belos::BlockGmresIter::setStateSize(): linear problem does not specify multivectors to clone from.");
441  V_ = MVT::Clone( *tmp, newsd );
442  }
443  else {
444  // Generate V_ by cloning itself ONLY if more space is needed.
445  if (MVT::GetNumberVecs(*V_) < newsd) {
446  Teuchos::RCP<const MV> tmp = V_;
447  V_ = MVT::Clone( *tmp, newsd );
448  }
449  }
450 
451  // Generate R_ only if it doesn't exist, otherwise resize it.
452  if (R_ == Teuchos::null) {
453  R_ = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>() );
454  }
455  if (initHessenberg_) {
456  R_->shape( newsd, newsd-blockSize_ );
457  }
458  else {
459  if (R_->numRows() < newsd || R_->numCols() < newsd-blockSize_) {
460  R_->shapeUninitialized( newsd, newsd-blockSize_ );
461  }
462  }
463 
464  // Generate H_ only if it doesn't exist, and we are keeping the upper Hessenberg matrix.
465  if (keepHessenberg_) {
466  if (H_ == Teuchos::null) {
467  H_ = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>() );
468  }
469  if (initHessenberg_) {
470  H_->shape( newsd, newsd-blockSize_ );
471  }
472  else {
473  if (H_->numRows() < newsd || H_->numCols() < newsd-blockSize_) {
474  H_->shapeUninitialized( newsd, newsd-blockSize_ );
475  }
476  }
477  }
478  else {
479  // Point H_ and R_ at the same object.
480  H_ = R_;
481  }
482 
483  // Generate z_ only if it doesn't exist, otherwise resize it.
484  if (z_ == Teuchos::null) {
485  z_ = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>() );
486  }
487  if (z_-> numRows() < newsd || z_->numCols() < blockSize_) {
488  z_->shapeUninitialized( newsd, blockSize_ );
489  }
490 
491  // State storage has now been initialized.
492  stateStorageInitialized_ = true;
493  }
494  }
495  }
496 
498  // Get the current update from this subspace.
499  template <class ScalarType, class MV, class OP>
501  {
502  //
503  // If this is the first iteration of the Arnoldi factorization,
504  // there is no update, so return Teuchos::null.
505  //
506  Teuchos::RCP<MV> currentUpdate = Teuchos::null;
507  if (curDim_==0) {
508  return currentUpdate;
509  } else {
510  const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
511  const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
512  Teuchos::BLAS<int,ScalarType> blas;
513  currentUpdate = MVT::Clone( *V_, blockSize_ );
514  //
515  // Make a view and then copy the RHS of the least squares problem. DON'T OVERWRITE IT!
516  //
517  Teuchos::SerialDenseMatrix<int,ScalarType> y( Teuchos::Copy, *z_, curDim_, blockSize_ );
518  //
519  // Solve the least squares problem.
520  //
521  blas.TRSM( Teuchos::LEFT_SIDE, Teuchos::UPPER_TRI, Teuchos::NO_TRANS,
522  Teuchos::NON_UNIT_DIAG, curDim_, blockSize_, one,
523  R_->values(), R_->stride(), y.values(), y.stride() );
524  //
525  // Compute the current update.
526  //
527  std::vector<int> index(curDim_);
528  for ( int i=0; i<curDim_; i++ ) {
529  index[i] = i;
530  }
531  Teuchos::RCP<const MV> Vjp1 = MVT::CloneView( *V_, index );
532  MVT::MvTimesMatAddMv( one, *Vjp1, y, zero, *currentUpdate );
533  }
534  return currentUpdate;
535  }
536 
537 
539  // Get the native residuals stored in this iteration.
540  // Note: No residual std::vector will be returned by Gmres.
541  template <class ScalarType, class MV, class OP>
542  Teuchos::RCP<const MV> BlockGmresIter<ScalarType,MV,OP>::getNativeResiduals( std::vector<MagnitudeType> *norms ) const
543  {
544  //
545  // NOTE: Make sure the incoming std::vector is the correct size!
546  //
547  if ( norms && (int)norms->size() < blockSize_ )
548  norms->resize( blockSize_ );
549 
550  if (norms) {
551  Teuchos::BLAS<int,ScalarType> blas;
552  for (int j=0; j<blockSize_; j++) {
553  (*norms)[j] = blas.NRM2( blockSize_, &(*z_)(curDim_, j), 1);
554  }
555  }
556  return Teuchos::null;
557  }
558 
559 
560 
562  // Initialize this iteration object
563  template <class ScalarType, class MV, class OP>
565  {
566  // Initialize the state storage if it isn't already.
567  if (!stateStorageInitialized_)
568  setStateSize();
569 
570  TEUCHOS_TEST_FOR_EXCEPTION(!stateStorageInitialized_,std::invalid_argument,
571  "Belos::BlockGmresIter::initialize(): Cannot initialize state storage!");
572 
573  const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero(), one = Teuchos::ScalarTraits<ScalarType>::one();
574 
575  // NOTE: In BlockGmresIter, V and Z are required!!!
576  // inconsitent multivectors widths and lengths will not be tolerated, and
577  // will be treated with exceptions.
578  //
579  std::string errstr("Belos::BlockGmresIter::initialize(): Specified multivectors must have a consistent length and width.");
580 
581  if (newstate.V != Teuchos::null && newstate.z != Teuchos::null) {
582 
583  // initialize V_,z_, and curDim_
584 
585  TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.V) != MVT::GetGlobalLength(*V_),
586  std::invalid_argument, errstr );
587  TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.V) < blockSize_,
588  std::invalid_argument, errstr );
589  TEUCHOS_TEST_FOR_EXCEPTION( newstate.curDim > blockSize_*(numBlocks_+1),
590  std::invalid_argument, errstr );
591 
592  curDim_ = newstate.curDim;
593  int lclDim = MVT::GetNumberVecs(*newstate.V);
594 
595  // check size of Z
596  TEUCHOS_TEST_FOR_EXCEPTION(newstate.z->numRows() < curDim_ || newstate.z->numCols() < blockSize_, std::invalid_argument, errstr);
597 
598 
599  // copy basis vectors from newstate into V
600  if (newstate.V != V_) {
601  // only copy over the first block and print a warning.
602  if (curDim_ == 0 && lclDim > blockSize_) {
603  om_->stream(Warnings) << "Belos::BlockGmresIter::initialize(): the solver was initialized with a kernel of " << lclDim << std::endl
604  << "The block size however is only " << blockSize_ << std::endl
605  << "The last " << lclDim - blockSize_ << " vectors will be discarded." << std::endl;
606  }
607  std::vector<int> nevind(curDim_+blockSize_);
608  for (int i=0; i<curDim_+blockSize_; i++) nevind[i] = i;
609  Teuchos::RCP<const MV> newV = MVT::CloneView( *newstate.V, nevind );
610  Teuchos::RCP<MV> lclV = MVT::CloneViewNonConst( *V_, nevind );
611  MVT::MvAddMv( one, *newV, zero, *newV, *lclV );
612 
613  // done with local pointers
614  lclV = Teuchos::null;
615  }
616 
617  // put data into z_, make sure old information is not still hanging around.
618  if (newstate.z != z_) {
619  z_->putScalar();
620  Teuchos::SerialDenseMatrix<int,ScalarType> newZ(Teuchos::View,*newstate.z,curDim_+blockSize_,blockSize_);
621  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lclZ;
622  lclZ = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*z_,curDim_+blockSize_,blockSize_) );
623  lclZ->assign(newZ);
624 
625  // done with local pointers
626  lclZ = Teuchos::null;
627  }
628 
629  }
630  else {
631 
632  TEUCHOS_TEST_FOR_EXCEPTION(newstate.V == Teuchos::null,std::invalid_argument,
633  "Belos::BlockGmresIter::initialize(): BlockGmresStateIterState does not have initial kernel V_0.");
634 
635  TEUCHOS_TEST_FOR_EXCEPTION(newstate.z == Teuchos::null,std::invalid_argument,
636  "Belos::BlockGmresIter::initialize(): BlockGmresStateIterState does not have initial norms z_0.");
637  }
638 
639  // the solver is initialized
640  initialized_ = true;
641 
642  /*
643  if (om_->isVerbosity( Debug ) ) {
644  // Check almost everything here
645  CheckList chk;
646  chk.checkV = true;
647  chk.checkArn = true;
648  chk.checkAux = true;
649  om_->print( Debug, accuracyCheck(chk, ": after initialize()") );
650  }
651  */
652 
653  }
654 
655 
657  // Iterate until the status test informs us we should stop.
658  template <class ScalarType, class MV, class OP>
660  {
661  //
662  // Allocate/initialize data structures
663  //
664  if (initialized_ == false) {
665  initialize();
666  }
667 
668  // Compute the current search dimension.
669  int searchDim = blockSize_*numBlocks_;
670 
672  // iterate until the status test tells us to stop.
673  //
674  // also break if our basis is full
675  //
676  while (stest_->checkStatus(this) != Passed && curDim_+blockSize_ <= searchDim) {
677 
678  iter_++;
679 
680  // F can be found at the curDim_ block, but the next block is at curDim_ + blockSize_.
681  int lclDim = curDim_ + blockSize_;
682 
683  // Get the current part of the basis.
684  std::vector<int> curind(blockSize_);
685  for (int i=0; i<blockSize_; i++) { curind[i] = lclDim + i; }
686  Teuchos::RCP<MV> Vnext = MVT::CloneViewNonConst(*V_,curind);
687 
688  // Get a view of the previous vectors.
689  // This is used for orthogonalization and for computing V^H K H
690  for (int i=0; i<blockSize_; i++) { curind[i] = curDim_ + i; }
691  Teuchos::RCP<const MV> Vprev = MVT::CloneView(*V_,curind);
692 
693  // Compute the next std::vector in the Krylov basis: Vnext = Op*Vprev
694  lp_->apply(*Vprev,*Vnext);
695  Vprev = Teuchos::null;
696 
697  // Remove all previous Krylov basis vectors from Vnext
698  // Get a view of all the previous vectors
699  std::vector<int> prevind(lclDim);
700  for (int i=0; i<lclDim; i++) { prevind[i] = i; }
701  Vprev = MVT::CloneView(*V_,prevind);
702  Teuchos::Array<Teuchos::RCP<const MV> > AVprev(1, Vprev);
703 
704  // Get a view of the part of the Hessenberg matrix needed to hold the ortho coeffs.
705  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
706  subH = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>
707  ( Teuchos::View,*H_,lclDim,blockSize_,0,curDim_ ) );
708  Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > AsubH;
709  AsubH.append( subH );
710 
711  // Get a view of the part of the Hessenberg matrix needed to hold the norm coeffs.
712  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
713  subH2 = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>
714  ( Teuchos::View,*H_,blockSize_,blockSize_,lclDim,curDim_ ) );
715  subH2->putScalar(); // Initialize subdiagonal to zero
716  int rank = ortho_->projectAndNormalize(*Vnext,AsubH,subH2,AVprev);
717 
718  // Copy over the coefficients if we are saving the upper Hessenberg matrix,
719  // just in case we run into an error.
720  if (keepHessenberg_) {
721  // Copy over the orthogonalization coefficients.
722  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
723  subR = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>
724  ( Teuchos::View,*R_,lclDim,blockSize_,0,curDim_ ) );
725  subR->assign(*subH);
726 
727  // Copy over the lower diagonal block of the Hessenberg matrix.
728  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> >
729  subR2 = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>
730  ( Teuchos::View,*R_,blockSize_,blockSize_,lclDim,curDim_ ) );
731  subR2->assign(*subH2);
732  }
733 
734  TEUCHOS_TEST_FOR_EXCEPTION(rank != blockSize_,GmresIterationOrthoFailure,
735  "Belos::BlockGmresIter::iterate(): couldn't generate basis of full rank.");
736  //
737  // V has been extended, and H has been extended.
738  //
739  // Update the QR factorization of the upper Hessenberg matrix
740  //
741  updateLSQR();
742  //
743  // Update basis dim and release all pointers.
744  //
745  Vnext = Teuchos::null;
746  curDim_ += blockSize_;
747  //
748  /*
749  // When required, monitor some orthogonalities
750  if (om_->isVerbosity( Debug ) ) {
751  // Check almost everything here
752  CheckList chk;
753  chk.checkV = true;
754  chk.checkArn = true;
755  om_->print( Debug, accuracyCheck(chk, ": after local update") );
756  }
757  else if (om_->isVerbosity( OrthoDetails ) ) {
758  CheckList chk;
759  chk.checkV = true;
760  om_->print( OrthoDetails, accuracyCheck(chk, ": after local update") );
761  }
762  */
763 
764  } // end while (statusTest == false)
765 
766  }
767 
768 
769  template<class ScalarType, class MV, class OP>
771  {
772  int i, j, maxidx;
773  ScalarType sigma, mu, vscale, maxelem;
774  const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero(), one = Teuchos::ScalarTraits<ScalarType>::one();
775 
776  // Get correct dimension based on input "dim"
777  // Remember that ortho failures result in an exit before updateLSQR() is called.
778  // Therefore, it is possible that dim == curDim_.
779  int curDim = curDim_;
780  if (dim >= curDim_ && dim < getMaxSubspaceDim()) {
781  curDim = dim;
782  }
783 
784  Teuchos::BLAS<int, ScalarType> blas;
785  //
786  // Apply previous transformations and compute new transformation to reduce upper-Hessenberg
787  // system to upper-triangular form.
788  //
789  if (blockSize_ == 1) {
790  //
791  // QR factorization of Least-Squares system with Givens rotations
792  //
793  for (i=0; i<curDim; i++) {
794  //
795  // Apply previous Givens rotations to new column of Hessenberg matrix
796  //
797  blas.ROT( 1, &(*R_)(i,curDim), 1, &(*R_)(i+1, curDim), 1, &cs[i], &sn[i] );
798  }
799  //
800  // Calculate new Givens rotation
801  //
802  blas.ROTG( &(*R_)(curDim,curDim), &(*R_)(curDim+1,curDim), &cs[curDim], &sn[curDim] );
803  (*R_)(curDim+1,curDim) = zero;
804  //
805  // Update RHS w/ new transformation
806  //
807  blas.ROT( 1, &(*z_)(curDim,0), 1, &(*z_)(curDim+1,0), 1, &cs[curDim], &sn[curDim] );
808  }
809  else {
810  //
811  // QR factorization of Least-Squares system with Householder reflectors
812  //
813  for (j=0; j<blockSize_; j++) {
814  //
815  // Apply previous Householder reflectors to new block of Hessenberg matrix
816  //
817  for (i=0; i<curDim+j; i++) {
818  sigma = blas.DOT( blockSize_, &(*R_)(i+1,i), 1, &(*R_)(i+1,curDim+j), 1);
819  sigma += (*R_)(i,curDim+j);
820  sigma *= beta[i];
821  blas.AXPY(blockSize_, ScalarType(-sigma), &(*R_)(i+1,i), 1, &(*R_)(i+1,curDim+j), 1);
822  (*R_)(i,curDim+j) -= sigma;
823  }
824  //
825  // Compute new Householder reflector
826  //
827  maxidx = blas.IAMAX( blockSize_+1, &(*R_)(curDim+j,curDim+j), 1 );
828  maxelem = (*R_)(curDim+j+maxidx-1,curDim+j);
829  for (i=0; i<blockSize_+1; i++)
830  (*R_)(curDim+j+i,curDim+j) /= maxelem;
831  sigma = blas.DOT( blockSize_, &(*R_)(curDim+j+1,curDim+j), 1,
832  &(*R_)(curDim+j+1,curDim+j), 1 );
833  if (sigma == zero) {
834  beta[curDim + j] = zero;
835  } else {
836  mu = Teuchos::ScalarTraits<ScalarType>::squareroot((*R_)(curDim+j,curDim+j)*(*R_)(curDim+j,curDim+j)+sigma);
837  if ( Teuchos::ScalarTraits<ScalarType>::real((*R_)(curDim+j,curDim+j))
838  < Teuchos::ScalarTraits<MagnitudeType>::zero() ) {
839  vscale = (*R_)(curDim+j,curDim+j) - mu;
840  } else {
841  vscale = -sigma / ((*R_)(curDim+j,curDim+j) + mu);
842  }
843  beta[curDim+j] = Teuchos::as<ScalarType>(2)*one*vscale*vscale/(sigma + vscale*vscale);
844  (*R_)(curDim+j,curDim+j) = maxelem*mu;
845  for (i=0; i<blockSize_; i++)
846  (*R_)(curDim+j+1+i,curDim+j) /= vscale;
847  }
848  //
849  // Apply new Householder reflector to rhs
850  //
851  for (i=0; i<blockSize_; i++) {
852  sigma = blas.DOT( blockSize_, &(*R_)(curDim+j+1,curDim+j),
853  1, &(*z_)(curDim+j+1,i), 1);
854  sigma += (*z_)(curDim+j,i);
855  sigma *= beta[curDim+j];
856  blas.AXPY(blockSize_, ScalarType(-sigma), &(*R_)(curDim+j+1,curDim+j),
857  1, &(*z_)(curDim+j+1,i), 1);
858  (*z_)(curDim+j,i) -= sigma;
859  }
860  }
861  } // end if (blockSize_ == 1)
862 
863  // If the least-squares problem is updated wrt "dim" then update the curDim_.
864  if (dim >= curDim_ && dim < getMaxSubspaceDim()) {
865  curDim_ = dim + blockSize_;
866  }
867 
868  } // end updateLSQR()
869 
870 } // end Belos namespace
871 
872 #endif /* BELOS_BLOCK_GMRES_ITER_HPP */
Belos::BlockGmresIter::BlockGmresIter
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 &params)
BlockGmresIter constructor with linear problem, solver utilities, and parameter list of solver option...
Definition: BelosBlockGmresIter.hpp:340
BelosConfigDefs.hpp
Belos header file which uses auto-configuration information to include necessary C++ headers.
Belos::BlockGmresIter::updateLSQR
void updateLSQR(int dim=-1)
Method for updating QR factorization of upper Hessenberg matrix.
Definition: BelosBlockGmresIter.hpp:770
Belos::BlockGmresIter::getProblem
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
Definition: BelosBlockGmresIter.hpp:239
Belos::BlockGmresIter::iterate
void iterate()
This method performs block Gmres iterations until the status test indicates the need to stop or an er...
Definition: BelosBlockGmresIter.hpp:659
Belos::GmresIterationState::z
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > z
The current right-hand side of the least squares system RY = Z.
Definition: BelosGmresIteration.hpp:88
Belos::GmresIterationState::V
Teuchos::RCP< const MV > V
The current Krylov basis.
Definition: BelosGmresIteration.hpp:71
Belos::BlockGmresIter::getMaxSubspaceDim
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace.
Definition: BelosBlockGmresIter.hpp:230
Belos::OperatorTraits
Class which defines basic traits for the operator type.
Definition: BelosOperatorTraits.hpp:109
Belos::Warnings
Definition: BelosTypes.hpp:259
Belos::OutputManager
Belos's basic output manager for sending information of select verbosity levels to the appropriate ou...
Definition: BelosIteration.hpp:64
BelosLinearProblem.hpp
Class which describes the linear problem to be solved by the iterative solver.
BelosStatusTest.hpp
Pure virtual base class for defining the status testing capabilities of Belos.
Belos::BlockGmresIter::MagnitudeType
SCT::magnitudeType MagnitudeType
Definition: BelosBlockGmresIter.hpp:93
Belos::BlockGmresIter::resetNumIters
void resetNumIters(int iter=0)
Reset the iteration count.
Definition: BelosBlockGmresIter.hpp:203
Belos::BlockGmresIter::isInitialized
bool isInitialized()
States whether the solver has been initialized or not.
Definition: BelosBlockGmresIter.hpp:262
Belos::Passed
Definition: BelosTypes.hpp:188
Belos::LinearProblem
A linear system to solve, and its associated information.
Definition: BelosIteration.hpp:61
Belos::BlockGmresIter::MVT
MultiVecTraits< ScalarType, MV > MVT
Definition: BelosBlockGmresIter.hpp:90
Belos::BlockGmresIter::~BlockGmresIter
virtual ~BlockGmresIter()
Destructor.
Definition: BelosBlockGmresIter.hpp:114
Belos::GmresIterationState::R
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > R
The current upper-triangular matrix from the QR reduction of H.
Definition: BelosGmresIteration.hpp:85
Belos::GmresIterationOrthoFailure
GmresIterationOrthoFailure is thrown when the GmresIteration object is unable to compute independent ...
Definition: BelosGmresIteration.hpp:123
BelosOutputManager.hpp
Class which manages the output and verbosity of the Belos solvers.
Belos::BlockGmresIter::setSize
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...
Definition: BelosBlockGmresIter.hpp:377
Belos::BlockGmresIter::getNativeResiduals
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *norms) const
Get the norms of the residuals native to the solver.
Definition: BelosBlockGmresIter.hpp:542
Belos
Definition: Belos_Details_EBelosSolverType.cpp:45
Belos::BlockGmresIter::OPT
OperatorTraits< ScalarType, MV, OP > OPT
Definition: BelosBlockGmresIter.hpp:91
Belos::BlockGmresIter::SCT
Teuchos::ScalarTraits< ScalarType > SCT
Definition: BelosBlockGmresIter.hpp:92
Belos::BlockGmresIter::getCurSubspaceDim
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current solution to the linear problem.
Definition: BelosBlockGmresIter.hpp:224
Belos::GmresIteration
Definition: BelosGmresIteration.hpp:141
BelosOperatorTraits.hpp
Class which defines basic traits for the operator type.
Belos::BlockGmresIter::getNumBlocks
int getNumBlocks() const
Get the maximum number of blocks used by the iterative solver in solving this linear problem.
Definition: BelosBlockGmresIter.hpp:248
BelosMatOrthoManager.hpp
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Belos::GmresIterationState::curDim
int curDim
The current dimension of the reduction.
Definition: BelosGmresIteration.hpp:68
Belos::MatOrthoManager
Belos's templated virtual class for providing routines for orthogonalization and orthonormzalition of...
Definition: BelosIteration.hpp:70
Belos::BlockGmresIter::getNumIters
int getNumIters() const
Get the current iteration count.
Definition: BelosBlockGmresIter.hpp:200
Belos::StatusTest
A pure virtual class for defining the status tests for the Belos iterative solvers.
Definition: BelosIteration.hpp:67
Belos::BlockGmresIter::getCurrentUpdate
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
Definition: BelosBlockGmresIter.hpp:500
Belos::BlockGmresIter
This class implements the block GMRES iteration, where a block Krylov subspace is constructed....
Definition: BelosBlockGmresIter.hpp:83
Belos::BlockGmresIter::getState
GmresIterationState< ScalarType, MV > getState() const
Get the current state of the linear solver.
Definition: BelosBlockGmresIter.hpp:183
BelosMultiVecTraits.hpp
Declaration of basic traits for the multivector type.
BelosTypes.hpp
Collection of types and exceptions used within the Belos solvers.
Belos::GmresIterationState
Structure to contain pointers to GmresIteration state variables.
Definition: BelosGmresIteration.hpp:63
BelosGmresIteration.hpp
Pure virtual base class which augments the basic interface for a Gmres linear solver iteration.
Belos::BlockGmresIter::getBlockSize
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
Definition: BelosBlockGmresIter.hpp:242
Belos::BlockGmresIter::setNumBlocks
void setNumBlocks(int numBlocks)
Set the maximum number of blocks used by the iterative solver.
Definition: BelosBlockGmresIter.hpp:251
Belos::BlockGmresIter::initializeGmres
void initializeGmres(GmresIterationState< ScalarType, MV > &newstate)
Initialize the solver to an iterate, providing a complete state.
Definition: BelosBlockGmresIter.hpp:564
Belos::MultiVecTraits
Traits class which defines basic operations on multivectors.
Definition: BelosMultiVecTraits.hpp:129
Belos::GmresIterationState::H
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > H
The current Hessenberg matrix.
Definition: BelosGmresIteration.hpp:82
Belos::BlockGmresIter::initialize
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
Definition: BelosBlockGmresIter.hpp:170
Belos::BlockGmresIter::setBlockSize
void setBlockSize(int blockSize)
Set the blocksize.
Definition: BelosBlockGmresIter.hpp:245

Generated on Thu Feb 27 2020 16:06:46 for Belos by doxygen 1.8.16