399 const int nev = problem_->getNEV();
402 Teuchos::RCP<Teuchos::FancyOStream>
403 out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(printer_->stream(
Debug)));
404 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
405 *out <<
"Entering Anasazi::BlockDavidsonSolMgr::solve()\n";
416 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convtest;
417 if (globalTest_ == Teuchos::null) {
421 convtest = globalTest_;
423 Teuchos::RCP<StatusTestWithOrdering<ScalarType,MV,OP> > ordertest
426 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > locktest;
428 if (lockingTest_ == Teuchos::null) {
432 locktest = lockingTest_;
436 Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests;
437 alltests.push_back(ordertest);
438 if (locktest != Teuchos::null) alltests.push_back(locktest);
439 if (debugTest_ != Teuchos::null) alltests.push_back(debugTest_);
441 Teuchos::RCP<StatusTestCombo<ScalarType,MV,OP> > combotest
444 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest;
445 if ( printer_->isVerbosity(
Debug) ) {
454 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho;
455 if (ortho_==
"SVQB") {
457 }
else if (ortho_==
"DGKS") {
460 TEUCHOS_TEST_FOR_EXCEPTION(ortho_!=
"SVQB"&&ortho_!=
"DGKS",std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): Invalid orthogonalization type.");
465 Teuchos::ParameterList plist;
466 plist.set(
"Block Size",blockSize_);
467 plist.set(
"Num Blocks",numBlocks_);
471 Teuchos::RCP<BlockDavidson<ScalarType,MV,OP> > bd_solver
474 Teuchos::RCP< const MV > probauxvecs = problem_->getAuxVecs();
475 if (probauxvecs != Teuchos::null) {
476 bd_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs) );
483 int curNumLocked = 0;
484 Teuchos::RCP<MV> lockvecs;
490 if (maxLocked_ > 0) {
491 lockvecs = MVT::Clone(*problem_->getInitVec(),maxLocked_);
493 std::vector<MagnitudeType> lockvals;
541 Teuchos::RCP<MV> workMV;
542 if (inSituRestart_ ==
false) {
544 if (useLocking_==
true || maxRestarts_ > 0) {
545 workMV = MVT::Clone(*problem_->getInitVec(),(numBlocks_-1)*blockSize_);
549 workMV = Teuchos::null;
558 if (maxRestarts_ > 0) {
559 workMV = MVT::Clone(*problem_->getInitVec(),1);
562 workMV = Teuchos::null;
567 const ScalarType ONE = SCT::one();
568 const ScalarType ZERO = SCT::zero();
569 Teuchos::LAPACK<int,ScalarType> lapack;
570 Teuchos::BLAS<int,ScalarType> blas;
575 problem_->setSolution(sol);
581#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
582 Teuchos::TimeMonitor slvtimer(*_timerSolve);
588 bd_solver->iterate();
595 if (debugTest_ != Teuchos::null && debugTest_->getStatus() ==
Passed) {
596 throw AnasaziError(
"Anasazi::BlockDavidsonSolMgr::solve(): User-specified debug status test returned Passed.");
603 else if (ordertest->getStatus() ==
Passed ) {
614 else if ( bd_solver->getCurSubspaceDim() == bd_solver->getMaxSubspaceDim() ) {
616#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
617 Teuchos::TimeMonitor restimer(*_timerRestarting);
620 if ( numRestarts >= maxRestarts_ ) {
625 printer_->stream(
IterationDetails) <<
" Performing restart number " << numRestarts <<
" of " << maxRestarts_ << std::endl << std::endl;
628 int curdim = state.
curDim;
629 int newdim = numRestartBlocks_*blockSize_;
633 std::vector<Value<ScalarType> > ritzvalues = bd_solver->getRitzValues();
634 *out <<
"Ritz values from solver:\n";
635 for (
unsigned int i=0; i<ritzvalues.size(); i++) {
636 *out << ritzvalues[i].realpart <<
" ";
644 Teuchos::SerialDenseMatrix<int,ScalarType> S(curdim,curdim);
645 std::vector<MagnitudeType> theta(curdim);
649 std::stringstream os;
650 os <<
"KK before HEEV...\n"
651 << printMat(*state.
KK) <<
"\n";
655 int info = msutils::directSolver(curdim,*state.
KK,Teuchos::null,S,theta,rank,10);
656 TEUCHOS_TEST_FOR_EXCEPTION(info != 0 ,std::logic_error,
657 "Anasazi::BlockDavidsonSolMgr::solve(): error calling SolverUtils::directSolver.");
658 TEUCHOS_TEST_FOR_EXCEPTION(rank != curdim,std::logic_error,
659 "Anasazi::BlockDavidsonSolMgr::solve(): direct solve did not compute all eigenvectors.");
663 std::stringstream os;
664 *out <<
"Ritz values from heev(KK):\n";
665 for (
unsigned int i=0; i<theta.size(); i++) *out << theta[i] <<
" ";
666 os <<
"\nRitz vectors from heev(KK):\n"
667 << printMat(S) <<
"\n";
675 std::vector<int> order(curdim);
676 sorter->sort(theta,Teuchos::rcpFromRef(order),curdim);
679 msutils::permuteVectors(order,S);
683 std::stringstream os;
684 *out <<
"Ritz values from heev(KK) after sorting:\n";
685 std::copy(theta.begin(), theta.end(), std::ostream_iterator<ScalarType>(*out,
" "));
686 os <<
"\nRitz vectors from heev(KK) after sorting:\n"
687 << printMat(S) <<
"\n";
693 Teuchos::SerialDenseMatrix<int,ScalarType> Sr(Teuchos::View,S,curdim,newdim);
696 std::stringstream os;
697 os <<
"Significant primitive Ritz vectors:\n"
698 << printMat(Sr) <<
"\n";
704 Teuchos::SerialDenseMatrix<int,ScalarType> newKK(newdim,newdim);
706 Teuchos::SerialDenseMatrix<int,ScalarType> KKtmp(curdim,newdim),
707 KKold(Teuchos::View,*state.
KK,curdim,curdim);
710 teuchosRet = KKtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,ONE,KKold,Sr,ZERO);
711 TEUCHOS_TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
712 "Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
714 teuchosRet = newKK.multiply(Teuchos::CONJ_TRANS,Teuchos::NO_TRANS,ONE,Sr,KKtmp,ZERO);
715 TEUCHOS_TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
716 "Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
718 for (
int j=0; j<newdim-1; ++j) {
719 for (
int i=j+1; i<newdim; ++i) {
720 newKK(i,j) = SCT::conjugate(newKK(j,i));
726 std::stringstream os;
728 << printMat(newKK) <<
"\n";
736 rstate.
KK = Teuchos::rcpFromRef(newKK);
743 rstate.
KX = state.
KX;
744 rstate.
MX = state.
MX;
746 rstate.
T = Teuchos::rcp(
new std::vector<MagnitudeType>(theta.begin(),theta.begin()+newdim) );
748 if (inSituRestart_ ==
true) {
750 *out <<
"Beginning in-situ restart...\n";
754 Teuchos::RCP<MV> solverbasis = Teuchos::rcp_const_cast<MV>(state.
V);
758 std::vector<ScalarType> tau(newdim), work(newdim);
760 lapack.GEQRF(curdim,newdim,Sr.values(),Sr.stride(),&tau[0],&work[0],work.size(),&geqrf_info);
761 TEUCHOS_TEST_FOR_EXCEPTION(geqrf_info != 0,std::logic_error,
762 "Anasazi::BlockDavidsonSolMgr::solve(): error calling GEQRF during restarting.");
763 if (printer_->isVerbosity(
Debug)) {
764 Teuchos::SerialDenseMatrix<int,ScalarType> R(Teuchos::Copy,Sr,newdim,newdim);
765 for (
int j=0; j<newdim; j++) {
766 R(j,j) = SCT::magnitude(R(j,j)) - 1.0;
767 for (
int i=j+1; i<newdim; i++) {
771 printer_->stream(
Debug) <<
"||Triangular factor of Sr - I||: " << R.normFrobenius() << std::endl;
778 std::vector<int> curind(curdim);
779 for (
int i=0; i<curdim; i++) curind[i] = i;
780 Teuchos::RCP<MV> oldV = MVT::CloneViewNonConst(*solverbasis,curind);
781 msutils::applyHouse(newdim,*oldV,Sr,tau,workMV);
787 rstate.
V = solverbasis;
791 *out <<
"Beginning ex-situ restart...\n";
794 std::vector<int> curind(curdim), newind(newdim);
795 for (
int i=0; i<curdim; i++) curind[i] = i;
796 for (
int i=0; i<newdim; i++) newind[i] = i;
797 Teuchos::RCP<const MV> oldV = MVT::CloneView(*state.
V,curind);
798 Teuchos::RCP<MV> newV = MVT::CloneViewNonConst(*workMV ,newind);
800 MVT::MvTimesMatAddMv(ONE,*oldV,Sr,ZERO,*newV);
808 bd_solver->initialize(rstate);
815 else if (locktest != Teuchos::null && locktest->getStatus() ==
Passed) {
817#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
818 Teuchos::TimeMonitor lcktimer(*_timerLocking);
824 const int curdim = state.
curDim;
828 TEUCHOS_TEST_FOR_EXCEPTION(locktest->howMany() <= 0,std::logic_error,
829 "Anasazi::BlockDavidsonSolMgr::solve(): status test mistake: howMany() non-positive.");
830 TEUCHOS_TEST_FOR_EXCEPTION(locktest->howMany() != (
int)locktest->whichVecs().size(),std::logic_error,
831 "Anasazi::BlockDavidsonSolMgr::solve(): status test mistake: howMany() not consistent with whichVecs().");
833 TEUCHOS_TEST_FOR_EXCEPTION(curNumLocked == maxLocked_,std::logic_error,
834 "Anasazi::BlockDavidsonSolMgr::solve(): status test mistake: locking not deactivated.");
837 std::vector<int> tmp_vector_int;
838 if (curNumLocked + locktest->howMany() > maxLocked_) {
840 tmp_vector_int.insert(tmp_vector_int.begin(),locktest->whichVecs().begin(),locktest->whichVecs().begin()+maxLocked_-curNumLocked);
843 tmp_vector_int = locktest->whichVecs();
845 const std::vector<int> lockind(tmp_vector_int);
846 const int numNewLocked = lockind.size();
850 const int numUnlocked = curdim-numNewLocked;
851 tmp_vector_int.resize(curdim);
852 for (
int i=0; i<curdim; i++) tmp_vector_int[i] = i;
853 const std::vector<int> curind(tmp_vector_int);
854 tmp_vector_int.resize(numUnlocked);
855 std::set_difference(curind.begin(),curind.end(),lockind.begin(),lockind.end(),tmp_vector_int.begin());
856 const std::vector<int> unlockind(tmp_vector_int);
857 tmp_vector_int.clear();
861 if (printer_->isVerbosity(
Debug)) {
862 printer_->print(
Debug,
"Locking vectors: ");
863 for (
unsigned int i=0; i<lockind.size(); i++) {printer_->stream(
Debug) <<
" " << lockind[i];}
864 printer_->print(
Debug,
"\n");
865 printer_->print(
Debug,
"Not locking vectors: ");
866 for (
unsigned int i=0; i<unlockind.size(); i++) {printer_->stream(
Debug) <<
" " << unlockind[i];}
867 printer_->print(
Debug,
"\n");
878 Teuchos::SerialDenseMatrix<int,ScalarType> S(curdim,curdim);
879 std::vector<MagnitudeType> theta(curdim);
882 int info = msutils::directSolver(curdim,*state.
KK,Teuchos::null,S,theta,rank,10);
883 TEUCHOS_TEST_FOR_EXCEPTION(info != 0 ,std::logic_error,
884 "Anasazi::BlockDavidsonSolMgr::solve(): error calling SolverUtils::directSolver.");
885 TEUCHOS_TEST_FOR_EXCEPTION(rank != curdim,std::logic_error,
886 "Anasazi::BlockDavidsonSolMgr::solve(): direct solve did not compute all eigenvectors.");
889 std::vector<int> order(curdim);
890 sorter->sort(theta,Teuchos::rcpFromRef(order),curdim);
893 msutils::permuteVectors(order,S);
899 Teuchos::SerialDenseMatrix<int,ScalarType> Su(curdim,numUnlocked);
900 for (
int i=0; i<numUnlocked; i++) {
901 blas.COPY(curdim, S[unlockind[i]], 1, Su[i], 1);
914 Teuchos::RCP<MV> defV, augV;
915 if (inSituRestart_ ==
true) {
918 Teuchos::RCP<MV> solverbasis = Teuchos::rcp_const_cast<MV>(state.
V);
922 Teuchos::SerialDenseMatrix<int,ScalarType> copySu(Su);
923 std::vector<ScalarType> tau(numUnlocked), work(numUnlocked);
925 lapack.GEQRF(curdim,numUnlocked,copySu.values(),copySu.stride(),&tau[0],&work[0],work.size(),&info);
926 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,std::logic_error,
927 "Anasazi::BlockDavidsonSolMgr::solve(): error calling GEQRF during restarting.");
928 if (printer_->isVerbosity(
Debug)) {
929 Teuchos::SerialDenseMatrix<int,ScalarType> R(Teuchos::Copy,copySu,numUnlocked,numUnlocked);
930 for (
int j=0; j<numUnlocked; j++) {
931 R(j,j) = SCT::magnitude(R(j,j)) - 1.0;
932 for (
int i=j+1; i<numUnlocked; i++) {
936 printer_->stream(
Debug) <<
"||Triangular factor of Su - I||: " << R.normFrobenius() << std::endl;
943 Teuchos::RCP<MV> oldV = MVT::CloneViewNonConst(*solverbasis,curind);
944 msutils::applyHouse(numUnlocked,*oldV,copySu,tau,workMV);
946 std::vector<int> defind(numUnlocked), augind(numNewLocked);
947 for (
int i=0; i<numUnlocked ; i++) defind[i] = i;
948 for (
int i=0; i<numNewLocked; i++) augind[i] = numUnlocked+i;
949 defV = MVT::CloneViewNonConst(*solverbasis,defind);
950 augV = MVT::CloneViewNonConst(*solverbasis,augind);
954 std::vector<int> defind(numUnlocked), augind(numNewLocked);
955 for (
int i=0; i<numUnlocked ; i++) defind[i] = i;
956 for (
int i=0; i<numNewLocked; i++) augind[i] = numUnlocked+i;
957 Teuchos::RCP<const MV> oldV = MVT::CloneView(*state.
V,curind);
958 defV = MVT::CloneViewNonConst(*workMV,defind);
959 augV = MVT::CloneViewNonConst(*workMV,augind);
961 MVT::MvTimesMatAddMv(ONE,*oldV,Su,ZERO,*defV);
975 Teuchos::RCP<const MV> curlocked, newLocked;
976 Teuchos::RCP<MV> augTmp;
979 if (curNumLocked > 0) {
980 std::vector<int> curlockind(curNumLocked);
981 for (
int i=0; i<curNumLocked; i++) curlockind[i] = i;
982 curlocked = MVT::CloneView(*lockvecs,curlockind);
985 curlocked = Teuchos::null;
988 std::vector<int> augtmpind(numNewLocked);
989 for (
int i=0; i<numNewLocked; i++) augtmpind[i] = curNumLocked+i;
990 augTmp = MVT::CloneViewNonConst(*lockvecs,augtmpind);
992 newLocked = MVT::CloneView(*bd_solver->getRitzVectors(),lockind);
998 MVT::MvRandom(*augV);
1003 Teuchos::Array<Teuchos::RCP<const MV> > against;
1004 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC;
1005 if (probauxvecs != Teuchos::null) against.push_back(probauxvecs);
1006 if (curlocked != Teuchos::null) against.push_back(curlocked);
1007 against.push_back(newLocked);
1008 against.push_back(defV);
1009 if (problem_->getM() != Teuchos::null) {
1010 OPT::Apply(*problem_->getM(),*augV,*augTmp);
1012 ortho->projectAndNormalizeMat(*augV,against,dummyC,Teuchos::null,augTmp);
1023 Teuchos::SerialDenseMatrix<int,ScalarType> newKK(curdim,curdim);
1025 Teuchos::SerialDenseMatrix<int,ScalarType> KKtmp(curdim,numUnlocked),
1026 KKold(Teuchos::View,*state.
KK,curdim,curdim),
1027 KK11(Teuchos::View,newKK,numUnlocked,numUnlocked);
1030 teuchosRet = KKtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,ONE,KKold,Su,ZERO);
1031 TEUCHOS_TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
1032 "Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
1034 teuchosRet = KK11.multiply(Teuchos::CONJ_TRANS,Teuchos::NO_TRANS,ONE,Su,KKtmp,ZERO);
1035 TEUCHOS_TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
1036 "Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
1041 OPT::Apply(*problem_->getOperator(),*augV,*augTmp);
1042 Teuchos::SerialDenseMatrix<int,ScalarType> KK12(Teuchos::View,newKK,numUnlocked,numNewLocked,0,numUnlocked),
1043 KK22(Teuchos::View,newKK,numNewLocked,numNewLocked,numUnlocked,numUnlocked);
1044 MVT::MvTransMv(ONE,*defV,*augTmp,KK12);
1045 MVT::MvTransMv(ONE,*augV,*augTmp,KK22);
1049 defV = Teuchos::null;
1050 augV = Teuchos::null;
1053 for (
int j=0; j<curdim; ++j) {
1054 for (
int i=j+1; i<curdim; ++i) {
1055 newKK(i,j) = SCT::conjugate(newKK(j,i));
1061 augTmp = Teuchos::null;
1063 std::vector<Value<ScalarType> > allvals = bd_solver->getRitzValues();
1064 for (
int i=0; i<numNewLocked; i++) {
1065 lockvals.push_back(allvals[lockind[i]].realpart);
1068 std::vector<int> indlock(numNewLocked);
1069 for (
int i=0; i<numNewLocked; i++) indlock[i] = curNumLocked+i;
1070 MVT::SetBlock(*newLocked,indlock,*lockvecs);
1071 newLocked = Teuchos::null;
1073 curNumLocked += numNewLocked;
1074 std::vector<int> curlockind(curNumLocked);
1075 for (
int i=0; i<curNumLocked; i++) curlockind[i] = i;
1076 curlocked = MVT::CloneView(*lockvecs,curlockind);
1082 ordertest->setAuxVals(lockvals);
1084 Teuchos::Array< Teuchos::RCP<const MV> > aux;
1085 if (probauxvecs != Teuchos::null) aux.push_back(probauxvecs);
1086 aux.push_back(curlocked);
1087 bd_solver->setAuxVecs(aux);
1089 if (curNumLocked == maxLocked_) {
1091 combotest->removeTest(locktest);
1099 if (inSituRestart_) {
1107 rstate.
KK = Teuchos::rcpFromRef(newKK);
1110 bd_solver->initialize(rstate);
1119 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): Invalid return from bd_solver::iterate().");
1124 <<
"Anasazi::BlockDavidsonSolMgr::solve() caught unexpected exception from Anasazi::BlockDavidson::iterate() at iteration " << bd_solver->getNumIters() << std::endl
1125 << err.what() << std::endl
1126 <<
"Anasazi::BlockDavidsonSolMgr::solve() returning Unconverged with no solutions." << std::endl;
1132 workMV = Teuchos::null;
1134 sol.
numVecs = ordertest->howMany();
1136 sol.
Evecs = MVT::Clone(*problem_->getInitVec(),sol.
numVecs);
1139 std::vector<MagnitudeType> vals(sol.
numVecs);
1142 std::vector<int> which = ordertest->whichVecs();
1146 std::vector<int> inlocked(0), insolver(0);
1147 for (
unsigned int i=0; i<which.size(); i++) {
1148 if (which[i] >= 0) {
1149 TEUCHOS_TEST_FOR_EXCEPTION(which[i] >= blockSize_,std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): positive indexing mistake from ordertest.");
1150 insolver.push_back(which[i]);
1154 TEUCHOS_TEST_FOR_EXCEPTION(which[i] < -curNumLocked,std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): negative indexing mistake from ordertest.");
1155 inlocked.push_back(which[i] + curNumLocked);
1159 TEUCHOS_TEST_FOR_EXCEPTION(insolver.size() + inlocked.size() != (
unsigned int)sol.
numVecs,std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): indexing mistake.");
1162 if (insolver.size() > 0) {
1164 int lclnum = insolver.size();
1165 std::vector<int> tosol(lclnum);
1166 for (
int i=0; i<lclnum; i++) tosol[i] = i;
1167 Teuchos::RCP<const MV> v = MVT::CloneView(*bd_solver->getRitzVectors(),insolver);
1168 MVT::SetBlock(*v,tosol,*sol.
Evecs);
1170 std::vector<Value<ScalarType> > fromsolver = bd_solver->getRitzValues();
1171 for (
unsigned int i=0; i<insolver.size(); i++) {
1172 vals[i] = fromsolver[insolver[i]].realpart;
1177 if (inlocked.size() > 0) {
1178 int solnum = insolver.size();
1180 int lclnum = inlocked.size();
1181 std::vector<int> tosol(lclnum);
1182 for (
int i=0; i<lclnum; i++) tosol[i] = solnum + i;
1183 Teuchos::RCP<const MV> v = MVT::CloneView(*lockvecs,inlocked);
1184 MVT::SetBlock(*v,tosol,*sol.
Evecs);
1186 for (
unsigned int i=0; i<inlocked.size(); i++) {
1187 vals[i+solnum] = lockvals[inlocked[i]];
1193 std::vector<int> order(sol.
numVecs);
1194 sorter->sort(vals,Teuchos::rcpFromRef(order),sol.
numVecs);
1196 for (
int i=0; i<sol.
numVecs; i++) {
1197 sol.
Evals[i].realpart = vals[i];
1198 sol.
Evals[i].imagpart = MT::zero();
1210 bd_solver->currentStatus(printer_->stream(
FinalSummary));
1213#ifdef ANASAZI_TEUCHOS_TIME_MONITOR
1215 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails ) );
1219 problem_->setSolution(sol);
1220 printer_->stream(
Debug) <<
"Returning " << sol.
numVecs <<
" eigenpairs to eigenproblem." << std::endl;
1223 numIters_ = bd_solver->getNumIters();