42 #ifndef ANASAZI_BLOCKDAVIDSON_SOLMGR_HPP 43 #define ANASAZI_BLOCKDAVIDSON_SOLMGR_HPP 65 #include "Teuchos_BLAS.hpp" 66 #include "Teuchos_LAPACK.hpp" 67 #include "Teuchos_TimeMonitor.hpp" 69 # include <Teuchos_FancyOStream.hpp> 125 template<
class ScalarType,
class MV,
class OP>
131 typedef Teuchos::ScalarTraits<ScalarType> SCT;
132 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
133 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
163 Teuchos::ParameterList &pl );
189 Teuchos::Array<Teuchos::RCP<Teuchos::Time> >
getTimers()
const {
190 return Teuchos::tuple(_timerSolve, _timerRestarting, _timerLocking);
242 Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
244 std::string whch_, ortho_;
246 MagnitudeType convtol_, locktol_;
249 bool relconvtol_, rellocktol_;
250 int blockSize_, numBlocks_, numIters_;
254 int numRestartBlocks_;
255 enum ResType convNorm_, lockNorm_;
257 Teuchos::RCP<Teuchos::Time> _timerSolve, _timerRestarting, _timerLocking;
259 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > globalTest_;
260 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > lockingTest_;
261 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > debugTest_;
263 Teuchos::RCP<BasicOutputManager<ScalarType> > printer_;
268 template<
class ScalarType,
class MV,
class OP>
271 Teuchos::ParameterList &pl ) :
275 convtol_(MT::prec()),
285 inSituRestart_(false),
287 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
288 , _timerSolve(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidsonSolMgr::solve()")),
289 _timerRestarting(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidsonSolMgr restarting")),
290 _timerLocking(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockDavidsonSolMgr locking"))
293 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument,
"Problem not given to solver manager.");
294 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(), std::invalid_argument,
"Problem not set.");
295 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isHermitian(), std::invalid_argument,
"Problem not symmetric.");
296 TEUCHOS_TEST_FOR_EXCEPTION(problem_->getInitVec() == Teuchos::null,std::invalid_argument,
"Problem does not contain initial vectors to clone from.");
301 whch_ = pl.get(
"Which",whch_);
302 TEUCHOS_TEST_FOR_EXCEPTION(whch_ !=
"SM" && whch_ !=
"LM" && whch_ !=
"SR" && whch_ !=
"LR",std::invalid_argument,
"Invalid sorting string.");
305 ortho_ = pl.get(
"Orthogonalization",ortho_);
306 if (ortho_ !=
"DGKS" && ortho_ !=
"SVQB") {
311 convtol_ = pl.get(
"Convergence Tolerance",convtol_);
312 relconvtol_ = pl.get(
"Relative Convergence Tolerance",relconvtol_);
313 strtmp = pl.get(
"Convergence Norm",std::string(
"2"));
315 convNorm_ = RES_2NORM;
317 else if (strtmp ==
"M") {
318 convNorm_ = RES_ORTH;
321 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
322 "Anasazi::BlockDavidsonSolMgr: Invalid Convergence Norm.");
326 useLocking_ = pl.get(
"Use Locking",useLocking_);
327 rellocktol_ = pl.get(
"Relative Locking Tolerance",rellocktol_);
329 locktol_ = convtol_/10;
330 locktol_ = pl.get(
"Locking Tolerance",locktol_);
331 strtmp = pl.get(
"Locking Norm",std::string(
"2"));
333 lockNorm_ = RES_2NORM;
335 else if (strtmp ==
"M") {
336 lockNorm_ = RES_ORTH;
339 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
340 "Anasazi::BlockDavidsonSolMgr: Invalid Locking Norm.");
344 maxRestarts_ = pl.get(
"Maximum Restarts",maxRestarts_);
347 blockSize_ = pl.get(
"Block Size",problem_->getNEV());
348 TEUCHOS_TEST_FOR_EXCEPTION(blockSize_ <= 0, std::invalid_argument,
349 "Anasazi::BlockDavidsonSolMgr: \"Block Size\" must be strictly positive.");
350 numBlocks_ = pl.get(
"Num Blocks",2);
351 TEUCHOS_TEST_FOR_EXCEPTION(numBlocks_ <= 1, std::invalid_argument,
352 "Anasazi::BlockDavidsonSolMgr: \"Num Blocks\" must be >= 1.");
356 maxLocked_ = pl.get(
"Max Locked",problem_->getNEV());
361 if (maxLocked_ == 0) {
364 TEUCHOS_TEST_FOR_EXCEPTION(maxLocked_ < 0, std::invalid_argument,
365 "Anasazi::BlockDavidsonSolMgr: \"Max Locked\" must be positive.");
366 TEUCHOS_TEST_FOR_EXCEPTION(maxLocked_ + blockSize_ < problem_->getNEV(),
367 std::invalid_argument,
368 "Anasazi::BlockDavidsonSolMgr: Not enough storage space for requested number of eigenpairs.");
369 TEUCHOS_TEST_FOR_EXCEPTION(static_cast<ptrdiff_t>(numBlocks_)*blockSize_ + maxLocked_ >
MVT::GetGlobalLength(*problem_->getInitVec()),
370 std::invalid_argument,
371 "Anasazi::BlockDavidsonSolMgr: Potentially impossible orthogonality requests. Reduce basis size or locking size.");
374 lockQuorum_ = pl.get(
"Locking Quorum",lockQuorum_);
375 TEUCHOS_TEST_FOR_EXCEPTION(lockQuorum_ <= 0,
376 std::invalid_argument,
377 "Anasazi::BlockDavidsonSolMgr: \"Locking Quorum\" must be strictly positive.");
381 numRestartBlocks_ = pl.get(
"Num Restart Blocks",numRestartBlocks_);
382 TEUCHOS_TEST_FOR_EXCEPTION(numRestartBlocks_ <= 0, std::invalid_argument,
383 "Anasazi::BlockDavidsonSolMgr: \"Num Restart Blocks\" must be strictly positive.");
384 TEUCHOS_TEST_FOR_EXCEPTION(numRestartBlocks_ >= numBlocks_, std::invalid_argument,
385 "Anasazi::BlockDavidsonSolMgr: \"Num Restart Blocks\" must be strictly less than \"Num Blocks\".");
388 if (pl.isParameter(
"In Situ Restarting")) {
389 if (Teuchos::isParameterType<bool>(pl,
"In Situ Restarting")) {
390 inSituRestart_ = pl.get(
"In Situ Restarting",inSituRestart_);
392 inSituRestart_ = ( Teuchos::getParameter<int>(pl,
"In Situ Restarting") != 0 );
397 std::string fntemplate =
"";
398 bool allProcs =
false;
399 if (pl.isParameter(
"Output on all processors")) {
400 if (Teuchos::isParameterType<bool>(pl,
"Output on all processors")) {
401 allProcs = pl.get(
"Output on all processors",allProcs);
403 allProcs = ( Teuchos::getParameter<int>(pl,
"Output on all processors") != 0 );
406 fntemplate = pl.get(
"Output filename template",fntemplate);
411 MPI_Initialized(&mpiStarted);
412 if (mpiStarted) MPI_Comm_rank(MPI_COMM_WORLD, &MyPID);
417 if (fntemplate !=
"") {
418 std::ostringstream MyPIDstr;
422 while ( (pos = fntemplate.find(
"%d",start)) != -1 ) {
423 fntemplate.replace(pos,2,MyPIDstr.str());
427 Teuchos::RCP<ostream> osp;
428 if (fntemplate !=
"") {
429 osp = Teuchos::rcp(
new std::ofstream(fntemplate.c_str(),std::ios::out | std::ios::app) );
431 osp = Teuchos::rcpFromRef(std::cout);
432 std::cout <<
"Anasazi::BlockDavidsonSolMgr::constructor(): Could not open file for write: " << fntemplate << std::endl;
436 osp = Teuchos::rcpFromRef(std::cout);
440 if (pl.isParameter(
"Verbosity")) {
441 if (Teuchos::isParameterType<int>(pl,
"Verbosity")) {
442 verbosity = pl.get(
"Verbosity", verbosity);
444 verbosity = (int)Teuchos::getParameter<Anasazi::MsgType>(pl,
"Verbosity");
459 template<
class ScalarType,
class MV,
class OP>
465 const int nev = problem_->getNEV();
468 Teuchos::RCP<Teuchos::FancyOStream>
469 out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(printer_->stream(
Debug)));
470 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
471 *out <<
"Entering Anasazi::BlockDavidsonSolMgr::solve()\n";
482 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convtest;
483 if (globalTest_ == Teuchos::null) {
487 convtest = globalTest_;
489 Teuchos::RCP<StatusTestWithOrdering<ScalarType,MV,OP> > ordertest
492 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > locktest;
494 if (lockingTest_ == Teuchos::null) {
498 locktest = lockingTest_;
502 Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests;
503 alltests.push_back(ordertest);
504 if (locktest != Teuchos::null) alltests.push_back(locktest);
505 if (debugTest_ != Teuchos::null) alltests.push_back(debugTest_);
507 Teuchos::RCP<StatusTestCombo<ScalarType,MV,OP> > combotest
510 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest;
511 if ( printer_->isVerbosity(
Debug) ) {
520 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho;
521 if (ortho_==
"SVQB") {
523 }
else if (ortho_==
"DGKS") {
526 TEUCHOS_TEST_FOR_EXCEPTION(ortho_!=
"SVQB"&&ortho_!=
"DGKS",std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): Invalid orthogonalization type.");
531 Teuchos::ParameterList plist;
532 plist.set(
"Block Size",blockSize_);
533 plist.set(
"Num Blocks",numBlocks_);
537 Teuchos::RCP<BlockDavidson<ScalarType,MV,OP> > bd_solver
540 Teuchos::RCP< const MV > probauxvecs = problem_->getAuxVecs();
541 if (probauxvecs != Teuchos::null) {
542 bd_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs) );
549 int curNumLocked = 0;
550 Teuchos::RCP<MV> lockvecs;
556 if (maxLocked_ > 0) {
557 lockvecs =
MVT::Clone(*problem_->getInitVec(),maxLocked_);
559 std::vector<MagnitudeType> lockvals;
607 Teuchos::RCP<MV> workMV;
608 if (inSituRestart_ ==
false) {
610 if (useLocking_==
true || maxRestarts_ > 0) {
611 workMV =
MVT::Clone(*problem_->getInitVec(),(numBlocks_-1)*blockSize_);
615 workMV = Teuchos::null;
624 if (maxRestarts_ > 0) {
625 workMV =
MVT::Clone(*problem_->getInitVec(),1);
628 workMV = Teuchos::null;
633 const ScalarType ONE = SCT::one();
634 const ScalarType ZERO = SCT::zero();
635 Teuchos::LAPACK<int,ScalarType> lapack;
636 Teuchos::BLAS<int,ScalarType> blas;
641 problem_->setSolution(sol);
647 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 648 Teuchos::TimeMonitor slvtimer(*_timerSolve);
654 bd_solver->iterate();
661 if (debugTest_ != Teuchos::null && debugTest_->getStatus() ==
Passed) {
662 throw AnasaziError(
"Anasazi::BlockDavidsonSolMgr::solve(): User-specified debug status test returned Passed.");
669 else if (ordertest->getStatus() ==
Passed ) {
680 else if ( bd_solver->getCurSubspaceDim() == bd_solver->getMaxSubspaceDim() ) {
682 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 683 Teuchos::TimeMonitor restimer(*_timerRestarting);
686 if ( numRestarts >= maxRestarts_ ) {
691 printer_->stream(
IterationDetails) <<
" Performing restart number " << numRestarts <<
" of " << maxRestarts_ << std::endl << std::endl;
694 int curdim = state.
curDim;
695 int newdim = numRestartBlocks_*blockSize_;
697 # ifdef TEUCHOS_DEBUG 699 std::vector<Value<ScalarType> > ritzvalues = bd_solver->getRitzValues();
700 *out <<
"Ritz values from solver:\n";
701 for (
unsigned int i=0; i<ritzvalues.size(); i++) {
702 *out << ritzvalues[i].realpart <<
" ";
710 Teuchos::SerialDenseMatrix<int,ScalarType> S(curdim,curdim);
711 std::vector<MagnitudeType> theta(curdim);
713 # ifdef TEUCHOS_DEBUG 715 std::stringstream os;
716 os <<
"KK before HEEV...\n" 717 << *state.
KK <<
"\n";
721 int info = msutils::directSolver(curdim,*state.
KK,Teuchos::null,S,theta,rank,10);
722 TEUCHOS_TEST_FOR_EXCEPTION(info != 0 ,std::logic_error,
723 "Anasazi::BlockDavidsonSolMgr::solve(): error calling SolverUtils::directSolver.");
724 TEUCHOS_TEST_FOR_EXCEPTION(rank != curdim,std::logic_error,
725 "Anasazi::BlockDavidsonSolMgr::solve(): direct solve did not compute all eigenvectors.");
727 # ifdef TEUCHOS_DEBUG 729 std::stringstream os;
730 *out <<
"Ritz values from heev(KK):\n";
731 for (
unsigned int i=0; i<theta.size(); i++) *out << theta[i] <<
" ";
732 os <<
"\nRitz vectors from heev(KK):\n" 741 std::vector<int> order(curdim);
742 sorter->sort(theta,Teuchos::rcpFromRef(order),curdim);
745 msutils::permuteVectors(order,S);
747 # ifdef TEUCHOS_DEBUG 749 std::stringstream os;
750 *out <<
"Ritz values from heev(KK) after sorting:\n";
751 std::copy(theta.begin(), theta.end(), std::ostream_iterator<ScalarType>(*out,
" "));
752 os <<
"\nRitz vectors from heev(KK) after sorting:\n" 759 Teuchos::SerialDenseMatrix<int,ScalarType> Sr(Teuchos::View,S,curdim,newdim);
760 # ifdef TEUCHOS_DEBUG 762 std::stringstream os;
763 os <<
"Significant primitive Ritz vectors:\n" 770 Teuchos::SerialDenseMatrix<int,ScalarType> newKK(newdim,newdim);
772 Teuchos::SerialDenseMatrix<int,ScalarType> KKtmp(curdim,newdim),
773 KKold(Teuchos::View,*state.
KK,curdim,curdim);
776 teuchosRet = KKtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,ONE,KKold,Sr,ZERO);
777 TEUCHOS_TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
778 "Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
780 teuchosRet = newKK.multiply(Teuchos::CONJ_TRANS,Teuchos::NO_TRANS,ONE,Sr,KKtmp,ZERO);
781 TEUCHOS_TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
782 "Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
784 for (
int j=0; j<newdim-1; ++j) {
785 for (
int i=j+1; i<newdim; ++i) {
786 newKK(i,j) = SCT::conjugate(newKK(j,i));
790 # ifdef TEUCHOS_DEBUG 792 std::stringstream os;
802 rstate.
KK = Teuchos::rcpFromRef(newKK);
809 rstate.
KX = state.
KX;
810 rstate.
MX = state.
MX;
812 rstate.
T = Teuchos::rcp(
new std::vector<MagnitudeType>(theta.begin(),theta.begin()+newdim) );
814 if (inSituRestart_ ==
true) {
815 # ifdef TEUCHOS_DEBUG 816 *out <<
"Beginning in-situ restart...\n";
820 Teuchos::RCP<MV> solverbasis = Teuchos::rcp_const_cast<MV>(state.
V);
824 std::vector<ScalarType> tau(newdim), work(newdim);
826 lapack.GEQRF(curdim,newdim,Sr.values(),Sr.stride(),&tau[0],&work[0],work.size(),&geqrf_info);
827 TEUCHOS_TEST_FOR_EXCEPTION(geqrf_info != 0,std::logic_error,
828 "Anasazi::BlockDavidsonSolMgr::solve(): error calling GEQRF during restarting.");
829 if (printer_->isVerbosity(
Debug)) {
830 Teuchos::SerialDenseMatrix<int,ScalarType> R(Teuchos::Copy,Sr,newdim,newdim);
831 for (
int j=0; j<newdim; j++) {
832 R(j,j) = SCT::magnitude(R(j,j)) - 1.0;
833 for (
int i=j+1; i<newdim; i++) {
837 printer_->stream(
Debug) <<
"||Triangular factor of Sr - I||: " << R.normFrobenius() << std::endl;
844 std::vector<int> curind(curdim);
845 for (
int i=0; i<curdim; i++) curind[i] = i;
847 msutils::applyHouse(newdim,*oldV,Sr,tau,workMV);
853 rstate.
V = solverbasis;
856 # ifdef TEUCHOS_DEBUG 857 *out <<
"Beginning ex-situ restart...\n";
860 std::vector<int> curind(curdim), newind(newdim);
861 for (
int i=0; i<curdim; i++) curind[i] = i;
862 for (
int i=0; i<newdim; i++) newind[i] = i;
874 bd_solver->initialize(rstate);
881 else if (locktest != Teuchos::null && locktest->getStatus() ==
Passed) {
883 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 884 Teuchos::TimeMonitor lcktimer(*_timerLocking);
890 const int curdim = state.
curDim;
894 TEUCHOS_TEST_FOR_EXCEPTION(locktest->howMany() <= 0,std::logic_error,
895 "Anasazi::BlockDavidsonSolMgr::solve(): status test mistake: howMany() non-positive.");
896 TEUCHOS_TEST_FOR_EXCEPTION(locktest->howMany() != (int)locktest->whichVecs().size(),std::logic_error,
897 "Anasazi::BlockDavidsonSolMgr::solve(): status test mistake: howMany() not consistent with whichVecs().");
899 TEUCHOS_TEST_FOR_EXCEPTION(curNumLocked == maxLocked_,std::logic_error,
900 "Anasazi::BlockDavidsonSolMgr::solve(): status test mistake: locking not deactivated.");
903 std::vector<int> tmp_vector_int;
904 if (curNumLocked + locktest->howMany() > maxLocked_) {
906 tmp_vector_int.insert(tmp_vector_int.begin(),locktest->whichVecs().begin(),locktest->whichVecs().begin()+maxLocked_-curNumLocked);
909 tmp_vector_int = locktest->whichVecs();
911 const std::vector<int> lockind(tmp_vector_int);
912 const int numNewLocked = lockind.size();
916 const int numUnlocked = curdim-numNewLocked;
917 tmp_vector_int.resize(curdim);
918 for (
int i=0; i<curdim; i++) tmp_vector_int[i] = i;
919 const std::vector<int> curind(tmp_vector_int);
920 tmp_vector_int.resize(numUnlocked);
921 std::set_difference(curind.begin(),curind.end(),lockind.begin(),lockind.end(),tmp_vector_int.begin());
922 const std::vector<int> unlockind(tmp_vector_int);
923 tmp_vector_int.clear();
927 if (printer_->isVerbosity(
Debug)) {
928 printer_->print(
Debug,
"Locking vectors: ");
929 for (
unsigned int i=0; i<lockind.size(); i++) {printer_->stream(
Debug) <<
" " << lockind[i];}
930 printer_->print(
Debug,
"\n");
931 printer_->print(
Debug,
"Not locking vectors: ");
932 for (
unsigned int i=0; i<unlockind.size(); i++) {printer_->stream(
Debug) <<
" " << unlockind[i];}
933 printer_->print(
Debug,
"\n");
944 Teuchos::SerialDenseMatrix<int,ScalarType> S(curdim,curdim);
945 std::vector<MagnitudeType> theta(curdim);
948 int info = msutils::directSolver(curdim,*state.
KK,Teuchos::null,S,theta,rank,10);
949 TEUCHOS_TEST_FOR_EXCEPTION(info != 0 ,std::logic_error,
950 "Anasazi::BlockDavidsonSolMgr::solve(): error calling SolverUtils::directSolver.");
951 TEUCHOS_TEST_FOR_EXCEPTION(rank != curdim,std::logic_error,
952 "Anasazi::BlockDavidsonSolMgr::solve(): direct solve did not compute all eigenvectors.");
955 std::vector<int> order(curdim);
956 sorter->sort(theta,Teuchos::rcpFromRef(order),curdim);
959 msutils::permuteVectors(order,S);
965 Teuchos::SerialDenseMatrix<int,ScalarType> Su(curdim,numUnlocked);
966 for (
int i=0; i<numUnlocked; i++) {
967 blas.COPY(curdim, S[unlockind[i]], 1, Su[i], 1);
980 Teuchos::RCP<MV> defV, augV;
981 if (inSituRestart_ ==
true) {
984 Teuchos::RCP<MV> solverbasis = Teuchos::rcp_const_cast<MV>(state.
V);
988 Teuchos::SerialDenseMatrix<int,ScalarType> copySu(Su);
989 std::vector<ScalarType> tau(numUnlocked), work(numUnlocked);
991 lapack.GEQRF(curdim,numUnlocked,copySu.values(),copySu.stride(),&tau[0],&work[0],work.size(),&info);
992 TEUCHOS_TEST_FOR_EXCEPTION(info != 0,std::logic_error,
993 "Anasazi::BlockDavidsonSolMgr::solve(): error calling GEQRF during restarting.");
994 if (printer_->isVerbosity(
Debug)) {
995 Teuchos::SerialDenseMatrix<int,ScalarType> R(Teuchos::Copy,copySu,numUnlocked,numUnlocked);
996 for (
int j=0; j<numUnlocked; j++) {
997 R(j,j) = SCT::magnitude(R(j,j)) - 1.0;
998 for (
int i=j+1; i<numUnlocked; i++) {
1002 printer_->stream(
Debug) <<
"||Triangular factor of Su - I||: " << R.normFrobenius() << std::endl;
1010 msutils::applyHouse(numUnlocked,*oldV,copySu,tau,workMV);
1012 std::vector<int> defind(numUnlocked), augind(numNewLocked);
1013 for (
int i=0; i<numUnlocked ; i++) defind[i] = i;
1014 for (
int i=0; i<numNewLocked; i++) augind[i] = numUnlocked+i;
1020 std::vector<int> defind(numUnlocked), augind(numNewLocked);
1021 for (
int i=0; i<numUnlocked ; i++) defind[i] = i;
1022 for (
int i=0; i<numNewLocked; i++) augind[i] = numUnlocked+i;
1041 Teuchos::RCP<const MV> curlocked, newLocked;
1042 Teuchos::RCP<MV> augTmp;
1045 if (curNumLocked > 0) {
1046 std::vector<int> curlockind(curNumLocked);
1047 for (
int i=0; i<curNumLocked; i++) curlockind[i] = i;
1051 curlocked = Teuchos::null;
1054 std::vector<int> augtmpind(numNewLocked);
1055 for (
int i=0; i<numNewLocked; i++) augtmpind[i] = curNumLocked+i;
1058 newLocked =
MVT::CloneView(*bd_solver->getRitzVectors(),lockind);
1069 Teuchos::Array<Teuchos::RCP<const MV> > against;
1070 Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC;
1071 if (probauxvecs != Teuchos::null) against.push_back(probauxvecs);
1072 if (curlocked != Teuchos::null) against.push_back(curlocked);
1073 against.push_back(newLocked);
1074 against.push_back(defV);
1075 if (problem_->getM() != Teuchos::null) {
1078 ortho->projectAndNormalizeMat(*augV,against,dummyC,Teuchos::null,augTmp);
1089 Teuchos::SerialDenseMatrix<int,ScalarType> newKK(curdim,curdim);
1091 Teuchos::SerialDenseMatrix<int,ScalarType> KKtmp(curdim,numUnlocked),
1092 KKold(Teuchos::View,*state.
KK,curdim,curdim),
1093 KK11(Teuchos::View,newKK,numUnlocked,numUnlocked);
1096 teuchosRet = KKtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,ONE,KKold,Su,ZERO);
1097 TEUCHOS_TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
1098 "Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
1100 teuchosRet = KK11.multiply(Teuchos::CONJ_TRANS,Teuchos::NO_TRANS,ONE,Su,KKtmp,ZERO);
1101 TEUCHOS_TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
1102 "Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
1107 OPT::Apply(*problem_->getOperator(),*augV,*augTmp);
1108 Teuchos::SerialDenseMatrix<int,ScalarType> KK12(Teuchos::View,newKK,numUnlocked,numNewLocked,0,numUnlocked),
1109 KK22(Teuchos::View,newKK,numNewLocked,numNewLocked,numUnlocked,numUnlocked);
1115 defV = Teuchos::null;
1116 augV = Teuchos::null;
1119 for (
int j=0; j<curdim; ++j) {
1120 for (
int i=j+1; i<curdim; ++i) {
1121 newKK(i,j) = SCT::conjugate(newKK(j,i));
1127 augTmp = Teuchos::null;
1129 std::vector<Value<ScalarType> > allvals = bd_solver->getRitzValues();
1130 for (
int i=0; i<numNewLocked; i++) {
1131 lockvals.push_back(allvals[lockind[i]].realpart);
1134 std::vector<int> indlock(numNewLocked);
1135 for (
int i=0; i<numNewLocked; i++) indlock[i] = curNumLocked+i;
1137 newLocked = Teuchos::null;
1139 curNumLocked += numNewLocked;
1140 std::vector<int> curlockind(curNumLocked);
1141 for (
int i=0; i<curNumLocked; i++) curlockind[i] = i;
1148 ordertest->setAuxVals(lockvals);
1150 Teuchos::Array< Teuchos::RCP<const MV> > aux;
1151 if (probauxvecs != Teuchos::null) aux.push_back(probauxvecs);
1152 aux.push_back(curlocked);
1153 bd_solver->setAuxVecs(aux);
1155 if (curNumLocked == maxLocked_) {
1157 combotest->removeTest(locktest);
1165 if (inSituRestart_) {
1173 rstate.
KK = Teuchos::rcpFromRef(newKK);
1176 bd_solver->initialize(rstate);
1185 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): Invalid return from bd_solver::iterate().");
1190 <<
"Anasazi::BlockDavidsonSolMgr::solve() caught unexpected exception from Anasazi::BlockDavidson::iterate() at iteration " << bd_solver->getNumIters() << std::endl
1191 << err.what() << std::endl
1192 <<
"Anasazi::BlockDavidsonSolMgr::solve() returning Unconverged with no solutions." << std::endl;
1198 workMV = Teuchos::null;
1200 sol.
numVecs = ordertest->howMany();
1205 std::vector<MagnitudeType> vals(sol.
numVecs);
1208 std::vector<int> which = ordertest->whichVecs();
1212 std::vector<int> inlocked(0), insolver(0);
1213 for (
unsigned int i=0; i<which.size(); i++) {
1214 if (which[i] >= 0) {
1215 TEUCHOS_TEST_FOR_EXCEPTION(which[i] >= blockSize_,std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): positive indexing mistake from ordertest.");
1216 insolver.push_back(which[i]);
1220 TEUCHOS_TEST_FOR_EXCEPTION(which[i] < -curNumLocked,std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): negative indexing mistake from ordertest.");
1221 inlocked.push_back(which[i] + curNumLocked);
1225 TEUCHOS_TEST_FOR_EXCEPTION(insolver.size() + inlocked.size() != (
unsigned int)sol.
numVecs,std::logic_error,
"Anasazi::BlockDavidsonSolMgr::solve(): indexing mistake.");
1228 if (insolver.size() > 0) {
1230 int lclnum = insolver.size();
1231 std::vector<int> tosol(lclnum);
1232 for (
int i=0; i<lclnum; i++) tosol[i] = i;
1233 Teuchos::RCP<const MV> v =
MVT::CloneView(*bd_solver->getRitzVectors(),insolver);
1236 std::vector<Value<ScalarType> > fromsolver = bd_solver->getRitzValues();
1237 for (
unsigned int i=0; i<insolver.size(); i++) {
1238 vals[i] = fromsolver[insolver[i]].realpart;
1243 if (inlocked.size() > 0) {
1244 int solnum = insolver.size();
1246 int lclnum = inlocked.size();
1247 std::vector<int> tosol(lclnum);
1248 for (
int i=0; i<lclnum; i++) tosol[i] = solnum + i;
1252 for (
unsigned int i=0; i<inlocked.size(); i++) {
1253 vals[i+solnum] = lockvals[inlocked[i]];
1259 std::vector<int> order(sol.
numVecs);
1260 sorter->sort(vals,Teuchos::rcpFromRef(order),sol.
numVecs);
1262 for (
int i=0; i<sol.
numVecs; i++) {
1263 sol.
Evals[i].realpart = vals[i];
1264 sol.
Evals[i].imagpart = MT::zero();
1276 bd_solver->currentStatus(printer_->stream(
FinalSummary));
1279 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 1281 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails ) );
1285 problem_->setSolution(sol);
1286 printer_->stream(
Debug) <<
"Returning " << sol.
numVecs <<
" eigenpairs to eigenproblem." << std::endl;
1289 numIters_ = bd_solver->getNumIters();
1298 template <
class ScalarType,
class MV,
class OP>
1303 globalTest_ = global;
1306 template <
class ScalarType,
class MV,
class OP>
1307 const Teuchos::RCP< StatusTest<ScalarType,MV,OP> > &
1313 template <
class ScalarType,
class MV,
class OP>
1321 template <
class ScalarType,
class MV,
class OP>
1322 const Teuchos::RCP< StatusTest<ScalarType,MV,OP> > &
1328 template <
class ScalarType,
class MV,
class OP>
1333 lockingTest_ = locking;
1336 template <
class ScalarType,
class MV,
class OP>
1337 const Teuchos::RCP< StatusTest<ScalarType,MV,OP> > &
1340 return lockingTest_;
static ptrdiff_t GetGlobalLength(const MV &mv)
Return the number of rows in the given multivector mv.
Pure virtual base class which describes the basic interface for a solver manager. ...
static void MvRandom(MV &mv)
Replace the vectors in mv with random vectors.
std::vector< Value< ScalarType > > Evals
The computed eigenvalues.
static void MvTimesMatAddMv(const ScalarType alpha, const MV &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta, MV &mv)
Update mv with .
void setLockingStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &locking)
Set the status test defining locking.
ResType
Enumerated type used to specify which residual norm used by residual norm status tests.
A special StatusTest for printing other status tests.
BlockDavidsonSolMgr(const Teuchos::RCP< Eigenproblem< ScalarType, MV, OP > > &problem, Teuchos::ParameterList &pl)
Basic constructor for BlockDavidsonSolMgr.
This class defines the interface required by an eigensolver and status test class to compute solution...
Teuchos::RCP< const MV > R
The current residual vectors.
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > KK
The current projected K matrix.
An implementation of the Anasazi::SortManager that performs a collection of common sorting techniques...
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > & getDebugStatusTest() const
Get the status test for debugging.
Virtual base class which defines basic traits for the operator type.
Teuchos::RCP< MV > Evecs
The computed eigenvectors.
Status test for forming logical combinations of other status tests.
Teuchos::RCP< const MV > KX
The image of the current eigenvectors under K.
The Anasazi::SolverManager is a templated virtual base class that defines the basic interface that an...
static void Apply(const OP &Op, const MV &x, MV &y)
Application method which performs operation y = Op*x. An OperatorError exception is thrown if there i...
Basic implementation of the Anasazi::SortManager class.
An implementation of the Anasazi::MatOrthoManager that performs orthogonalization using the SVQB iter...
An exception class parent to all Anasazi exceptions.
This class implements a Block Davidson iteration, a preconditioned iteration for solving linear Hermi...
Implementation of the block Davidson method.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package...
A status test for testing the norm of the eigenvectors residuals along with a set of auxiliary eigenv...
Anasazi's templated, static class providing utilities for the solvers.
int numVecs
The number of computed eigenpairs.
Basic output manager for sending information of select verbosity levels to the appropriate output str...
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > & getLockingStatusTest() const
Get the status test defining locking.
Teuchos::RCP< MV > Espace
An orthonormal basis for the computed eigenspace.
Anasazi's basic output manager for sending information of select verbosity levels to the appropriate ...
Abstract base class which defines the interface required by an eigensolver and status test class to c...
ReturnType
Enumerated type used to pass back information from a solver manager.
Teuchos::RCP< const MV > V
The basis for the Krylov space.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
A status test for testing the norm of the eigenvectors residuals.
virtual ~BlockDavidsonSolMgr()
Destructor.
Traits class which defines basic operations on multivectors.
static void MvTransMv(const ScalarType alpha, const MV &A, const MV &B, Teuchos::SerialDenseMatrix< int, ScalarType > &C)
Compute C := alpha * A^H B.
std::vector< int > index
An index into Evecs to allow compressed storage of eigenvectors for real, non-Hermitian problems...
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > & getGlobalStatusTest() const
Get the status test defining global convergence.
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
Orthogonalization manager based on the SVQB technique described in "A Block Orthogonalization Procedu...
static Teuchos::RCP< MV > CloneViewNonConst(MV &mv, const std::vector< int > &index)
Creates a new MV that shares the selected contents of mv (shallow copy).
Struct for storing an eigenproblem solution.
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Return the eigenvalue problem.
static Teuchos::RCP< const MV > CloneView(const MV &mv, const std::vector< int > &index)
Creates a new const MV that shares the selected contents of mv (shallow copy).
static void SetBlock(const MV &A, const std::vector< int > &index, MV &mv)
Copy the vectors in A to a set of vectors in mv indicated by the indices given in index...
int curDim
The current dimension of the solver.
Structure to contain pointers to BlockDavidson state variables.
Special StatusTest for printing status tests.
A status test for testing the norm of the eigenvectors residuals along with a set of auxiliary eigenv...
int getNumIters() const
Get the iteration count for the most recent call to solve().
void setDebugStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &debug)
Set the status test for debugging.
Teuchos::RCP< const MV > X
The current eigenvectors.
Teuchos::RCP< const MV > MX
The image of the current eigenvectors under M, or Teuchos::null if M was not specified.
Status test for forming logical combinations of other status tests.
An implementation of the Anasazi::MatOrthoManager that performs orthogonalization using (potentially)...
Types and exceptions used within Anasazi solvers and interfaces.
The BlockDavidsonSolMgr provides a powerful solver manager over the BlockDavidson eigensolver...
Common interface of stopping criteria for Anasazi's solvers.
A status test for testing the norm of the eigenvectors residuals.
Basic implementation of the Anasazi::OrthoManager class.
void setGlobalStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &global)
Set the status test defining global convergence.
ReturnType solve()
This method performs possibly repeated calls to the underlying eigensolver's iterate() routine until ...
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
Teuchos::RCP< const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > T
The current Ritz values. This vector is a copy of the internal data.
Class which provides internal utilities for the Anasazi solvers.