Belos  Version of the Day
BelosPseudoBlockGmresIter.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_PSEUDO_BLOCK_GMRES_ITER_HPP
43 #define BELOS_PSEUDO_BLOCK_GMRES_ITER_HPP
44 
49 #include "BelosConfigDefs.hpp"
50 #include "BelosTypes.hpp"
51 #include "BelosIteration.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 
83 
84 
89  template <class ScalarType, class MV>
91 
92  typedef Teuchos::ScalarTraits<ScalarType> SCT;
93  typedef typename SCT::magnitudeType MagnitudeType;
94 
99  int curDim;
101  std::vector<Teuchos::RCP<const MV> > V;
107  std::vector<Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> > > H;
109  std::vector<Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> > > R;
111  std::vector<Teuchos::RCP<const Teuchos::SerialDenseVector<int,ScalarType> > > Z;
113  std::vector<Teuchos::RCP<const Teuchos::SerialDenseVector<int,ScalarType> > > sn;
114  std::vector<Teuchos::RCP<const Teuchos::SerialDenseVector<int,MagnitudeType> > > cs;
115 
117  H(0), R(0), Z(0),
118  sn(0), cs(0)
119  {}
120  };
121 
123 
124 
138  PseudoBlockGmresIterInitFailure(const std::string& what_arg) : BelosError(what_arg)
139  {}};
140 
148  PseudoBlockGmresIterOrthoFailure(const std::string& what_arg) : BelosError(what_arg)
149  {}};
150 
152 
153 
154  template<class ScalarType, class MV, class OP>
155  class PseudoBlockGmresIter : virtual public Iteration<ScalarType,MV,OP> {
156 
157  public:
158 
159  //
160  // Convenience typedefs
161  //
164  typedef Teuchos::ScalarTraits<ScalarType> SCT;
165  typedef typename SCT::magnitudeType MagnitudeType;
166 
168 
169 
178  PseudoBlockGmresIter( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
179  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
180  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
181  const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > &ortho,
182  Teuchos::ParameterList &params );
183 
185  virtual ~PseudoBlockGmresIter() {};
187 
188 
190 
191 
213  void iterate();
214 
237 
241  void initialize()
242  {
244  initialize(empty);
245  }
246 
256  state.curDim = curDim_;
257  state.V.resize(numRHS_);
258  state.H.resize(numRHS_);
259  state.Z.resize(numRHS_);
260  state.sn.resize(numRHS_);
261  state.cs.resize(numRHS_);
262  for (int i=0; i<numRHS_; ++i) {
263  state.V[i] = V_[i];
264  state.H[i] = H_[i];
265  state.Z[i] = Z_[i];
266  state.sn[i] = sn_[i];
267  state.cs[i] = cs_[i];
268  }
269  return state;
270  }
271 
273 
274 
276 
277 
279  int getNumIters() const { return iter_; }
280 
282  void resetNumIters( int iter = 0 ) { iter_ = iter; }
283 
301  Teuchos::RCP<const MV> getNativeResiduals( std::vector<MagnitudeType> *norms ) const;
302 
304 
309  Teuchos::RCP<MV> getCurrentUpdate() const;
310 
312 
315  void updateLSQR( int dim = -1 );
316 
318  int getCurSubspaceDim() const {
319  if (!initialized_) return 0;
320  return curDim_;
321  };
322 
324  int getMaxSubspaceDim() const { return numBlocks_; }
325 
327 
328 
330 
331 
333  const LinearProblem<ScalarType,MV,OP>& getProblem() const { return *lp_; }
334 
336  int getBlockSize() const { return 1; }
337 
339  void setBlockSize(int blockSize) {
340  TEUCHOS_TEST_FOR_EXCEPTION(blockSize!=1,std::invalid_argument,
341  "Belos::PseudoBlockGmresIter::setBlockSize(): Cannot use a block size that is not one.");
342  }
343 
345  int getNumBlocks() const { return numBlocks_; }
346 
348  void setNumBlocks(int numBlocks);
349 
351  bool isInitialized() { return initialized_; }
352 
354 
355  private:
356 
357  //
358  // Classes inputed through constructor that define the linear problem to be solved.
359  //
360  const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > lp_;
361  const Teuchos::RCP<OutputManager<ScalarType> > om_;
362  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > stest_;
363  const Teuchos::RCP<OrthoManager<ScalarType,MV> > ortho_;
364 
365  //
366  // Algorithmic parameters
367  //
368  // numRHS_ is the current number of linear systems being solved.
369  int numRHS_;
370  // numBlocks_ is the size of the allocated space for the Krylov basis, in blocks.
371  int numBlocks_;
372 
373  // Storage for QR factorization of the least squares system.
374  std::vector<Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > > sn_;
375  std::vector<Teuchos::RCP<Teuchos::SerialDenseVector<int,MagnitudeType> > > cs_;
376 
377  // Pointers to a work vector used to improve aggregate performance.
378  Teuchos::RCP<MV> U_vec_, AU_vec_;
379 
380  // Pointers to the current right-hand side and solution multivecs being solved for.
381  Teuchos::RCP<MV> cur_block_rhs_, cur_block_sol_;
382 
383  //
384  // Current solver state
385  //
386  // initialized_ specifies that the basis vectors have been initialized and the iterate() routine
387  // is capable of running; _initialize is controlled by the initialize() member method
388  // For the implications of the state of initialized_, please see documentation for initialize()
389  bool initialized_;
390 
391  // Current subspace dimension, and number of iterations performed.
392  int curDim_, iter_;
393 
394  //
395  // State Storage
396  //
397  std::vector<Teuchos::RCP<MV> > V_;
398  //
399  // Projected matrices
400  // H_ : Projected matrix from the Krylov factorization AV = VH + FE^T
401  //
402  std::vector<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > H_;
403  //
404  // QR decomposition of Projected matrices for solving the least squares system HY = B.
405  // R_: Upper triangular reduction of H
406  // Z_: Q applied to right-hand side of the least squares system
407  std::vector<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > R_;
408  std::vector<Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > > Z_;
409  };
410 
412  // Constructor.
413  template<class ScalarType, class MV, class OP>
415  const Teuchos::RCP<OutputManager<ScalarType> > &printer,
416  const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
417  const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > &ortho,
418  Teuchos::ParameterList &params ):
419  lp_(problem),
420  om_(printer),
421  stest_(tester),
422  ortho_(ortho),
423  numRHS_(0),
424  numBlocks_(0),
425  initialized_(false),
426  curDim_(0),
427  iter_(0)
428  {
429  // Get the maximum number of blocks allowed for each Krylov subspace
430  TEUCHOS_TEST_FOR_EXCEPTION(!params.isParameter("Num Blocks"), std::invalid_argument,
431  "Belos::PseudoBlockGmresIter::constructor: mandatory parameter 'Num Blocks' is not specified.");
432  int nb = Teuchos::getParameter<int>(params, "Num Blocks");
433 
434  setNumBlocks( nb );
435  }
436 
438  // Set the block size and make necessary adjustments.
439  template <class ScalarType, class MV, class OP>
441  {
442  // This routine only allocates space; it doesn't not perform any computation
443  // any change in size will invalidate the state of the solver.
444 
445  TEUCHOS_TEST_FOR_EXCEPTION(numBlocks <= 0, std::invalid_argument, "Belos::PseudoBlockGmresIter::setNumBlocks was passed a non-positive argument.");
446 
447  numBlocks_ = numBlocks;
448  curDim_ = 0;
449 
450  initialized_ = false;
451  }
452 
454  // Get the current update from this subspace.
455  template <class ScalarType, class MV, class OP>
457  {
458  //
459  // If this is the first iteration of the Arnoldi factorization,
460  // there is no update, so return Teuchos::null.
461  //
462  Teuchos::RCP<MV> currentUpdate = Teuchos::null;
463  if (curDim_==0) {
464  return currentUpdate;
465  } else {
466  currentUpdate = MVT::Clone(*(V_[0]), numRHS_);
467  std::vector<int> index(1), index2(curDim_);
468  for (int i=0; i<curDim_; ++i) {
469  index2[i] = i;
470  }
471  const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
472  const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
473  Teuchos::BLAS<int,ScalarType> blas;
474 
475  for (int i=0; i<numRHS_; ++i) {
476  index[0] = i;
477  Teuchos::RCP<MV> cur_block_copy_vec = MVT::CloneViewNonConst( *currentUpdate, index );
478  //
479  // Make a view and then copy the RHS of the least squares problem. DON'T OVERWRITE IT!
480  //
481  Teuchos::SerialDenseVector<int,ScalarType> y( Teuchos::Copy, Z_[i]->values(), curDim_ );
482  //
483  // Solve the least squares problem and compute current solutions.
484  //
485  blas.TRSM( Teuchos::LEFT_SIDE, Teuchos::UPPER_TRI, Teuchos::NO_TRANS,
486  Teuchos::NON_UNIT_DIAG, curDim_, 1, one,
487  H_[i]->values(), H_[i]->stride(), y.values(), y.stride() );
488 
489  Teuchos::RCP<const MV> Vjp1 = MVT::CloneView( *V_[i], index2 );
490  MVT::MvTimesMatAddMv( one, *Vjp1, y, zero, *cur_block_copy_vec );
491  }
492  }
493  return currentUpdate;
494  }
495 
496 
498  // Get the native residuals stored in this iteration.
499  // Note: No residual vector will be returned by Gmres.
500  template <class ScalarType, class MV, class OP>
501  Teuchos::RCP<const MV>
503  getNativeResiduals (std::vector<MagnitudeType> *norms) const
504  {
505  typedef typename Teuchos::ScalarTraits<ScalarType> STS;
506 
507  if (norms)
508  { // Resize the incoming std::vector if necessary. The type
509  // cast avoids the compiler warning resulting from a signed /
510  // unsigned integer comparison.
511  if (static_cast<int> (norms->size()) < numRHS_)
512  norms->resize (numRHS_);
513 
514  Teuchos::BLAS<int, ScalarType> blas;
515  for (int j = 0; j < numRHS_; ++j)
516  {
517  const ScalarType curNativeResid = (*Z_[j])(curDim_);
518  (*norms)[j] = STS::magnitude (curNativeResid);
519  }
520  }
521  return Teuchos::null;
522  }
523 
524 
525  template <class ScalarType, class MV, class OP>
526  void
529  {
530  using Teuchos::RCP;
531 
532  // (Re)set the number of right-hand sides, by interrogating the
533  // current LinearProblem to solve.
534  this->numRHS_ = MVT::GetNumberVecs (*(lp_->getCurrLHSVec()));
535 
536  // NOTE: In PseudoBlockGmresIter, V and Z are required!!!
537  // Inconsistent multivectors widths and lengths will not be tolerated, and
538  // will be treated with exceptions.
539  //
540  std::string errstr ("Belos::PseudoBlockGmresIter::initialize(): "
541  "Specified multivectors must have a consistent "
542  "length and width.");
543 
544  // Check that newstate has V and Z arrays with nonzero length.
545  TEUCHOS_TEST_FOR_EXCEPTION((int)newstate.V.size()==0 || (int)newstate.Z.size()==0,
546  std::invalid_argument,
547  "Belos::PseudoBlockGmresIter::initialize(): "
548  "V and/or Z was not specified in the input state; "
549  "the V and/or Z arrays have length zero.");
550 
551  // In order to create basis multivectors, we have to clone them
552  // from some already existing multivector. We require that at
553  // least one of the right-hand side B and left-hand side X in the
554  // LinearProblem be non-null. Thus, we can clone from either B or
555  // X. We prefer to close from B, since B is in the range of the
556  // operator A and the basis vectors should also be in the range of
557  // A (the first basis vector is a scaled residual vector).
558  // However, if B is not given, we will try our best by cloning
559  // from X.
560  RCP<const MV> lhsMV = lp_->getLHS();
561  RCP<const MV> rhsMV = lp_->getRHS();
562 
563  // If the right-hand side is null, we make do with the left-hand
564  // side, otherwise we use the right-hand side.
565  RCP<const MV> vectorInBasisSpace = rhsMV.is_null() ? lhsMV : rhsMV;
566  //RCP<const MV> tmp = ( (rhsMV!=Teuchos::null)? rhsMV: lhsMV );
567 
568  TEUCHOS_TEST_FOR_EXCEPTION(vectorInBasisSpace.is_null(),
569  std::invalid_argument,
570  "Belos::PseudoBlockGmresIter::initialize(): "
571  "The linear problem to solve does not specify multi"
572  "vectors from which we can clone basis vectors. The "
573  "right-hand side(s), left-hand side(s), or both should "
574  "be nonnull.");
575 
576  // Check the new dimension is not more that the maximum number of
577  // allowable blocks.
578  TEUCHOS_TEST_FOR_EXCEPTION(newstate.curDim > numBlocks_+1,
579  std::invalid_argument,
580  errstr);
581  curDim_ = newstate.curDim;
582 
583  // Initialize the state storage. If the subspace has not be
584  // initialized before, generate it using the right-hand side or
585  // left-hand side from the LinearProblem lp_ to solve.
586  V_.resize(numRHS_);
587  for (int i=0; i<numRHS_; ++i) {
588  // Create a new vector if we need to. We "need to" if the
589  // current vector V_[i] is null, or if it doesn't have enough
590  // columns.
591  if (V_[i].is_null() || MVT::GetNumberVecs(*V_[i]) < numBlocks_ + 1) {
592  V_[i] = MVT::Clone (*vectorInBasisSpace, numBlocks_ + 1);
593  }
594  // Check that the newstate vector newstate.V[i] has dimensions
595  // consistent with those of V_[i].
596  TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.V[i]) != MVT::GetGlobalLength(*V_[i]),
597  std::invalid_argument, errstr );
598  TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.V[i]) < newstate.curDim,
599  std::invalid_argument, errstr );
600  //
601  // If newstate.V[i] and V_[i] are not identically the same
602  // vector, then copy newstate.V[i] into V_[i].
603  //
604  int lclDim = MVT::GetNumberVecs(*newstate.V[i]);
605  if (newstate.V[i] != V_[i]) {
606  // Only copy over the first block and print a warning.
607  if (curDim_ == 0 && lclDim > 1) {
608  om_->stream(Warnings)
609  << "Belos::PseudoBlockGmresIter::initialize(): the solver was "
610  << "initialized with a kernel of " << lclDim
611  << std::endl
612  << "The block size however is only " << 1
613  << std::endl
614  << "The last " << lclDim - 1 << " vectors will be discarded."
615  << std::endl;
616  }
617  std::vector<int> nevind (curDim_ + 1);
618  for (int j = 0; j < curDim_ + 1; ++j)
619  nevind[j] = j;
620 
621  RCP<const MV> newV = MVT::CloneView (*newstate.V[i], nevind);
622  RCP<MV> lclV = MVT::CloneViewNonConst( *V_[i], nevind );
623  const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
624  const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
625  MVT::MvAddMv (one, *newV, zero, *newV, *lclV);
626 
627  // Done with local pointers
628  lclV = Teuchos::null;
629  }
630  }
631 
632 
633  // Check size of Z
634  Z_.resize(numRHS_);
635  for (int i=0; i<numRHS_; ++i) {
636  // Create a vector if we need to.
637  if (Z_[i] == Teuchos::null) {
638  Z_[i] = Teuchos::rcp( new Teuchos::SerialDenseVector<int,ScalarType>() );
639  }
640  if (Z_[i]->length() < numBlocks_+1) {
641  Z_[i]->shapeUninitialized(numBlocks_+1, 1);
642  }
643 
644  // Check that the newstate vector is consistent.
645  TEUCHOS_TEST_FOR_EXCEPTION(newstate.Z[i]->numRows() < curDim_, std::invalid_argument, errstr);
646 
647  // Put data into Z_, make sure old information is not still hanging around.
648  if (newstate.Z[i] != Z_[i]) {
649  if (curDim_==0)
650  Z_[i]->putScalar();
651 
652  Teuchos::SerialDenseVector<int,ScalarType> newZ(Teuchos::View,newstate.Z[i]->values(),curDim_+1);
653  Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > lclZ;
654  lclZ = Teuchos::rcp( new Teuchos::SerialDenseVector<int,ScalarType>(Teuchos::View,Z_[i]->values(),curDim_+1) );
655  lclZ->assign(newZ);
656 
657  // Done with local pointers
658  lclZ = Teuchos::null;
659  }
660  }
661 
662 
663  // Check size of H
664  H_.resize(numRHS_);
665  for (int i=0; i<numRHS_; ++i) {
666  // Create a matrix if we need to.
667  if (H_[i] == Teuchos::null) {
668  H_[i] = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>() );
669  }
670  if (H_[i]->numRows() < numBlocks_+1 || H_[i]->numCols() < numBlocks_) {
671  H_[i]->shapeUninitialized(numBlocks_+1, numBlocks_);
672  }
673 
674  // Put data into H_ if it exists, make sure old information is not still hanging around.
675  if ((int)newstate.H.size() == numRHS_) {
676 
677  // Check that the newstate matrix is consistent.
678  TEUCHOS_TEST_FOR_EXCEPTION((newstate.H[i]->numRows() < curDim_ || newstate.H[i]->numCols() < curDim_), std::invalid_argument,
679  "Belos::PseudoBlockGmresIter::initialize(): Specified Hessenberg matrices must have a consistent size to the current subspace dimension");
680 
681  if (newstate.H[i] != H_[i]) {
682  // H_[i]->putScalar();
683 
684  Teuchos::SerialDenseMatrix<int,ScalarType> newH(Teuchos::View,*newstate.H[i],curDim_+1, curDim_);
685  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > lclH;
686  lclH = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(Teuchos::View,*H_[i],curDim_+1, curDim_) );
687  lclH->assign(newH);
688 
689  // Done with local pointers
690  lclH = Teuchos::null;
691  }
692  }
693  }
694 
696  // Reinitialize storage for least squares solve
697  //
698  cs_.resize(numRHS_);
699  sn_.resize(numRHS_);
700 
701  // Copy over rotation angles if they exist
702  if ((int)newstate.cs.size() == numRHS_ && (int)newstate.sn.size() == numRHS_) {
703  for (int i=0; i<numRHS_; ++i) {
704  if (cs_[i] != newstate.cs[i])
705  cs_[i] = Teuchos::rcp( new Teuchos::SerialDenseVector<int,MagnitudeType>(*newstate.cs[i]) );
706  if (sn_[i] != newstate.sn[i])
707  sn_[i] = Teuchos::rcp( new Teuchos::SerialDenseVector<int,ScalarType>(*newstate.sn[i]) );
708  }
709  }
710 
711  // Resize or create the vectors as necessary
712  for (int i=0; i<numRHS_; ++i) {
713  if (cs_[i] == Teuchos::null)
714  cs_[i] = Teuchos::rcp( new Teuchos::SerialDenseVector<int,MagnitudeType>(numBlocks_+1) );
715  else
716  cs_[i]->resize(numBlocks_+1);
717  if (sn_[i] == Teuchos::null)
718  sn_[i] = Teuchos::rcp( new Teuchos::SerialDenseVector<int,ScalarType>(numBlocks_+1) );
719  else
720  sn_[i]->resize(numBlocks_+1);
721  }
722 
723  // the solver is initialized
724  initialized_ = true;
725 
726  /*
727  if (om_->isVerbosity( Debug ) ) {
728  // Check almost everything here
729  CheckList chk;
730  chk.checkV = true;
731  chk.checkArn = true;
732  chk.checkAux = true;
733  om_->print( Debug, accuracyCheck(chk, ": after initialize()") );
734  }
735  */
736 
737  }
738 
739 
741  // Iterate until the status test informs us we should stop.
742  template <class ScalarType, class MV, class OP>
744  {
745  //
746  // Allocate/initialize data structures
747  //
748  if (initialized_ == false) {
749  initialize();
750  }
751 
752  const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
753  const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
754 
755  // Compute the current search dimension.
756  int searchDim = numBlocks_;
757  //
758  // Associate each initial block of V_[i] with U_vec[i]
759  // Reset the index vector (this might have been changed if there was a restart)
760  //
761  std::vector<int> index(1);
762  std::vector<int> index2(1);
763  index[0] = curDim_;
764  Teuchos::RCP<MV> U_vec = MVT::Clone( *V_[0], numRHS_ );
765 
766  // Create AU_vec to hold A*U_vec.
767  Teuchos::RCP<MV> AU_vec = MVT::Clone( *V_[0], numRHS_ );
768 
769  for (int i=0; i<numRHS_; ++i) {
770  index2[0] = i;
771  Teuchos::RCP<const MV> tmp_vec = MVT::CloneView( *V_[i], index );
772  Teuchos::RCP<MV> U_vec_view = MVT::CloneViewNonConst( *U_vec, index2 );
773  MVT::MvAddMv( one, *tmp_vec, zero, *tmp_vec, *U_vec_view );
774  }
775 
777  // iterate until the status test tells us to stop.
778  //
779  // also break if our basis is full
780  //
781  while (stest_->checkStatus(this) != Passed && curDim_ < searchDim) {
782 
783  iter_++;
784  //
785  // Apply the operator to _work_vector
786  //
787  lp_->apply( *U_vec, *AU_vec );
788  //
789  //
790  // Resize index.
791  //
792  int num_prev = curDim_+1;
793  index.resize( num_prev );
794  for (int i=0; i<num_prev; ++i) {
795  index[i] = i;
796  }
797  //
798  // Orthogonalize next Krylov vector for each right-hand side.
799  //
800  for (int i=0; i<numRHS_; ++i) {
801  //
802  // Get previous Krylov vectors.
803  //
804  Teuchos::RCP<const MV> V_prev = MVT::CloneView( *V_[i], index );
805  Teuchos::Array< Teuchos::RCP<const MV> > V_array( 1, V_prev );
806  //
807  // Get a view of the new candidate std::vector.
808  //
809  index2[0] = i;
810  Teuchos::RCP<MV> V_new = MVT::CloneViewNonConst( *AU_vec, index2 );
811  //
812  // Get a view of the current part of the upper-hessenberg matrix.
813  //
814  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > h_new
815  = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>
816  ( Teuchos::View, *H_[i], num_prev, 1, 0, curDim_ ) );
817  Teuchos::Array< Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > h_array( 1, h_new );
818 
819  Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > r_new
820  = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>
821  ( Teuchos::View, *H_[i], 1, 1, num_prev, curDim_ ) );
822  //
823  // Orthonormalize the new block of the Krylov expansion
824  // NOTE: Rank deficiencies are not checked because this is a single-std::vector Krylov method.
825  //
826  ortho_->projectAndNormalize( *V_new, h_array, r_new, V_array );
827  //
828  // NOTE: V_new is a copy of the iter+1 vector in V_[i], so the normalized vector has to be
829  // be copied back in when V_new is changed.
830  //
831  index2[0] = curDim_+1;
832  Teuchos::RCP<MV> tmp_vec = MVT::CloneViewNonConst( *V_[i], index2 );
833  MVT::MvAddMv( one, *V_new, zero, *V_new, *tmp_vec );
834  }
835  //
836  // Now _AU_vec is the new _U_vec, so swap these two vectors.
837  // NOTE: This alleviates the need for allocating a vector for AU_vec each iteration.
838  //
839  Teuchos::RCP<MV> tmp_AU_vec = U_vec;
840  U_vec = AU_vec;
841  AU_vec = tmp_AU_vec;
842  //
843  // V has been extended, and H has been extended.
844  //
845  // Update the QR factorization of the upper Hessenberg matrix
846  //
847  updateLSQR();
848  //
849  // Update basis dim and release all pointers.
850  //
851  curDim_ += 1;
852  //
853  /*
854  // When required, monitor some orthogonalities
855  if (om_->isVerbosity( Debug ) ) {
856  // Check almost everything here
857  CheckList chk;
858  chk.checkV = true;
859  chk.checkArn = true;
860  om_->print( Debug, accuracyCheck(chk, ": after local update") );
861  }
862  else if (om_->isVerbosity( OrthoDetails ) ) {
863  CheckList chk;
864  chk.checkV = true;
865  om_->print( OrthoDetails, accuracyCheck(chk, ": after local update") );
866  }
867  */
868 
869  } // end while (statusTest == false)
870 
871  }
872 
874  // Update the least squares solution for each right-hand side.
875  template<class ScalarType, class MV, class OP>
877  {
878  // Get correct dimension based on input "dim"
879  // Remember that ortho failures result in an exit before updateLSQR() is called.
880  // Therefore, it is possible that dim == curDim_.
881  int curDim = curDim_;
882  if (dim >= curDim_ && dim < getMaxSubspaceDim()) {
883  curDim = dim;
884  }
885 
886  int i, j;
887  const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
888 
889  Teuchos::BLAS<int, ScalarType> blas;
890 
891  for (i=0; i<numRHS_; ++i) {
892  //
893  // Update the least-squares QR for each linear system.
894  //
895  // QR factorization of Least-Squares system with Givens rotations
896  //
897  for (j=0; j<curDim; j++) {
898  //
899  // Apply previous Givens rotations to new column of Hessenberg matrix
900  //
901  blas.ROT( 1, &(*H_[i])(j,curDim), 1, &(*H_[i])(j+1, curDim), 1, &(*cs_[i])[j], &(*sn_[i])[j] );
902  }
903  //
904  // Calculate new Givens rotation
905  //
906  blas.ROTG( &(*H_[i])(curDim,curDim), &(*H_[i])(curDim+1,curDim), &(*cs_[i])[curDim], &(*sn_[i])[curDim] );
907  (*H_[i])(curDim+1,curDim) = zero;
908  //
909  // Update RHS w/ new transformation
910  //
911  blas.ROT( 1, &(*Z_[i])(curDim), 1, &(*Z_[i])(curDim+1), 1, &(*cs_[i])[curDim], &(*sn_[i])[curDim] );
912  }
913 
914  } // end updateLSQR()
915 
916 } // end Belos namespace
917 
918 #endif /* BELOS_PSEUDO_BLOCK_GMRES_ITER_HPP */
BelosConfigDefs.hpp
Belos header file which uses auto-configuration information to include necessary C++ headers.
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::PseudoBlockGmresIter::SCT
Teuchos::ScalarTraits< ScalarType > SCT
Definition: BelosPseudoBlockGmresIter.hpp:164
Belos::PseudoBlockGmresIter::~PseudoBlockGmresIter
virtual ~PseudoBlockGmresIter()
Destructor.
Definition: BelosPseudoBlockGmresIter.hpp:185
Belos::Iteration
Definition: BelosIteration.hpp:73
Belos::PseudoBlockGmresIter::getProblem
const LinearProblem< ScalarType, MV, OP > & getProblem() const
Get a constant reference to the linear problem.
Definition: BelosPseudoBlockGmresIter.hpp:333
Belos::PseudoBlockGmresIterState::R
std::vector< Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > > R
The current upper-triangular matrix from the QR reduction of H.
Definition: BelosPseudoBlockGmresIter.hpp:109
Belos::PseudoBlockGmresIter::isInitialized
bool isInitialized()
States whether the solver has been initialized or not.
Definition: BelosPseudoBlockGmresIter.hpp:351
Belos::PseudoBlockGmresIter::getCurSubspaceDim
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current solution to the linear problem.
Definition: BelosPseudoBlockGmresIter.hpp:318
Belos::PseudoBlockGmresIterInitFailure::PseudoBlockGmresIterInitFailure
PseudoBlockGmresIterInitFailure(const std::string &what_arg)
Definition: BelosPseudoBlockGmresIter.hpp:138
Belos::Passed
Definition: BelosTypes.hpp:188
Belos::PseudoBlockGmresIterState::V
std::vector< Teuchos::RCP< const MV > > V
The current Krylov basis.
Definition: BelosPseudoBlockGmresIter.hpp:101
Belos::PseudoBlockGmresIter::getBlockSize
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
Definition: BelosPseudoBlockGmresIter.hpp:336
Belos::LinearProblem
A linear system to solve, and its associated information.
Definition: BelosIteration.hpp:61
BelosOutputManager.hpp
Class which manages the output and verbosity of the Belos solvers.
Belos::PseudoBlockGmresIter::getNumBlocks
int getNumBlocks() const
Get the maximum number of blocks used by the iterative solver in solving this linear problem.
Definition: BelosPseudoBlockGmresIter.hpp:345
Belos
Definition: Belos_Details_EBelosSolverType.cpp:45
Belos::PseudoBlockGmresIterOrthoFailure
PseudoBlockGmresIterOrthoFailure is thrown when the orthogonalization manager is unable to generate o...
Definition: BelosPseudoBlockGmresIter.hpp:147
Belos::PseudoBlockGmresIterState::cs
std::vector< Teuchos::RCP< const Teuchos::SerialDenseVector< int, MagnitudeType > > > cs
Definition: BelosPseudoBlockGmresIter.hpp:114
Belos::PseudoBlockGmresIter::PseudoBlockGmresIter
PseudoBlockGmresIter(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)
PseudoBlockGmresIter constructor with linear problem, solver utilities, and parameter list of solver ...
Definition: BelosPseudoBlockGmresIter.hpp:414
Belos::PseudoBlockGmresIter::initialize
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
Definition: BelosPseudoBlockGmresIter.hpp:241
Belos::PseudoBlockGmresIterInitFailure
PseudoBlockGmresIterInitFailure is thrown when the PseudoBlockGmresIter object is unable to generate ...
Definition: BelosPseudoBlockGmresIter.hpp:137
Belos::PseudoBlockGmresIter
This class implements the pseudo-block GMRES iteration, where a block Krylov subspace is constructed ...
Definition: BelosPseudoBlockGmresIter.hpp:155
BelosOperatorTraits.hpp
Class which defines basic traits for the operator type.
Belos::PseudoBlockGmresIterState::MagnitudeType
SCT::magnitudeType MagnitudeType
Definition: BelosPseudoBlockGmresIter.hpp:93
BelosMatOrthoManager.hpp
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Belos::PseudoBlockGmresIter::OPT
OperatorTraits< ScalarType, MV, OP > OPT
Definition: BelosPseudoBlockGmresIter.hpp:163
Belos::PseudoBlockGmresIter::iterate
void iterate()
This method performs block Gmres iterations until the status test indicates the need to stop or an er...
Definition: BelosPseudoBlockGmresIter.hpp:743
Belos::MatOrthoManager
Belos's templated virtual class for providing routines for orthogonalization and orthonormzalition of...
Definition: BelosIteration.hpp:70
Belos::PseudoBlockGmresIter::MVT
MultiVecTraits< ScalarType, MV > MVT
Definition: BelosPseudoBlockGmresIter.hpp:162
Belos::PseudoBlockGmresIterState::PseudoBlockGmresIterState
PseudoBlockGmresIterState()
Definition: BelosPseudoBlockGmresIter.hpp:116
Belos::PseudoBlockGmresIter::setNumBlocks
void setNumBlocks(int numBlocks)
Set the maximum number of blocks used by the iterative solver.
Definition: BelosPseudoBlockGmresIter.hpp:440
Belos::StatusTest
A pure virtual class for defining the status tests for the Belos iterative solvers.
Definition: BelosIteration.hpp:67
Belos::PseudoBlockGmresIter::updateLSQR
void updateLSQR(int dim=-1)
Method for updating QR factorization of upper Hessenberg matrix.
Definition: BelosPseudoBlockGmresIter.hpp:876
Belos::PseudoBlockGmresIter::getNumIters
int getNumIters() const
Get the current iteration count.
Definition: BelosPseudoBlockGmresIter.hpp:279
Belos::PseudoBlockGmresIterOrthoFailure::PseudoBlockGmresIterOrthoFailure
PseudoBlockGmresIterOrthoFailure(const std::string &what_arg)
Definition: BelosPseudoBlockGmresIter.hpp:148
Belos::BelosError
Parent class to all Belos exceptions.
Definition: BelosTypes.hpp:60
BelosMultiVecTraits.hpp
Declaration of basic traits for the multivector type.
Belos::PseudoBlockGmresIter::getNativeResiduals
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *norms) const
Get the norms of the "native" residual vectors.
Definition: BelosPseudoBlockGmresIter.hpp:503
BelosTypes.hpp
Collection of types and exceptions used within the Belos solvers.
Belos::PseudoBlockGmresIterState::SCT
Teuchos::ScalarTraits< ScalarType > SCT
Definition: BelosPseudoBlockGmresIter.hpp:92
Belos::PseudoBlockGmresIterState::sn
std::vector< Teuchos::RCP< const Teuchos::SerialDenseVector< int, ScalarType > > > sn
The current Given's rotation coefficients.
Definition: BelosPseudoBlockGmresIter.hpp:113
Belos::PseudoBlockGmresIter::getCurrentUpdate
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
Definition: BelosPseudoBlockGmresIter.hpp:456
Belos::PseudoBlockGmresIter::getMaxSubspaceDim
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace.
Definition: BelosPseudoBlockGmresIter.hpp:324
Belos::PseudoBlockGmresIterState::H
std::vector< Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > > H
The current Hessenberg matrix.
Definition: BelosPseudoBlockGmresIter.hpp:107
BelosIteration.hpp
Pure virtual base class which describes the basic interface to the linear solver iteration.
Belos::PseudoBlockGmresIterState::Z
std::vector< Teuchos::RCP< const Teuchos::SerialDenseVector< int, ScalarType > > > Z
The current right-hand side of the least squares system RY = Z.
Definition: BelosPseudoBlockGmresIter.hpp:111
Belos::PseudoBlockGmresIter::resetNumIters
void resetNumIters(int iter=0)
Reset the iteration count.
Definition: BelosPseudoBlockGmresIter.hpp:282
Belos::PseudoBlockGmresIter::MagnitudeType
SCT::magnitudeType MagnitudeType
Definition: BelosPseudoBlockGmresIter.hpp:165
Belos::PseudoBlockGmresIterState::curDim
int curDim
The current dimension of the reduction.
Definition: BelosPseudoBlockGmresIter.hpp:99
Belos::MultiVecTraits
Traits class which defines basic operations on multivectors.
Definition: BelosMultiVecTraits.hpp:129
Belos::PseudoBlockGmresIterState
Structure to contain pointers to PseudoBlockGmresIter state variables.
Definition: BelosPseudoBlockGmresIter.hpp:90
Belos::PseudoBlockGmresIter::setBlockSize
void setBlockSize(int blockSize)
Set the blocksize.
Definition: BelosPseudoBlockGmresIter.hpp:339
Belos::PseudoBlockGmresIter::getState
PseudoBlockGmresIterState< ScalarType, MV > getState() const
Get the current state of the linear solver.
Definition: BelosPseudoBlockGmresIter.hpp:254

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