Belos Version of the Day
Loading...
Searching...
No Matches
BelosPseudoBlockGmresIter.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Belos: Block Linear Solvers Package
4//
5// Copyright 2004-2016 NTESS and the Belos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef BELOS_PSEUDO_BLOCK_GMRES_ITER_HPP
11#define BELOS_PSEUDO_BLOCK_GMRES_ITER_HPP
12
17#include "BelosConfigDefs.hpp"
18#include "BelosTypes.hpp"
19#include "BelosIteration.hpp"
21
25#include "BelosStatusTest.hpp"
29
30#include "Teuchos_BLAS.hpp"
31#include "Teuchos_ScalarTraits.hpp"
32#include "Teuchos_ParameterList.hpp"
33#include "Teuchos_TimeMonitor.hpp"
34
48namespace Belos {
49
50 template<class ScalarType, class MV, class OP, class DM>
51 class PseudoBlockGmresIter : virtual public Iteration<ScalarType,MV,OP,DM> {
52
53 public:
54
55 //
56 // Convenience typedefs
57 //
61 typedef Teuchos::ScalarTraits<ScalarType> SCT;
62 typedef typename SCT::magnitudeType MagnitudeType;
63
65
66
76 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
77 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > &tester,
78 const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > &ortho,
79 Teuchos::ParameterList &params );
80
84
85
87
88
110 void iterate();
111
134
143
153 state.curDim = curDim_;
154 state.V.resize(numRHS_);
155 state.H.resize(numRHS_);
156 state.Z.resize(numRHS_);
157 state.sn.resize(numRHS_);
158 state.cs.resize(numRHS_);
159 for (int i=0; i<numRHS_; ++i) {
160 state.V[i] = V_[i];
161 state.H[i] = H_[i];
162 state.Z[i] = Z_[i];
163 state.sn[i] = sn_[i];
164 state.cs[i] = cs_[i];
165 }
166 return state;
167 }
168
170
171
173
174
176 int getNumIters() const { return iter_; }
177
179 void resetNumIters( int iter = 0 ) { iter_ = iter; }
180
198 Teuchos::RCP<const MV> getNativeResiduals( std::vector<MagnitudeType> *norms ) const;
199
201
206 Teuchos::RCP<MV> getCurrentUpdate() const;
207
209
212 void updateLSQR( int dim = -1 );
213
215 int getCurSubspaceDim() const {
216 if (!initialized_) return 0;
217 return curDim_;
218 };
219
221 int getMaxSubspaceDim() const { return numBlocks_; }
222
224
225
227
228
230 const LinearProblem<ScalarType,MV,OP,DM>& getProblem() const { return *lp_; }
231
233 int getBlockSize() const { return 1; }
234
237 TEUCHOS_TEST_FOR_EXCEPTION(blockSize!=1,std::invalid_argument,
238 "Belos::PseudoBlockGmresIter::setBlockSize(): Cannot use a block size that is not one.");
239 }
240
242 int getNumBlocks() const { return numBlocks_; }
243
245 void setNumBlocks(int numBlocks);
246
248 bool isInitialized() { return initialized_; }
249
251
252 private:
253
254 //
255 // Classes inputed through constructor that define the linear problem to be solved.
256 //
257 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > lp_;
258 const Teuchos::RCP<OutputManager<ScalarType> > om_;
259 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > stest_;
260 const Teuchos::RCP<OrthoManager<ScalarType,MV,DM> > ortho_;
261
262 //
263 // Algorithmic parameters
264 //
265 // numRHS_ is the current number of linear systems being solved.
266 int numRHS_;
267 // numBlocks_ is the size of the allocated space for the Krylov basis, in blocks.
268 int numBlocks_;
269
270 // Storage for QR factorization of the least squares system.
271 std::vector<Teuchos::RCP<std::vector<ScalarType> > > sn_;
272 std::vector<Teuchos::RCP<std::vector<MagnitudeType> > > cs_;
273
274 // Pointers to a work vector used to improve aggregate performance.
275 Teuchos::RCP<MV> U_vec_, AU_vec_;
276
277 // Pointers to the current right-hand side and solution multivecs being solved for.
278 Teuchos::RCP<MV> cur_block_rhs_, cur_block_sol_;
279
280 //
281 // Current solver state
282 //
283 // initialized_ specifies that the basis vectors have been initialized and the iterate() routine
284 // is capable of running; _initialize is controlled by the initialize() member method
285 // For the implications of the state of initialized_, please see documentation for initialize()
286 bool initialized_;
287
288 // Current subspace dimension, and number of iterations performed.
289 int curDim_, iter_;
290
291 //
292 // State Storage
293 //
294 std::vector<Teuchos::RCP<MV> > V_;
295 //
296 // Projected matrices
297 // H_ : Projected matrix from the Krylov factorization AV = VH + FE^T
298 //
299 std::vector<Teuchos::RCP<DM> > H_;
300 //
301 // QR decomposition of Projected matrices for solving the least squares system HY = B.
302 // R_: Upper triangular reduction of H
303 // Z_: Q applied to right-hand side of the least squares system
304 std::vector<Teuchos::RCP<DM> > R_;
305 std::vector<Teuchos::RCP<DM> > Z_;
306 };
307
309 // Constructor.
310 template<class ScalarType, class MV, class OP, class DM>
312 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
313 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > &tester,
314 const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > &ortho,
315 Teuchos::ParameterList &params ):
316 lp_(problem),
317 om_(printer),
318 stest_(tester),
319 ortho_(ortho),
320 numRHS_(0),
321 numBlocks_(0),
322 initialized_(false),
323 curDim_(0),
324 iter_(0)
325 {
326 // Get the maximum number of blocks allowed for each Krylov subspace
327 TEUCHOS_TEST_FOR_EXCEPTION(!params.isParameter("Num Blocks"), std::invalid_argument,
328 "Belos::PseudoBlockGmresIter::constructor: mandatory parameter 'Num Blocks' is not specified.");
329 int nb = Teuchos::getParameter<int>(params, "Num Blocks");
330
331 setNumBlocks( nb );
332 }
333
335 // Set the block size and make necessary adjustments.
336 template <class ScalarType, class MV, class OP, class DM>
338 {
339 // This routine only allocates space; it doesn't not perform any computation
340 // any change in size will invalidate the state of the solver.
341
342 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks <= 0, std::invalid_argument, "Belos::PseudoBlockGmresIter::setNumBlocks was passed a non-positive argument.");
343
344 numBlocks_ = numBlocks;
345 curDim_ = 0;
346
347 initialized_ = false;
348 }
349
351 // Get the current update from this subspace.
352 template <class ScalarType, class MV, class OP, class DM>
354 {
355 //
356 // If this is the first iteration of the Arnoldi factorization,
357 // there is no update, so return Teuchos::null.
358 //
359 Teuchos::RCP<MV> currentUpdate = Teuchos::null;
360 if (curDim_==0) {
361 return currentUpdate;
362 } else {
363 currentUpdate = MVT::Clone(*(V_[0]), numRHS_);
364 std::vector<int> index(1), index2(curDim_);
365 for (int i=0; i<curDim_; ++i) {
366 index2[i] = i;
367 }
368 const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
369 const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
370 Teuchos::BLAS<int,ScalarType> blas;
371
372 for (int i=0; i<numRHS_; ++i) {
373 index[0] = i;
374 Teuchos::RCP<MV> cur_block_copy_vec = MVT::CloneViewNonConst( *currentUpdate, index );
375 //
376 // Make a view and then copy the RHS of the least squares problem. DON'T OVERWRITE IT!
377 //
378 Teuchos::RCP<DM> y = DMT::SubviewCopy(*Z_[i], curDim_, 1);
379 DMT::SyncDeviceToHost( *y );
380 DMT::SyncDeviceToHost( *H_[i] );
381 //
382 // Solve the least squares problem and compute current solutions.
383 //
384 blas.TRSM( Teuchos::LEFT_SIDE, Teuchos::UPPER_TRI, Teuchos::NO_TRANS,
385 Teuchos::NON_UNIT_DIAG, curDim_, 1, one,
386 DMT::GetConstRawHostPtr(*H_[i]), DMT::GetStride(*H_[i]),
387 DMT::GetRawHostPtr(*y), DMT::GetStride(*y) );
388
389 DMT::SyncHostToDevice( *y );
390 DMT::SyncHostToDevice( *H_[i] );
391 Teuchos::RCP<const MV> Vjp1 = MVT::CloneView( *V_[i], index2 );
392 MVT::MvTimesMatAddMv( one, *Vjp1, *y, zero, *cur_block_copy_vec );
393 }
394 }
395 return currentUpdate;
396 }
397
398
400 // Get the native residuals stored in this iteration.
401 // Note: No residual vector will be returned by Gmres.
402 template <class ScalarType, class MV, class OP, class DM>
403 Teuchos::RCP<const MV>
405 getNativeResiduals (std::vector<MagnitudeType> *norms) const
406 {
407 if (norms)
408 { // Resize the incoming std::vector if necessary. The type
409 // cast avoids the compiler warning resulting from a signed /
410 // unsigned integer comparison.
411 if (static_cast<int> (norms->size()) < numRHS_)
412 norms->resize (numRHS_);
413
414 for (int j = 0; j < numRHS_; ++j)
415 {
416 DMT::SyncDeviceToHost( *Z_[j] );
417 const ScalarType curNativeResid = DMT::ValueConst(*Z_[j],curDim_,0);
418 (*norms)[j] = SCT::magnitude (curNativeResid);
419 }
420 }
421 return Teuchos::null;
422 }
423
424
425 template <class ScalarType, class MV, class OP, class DM>
426 void
429 {
430 using Teuchos::RCP;
431
432 // (Re)set the number of right-hand sides, by interrogating the
433 // current LinearProblem to solve.
434 this->numRHS_ = MVT::GetNumberVecs (*(lp_->getCurrLHSVec()));
435
436 // NOTE: In PseudoBlockGmresIter, V and Z are required!!!
437 // Inconsistent multivectors widths and lengths will not be tolerated, and
438 // will be treated with exceptions.
439 //
440 std::string errstr ("Belos::PseudoBlockGmresIter::initialize(): "
441 "Specified multivectors must have a consistent "
442 "length and width.");
443
444 // Check that newstate has V and Z arrays with nonzero length.
445 TEUCHOS_TEST_FOR_EXCEPTION((int)newstate.V.size()==0 || (int)newstate.Z.size()==0,
446 std::invalid_argument,
447 "Belos::PseudoBlockGmresIter::initialize(): "
448 "V and/or Z was not specified in the input state; "
449 "the V and/or Z arrays have length zero.");
450
451 // In order to create basis multivectors, we have to clone them
452 // from some already existing multivector. We require that at
453 // least one of the right-hand side B and left-hand side X in the
454 // LinearProblem be non-null. Thus, we can clone from either B or
455 // X. We prefer to close from B, since B is in the range of the
456 // operator A and the basis vectors should also be in the range of
457 // A (the first basis vector is a scaled residual vector).
458 // However, if B is not given, we will try our best by cloning
459 // from X.
460 RCP<const MV> lhsMV = lp_->getLHS();
461 RCP<const MV> rhsMV = lp_->getRHS();
462
463 // If the right-hand side is null, we make do with the left-hand
464 // side, otherwise we use the right-hand side.
466 //RCP<const MV> tmp = ( (rhsMV!=Teuchos::null)? rhsMV: lhsMV );
467
469 std::invalid_argument,
470 "Belos::PseudoBlockGmresIter::initialize(): "
471 "The linear problem to solve does not specify multi"
472 "vectors from which we can clone basis vectors. The "
473 "right-hand side(s), left-hand side(s), or both should "
474 "be nonnull.");
475
476 // Check the new dimension is not more that the maximum number of
477 // allowable blocks.
478 TEUCHOS_TEST_FOR_EXCEPTION(newstate.curDim > numBlocks_+1,
479 std::invalid_argument,
480 errstr);
481 curDim_ = newstate.curDim;
482
483 // Initialize the state storage. If the subspace has not be
484 // initialized before, generate it using the right-hand side or
485 // left-hand side from the LinearProblem lp_ to solve.
486 V_.resize(numRHS_);
487 for (int i=0; i<numRHS_; ++i) {
488 // Create a new vector if we need to. We "need to" if the
489 // current vector V_[i] is null, or if it doesn't have enough
490 // columns.
491 if (V_[i].is_null() || MVT::GetNumberVecs(*V_[i]) < numBlocks_ + 1) {
492 V_[i] = MVT::Clone (*vectorInBasisSpace, numBlocks_ + 1);
493 }
494 // Check that the newstate vector newstate.V[i] has dimensions
495 // consistent with those of V_[i].
496 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetGlobalLength(*newstate.V[i]) != MVT::GetGlobalLength(*V_[i]),
497 std::invalid_argument, errstr );
498 TEUCHOS_TEST_FOR_EXCEPTION( MVT::GetNumberVecs(*newstate.V[i]) < newstate.curDim,
499 std::invalid_argument, errstr );
500 //
501 // If newstate.V[i] and V_[i] are not identically the same
502 // vector, then copy newstate.V[i] into V_[i].
503 //
504 int lclDim = MVT::GetNumberVecs(*newstate.V[i]);
505 if (newstate.V[i] != V_[i]) {
506 // Only copy over the first block and print a warning.
507 if (curDim_ == 0 && lclDim > 1) {
508 om_->stream(Warnings)
509 << "Belos::PseudoBlockGmresIter::initialize(): the solver was "
510 << "initialized with a kernel of " << lclDim
511 << std::endl
512 << "The block size however is only " << 1
513 << std::endl
514 << "The last " << lclDim - 1 << " vectors will be discarded."
515 << std::endl;
516 }
517 std::vector<int> nevind (curDim_ + 1);
518 for (int j = 0; j < curDim_ + 1; ++j)
519 nevind[j] = j;
520
521 RCP<const MV> newV = MVT::CloneView (*newstate.V[i], nevind);
522 RCP<MV> lclV = MVT::CloneViewNonConst( *V_[i], nevind );
523 MVT::Assign(*newV, *lclV);
524
525 // Done with local pointers
526 lclV = Teuchos::null;
527 }
528 }
529
530
531 // Check size of Z
532 Z_.resize(numRHS_);
533 for (int i=0; i<numRHS_; ++i) {
534 // Create a vector if we need to.
535 if (Z_[i] == Teuchos::null) {
536 Z_[i] = DMT::Create();
537 }
538 if (DMT::GetNumRows(*Z_[i]) < numBlocks_+1) {
539 DMT::Reshape(*Z_[i], numBlocks_+1, 1, false);
540 }
541
542 // Check that the newstate vector is consistent.
543 TEUCHOS_TEST_FOR_EXCEPTION(DMT::GetNumRows(*newstate.Z[i]) < curDim_, std::invalid_argument, errstr);
544
545 // Put data into Z_, make sure old information is not still hanging around.
546 if (newstate.Z[i] != Z_[i]) {
547 if (curDim_==0)
548 DMT::PutScalar(*Z_[i]);
549
550 Teuchos::RCP<const DM> newZ = DMT::SubviewConst(*newstate.Z[i],curDim_+1,1);
551 Teuchos::RCP<DM> lclZ = DMT::Subview(*Z_[i],curDim_+1,1);
552 DMT::Assign(*lclZ,*newZ);
553
554 // Done with local pointers
555 lclZ = Teuchos::null;
556 }
557 }
558
559
560 // Check size of H
561 H_.resize(numRHS_);
562 for (int i=0; i<numRHS_; ++i) {
563 // Create a matrix if we need to.
564 if (H_[i] == Teuchos::null) {
565 H_[i] = DMT::Create();
566 }
567 if (DMT::GetNumRows(*H_[i]) < numBlocks_+1 || DMT::GetNumCols(*H_[i]) < numBlocks_) {
568 DMT::Reshape(*H_[i], numBlocks_+1, numBlocks_, false);
569 }
570
571 // Put data into H_ if it exists, make sure old information is not still hanging around.
572 if ((int)newstate.H.size() == numRHS_) {
573
574 // Check that the newstate matrix is consistent.
575 TEUCHOS_TEST_FOR_EXCEPTION((DMT::GetNumRows(*newstate.H[i]) < curDim_ || DMT::GetNumCols(*newstate.H[i]) < curDim_), std::invalid_argument,
576 "Belos::PseudoBlockGmresIter::initialize(): Specified Hessenberg matrices must have a consistent size to the current subspace dimension");
577
578 if (newstate.H[i] != H_[i]) {
579
580 Teuchos::RCP<const DM> newH = DMT::SubviewConst(*newstate.H[i],curDim_+1, curDim_);
581 Teuchos::RCP<DM> lclH = DMT::Subview(*H_[i],curDim_+1, curDim_);
582 DMT::Assign(*lclH,*newH);
583
584 // Done with local pointers
585 lclH = Teuchos::null;
586 }
587 }
588 }
589
591 // Reinitialize storage for least squares solve
592 //
593 cs_.resize(numRHS_);
594 sn_.resize(numRHS_);
595
596 // Copy over rotation angles if they exist
597 if ((int)newstate.cs.size() == numRHS_ && (int)newstate.sn.size() == numRHS_) {
598 for (int i=0; i<numRHS_; ++i) {
599 if (cs_[i] != newstate.cs[i])
600 cs_[i] = Teuchos::rcp( new std::vector<MagnitudeType>(*newstate.cs[i]) );
601 if (sn_[i] != newstate.sn[i])
602 sn_[i] = Teuchos::rcp( new std::vector<ScalarType>(*newstate.sn[i]) );
603 }
604 }
605
606 // Resize or create the vectors as necessary
607 for (int i=0; i<numRHS_; ++i) {
608 if (cs_[i] == Teuchos::null)
609 cs_[i] = Teuchos::rcp( new std::vector<MagnitudeType>(numBlocks_+1) );
610 else
611 cs_[i]->resize(numBlocks_+1);
612 if (sn_[i] == Teuchos::null)
613 sn_[i] = Teuchos::rcp( new std::vector<ScalarType>(numBlocks_+1) );
614 else
615 sn_[i]->resize(numBlocks_+1);
616 }
617
618 // the solver is initialized
619 initialized_ = true;
620
621 }
622
623
625 // Iterate until the status test informs us we should stop.
626 template <class ScalarType, class MV, class OP, class DM>
628 {
629 //
630 // Allocate/initialize data structures
631 //
632 if (initialized_ == false) {
633 initialize();
634 }
635
636 // Compute the current search dimension.
637 int searchDim = numBlocks_;
638 //
639 // Associate each initial block of V_[i] with U_vec[i]
640 // Reset the index vector (this might have been changed if there was a restart)
641 //
642 std::vector<int> index(1);
643 std::vector<int> index2(1);
644 index[0] = curDim_;
645 Teuchos::RCP<MV> U_vec = MVT::Clone( *V_[0], numRHS_ );
646
647 // Create AU_vec to hold A*U_vec.
648 Teuchos::RCP<MV> AU_vec = MVT::Clone( *V_[0], numRHS_ );
649
650 for (int i=0; i<numRHS_; ++i) {
651 index2[0] = i;
652 Teuchos::RCP<const MV> tmp_vec = MVT::CloneView( *V_[i], index );
653 Teuchos::RCP<MV> U_vec_view = MVT::CloneViewNonConst( *U_vec, index2 );
654 MVT::Assign( *tmp_vec, *U_vec_view );
655 }
656
658 // iterate until the status test tells us to stop.
659 //
660 // also break if our basis is full
661 //
662 while (stest_->checkStatus(this) != Passed && curDim_ < searchDim) {
663
664 iter_++;
665 //
666 // Apply the operator to _work_vector
667 //
668 lp_->apply( *U_vec, *AU_vec );
669 //
670 //
671 // Resize index.
672 //
673 int num_prev = curDim_+1;
674 index.resize( num_prev );
675 for (int i=0; i<num_prev; ++i) {
676 index[i] = i;
677 }
678 //
679 // Orthogonalize next Krylov vector for each right-hand side.
680 //
681 for (int i=0; i<numRHS_; ++i) {
682 //
683 // Get previous Krylov vectors.
684 //
685 Teuchos::RCP<const MV> V_prev = MVT::CloneView( *V_[i], index );
686 Teuchos::Array< Teuchos::RCP<const MV> > V_array( 1, V_prev );
687 //
688 // Get a view of the new candidate std::vector.
689 //
690 index2[0] = i;
691 Teuchos::RCP<MV> V_new = MVT::CloneViewNonConst( *AU_vec, index2 );
692 //
693 // Get a view of the current part of the upper-hessenberg matrix.
694 //
695 Teuchos::RCP<DM> h_new = DMT::Subview(*H_[i], num_prev, 1, 0, curDim_);
696 Teuchos::Array< Teuchos::RCP<DM> > h_array( 1, h_new );
697
698 Teuchos::RCP<DM> r_new = DMT::Subview(*H_[i], 1, 1, num_prev, curDim_);
699 //
700 // Orthonormalize the new block of the Krylov expansion
701 // NOTE: Rank deficiencies are not checked because this is a single-std::vector Krylov method.
702 //
703 ortho_->projectAndNormalize( *V_new, h_array, r_new, V_array );
704 //
705 // NOTE: V_new is a copy of the iter+1 vector in V_[i], so the normalized vector has to be
706 // be copied back in when V_new is changed.
707 //
708 index2[0] = curDim_+1;
709 Teuchos::RCP<MV> tmp_vec = MVT::CloneViewNonConst( *V_[i], index2 );
710 MVT::Assign( *V_new, *tmp_vec );
711 }
712 //
713 // Now _AU_vec is the new _U_vec, so swap these two vectors.
714 // NOTE: This alleviates the need for allocating a vector for AU_vec each iteration.
715 //
716 Teuchos::RCP<MV> tmp_AU_vec = U_vec;
717 U_vec = AU_vec;
719 //
720 // V has been extended, and H has been extended.
721 //
722 // Update the QR factorization of the upper Hessenberg matrix
723 //
724 updateLSQR();
725 //
726 // Update basis dim and release all pointers.
727 //
728 curDim_ += 1;
729 //
730 } // end while (statusTest == false)
731
732 }
733
735 // Update the least squares solution for each right-hand side.
736 template<class ScalarType, class MV, class OP, class DM>
738 {
739 // Get correct dimension based on input "dim"
740 // Remember that ortho failures result in an exit before updateLSQR() is called.
741 // Therefore, it is possible that dim == curDim_.
742 int curDim = curDim_;
743 if (dim >= curDim_ && dim < getMaxSubspaceDim()) {
744 curDim = dim;
745 }
746
747 int i, j;
748 const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
749
750 Teuchos::BLAS<int, ScalarType> blas;
751
752 for (i=0; i<numRHS_; ++i) {
753 //
754 // Update the least-squares QR for each linear system.
755 //
756 // QR factorization of Least-Squares system with Givens rotations
757 //
758 DMT::SyncDeviceToHost(*H_[i]);
759 DMT::SyncDeviceToHost(*Z_[i]);
760 //
761 for (j=0; j<curDim; j++) {
762 //
763 // Apply previous Givens rotations to new column of Hessenberg matrix
764 //
765 blas.ROT( 1, &(DMT::Value(*H_[i],j,curDim)), 1, &(DMT::Value(*H_[i],j+1, curDim)),
766 1, &(*cs_[i])[j], &(*sn_[i])[j] );
767 }
768 //
769 // Calculate new Givens rotation
770 //
771 blas.ROTG( &(DMT::Value(*H_[i],curDim,curDim)), &(DMT::Value(*H_[i],curDim+1,curDim)),
772 &(*cs_[i])[curDim], &(*sn_[i])[curDim] );
773 DMT::Value(*H_[i],curDim+1,curDim) = zero;
774 //
775 // Update RHS w/ new transformation
776 //
777 blas.ROT( 1, &(DMT::Value(*Z_[i],curDim,0)), 1, &(DMT::Value(*Z_[i],curDim+1,0)),
778 1, &(*cs_[i])[curDim], &(*sn_[i])[curDim] );
779 //
780 DMT::SyncHostToDevice(*H_[i]);
781 DMT::SyncHostToDevice(*Z_[i]);
782 //
783 }
784
785 } // end updateLSQR()
786
787} // end Belos namespace
788
789#endif /* BELOS_PSEUDO_BLOCK_GMRES_ITER_HPP */
Belos header file which uses auto-configuration information to include necessary C++ headers.
Pure virtual base class which augments the basic interface for a Gmres linear solver iteration.
Pure virtual base class which describes the basic interface to the linear solver iteration.
Class which describes the linear problem to be solved by the iterative solver.
Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based ...
Declaration of basic traits for the multivector type.
Class which defines basic traits for the operator type.
Class which manages the output and verbosity of the Belos solvers.
Pure virtual base class for defining the status testing capabilities of Belos.
Collection of types and exceptions used within the Belos solvers.
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).
This class implements the pseudo-block GMRES iteration, where a block Krylov subspace is constructed ...
void setNumBlocks(int numBlocks)
Set the maximum number of blocks used by the iterative solver.
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
OperatorTraits< ScalarType, MV, OP > OPT
void setBlockSize(int blockSize)
Set the blocksize.
int getMaxSubspaceDim() const
Get the maximum dimension allocated for the search subspace.
void iterate()
This method performs block Gmres iterations until the status test indicates the need to stop or an er...
PseudoBlockGmresIterState< ScalarType, MV, DM > getState() const
Get the current state of the linear solver.
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
int getNumIters() const
Get the current iteration count.
DenseMatTraits< ScalarType, DM > DMT
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const
Get a constant reference to the linear problem.
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.
PseudoBlockGmresIter(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &problem, const Teuchos::RCP< OutputManager< ScalarType > > &printer, const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &tester, const Teuchos::RCP< MatOrthoManager< ScalarType, MV, OP, DM > > &ortho, Teuchos::ParameterList &params)
PseudoBlockGmresIter constructor with linear problem, solver utilities, and parameter list of solver ...
void resetNumIters(int iter=0)
Reset the iteration count.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *norms) const
Get the norms of the "native" residual vectors.
bool isInitialized()
States whether the solver has been initialized or not.
MultiVecTraits< ScalarType, MV, DM > MVT
int getCurSubspaceDim() const
Get the dimension of the search subspace used to generate the current solution to the linear problem.
Teuchos::ScalarTraits< ScalarType > SCT
int getNumBlocks() const
Get the maximum number of blocks used by the iterative solver in solving this linear problem.

Generated for Belos by doxygen 1.9.8