42 #ifndef ANASAZI_TraceMinBase_SOLMGR_HPP 43 #define ANASAZI_TraceMinBase_SOLMGR_HPP 60 #include "AnasaziStatusTestSpecTrans.hpp" 67 #include "Teuchos_TimeMonitor.hpp" 69 # include <Teuchos_FancyOStream.hpp> 114 template<
class ScalarType,
class MV,
class OP>
120 typedef Teuchos::ScalarTraits<ScalarType> SCT;
121 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
122 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
172 Teuchos::ParameterList &pl );
199 return Teuchos::tuple(_timerSolve, _timerRestarting, _timerLocking);
253 RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
258 int blockSize_, numBlocks_, numRestartBlocks_;
261 RCP<BasicOutputManager<ScalarType> > printer_;
264 MagnitudeType convTol_;
269 MagnitudeType lockTol_;
270 int maxLocked_, lockQuorum_;
271 bool useLocking_, relLockTol_;
275 enum WhenToShiftType whenToShift_;
276 MagnitudeType traceThresh_, shiftTol_;
277 enum HowToShiftType howToShift_;
278 bool useMultipleShifts_, relShiftTol_, considerClusters_;
279 std::string shiftNorm_;
283 std::string ortho_, which_;
284 enum SaddleSolType saddleSolType_;
285 bool projectAllVecs_, projectLockedVecs_, computeAllRes_, useRHSR_, useHarmonic_, noSort_;
286 MagnitudeType alpha_;
289 RCP<Teuchos::Time> _timerSolve, _timerRestarting, _timerLocking;
292 RCP<StatusTest<ScalarType,MV,OP> > globalTest_;
293 RCP<StatusTest<ScalarType,MV,OP> > lockingTest_;
294 RCP<StatusTest<ScalarType,MV,OP> > debugTest_;
299 void setParameters(Teuchos::ParameterList &pl)
const;
301 void printParameters(std::ostream &os)
const;
303 virtual RCP< TraceMinBase<ScalarType,MV,OP> > createSolver(
304 const RCP<
SortManager<
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > &sorter,
307 Teuchos::ParameterList &plist
319 template<
class ScalarType,
class MV,
class OP>
322 Teuchos::ParameterList &pl ) :
324 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
325 , _timerSolve(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBaseSolMgr::solve()")),
326 _timerRestarting(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBaseSolMgr restarting")),
327 _timerLocking(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: TraceMinBaseSolMgr locking"))
330 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument,
"Problem not given to solver manager.");
331 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(), std::invalid_argument,
"Problem not set.");
332 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isHermitian(), std::invalid_argument,
"Problem not symmetric.");
333 TEUCHOS_TEST_FOR_EXCEPTION(problem_->getInitVec() == Teuchos::null,std::invalid_argument,
"Problem does not contain initial vectors to clone from.");
355 std::string fntemplate =
"";
356 bool allProcs =
false;
357 if (pl.isParameter(
"Output on all processors")) {
358 if (Teuchos::isParameterType<bool>(pl,
"Output on all processors")) {
359 allProcs = pl.get(
"Output on all processors",allProcs);
361 allProcs = ( Teuchos::getParameter<int>(pl,
"Output on all processors") != 0 );
364 fntemplate = pl.get(
"Output filename template",fntemplate);
369 MPI_Initialized(&mpiStarted);
370 if (mpiStarted) MPI_Comm_rank(MPI_COMM_WORLD, &MyPID);
375 if (fntemplate !=
"") {
376 std::ostringstream MyPIDstr;
380 while ( (pos = fntemplate.find(
"%d",start)) != -1 ) {
381 fntemplate.replace(pos,2,MyPIDstr.str());
386 if (fntemplate !=
"") {
387 osp = rcp(
new std::ofstream(fntemplate.c_str(),std::ios::out | std::ios::app) );
389 osp = Teuchos::rcpFromRef(std::cout);
390 std::cout <<
"Anasazi::TraceMinBaseSolMgr::constructor(): Could not open file for write: " << fntemplate << std::endl;
394 osp = Teuchos::rcpFromRef(std::cout);
398 if (pl.isParameter(
"Verbosity")) {
399 if (Teuchos::isParameterType<int>(pl,
"Verbosity")) {
400 verbosity = pl.get(
"Verbosity", verbosity);
402 verbosity = (int)Teuchos::getParameter<Anasazi::MsgType>(pl,
"Verbosity");
418 convTol_ = pl.get(
"Convergence Tolerance",MT::prec());
419 TEUCHOS_TEST_FOR_EXCEPTION(convTol_ < 0, std::invalid_argument,
420 "Anasazi::TraceMinBaseSolMgr: \"Convergence Tolerance\" must be nonnegative.");
422 relConvTol_ = pl.get(
"Relative Convergence Tolerance",
true);
423 strtmp = pl.get(
"Convergence Norm",std::string(
"2"));
425 convNorm_ = RES_2NORM;
427 else if (strtmp ==
"M") {
428 convNorm_ = RES_ORTH;
431 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
432 "Anasazi::TraceMinBaseSolMgr: Invalid Convergence Norm.");
437 useLocking_ = pl.get(
"Use Locking",
true);
438 relLockTol_ = pl.get(
"Relative Locking Tolerance",
true);
439 lockTol_ = pl.get(
"Locking Tolerance",convTol_/10);
441 TEUCHOS_TEST_FOR_EXCEPTION(relConvTol_ != relLockTol_, std::invalid_argument,
442 "Anasazi::TraceMinBaseSolMgr: \"Relative Convergence Tolerance\" and \"Relative Locking Tolerance\" have different values. If you set one, you should always set the other.");
444 TEUCHOS_TEST_FOR_EXCEPTION(lockTol_ < 0, std::invalid_argument,
445 "Anasazi::TraceMinBaseSolMgr: \"Locking Tolerance\" must be nonnegative.");
447 strtmp = pl.get(
"Locking Norm",std::string(
"2"));
449 lockNorm_ = RES_2NORM;
451 else if (strtmp ==
"M") {
452 lockNorm_ = RES_ORTH;
455 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
456 "Anasazi::TraceMinBaseSolMgr: Invalid Locking Norm.");
461 maxLocked_ = pl.get(
"Max Locked",problem_->getNEV());
462 TEUCHOS_TEST_FOR_EXCEPTION(maxLocked_ <= 0, std::invalid_argument,
463 "Anasazi::TraceMinBaseSolMgr: \"Max Locked\" must be strictly positive.");
470 lockQuorum_ = pl.get(
"Locking Quorum",1);
471 TEUCHOS_TEST_FOR_EXCEPTION(lockQuorum_ <= 0, std::invalid_argument,
472 "Anasazi::TraceMinBaseSolMgr: \"Locking Quorum\" must be strictly positive.");
479 strtmp = pl.get(
"When To Shift",
"Always");
481 if(strtmp ==
"Never")
482 whenToShift_ = NEVER_SHIFT;
483 else if(strtmp ==
"After Trace Levels")
484 whenToShift_ = SHIFT_WHEN_TRACE_LEVELS;
485 else if(strtmp ==
"Residual Becomes Small")
486 whenToShift_ = SHIFT_WHEN_RESID_SMALL;
487 else if(strtmp ==
"Always")
488 whenToShift_ = ALWAYS_SHIFT;
490 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
491 "Anasazi::TraceMinBaseSolMgr: Invalid value for \"When To Shift\"; valid options are \"Never\", \"After Trace Levels\", \"Residual Becomes Small\", \"Always\".");
495 traceThresh_ = pl.get(
"Trace Threshold", 0.02);
497 TEUCHOS_TEST_FOR_EXCEPTION(traceThresh_ < 0, std::invalid_argument,
498 "Anasazi::TraceMinBaseSolMgr: \"Trace Threshold\" must be nonnegative.");
501 shiftTol_ = pl.get(
"Shift Tolerance", 0.1);
503 TEUCHOS_TEST_FOR_EXCEPTION(shiftTol_ < 0, std::invalid_argument,
504 "Anasazi::TraceMinBaseSolMgr: \"Shift Tolerance\" must be nonnegative.");
507 relShiftTol_ = pl.get(
"Relative Shift Tolerance",
true);
510 shiftNorm_ = pl.get(
"Shift Norm",
"2");
512 TEUCHOS_TEST_FOR_EXCEPTION(shiftNorm_ !=
"2" && shiftNorm_ !=
"M", std::invalid_argument,
513 "Anasazi::TraceMinBaseSolMgr: Invalid value for \"Shift Norm\"; valid options are \"2\" and \"M\".");
515 noSort_ = pl.get(
"No Sorting",
false);
518 strtmp = pl.get(
"How To Choose Shift",
"Adjusted Ritz Values");
520 if(strtmp ==
"Largest Converged")
521 howToShift_ = LARGEST_CONVERGED_SHIFT;
522 else if(strtmp ==
"Adjusted Ritz Values")
523 howToShift_ = ADJUSTED_RITZ_SHIFT;
524 else if(strtmp ==
"Ritz Values")
525 howToShift_ = RITZ_VALUES_SHIFT;
526 else if(strtmp ==
"Experimental Shift")
527 howToShift_ = EXPERIMENTAL_SHIFT;
529 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
530 "Anasazi::TraceMinBaseSolMgr: Invalid value for \"How To Choose Shift\"; valid options are \"Largest Converged\", \"Adjusted Ritz Values\", \"Ritz Values\".");
533 considerClusters_ = pl.get(
"Consider Clusters",
true);
536 useMultipleShifts_ = pl.get(
"Use Multiple Shifts",
true);
542 ortho_ = pl.get(
"Orthogonalization",
"SVQB");
543 TEUCHOS_TEST_FOR_EXCEPTION(ortho_ !=
"DGKS" && ortho_ !=
"SVQB" && ortho_ !=
"ICGS", std::invalid_argument,
544 "Anasazi::TraceMinBaseSolMgr: Invalid value for \"Orthogonalization\"; valid options are \"DGKS\", \"SVQB\", \"ICGS\".");
546 strtmp = pl.get(
"Saddle Solver Type",
"Projected Krylov");
548 if(strtmp ==
"Projected Krylov")
549 saddleSolType_ = PROJECTED_KRYLOV_SOLVER;
550 else if(strtmp ==
"Schur Complement")
551 saddleSolType_ = SCHUR_COMPLEMENT_SOLVER;
552 else if(strtmp ==
"Block Diagonal Preconditioned Minres")
553 saddleSolType_ = BD_PREC_MINRES;
554 else if(strtmp ==
"HSS Preconditioned Gmres")
555 saddleSolType_ = HSS_PREC_GMRES;
557 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
558 "Anasazi::TraceMinBaseSolMgr: Invalid value for \"Saddle Solver Type\"; valid options are \"Projected Krylov\", \"Schur Complement\", and \"Block Diagonal Preconditioned Minres\".");
560 projectAllVecs_ = pl.get(
"Project All Vectors",
true);
561 projectLockedVecs_ = pl.get(
"Project Locked Vectors",
true);
562 computeAllRes_ = pl.get(
"Compute All Residuals",
true);
563 useRHSR_ = pl.get(
"Use Residual as RHS",
false);
564 alpha_ = pl.get(
"HSS: alpha", 1.0);
566 TEUCHOS_TEST_FOR_EXCEPTION(projectLockedVecs_ && ! projectAllVecs_, std::invalid_argument,
567 "Anasazi::TraceMinBaseSolMgr: If you want to project out the locked vectors, you should really project out ALL the vectors of X.");
570 maxKrylovIter_ = pl.get(
"Maximum Krylov Iterations", 200);
571 TEUCHOS_TEST_FOR_EXCEPTION(maxKrylovIter_ < 1, std::invalid_argument,
572 "Anasazi::TraceMinBaseSolMgr: \"Maximum Krylov Iterations\" must be greater than 0.");
575 which_ = pl.get(
"Which",
"SM");
576 TEUCHOS_TEST_FOR_EXCEPTION(which_ !=
"SM" && which_ !=
"LM", std::invalid_argument,
577 "Anasazi::TraceMinBaseSolMgr: Invalid value for \"Which\"; valid options are \"SM\" and \"LM\".");
581 TEUCHOS_TEST_FOR_EXCEPTION(problem_->getOperator() == Teuchos::null && whenToShift_ != NEVER_SHIFT, std::invalid_argument,
582 "Anasazi::TraceMinBaseSolMgr: It is an exceptionally bad idea to use Ritz shifts when finding the largest eigenpairs of a standard eigenvalue problem. If we don't use Ritz shifts, it may take extra iterations to converge, but we NEVER have to solve a single linear system. Using Ritz shifts forces us to solve systems of the form (I + sigma A)x=f, and it probably doesn't benefit us enough to outweigh the extra cost. We may add support for this feature in the future, but for now, please set \"When To Shift\" to \"Never\".");
584 #ifdef BELOS_PSEUDO_BLOCK_GMRES_SOLMGR_HPP 587 TEUCHOS_TEST_FOR_EXCEPTION(problem_->getPrec() != Teuchos::null && saddleSolType_ == PROJECTED_KRYLOV_SOLVER && useMultipleShifts_, std::invalid_argument,
588 "Anasazi::TraceMinBaseSolMgr: When you use the projected Krylov solver with preconditioning, the preconditioner must be projected as well. In theory, if the preconditioner is SPD, the projected preconditioner will be SPSD, but in practice, it can have small negative eigenvalues, presumably due to machine arithmetic. This means we can't use TraceMin's built-in MINRES, and we are forced to use Belos for now. When you use multiple Ritz shifts, you are essentially using a different operator to solve each linear system. Belos can't handle this right now, but we're working on a solution. For now, please set \"Use Multiple Shifts\" to false.");
595 TEUCHOS_TEST_FOR_EXCEPTION(problem_->getPrec() != Teuchos::null && saddleSolType_ == PROJECTED_KRYLOV_SOLVER, std::invalid_argument,
596 "Anasazi::TraceMinBaseSolMgr: When you use the projected Krylov solver with preconditioning, the preconditioner must be projected as well. In theory, if the preconditioner is SPD, the projected preconditioner will be SPSD, but in practice, it can have small negative eigenvalues, presumably due to machine arithmetic. This means we can't use TraceMin's built-in MINRES, and we are forced to use Belos for now. You didn't install Belos. You have three options to correct this problem:\n1. Reinstall Trilinos with Belos enabled\n2. Don't use a preconditioner\n3. Choose a different method for solving the saddle-point problem (Recommended)");
608 template<
class ScalarType,
class MV,
class OP>
614 const int nev = problem_->getNEV();
617 RCP<Teuchos::FancyOStream>
618 out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(printer_->stream(
Debug)));
619 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
620 *out <<
"Entering Anasazi::TraceMinBaseSolMgr::solve()\n";
632 RCP<const OP> swapHelper = problem_->getOperator();
633 problem_->setOperator(problem_->getM());
634 problem_->setM(swapHelper);
635 problem_->setProblem();
642 RCP<StatusTest<ScalarType,MV,OP> > convtest;
643 if (globalTest_ == Teuchos::null) {
647 convtest = rcp(
new StatusTestSpecTrans<ScalarType,MV,OP>(convTol_,nev,convNorm_,relConvTol_,
true,problem_->getOperator()) );
650 convtest = globalTest_;
652 RCP<StatusTestWithOrdering<ScalarType,MV,OP> > ordertest
655 RCP<StatusTest<ScalarType,MV,OP> > locktest;
657 if (lockingTest_ == Teuchos::null) {
661 locktest = rcp(
new StatusTestSpecTrans<ScalarType,MV,OP>(lockTol_,lockQuorum_,lockNorm_,relLockTol_,
true,problem_->getOperator()) );
664 locktest = lockingTest_;
668 Teuchos::Array<RCP<StatusTest<ScalarType,MV,OP> > > alltests;
669 alltests.push_back(ordertest);
670 if (locktest != Teuchos::null) alltests.push_back(locktest);
671 if (debugTest_ != Teuchos::null) alltests.push_back(debugTest_);
673 RCP<StatusTestCombo<ScalarType,MV,OP> > combotest
676 RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest;
677 if ( printer_->isVerbosity(
Debug) ) {
686 RCP<MatOrthoManager<ScalarType,MV,OP> > ortho;
687 if (ortho_==
"SVQB") {
689 }
else if (ortho_==
"DGKS") {
691 }
else if (ortho_==
"ICGS") {
694 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Anasazi::TraceMinBaseSolMgr::solve(): Invalid orthogonalization type.");
699 Teuchos::ParameterList plist;
700 setParameters(plist);
704 RCP<TraceMinBase<ScalarType,MV,OP> > tm_solver
705 = createSolver(sorter,outputtest,ortho,plist);
707 RCP< const MV > probauxvecs = problem_->getAuxVecs();
708 if (probauxvecs != Teuchos::null) {
709 tm_solver->setAuxVecs( Teuchos::tuple< RCP<const MV> >(probauxvecs) );
716 int curNumLocked = 0;
723 if (maxLocked_ > 0) {
724 lockvecs =
MVT::Clone(*problem_->getInitVec(),maxLocked_);
726 std::vector<MagnitudeType> lockvals;
771 const ScalarType ONE = SCT::one();
772 const ScalarType ZERO = SCT::zero();
777 problem_->setSolution(sol);
783 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 784 Teuchos::TimeMonitor slvtimer(*_timerSolve);
790 tm_solver->iterate();
796 if (debugTest_ != Teuchos::null && debugTest_->getStatus() ==
Passed) {
797 throw AnasaziError(
"Anasazi::TraceMinBaseSolMgr::solve(): User-specified debug status test returned Passed.");
804 else if (ordertest->getStatus() ==
Passed ) {
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::TraceMinBaseSolMgr::solve(): status test mistake: howMany() non-positive.");
830 TEUCHOS_TEST_FOR_EXCEPTION(locktest->howMany() != (int)locktest->whichVecs().size(),std::logic_error,
831 "Anasazi::TraceMinBaseSolMgr::solve(): status test mistake: howMany() not consistent with whichVecs().");
833 TEUCHOS_TEST_FOR_EXCEPTION(curNumLocked == maxLocked_,std::logic_error,
834 "Anasazi::TraceMinBaseSolMgr::solve(): status test mistake: locking not deactivated.");
837 std::vector<int> tmp_vector_int;
838 if (curNumLocked + locktest->howMany() > maxLocked_) {
840 for(
int i=0; i<maxLocked_-curNumLocked; i++)
841 tmp_vector_int.push_back(locktest->whichVecs()[i]);
845 tmp_vector_int = locktest->whichVecs();
848 const std::vector<int> lockind(tmp_vector_int);
849 const int numNewLocked = lockind.size();
853 const int numUnlocked = curdim-numNewLocked;
854 tmp_vector_int.resize(curdim);
855 for (
int i=0; i<curdim; i++) tmp_vector_int[i] = i;
856 const std::vector<int> curind(tmp_vector_int);
857 tmp_vector_int.resize(numUnlocked);
858 std::set_difference(curind.begin(),curind.end(),lockind.begin(),lockind.end(),tmp_vector_int.begin());
859 const std::vector<int> unlockind(tmp_vector_int);
860 tmp_vector_int.clear();
864 if (printer_->isVerbosity(
Debug)) {
865 printer_->print(
Debug,
"Locking vectors: ");
866 for (
unsigned int i=0; i<lockind.size(); i++) {printer_->stream(
Debug) <<
" " << lockind[i];}
867 printer_->print(
Debug,
"\n");
868 printer_->print(
Debug,
"Not locking vectors: ");
869 for (
unsigned int i=0; i<unlockind.size(); i++) {printer_->stream(
Debug) <<
" " << unlockind[i];}
870 printer_->print(
Debug,
"\n");
874 std::vector<Value<ScalarType> > allvals = tm_solver->getRitzValues();
875 for(
unsigned int i=0; i<allvals.size(); i++)
876 printer_->stream(
Debug) <<
"Ritz value[" << i <<
"] = " << allvals[i].realpart << std::endl;
877 for (
int i=0; i<numNewLocked; i++) {
878 lockvals.push_back(allvals[lockind[i]].realpart);
882 RCP<const MV> newLocked =
MVT::CloneView(*tm_solver->getRitzVectors(),lockind);
883 std::vector<int> indlock(numNewLocked);
884 for (
int i=0; i<numNewLocked; i++) indlock[i] = curNumLocked+i;
888 ortho->normalizeMat(*tempMV);
901 for(
unsigned int aliciaInd=0; aliciaInd<lockvals.size(); aliciaInd++)
903 lockvals[aliciaInd] = 0.0;
906 ordertest->setAuxVals(lockvals);
910 curNumLocked += numNewLocked;
912 if(ordertest->getStatus() ==
Passed)
break;
914 std::vector<int> curlockind(curNumLocked);
915 for (
int i=0; i<curNumLocked; i++) curlockind[i] = i;
918 Teuchos::Array< RCP<const MV> > aux;
919 if (probauxvecs != Teuchos::null) aux.push_back(probauxvecs);
920 aux.push_back(curlocked);
921 tm_solver->setAuxVecs(aux);
924 printer_->stream(
Debug) <<
"curNumLocked: " << curNumLocked << std::endl;
925 printer_->stream(
Debug) <<
"maxLocked: " << maxLocked_ << std::endl;
926 if (curNumLocked == maxLocked_) {
928 combotest->removeTest(locktest);
929 locktest = Teuchos::null;
930 printer_->stream(
Debug) <<
"Removed locking test\n";
933 int newdim = numRestartBlocks_*blockSize_;
935 if(newdim <= numUnlocked)
939 std::vector<int> desiredSubscripts(newdim);
940 for(
int i=0; i<newdim; i++)
942 desiredSubscripts[i] = unlockind[i];
943 printer_->stream(
Debug) <<
"H desiredSubscripts[" << i <<
"] = " << desiredSubscripts[i] << std::endl;
945 newstate.
V =
MVT::CloneView(*tm_solver->getRitzVectors(),desiredSubscripts);
950 std::vector<int> desiredSubscripts(newdim);
951 for(
int i=0; i<newdim; i++)
953 desiredSubscripts[i] = unlockind[i];
954 printer_->stream(
Debug) <<
"desiredSubscripts[" << i <<
"] = " << desiredSubscripts[i] << std::endl;
957 copyPartOfState(state, newstate, desiredSubscripts);
965 int nrandom = newdim-numUnlocked;
967 RCP<const MV> helperMV;
968 RCP<MV> totalV =
MVT::Clone(*tm_solver->getRitzVectors(),newdim);
971 tmp_vector_int.resize(numUnlocked);
972 for(
int i=0; i<numUnlocked; i++) tmp_vector_int[i] = i;
977 helperMV =
MVT::CloneView(*tm_solver->getRitzVectors(),unlockind);
983 tmp_vector_int.resize(nrandom);
984 for(
int i=0; i<nrandom; i++) tmp_vector_int[i] = i+numUnlocked;
994 RCP< std::vector<ScalarType> > helperRS = rcp(
new std::vector<ScalarType>(blockSize_) );
995 for(
unsigned int i=0; i<(
unsigned int)blockSize_; i++)
997 if(i < unlockind.size() && unlockind[i] < blockSize_)
998 (*helperRS)[i] = (*state.
ritzShifts)[unlockind[i]];
1000 (*helperRS)[i] = ZERO;
1007 for(
size_t i=0; i<lockvals.size(); i++)
1013 newstate.
NEV = state.
NEV - numNewLocked;
1014 tm_solver->initialize(newstate);
1021 else if ( needToRestart(tm_solver) ) {
1023 if(performRestart(numRestarts, tm_solver) ==
false)
1033 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Anasazi::TraceMinBaseSolMgr::solve(): Invalid return from tm_solver::iterate().");
1038 <<
"Anasazi::TraceMinBaseSolMgr::solve() caught unexpected exception from Anasazi::TraceMinBase::iterate() at iteration " << tm_solver->getNumIters() << std::endl
1039 << err.what() << std::endl
1040 <<
"Anasazi::TraceMinBaseSolMgr::solve() returning Unconverged with no solutions." << std::endl;
1045 sol.
numVecs = ordertest->howMany();
1050 std::vector<MagnitudeType> vals(sol.
numVecs);
1053 std::vector<int> which = ordertest->whichVecs();
1057 std::vector<int> inlocked(0), insolver(0);
1058 for (
unsigned int i=0; i<which.size(); i++) {
1059 if (which[i] >= 0) {
1060 TEUCHOS_TEST_FOR_EXCEPTION(which[i] >= blockSize_,std::logic_error,
"Anasazi::TraceMinBaseSolMgr::solve(): positive indexing mistake from ordertest.");
1061 insolver.push_back(which[i]);
1065 TEUCHOS_TEST_FOR_EXCEPTION(which[i] < -curNumLocked,std::logic_error,
"Anasazi::TraceMinBaseSolMgr::solve(): negative indexing mistake from ordertest.");
1066 inlocked.push_back(which[i] + curNumLocked);
1070 TEUCHOS_TEST_FOR_EXCEPTION(insolver.size() + inlocked.size() != (
unsigned int)sol.
numVecs,std::logic_error,
"Anasazi::TraceMinBaseSolMgr::solve(): indexing mistake.");
1073 if (insolver.size() > 0) {
1075 int lclnum = insolver.size();
1076 std::vector<int> tosol(lclnum);
1077 for (
int i=0; i<lclnum; i++) tosol[i] = i;
1078 RCP<const MV> v =
MVT::CloneView(*tm_solver->getRitzVectors(),insolver);
1081 std::vector<Value<ScalarType> > fromsolver = tm_solver->getRitzValues();
1082 for (
unsigned int i=0; i<insolver.size(); i++) {
1083 vals[i] = fromsolver[insolver[i]].realpart;
1088 if (inlocked.size() > 0) {
1089 int solnum = insolver.size();
1091 int lclnum = inlocked.size();
1092 std::vector<int> tosol(lclnum);
1093 for (
int i=0; i<lclnum; i++) tosol[i] = solnum + i;
1097 for (
unsigned int i=0; i<inlocked.size(); i++) {
1098 vals[i+solnum] = lockvals[inlocked[i]];
1106 for(
size_t i=0; i<vals.size(); i++)
1107 vals[i] = ONE/vals[i];
1112 std::vector<int> order(sol.
numVecs);
1113 sorter->sort(vals,Teuchos::rcpFromRef(order),sol.
numVecs);
1115 for (
int i=0; i<sol.
numVecs; i++) {
1116 sol.
Evals[i].realpart = vals[i];
1117 sol.
Evals[i].imagpart = MT::zero();
1129 tm_solver->currentStatus(printer_->stream(
FinalSummary));
1134 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 1136 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails ) );
1140 problem_->setSolution(sol);
1141 printer_->stream(
Debug) <<
"Returning " << sol.
numVecs <<
" eigenpairs to eigenproblem." << std::endl;
1144 numIters_ = tm_solver->getNumIters();
1153 template <
class ScalarType,
class MV,
class OP>
1158 globalTest_ = global;
1161 template <
class ScalarType,
class MV,
class OP>
1162 const RCP< StatusTest<ScalarType,MV,OP> > &
1168 template <
class ScalarType,
class MV,
class OP>
1176 template <
class ScalarType,
class MV,
class OP>
1177 const RCP< StatusTest<ScalarType,MV,OP> > &
1183 template <
class ScalarType,
class MV,
class OP>
1188 lockingTest_ = locking;
1191 template <
class ScalarType,
class MV,
class OP>
1192 const RCP< StatusTest<ScalarType,MV,OP> > &
1195 return lockingTest_;
1198 template <
class ScalarType,
class MV,
class OP>
1201 const ScalarType ONE = Teuchos::ScalarTraits<MagnitudeType>::one();
1202 const ScalarType ZERO = Teuchos::ScalarTraits<MagnitudeType>::zero();
1204 newState.
curDim = indToCopy.size();
1205 std::vector<int> fullIndices(oldState.
curDim);
1206 for(
int i=0; i<oldState.
curDim; i++) fullIndices[i] = i;
1214 std::vector<int> oldIndices;
1215 std::vector<int> newIndices;
1216 for(
int i=0; i<newState.
curDim; i++)
1218 if(indToCopy[i] < blockSize_)
1219 oldIndices.push_back(indToCopy[i]);
1221 newIndices.push_back(indToCopy[i]);
1224 int olddim = oldIndices.size();
1225 int newdim = newIndices.size();
1232 newState.
X = newState.
V;
1234 if(problem_->getOperator() != Teuchos::null)
1237 newState.
KX = newState.
KV;
1241 newState.
KV = Teuchos::null;
1242 newState.
KX = Teuchos::null;
1245 if(problem_->getM() != Teuchos::null)
1248 newState.
MX = newState.
MopV;
1252 newState.
MopV = Teuchos::null;
1253 newState.
MX = Teuchos::null;
1256 else if(newdim == 0)
1258 std::vector<int> blockind(blockSize_);
1259 for(
int i=0; i<blockSize_; i++)
1269 if(problem_->getM() != Teuchos::null)
1276 newState.
MopV = Teuchos::null;
1277 newState.
MX = Teuchos::null;
1283 std::vector<int> oldPart(olddim);
1284 for(
int i=0; i<olddim; i++) oldPart[i] = i;
1285 std::vector<int> newPart(newdim);
1286 for(
int i=0; i<newdim; i++) newPart[i] = olddim+i;
1292 RCP<const MV> viewHelper;
1295 Teuchos::SerialDenseMatrix<int,ScalarType> newRV(oldState.
curDim,newdim);
1296 for(
int r=0; r<oldState.
curDim; r++)
1298 for(
int c=0; c<newdim; c++)
1299 newRV(r,c) = (*oldState.
RV)(r,newIndices[c]);
1317 if(problem_->getM() != Teuchos::null)
1326 newState.
MopV = newState.
V;
1329 std::vector<int> blockVec(blockSize_);
1330 for(
int i=0; i<blockSize_; i++) blockVec[i] = i;
1336 if(blockSize_-oldIndices.size() > 0)
1339 newPart.resize(blockSize_-oldIndices.size());
1346 std::vector<ScalarType> scalarVec(blockSize_-oldIndices.size());
1347 for(
unsigned int i=0; i<(
unsigned int)blockSize_-oldIndices.size(); i++) scalarVec[i] = (*oldState.
T)[newPart[i]];
1359 newState.
R = oldState.
R;
1366 RCP< std::vector<ScalarType> > helperT = rcp(
new std::vector<ScalarType>(newState.
curDim) );
1367 for(
int i=0; i<newState.
curDim; i++) (*helperT)[i] = (*oldState.
T)[indToCopy[i]];
1368 newState.
T = helperT;
1371 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > newKK = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(newState.
curDim,newState.
curDim) );
1372 for(
int i=0; i<newState.
curDim; i++)
1373 (*newKK)(i,i) = (*newState.
T)[i];
1374 newState.
KK = newKK;
1377 RCP< Teuchos::SerialDenseMatrix<int,ScalarType> > newRV = rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>(newState.
curDim,newState.
curDim) );
1378 for(
int i=0; i<newState.
curDim; i++)
1379 (*newRV)(i,i) = ONE;
1380 newState.
RV = newRV;
1383 RCP< std::vector<ScalarType> > helperRS = rcp(
new std::vector<ScalarType>(blockSize_) );
1384 for(
int i=0; i<blockSize_; i++)
1386 if(indToCopy[i] < blockSize_)
1387 (*helperRS)[i] = (*oldState.
ritzShifts)[indToCopy[i]];
1389 (*helperRS)[i] = ZERO;
1395 template <
class ScalarType,
class MV,
class OP>
1398 pl.set(
"Block Size", blockSize_);
1399 pl.set(
"Num Blocks", numBlocks_);
1400 pl.set(
"Num Restart Blocks", numRestartBlocks_);
1401 pl.set(
"When To Shift", whenToShift_);
1402 pl.set(
"Trace Threshold", traceThresh_);
1403 pl.set(
"Shift Tolerance", shiftTol_);
1404 pl.set(
"Relative Shift Tolerance", relShiftTol_);
1405 pl.set(
"Shift Norm", shiftNorm_);
1406 pl.set(
"How To Choose Shift", howToShift_);
1407 pl.set(
"Consider Clusters", considerClusters_);
1408 pl.set(
"Use Multiple Shifts", useMultipleShifts_);
1409 pl.set(
"Saddle Solver Type", saddleSolType_);
1410 pl.set(
"Project All Vectors", projectAllVecs_);
1411 pl.set(
"Project Locked Vectors", projectLockedVecs_);
1412 pl.set(
"Compute All Residuals", computeAllRes_);
1413 pl.set(
"Use Residual as RHS", useRHSR_);
1414 pl.set(
"Use Harmonic Ritz Values", useHarmonic_);
1415 pl.set(
"Maximum Krylov Iterations", maxKrylovIter_);
1416 pl.set(
"HSS: alpha", alpha_);
1420 template <
class ScalarType,
class MV,
class OP>
1424 os <<
"========================================\n";
1425 os <<
"========= TraceMin parameters ==========\n";
1426 os <<
"========================================\n";
1427 os <<
"=========== Block parameters ===========\n";
1428 os <<
"Block Size: " << blockSize_ << std::endl;
1429 os <<
"Num Blocks: " << numBlocks_ << std::endl;
1430 os <<
"Num Restart Blocks: " << numRestartBlocks_ << std::endl;
1431 os <<
"======== Convergence parameters ========\n";
1432 os <<
"Convergence Tolerance: " << convTol_ << std::endl;
1433 os <<
"Relative Convergence Tolerance: " << relConvTol_ << std::endl;
1434 os <<
"========== Locking parameters ==========\n";
1435 os <<
"Use Locking: " << useLocking_ << std::endl;
1436 os <<
"Locking Tolerance: " << lockTol_ << std::endl;
1437 os <<
"Relative Locking Tolerance: " << relLockTol_ << std::endl;
1438 os <<
"Max Locked: " << maxLocked_ << std::endl;
1439 os <<
"Locking Quorum: " << lockQuorum_ << std::endl;
1440 os <<
"========== Shifting parameters =========\n";
1441 os <<
"When To Shift: ";
1442 if(whenToShift_ == NEVER_SHIFT) os <<
"Never\n";
1443 else if(whenToShift_ == SHIFT_WHEN_TRACE_LEVELS) os <<
"After Trace Levels\n";
1444 else if(whenToShift_ == SHIFT_WHEN_RESID_SMALL) os <<
"Residual Becomes Small\n";
1445 else if(whenToShift_ == ALWAYS_SHIFT) os <<
"Always\n";
1446 os <<
"Consider Clusters: " << considerClusters_ << std::endl;
1447 os <<
"Trace Threshohld: " << traceThresh_ << std::endl;
1448 os <<
"Shift Tolerance: " << shiftTol_ << std::endl;
1449 os <<
"Relative Shift Tolerance: " << relShiftTol_ << std::endl;
1450 os <<
"How To Choose Shift: ";
1451 if(howToShift_ == LARGEST_CONVERGED_SHIFT) os <<
"Largest Converged\n";
1452 else if(howToShift_ == ADJUSTED_RITZ_SHIFT) os <<
"Adjusted Ritz Values\n";
1453 else if(howToShift_ == RITZ_VALUES_SHIFT) os <<
"Ritz Values\n";
1454 os <<
"Use Multiple Shifts: " << useMultipleShifts_ << std::endl;
1455 os <<
"=========== Other parameters ===========\n";
1456 os <<
"Orthogonalization: " << ortho_ << std::endl;
1457 os <<
"Saddle Solver Type: ";
1458 if(saddleSolType_ == PROJECTED_KRYLOV_SOLVER) os <<
"Projected Krylov\n";
1459 else if(saddleSolType_ == SCHUR_COMPLEMENT_SOLVER) os <<
"Schur Complement\n";
1460 os <<
"Project All Vectors: " << projectAllVecs_ << std::endl;
1461 os <<
"Project Locked Vectors: " << projectLockedVecs_ << std::endl;
1462 os <<
"Compute All Residuals: " << computeAllRes_ << std::endl;
1463 os <<
"========================================\n\n\n";
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.
static void MvTimesMatAddMv(const ScalarType alpha, const MV &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta, MV &mv)
Update mv with .
std::vector< Value< ScalarType > > Evals
The computed eigenvalues.
Abstract base class for trace minimization eigensolvers.
int NEV
Number of unconverged eigenvalues.
TraceMinBaseSolMgr(const RCP< Eigenproblem< ScalarType, MV, OP > > &problem, Teuchos::ParameterList &pl)
Basic constructor for TraceMinBaseSolMgr.
const RCP< StatusTest< ScalarType, MV, OP > > & getGlobalStatusTest() const
Get the status test defining global convergence.
ResType
Enumerated type used to specify which residual norm used by residual norm status tests.
RCP< const MV > X
The current eigenvectors.
A special StatusTest for printing other status tests.
This class defines the interface required by an eigensolver and status test class to compute solution...
Structure to contain pointers to TraceMinBase state variables.
An implementation of the Anasazi::SortManager that performs a collection of common sorting techniques...
RCP< const MV > V
The current basis.
RCP< const MV > MopV
The image of V under M, or Teuchos::null if M was not specified.
Virtual base class which defines basic traits for the operator type.
Teuchos::RCP< MV > Evecs
The computed eigenvectors.
An implementation of the Anasazi::GenOrthoManager that performs orthogonalization using iterated clas...
Status test for forming logical combinations of other status tests.
The Anasazi::SolverManager is a templated virtual base class that defines the basic interface that an...
void setGlobalStatusTest(const RCP< StatusTest< ScalarType, MV, OP > > &global)
Set the status test defining global convergence.
Basic implementation of the Anasazi::SortManager class.
An implementation of the Anasazi::MatOrthoManager that performs orthogonalization using the SVQB iter...
static void Assign(const MV &A, MV &mv)
mv := A
An exception class parent to all Anasazi exceptions.
bool isOrtho
Whether V has been projected and orthonormalized already.
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.
ReturnType solve()
This method performs possibly repeated calls to the underlying eigensolver's iterate() routine until ...
int numVecs
The number of computed eigenpairs.
Basic output manager for sending information of select verbosity levels to the appropriate output str...
Anasazi's templated virtual class for providing routines for orthogonalization and orthonormalization...
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.
const RCP< StatusTest< ScalarType, MV, OP > > & getDebugStatusTest() const
Get the status test for debugging.
A status test for testing the norm of the eigenvectors residuals.
Traits class which defines basic operations on multivectors.
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
Creates a new MV and copies contents of mv into the new vector (deep copy).
std::vector< int > index
An index into Evecs to allow compressed storage of eigenvectors for real, non-Hermitian problems...
static void MvScale(MV &mv, const ScalarType alpha)
Scale each element of the vectors in mv with alpha.
int curDim
The current dimension of the solver.
RCP< const MV > KV
The image of V under K.
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.
RCP< const MV > MX
The image of the current eigenvectors under M, or Teuchos::null if M was not specified.
The Anasazi::TraceMinBaseSolMgr provides an abstract base class for the TraceMin series of solver man...
RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > RV
The current Ritz vectors.
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...
ScalarType largestSafeShift
Largest safe shift.
RCP< const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > T
The current Ritz values. This vector is a copy of the internal data.
static void MvAddMv(const ScalarType alpha, const MV &A, const ScalarType beta, const MV &B, MV &mv)
Replace mv with .
RCP< const std::vector< ScalarType > > ritzShifts
Current Ritz shifts.
Teuchos::Array< RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
virtual ~TraceMinBaseSolMgr()
Destructor.
Special StatusTest for printing status tests.
A status test for testing the norm of the eigenvectors residuals along with a set of auxiliary eigenv...
RCP< const MV > KX
The image of the current eigenvectors under K.
RCP< const MV > R
The current residual vectors.
RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > KK
The current projected K matrix.
void setLockingStatusTest(const RCP< StatusTest< ScalarType, MV, OP > > &locking)
Set the status test defining locking.
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.
int getNumIters() const
Get the iteration count for the most recent call to solve().
const RCP< StatusTest< ScalarType, MV, OP > > & getLockingStatusTest() const
Get the status test defining locking.
This is an abstract base class for the trace minimization eigensolvers.
void setDebugStatusTest(const RCP< StatusTest< ScalarType, MV, OP > > &debug)
Set the status test for debugging.
Anasazi's templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Return the eigenvalue problem.
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.
Basic implementation of the Anasazi::OrthoManager class.
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
Class which provides internal utilities for the Anasazi solvers.