143 typedef Teuchos::ScalarTraits<ScalarType>
SCT;
145 typedef Teuchos::SerialDenseMatrix<int,ScalarType>
SDM;
146 typedef Teuchos::SerialDenseVector<int,ScalarType>
SDV;
163 Teuchos::ParameterList ¶ms );
289 if (!initialized_)
return 0;
311 void setSize(
int recycledBlocks,
int numBlocks ) {
313 if ( (recycledBlocks_ != recycledBlocks) || (numBlocks_ != numBlocks) ) {
314 recycledBlocks_ = recycledBlocks;
315 numBlocks_ = numBlocks;
316 cs_.resize( numBlocks_ );
317 sn_.resize( numBlocks_ );
318 Z_.shapeUninitialized( numBlocks_*blockSize_, blockSize_ );
334 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > lp_;
335 const Teuchos::RCP<OutputManager<ScalarType> > om_;
336 const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > stest_;
337 const Teuchos::RCP<OrthoManager<ScalarType,MV> > ortho_;
345 int numBlocks_, blockSize_;
350 std::vector<bool> trueRHSIndices_;
356 std::vector<ScalarType> sn_;
357 std::vector<MagnitudeType> cs_;
364 std::vector< SDM >House_;
375 int curDim_, iter_, lclIter_;
386 Teuchos::RCP<MV> U_, C_;
395 Teuchos::RCP<SDM > H_;
400 Teuchos::RCP<SDM > B_;
408 Teuchos::RCP<SDM> R_;
428 Teuchos::ParameterList ¶ms ):lp_(problem),
429 om_(printer), stest_(tester), ortho_(ortho) {
433 initialized_ =
false;
444 TEUCHOS_TEST_FOR_EXCEPTION(!params.isParameter(
"Num Blocks"), std::invalid_argument,
"Belos::BlockGCRODRIter::constructor: mandatory parameter \"Num Blocks\" is not specified.");
445 int nb = Teuchos::getParameter<int>(params,
"Num Blocks");
447 TEUCHOS_TEST_FOR_EXCEPTION(!params.isParameter(
"Recycled Blocks"), std::invalid_argument,
"Belos::BlockGCRODRIter::constructor: mandatory parameter \"Recycled Blocks\" is not specified.");
448 int rb = Teuchos::getParameter<int>(params,
"Recycled Blocks");
450 TEUCHOS_TEST_FOR_EXCEPTION(nb <= 0, std::invalid_argument,
"Belos::BlockGCRODRIter() was passed a non-positive argument for \"Num Blocks\".");
451 TEUCHOS_TEST_FOR_EXCEPTION(rb >= nb, std::invalid_argument,
"Belos::BlockGCRODRIter() the number of recycled blocks is larger than the allowable subspace.");
454 int bs = Teuchos::getParameter<int>(params,
"Block Size");
456 TEUCHOS_TEST_FOR_EXCEPTION(bs <= 0, std::invalid_argument,
"Belos::BlockGCRODRIter() the block size was passed a non-postitive argument.");
460 recycledBlocks_ = rb;
465 trueRHSIndices_.resize(blockSize_);
467 for(i=0; i<blockSize_; i++){
468 trueRHSIndices_[i] =
true;
473 cs_.resize( numBlocks_+1 );
474 sn_.resize( numBlocks_+1 );
475 Z_.shapeUninitialized( (numBlocks_+1)*blockSize_,blockSize_ );
477 House_.resize(numBlocks_);
479 for(i=0; i<numBlocks_;i++){
480 House_[i].shapeUninitialized(2*blockSize_, 2*blockSize_);
488 TEUCHOS_TEST_FOR_EXCEPTION( initialized_ ==
false,
BlockGCRODRIterInitFailure,
"Belos::BlockGCRODRIter::iterate(): GCRODRIter class not initialized." );
494 setSize( recycledBlocks_, numBlocks_ );
496 Teuchos::RCP<MV> Vnext;
497 Teuchos::RCP<const MV> Vprev;
498 std::vector<int> curind(blockSize_);
504 for(
int i = 0; i<blockSize_; i++){curind[i] = i;};
512 Teuchos::RCP<SDM > Z0 =
513 Teuchos::rcp(
new SDM(blockSize_,blockSize_) );
514 int rank = ortho_->normalize(*Vnext,Z0);
519 TEUCHOS_TEST_FOR_EXCEPTION(rank != blockSize_,
BlockGCRODRIterOrthoFailure,
"Belos::BlockGCRODRIter::iterate(): couldn't generate basis of full rank at the initial step.");
521 Teuchos::RCP<SDM > Z_block = Teuchos::rcp(
new SDM(Teuchos::View, Z_, blockSize_,blockSize_) );
522 Z_block->assign(*Z0);
524 std::vector<int> prevind(blockSize_*(numBlocks_ + 1));
531 while( (stest_->checkStatus(
this) !=
Passed) && (curDim_+blockSize_-1) < (numBlocks_*blockSize_)) {
537 int HFirstCol = curDim_-blockSize_;
538 int HLastCol = HFirstCol + blockSize_-1 ;
539 int HLastOrthRow = HLastCol;
540 int HFirstNormRow = HLastOrthRow + 1;
544 for(
int i = 0; i< blockSize_; i++){
545 curind[i] = curDim_ + i;
552 for(
int i = 0; i< blockSize_; i++){
553 curind[blockSize_ - 1 - i] = curDim_ - i - 1;
557 lp_->apply(*Vprev,*Vnext);
558 Vprev = Teuchos::null;
564 Teuchos::Array<Teuchos::RCP<const MV> > C(1, C_);
567 subB = Teuchos::rcp(
new SDM ( Teuchos::View,*B_,recycledBlocks_,blockSize_,0, HFirstCol ) );
569 Teuchos::Array<Teuchos::RCP<SDM > > AsubB;
570 AsubB.append( subB );
572 ortho_->project( *Vnext, AsubB, C );
576 prevind.resize(curDim_);
577 for (
int i=0; i<curDim_; i++) { prevind[i] = i; }
579 Teuchos::Array<Teuchos::RCP<const MV> > AVprev(1, Vprev);
582 Teuchos::RCP<SDM> subH = Teuchos::rcp(
new SDM ( Teuchos::View,*H_,curDim_,blockSize_,0,HFirstCol ) );
583 Teuchos::Array<Teuchos::RCP<SDM > > AsubH;
584 AsubH.append( subH );
586 Teuchos::RCP<SDM > subR = Teuchos::rcp(
new SDM ( Teuchos::View,*H_,blockSize_,blockSize_,HFirstNormRow,HFirstCol ) );
588 int rank = ortho_->projectAndNormalize(*Vnext,AsubH,subR,AVprev);
591 SDM subR2( Teuchos::View,*R_,(lclIter_+1)*blockSize_,blockSize_,0,HFirstCol);
592 SDM subH2( Teuchos::View,*H_,(lclIter_+1)*blockSize_,blockSize_,0,HFirstCol);
595 TEUCHOS_TEST_FOR_EXCEPTION(rank != blockSize_,
BlockGCRODRIterOrthoFailure,
"Belos::BlockGCRODRIter::iterate(): couldn't generate basis of full rank.");
601 curDim_ = curDim_ + blockSize_;
682 Teuchos::RCP<MV> currentUpdate = Teuchos::null;
684 if(curDim_<=blockSize_) {
685 return currentUpdate;
688 const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
689 const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
690 Teuchos::BLAS<int,ScalarType> blas;
691 currentUpdate =
MVT::Clone( *V_, blockSize_ );
695 SDM Y( Teuchos::Copy, Z_, curDim_-blockSize_, blockSize_ );
696 Teuchos::RCP<SDM> Rtmp = Teuchos::rcp(
new SDM(Teuchos::View, *R_, curDim_, curDim_-blockSize_));
713 blas.TRSM( Teuchos::LEFT_SIDE, Teuchos::UPPER_TRI, Teuchos::NO_TRANS,
714 Teuchos::NON_UNIT_DIAG, curDim_-blockSize_, blockSize_, one,
715 Rtmp->values(), Rtmp->stride(), Y.values(), Y.stride() );
722 std::vector<int> index(curDim_-blockSize_);
723 for (
int i=0; i<curDim_-blockSize_; i++ ) index[i] = i;
732 if (U_ != Teuchos::null) {
733 SDM z(recycledBlocks_,blockSize_);
734 SDM subB( Teuchos::View, *B_, recycledBlocks_, curDim_-blockSize_ );
735 z.multiply( Teuchos::NO_TRANS, Teuchos::NO_TRANS, one, subB, Y, zero );
744 return currentUpdate;
751 const ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
752 const ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
759 int curDim = curDim_;
764 Teuchos::BLAS<int, ScalarType> blas;
773 for (i=0; i<curDim-1; i++) {
777 blas.ROT( 1, &(*R_)(i,curDim-1), 1, &(*R_)(i+1, curDim-1), 1, &cs_[i], &sn_[i] );
782 blas.ROTG( &(*R_)(curDim-1,curDim-1), &(*R_)(curDim,curDim-1), &cs_[curDim-1], &sn_[curDim-1] );
783 (*R_)(curDim,curDim-1) = zero;
787 blas.ROT( 1, &Z_(curDim-1,0), 1, &Z_(curDim,0), 1, &cs_[curDim-1], &sn_[curDim-1] );
802 Teuchos::RCP< SDM > workmatrix = Teuchos::null;
803 Teuchos::RCP< SDV > workvec = Teuchos::null;
804 Teuchos::RCP<SDV> v_refl = Teuchos::null;
805 int R_colStart = curDim_-blockSize_;
806 Teuchos::RCP< SDM >Rblock = Teuchos::null;
811 for(i=0; i<lclIter_-1; i++){
812 int R_rowStart = i*blockSize_;
814 Teuchos::RCP< SDM > RblockCopy = rcp(
new SDM (Teuchos::Copy, *R_, 2*blockSize_,blockSize_, R_rowStart, R_colStart));
815 Teuchos::RCP< SDM > RblockView = rcp(
new SDM (Teuchos::View, *R_, 2*blockSize_,blockSize_, R_rowStart, R_colStart));
816 blas.GEMM(Teuchos::NO_TRANS,Teuchos::NO_TRANS, 2*blockSize_,blockSize_,2*blockSize_,one,House_[i].values(),House_[i].stride(), RblockCopy->values(),RblockCopy -> stride(), zero, RblockView->values(),RblockView -> stride());
823 Rblock = rcp(
new SDM (Teuchos::View, *R_, 2*blockSize_,blockSize_, curDim_-blockSize_, curDim_-blockSize_));
826 for(i=0; i<blockSize_; i++){
830 int curcol = (lclIter_ - 1)*blockSize_ + i;
832 ScalarType signDiag = (*R_)(curcol,curcol) / Teuchos::ScalarTraits<ScalarType>::magnitude((*R_)(curcol,curcol));
836 ScalarType nvs = blas.NRM2(blockSize_+1,&((*R_)[curcol][curcol]),1);
837 ScalarType alpha = -signDiag*nvs;
855 v_refl = rcp(
new SDV(Teuchos::Copy, &((*R_)(curcol,curcol)), blockSize_ + 1 ));
856 (*v_refl)[0] -= alpha;
857 nvs = blas.NRM2(blockSize_+1,v_refl -> values(),1);
873 if(i < blockSize_ - 1){
874 workvec = Teuchos::rcp(
new SDV(blockSize_ - i -1));
876 workmatrix = Teuchos::rcp(
new SDM (Teuchos::View, *Rblock, blockSize_+1, blockSize_ - i -1, lclCurcol, lclCurcol +1 ) );
877 blas.GEMV(Teuchos::TRANS, workmatrix->numRows(), workmatrix->numCols(), one, workmatrix->values(), workmatrix->stride(), v_refl->values(), 1, zero, workvec->values(), 1);
878 blas.GER(workmatrix->numRows(),workmatrix->numCols(), -2.0*one/nvs, v_refl->values(),1,workvec->values(),1,workmatrix->values(),workmatrix->stride());
885 workvec = Teuchos::rcp(
new SDV(2*blockSize_));
886 workmatrix = Teuchos::rcp(
new SDM (Teuchos::View, House_[lclIter_ -1], blockSize_+1, 2*blockSize_, i, 0 ) );
887 blas.GEMV(Teuchos::TRANS,workmatrix->numRows(),workmatrix->numCols(),one,workmatrix->values(),workmatrix->stride(), v_refl->values(), 1,zero,workvec->values(),1);
888 blas.GER(workmatrix->numRows(),workmatrix->numCols(), -2.0*one/nvs, v_refl -> values(),1,workvec->values(),1,workmatrix->values(),(*workmatrix).stride());
893 workvec = Teuchos::rcp(
new SDV(blockSize_));
894 workmatrix = Teuchos::rcp(
new SDM (Teuchos::View, Z_, blockSize_+1, blockSize_, curcol, 0 ) );
895 blas.GEMV(Teuchos::TRANS, workmatrix->numRows(), workmatrix->numCols(), one, workmatrix-> values(), workmatrix->stride(), v_refl -> values(), 1, zero, workvec->values(), 1);
896 blas.GER((*workmatrix).numRows(),(*workmatrix).numCols(), -2.0*one/nvs,v_refl -> values(), 1,&((*workvec)[0]),1,(*workmatrix)[0],(*workmatrix).stride());
901 (*R_)[curcol][curcol] = alpha;
902 for(
int ii=1; ii<= blockSize_; ii++){
903 (*R_)[curcol][curcol+ii] = 0;