447 const int nev = problem_->getNEV();
463 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxtest;
468 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convtest;
469 if (globalTest_ == Teuchos::null) {
473 convtest = globalTest_;
475 Teuchos::RCP<StatusTestWithOrdering<ScalarType,MV,OP> > ordertest
478 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > locktest;
480 if (lockingTest_ == Teuchos::null) {
484 locktest = lockingTest_;
488 Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests;
489 alltests.push_back(ordertest);
490 if (locktest != Teuchos::null) alltests.push_back(locktest);
491 if (debugTest_ != Teuchos::null) alltests.push_back(debugTest_);
492 if (maxtest != Teuchos::null) alltests.push_back(maxtest);
493 Teuchos::RCP<StatusTestCombo<ScalarType,MV,OP> > combotest
496 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest;
497 if ( printer->isVerbosity(
Debug) ) {
506 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho;
507 if (ortho_==
"SVQB") {
509 }
else if (ortho_==
"DGKS") {
511 }
else if (ortho_==
"ICGS") {
514 TEUCHOS_TEST_FOR_EXCEPTION(ortho_!=
"SVQB"&&ortho_!=
"DGKS"&&ortho_!=
"ICGS",std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): Invalid orthogonalization type.");
519 Teuchos::ParameterList plist;
520 plist.set(
"Block Size",blockSize_);
521 plist.set(
"Full Ortho",fullOrtho_);
525 Teuchos::RCP<LOBPCG<ScalarType,MV,OP> > lobpcg_solver
528 Teuchos::RCP< const MV > probauxvecs = problem_->getAuxVecs();
529 if (probauxvecs != Teuchos::null) {
530 lobpcg_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs) );
537 int curNumLocked = 0;
538 Teuchos::RCP<MV> lockvecs;
540 lockvecs = MVT::Clone(*problem_->getInitVec(),maxLocked_);
542 std::vector<MagnitudeType> lockvals;
551 Teuchos::RCP<MV> workMV;
552 if (fullOrtho_ ==
false && recover_ ==
true) {
553 workMV = MVT::Clone(*problem_->getInitVec(),2*3*blockSize_);
555 else if (useLocking_) {
556 if (problem_->getM() != Teuchos::null) {
557 workMV = MVT::Clone(*problem_->getInitVec(),4*blockSize_);
560 workMV = MVT::Clone(*problem_->getInitVec(),2*blockSize_);
567 problem_->setSolution(sol);
570 if (state_ != Teuchos::null) {
571 lobpcg_solver->initialize(*state_);
576#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
577 Teuchos::TimeMonitor slvtimer(*_timerSolve);
583 lobpcg_solver->iterate();
590 if (debugTest_ != Teuchos::null && debugTest_->getStatus() ==
Passed) {
591 throw AnasaziError(
"Anasazi::LOBPCGSolMgr::solve(): User-specified debug status test returned Passed.");
598 else if (ordertest->getStatus() ==
Passed || (maxtest != Teuchos::null && maxtest->getStatus() ==
Passed) ) {
609 else if (locktest != Teuchos::null && locktest->getStatus() ==
Passed) {
611#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
612 Teuchos::TimeMonitor lcktimer(*_timerLocking);
616 TEUCHOS_TEST_FOR_EXCEPTION(locktest->howMany() <= 0,std::logic_error,
617 "Anasazi::LOBPCGSolMgr::solve(): status test mistake: howMany() non-positive.");
618 TEUCHOS_TEST_FOR_EXCEPTION(locktest->howMany() != (
int)locktest->whichVecs().size(),std::logic_error,
619 "Anasazi::LOBPCGSolMgr::solve(): status test mistake: howMany() not consistent with whichVecs().");
620 TEUCHOS_TEST_FOR_EXCEPTION(curNumLocked == maxLocked_,std::logic_error,
621 "Anasazi::LOBPCGSolMgr::solve(): status test mistake: locking not deactivated.");
623 int numnew = locktest->howMany();
624 std::vector<int> indnew = locktest->whichVecs();
627 if (curNumLocked + numnew > maxLocked_) {
628 numnew = maxLocked_ - curNumLocked;
629 indnew.resize(numnew);
634 bool hadP = lobpcg_solver->hasP();
638 printer->print(
Debug,
"Locking vectors: ");
639 for (
unsigned int i=0; i<indnew.size(); i++) {printer->stream(
Debug) <<
" " << indnew[i];}
640 printer->print(
Debug,
"\n");
642 std::vector<MagnitudeType> newvals(numnew);
643 Teuchos::RCP<const MV> newvecs;
647 newvecs = MVT::CloneView(*lobpcg_solver->getRitzVectors(),indnew);
649 std::vector<Value<ScalarType> > allvals = lobpcg_solver->getRitzValues();
650 for (
int i=0; i<numnew; i++) {
651 newvals[i] = allvals[indnew[i]].realpart;
656 std::vector<int> indlock(numnew);
657 for (
int i=0; i<numnew; i++) indlock[i] = curNumLocked+i;
658 MVT::SetBlock(*newvecs,indlock,*lockvecs);
659 newvecs = Teuchos::null;
662 lockvals.insert(lockvals.end(),newvals.begin(),newvals.end());
663 curNumLocked += numnew;
666 std::vector<int> indlock(curNumLocked);
667 for (
int i=0; i<curNumLocked; i++) indlock[i] = i;
668 Teuchos::RCP<const MV> curlocked = MVT::CloneView(*lockvecs,indlock);
669 if (probauxvecs != Teuchos::null) {
670 lobpcg_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs,curlocked) );
673 lobpcg_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(curlocked) );
677 ordertest->setAuxVals(lockvals);
681 Teuchos::RCP<MV> newstateX, newstateMX, newstateP, newstateMP;
686 std::vector<int> bsind(blockSize_);
687 for (
int i=0; i<blockSize_; i++) bsind[i] = i;
688 newstateX = MVT::CloneViewNonConst(*workMV,bsind);
689 MVT::SetBlock(*state.
X,bsind,*newstateX);
691 if (state.
MX != Teuchos::null) {
692 std::vector<int> block3(blockSize_);
693 for (
int i=0; i<blockSize_; i++) block3[i] = 2*blockSize_+i;
694 newstateMX = MVT::CloneViewNonConst(*workMV,block3);
695 MVT::SetBlock(*state.
MX,bsind,*newstateMX);
700 Teuchos::RCP<MV> newX = MVT::CloneViewNonConst(*newstateX,indnew);
701 MVT::MvRandom(*newX);
703 if (newstateMX != Teuchos::null) {
704 Teuchos::RCP<MV> newMX = MVT::CloneViewNonConst(*newstateMX,indnew);
705 OPT::Apply(*problem_->getM(),*newX,*newMX);
709 Teuchos::Array<Teuchos::RCP<const MV> > curauxvecs = lobpcg_solver->getAuxVecs();
710 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC;
712 ortho->projectAndNormalizeMat(*newstateX,curauxvecs,dummyC,Teuchos::null,newstateMX);
717 std::vector<int> block2(blockSize_);
718 for (
int i=0; i<blockSize_; i++) block2[i] = blockSize_+i;
719 newstateP = MVT::CloneViewNonConst(*workMV,block2);
720 MVT::SetBlock(*state.
P,bsind,*newstateP);
722 if (state.
MP != Teuchos::null) {
723 std::vector<int> block4(blockSize_);
724 for (
int i=0; i<blockSize_; i++) block4[i] = 3*blockSize_+i;
725 newstateMP = MVT::CloneViewNonConst(*workMV,block4);
726 MVT::SetBlock(*state.
MP,bsind,*newstateMP);
731 curauxvecs.push_back(newstateX);
732 ortho->projectAndNormalizeMat(*newstateP,curauxvecs,dummyC,Teuchos::null,newstateMP);
736 ortho->projectAndNormalizeMat(*newstateP,curauxvecs,dummyC,Teuchos::null,newstateMP);
741 newstate.
X = newstateX;
742 newstate.
MX = newstateMX;
743 newstate.
P = newstateP;
744 newstate.
MP = newstateMP;
745 lobpcg_solver->initialize(newstate);
748 if (curNumLocked == maxLocked_) {
750 combotest->removeTest(locktest);
754 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): Invalid return from lobpcg_solver::iterate().");
763 if (fullOrtho_==
true || recover_==
false) {
767 printer->stream(
Warnings) <<
"Error! Caught LOBPCGRitzFailure at iteration " << lobpcg_solver->getNumIters() << std::endl
768 <<
"Will not try to recover." << std::endl;
771 printer->stream(
Warnings) <<
"Error! Caught LOBPCGRitzFailure at iteration " << lobpcg_solver->getNumIters() << std::endl
772 <<
"Full orthogonalization is off; will try to recover." << std::endl;
778 Teuchos::RCP<MV> restart, Krestart, Mrestart;
779 int localsize = lobpcg_solver->hasP() ? 3*blockSize_ : 2*blockSize_;
780 bool hasM = problem_->getM() != Teuchos::null;
782 std::vector<int> recind(localsize);
783 for (
int i=0; i<localsize; i++) recind[i] = i;
784 restart = MVT::CloneViewNonConst(*workMV,recind);
787 std::vector<int> recind(localsize);
788 for (
int i=0; i<localsize; i++) recind[i] = localsize+i;
789 Krestart = MVT::CloneViewNonConst(*workMV,recind);
802 std::vector<int> blk1(blockSize_);
803 for (
int i=0; i < blockSize_; i++) blk1[i] = i;
804 MVT::SetBlock(*curstate.
X,blk1,*restart);
808 MVT::SetBlock(*curstate.
MX,blk1,*Mrestart);
814 std::vector<int> blk2(blockSize_);
815 for (
int i=0; i < blockSize_; i++) blk2[i] = blockSize_+i;
816 MVT::SetBlock(*curstate.
H,blk2,*restart);
820 MVT::SetBlock(*curstate.
MH,blk2,*Mrestart);
824 if (localsize == 3*blockSize_) {
825 std::vector<int> blk3(blockSize_);
826 for (
int i=0; i < blockSize_; i++) blk3[i] = 2*blockSize_+i;
827 MVT::SetBlock(*curstate.
P,blk3,*restart);
831 MVT::SetBlock(*curstate.
MP,blk3,*Mrestart);
835 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC;
836 Teuchos::Array<Teuchos::RCP<const MV> > Q;
838 if (curNumLocked > 0) {
839 std::vector<int> indlock(curNumLocked);
840 for (
int i=0; i<curNumLocked; i++) indlock[i] = i;
841 Teuchos::RCP<const MV> curlocked = MVT::CloneView(*lockvecs,indlock);
842 Q.push_back(curlocked);
844 if (probauxvecs != Teuchos::null) {
845 Q.push_back(probauxvecs);
848 int rank = ortho->projectAndNormalizeMat(*restart,Q,dummyC,Teuchos::null,Mrestart);
849 if (rank < blockSize_) {
851 printer->stream(
Errors) <<
"Error! Recovered basis only rank " << rank <<
". Block size is " << blockSize_ <<
".\n"
852 <<
"Recovery failed." << std::endl;
856 if (rank < localsize) {
858 std::vector<int> redind(localsize);
859 for (
int i=0; i<localsize; i++) redind[i] = i;
861 restart = MVT::CloneViewNonConst(*restart,redind);
862 Krestart = MVT::CloneViewNonConst(*Krestart,redind);
870 Teuchos::SerialDenseMatrix<int,ScalarType> KK(localsize,localsize), MM(localsize,localsize), S(localsize,localsize);
871 std::vector<MagnitudeType> theta(localsize);
875 MVT::MvTransMv(1.0,*restart,*Mrestart,MM);
878 OPT::Apply(*problem_->getOperator(),*restart,*Krestart);
881 MVT::MvTransMv(1.0,*restart,*Krestart,KK);
883 msutils::directSolver(localsize,KK,Teuchos::rcpFromRef(MM),S,theta,rank,1);
884 if (rank < blockSize_) {
885 printer->stream(
Errors) <<
"Error! Recovered basis of rank " << rank <<
" produced only " << rank <<
"ritz vectors.\n"
886 <<
"Block size is " << blockSize_ <<
".\n"
887 <<
"Recovery failed." << std::endl;
894 Teuchos::BLAS<int,ScalarType> blas;
895 std::vector<int> order(rank);
897 sorter->sort( theta, Teuchos::rcpFromRef(order),rank );
899 Teuchos::SerialDenseMatrix<int,ScalarType> curS(Teuchos::View,S,rank,rank);
900 msutils::permuteVectors(order,curS);
903 Teuchos::SerialDenseMatrix<int,ScalarType> S1(Teuchos::View,S,localsize,blockSize_);
907 Teuchos::RCP<MV> newX;
909 std::vector<int> bsind(blockSize_);
910 for (
int i=0; i<blockSize_; i++) bsind[i] = i;
911 newX = MVT::CloneViewNonConst(*Krestart,bsind);
913 MVT::MvTimesMatAddMv(1.0,*restart,S1,0.0,*newX);
916 theta.resize(blockSize_);
917 newstate.
T = Teuchos::rcpFromRef(theta);
919 lobpcg_solver->initialize(newstate);
923 <<
"Anasazi::LOBPCGSolMgr::solve() caught unexpected exception from Anasazi::LOBPCG::iterate() at iteration " << lobpcg_solver->getNumIters() << std::endl
924 << err.what() << std::endl
925 <<
"Anasazi::LOBPCGSolMgr::solve() returning Unconverged with no solutions." << std::endl;
931 sol.
numVecs = ordertest->howMany();
933 sol.
Evecs = MVT::Clone(*problem_->getInitVec(),sol.
numVecs);
936 std::vector<MagnitudeType> vals(sol.
numVecs);
939 std::vector<int> which = ordertest->whichVecs();
943 std::vector<int> inlocked(0), insolver(0);
944 for (
unsigned int i=0; i<which.size(); i++) {
946 TEUCHOS_TEST_FOR_EXCEPTION(which[i] >= blockSize_,std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): positive indexing mistake from ordertest.");
947 insolver.push_back(which[i]);
951 TEUCHOS_TEST_FOR_EXCEPTION(which[i] < -curNumLocked,std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): negative indexing mistake from ordertest.");
952 inlocked.push_back(which[i] + curNumLocked);
956 TEUCHOS_TEST_FOR_EXCEPTION(insolver.size() + inlocked.size() != (
unsigned int)sol.
numVecs,std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): indexing mistake.");
959 if (insolver.size() > 0) {
961 int lclnum = insolver.size();
962 std::vector<int> tosol(lclnum);
963 for (
int i=0; i<lclnum; i++) tosol[i] = i;
964 Teuchos::RCP<const MV> v = MVT::CloneView(*lobpcg_solver->getRitzVectors(),insolver);
965 MVT::SetBlock(*v,tosol,*sol.
Evecs);
967 std::vector<Value<ScalarType> > fromsolver = lobpcg_solver->getRitzValues();
968 for (
unsigned int i=0; i<insolver.size(); i++) {
969 vals[i] = fromsolver[insolver[i]].realpart;
974 if (inlocked.size() > 0) {
975 int solnum = insolver.size();
977 int lclnum = inlocked.size();
978 std::vector<int> tosol(lclnum);
979 for (
int i=0; i<lclnum; i++) tosol[i] = solnum + i;
980 Teuchos::RCP<const MV> v = MVT::CloneView(*lockvecs,inlocked);
981 MVT::SetBlock(*v,tosol,*sol.
Evecs);
983 for (
unsigned int i=0; i<inlocked.size(); i++) {
984 vals[i+solnum] = lockvals[inlocked[i]];
990 std::vector<int> order(sol.
numVecs);
991 sorter->sort( vals, Teuchos::rcpFromRef(order), sol.
numVecs);
993 for (
int i=0; i<sol.
numVecs; i++) {
994 sol.
Evals[i].realpart = vals[i];
995 sol.
Evals[i].imagpart = MT::zero();
1007 lobpcg_solver->currentStatus(printer->stream(
FinalSummary));
1010#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1012 Teuchos::TimeMonitor::summarize( printer->stream(
TimingDetails ) );
1016 problem_->setSolution(sol);
1017 printer->stream(
Debug) <<
"Returning " << sol.
numVecs <<
" eigenpairs to eigenproblem." << std::endl;
1020 numIters_ = lobpcg_solver->getNumIters();