42 #ifndef ANASAZI_BLOCK_KRYLOV_SCHUR_SOLMGR_HPP
43 #define ANASAZI_BLOCK_KRYLOV_SCHUR_SOLMGR_HPP
71 #include "Teuchos_FancyOStream.hpp"
156 template<
class ScalarType,
class MV,
class OP>
214 std::vector<Value<ScalarType> > ret( ritzValues_ );
225 return Teuchos::tuple(timerSolve_, timerRestarting_);
271 std::string whch_, ortho_;
272 MagnitudeType ortho_kappa_;
274 MagnitudeType convtol_;
276 bool relconvtol_,conjSplit_;
277 int blockSize_, numBlocks_, stepSize_, nevBlocks_, xtra_nevBlocks_;
280 bool inSituRestart_, dynXtraNev_;
283 std::vector<Value<ScalarType> > ritzValues_;
297 template<
class ScalarType,
class MV,
class OP>
315 verbosity_(Anasazi::
Errors),
316 inSituRestart_(false),
320 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
321 ,timerSolve_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockKrylovSchurSolMgr::solve()")),
322 timerRestarting_(Teuchos::TimeMonitor::getNewTimer(
"Anasazi: BlockKrylovSchurSolMgr restarting"))
327 TEUCHOS_TEST_FOR_EXCEPTION(problem_->getInitVec() == Teuchos::null, std::invalid_argument,
"Problem does not contain initial vectors to clone from.");
329 const int nev = problem_->getNEV();
332 convtol_ = pl.
get(
"Convergence Tolerance",
MT::prec());
333 relconvtol_ = pl.
get(
"Relative Convergence Tolerance",relconvtol_);
336 maxRestarts_ = pl.
get(
"Maximum Restarts",maxRestarts_);
339 blockSize_ = pl.
get(
"Block Size",1);
341 "Anasazi::BlockKrylovSchurSolMgr: \"Block Size\" must be strictly positive.");
344 xtra_nevBlocks_ = pl.
get(
"Extra NEV Blocks",0);
345 if (nev%blockSize_) {
346 nevBlocks_ = nev/blockSize_ + 1;
348 nevBlocks_ = nev/blockSize_;
355 if (Teuchos::isParameterType<bool>(pl,
"Dynamic Extra NEV")) {
356 dynXtraNev_ = pl.
get(
"Dynamic Extra NEV",dynXtraNev_);
358 dynXtraNev_ = ( Teuchos::getParameter<int>(pl,
"Dynamic Extra NEV") != 0 );
362 numBlocks_ = pl.
get(
"Num Blocks",3*nevBlocks_);
364 "Anasazi::BlockKrylovSchurSolMgr: \"Num Blocks\" must be strictly positive and large enough to compute the requested eigenvalues.");
367 std::invalid_argument,
368 "Anasazi::BlockKrylovSchurSolMgr: Potentially impossible orthogonality requests. Reduce basis size.");
372 stepSize_ = pl.
get(
"Step Size", (maxRestarts_+1)*(numBlocks_+1));
374 stepSize_ = pl.
get(
"Step Size", numBlocks_+1);
377 "Anasazi::BlockKrylovSchurSolMgr: \"Step Size\" must be strictly positive.");
381 sort_ = Teuchos::getParameter<Teuchos::RCP<Anasazi::SortManager<MagnitudeType> > >(pl,
"Sort Manager");
384 whch_ = pl.
get(
"Which",whch_);
385 TEUCHOS_TEST_FOR_EXCEPTION(whch_ !=
"SM" && whch_ !=
"LM" && whch_ !=
"SR" && whch_ !=
"LR" && whch_ !=
"SI" && whch_ !=
"LI",
386 std::invalid_argument,
"Invalid sorting string.");
391 ortho_ = pl.
get(
"Orthogonalization",ortho_);
392 if (ortho_ !=
"DGKS" && ortho_ !=
"SVQB" && ortho_ !=
"ICGS") {
397 ortho_kappa_ = pl.
get(
"Orthogonalization Constant",ortho_kappa_);
401 osProc_ = pl.
get(
"Output Processor", osProc_);
405 osp_ = Teuchos::getParameter<Teuchos::RCP<Teuchos::FancyOStream> >(pl,
"Output Stream");
413 if (Teuchos::isParameterType<int>(pl,
"Verbosity")) {
414 verbosity_ = pl.
get(
"Verbosity", verbosity_);
416 verbosity_ = (int)Teuchos::getParameter<Anasazi::MsgType>(pl,
"Verbosity");
422 if (Teuchos::isParameterType<bool>(pl,
"In Situ Restarting")) {
423 inSituRestart_ = pl.
get(
"In Situ Restarting",inSituRestart_);
425 inSituRestart_ = ( Teuchos::getParameter<int>(pl,
"In Situ Restarting") != 0 );
429 printNum_ = pl.
get<
int>(
"Print Number of Ritz Values",printNum_);
434 template<
class ScalarType,
class MV,
class OP>
438 const int nev = problem_->getNEV();
454 if (globalTest_ == Teuchos::null) {
458 convtest = globalTest_;
466 if (debugTest_ != Teuchos::null) alltests.
push_back(debugTest_);
472 if ( printer->isVerbosity(
Debug) ) {
482 if (ortho_==
"SVQB") {
484 }
else if (ortho_==
"DGKS") {
485 if (ortho_kappa_ <= 0) {
490 }
else if (ortho_==
"ICGS") {
493 TEUCHOS_TEST_FOR_EXCEPTION(ortho_!=
"SVQB"&&ortho_!=
"DGKS"&&ortho_!=
"ICGS",std::logic_error,
"Anasazi::BlockKrylovSchurSolMgr::solve(): Invalid orthogonalization type.");
499 plist.
set(
"Block Size",blockSize_);
500 plist.
set(
"Num Blocks",numBlocks_);
501 plist.
set(
"Step Size",stepSize_);
502 if (printNum_ == -1) {
503 plist.
set(
"Print Number of Ritz Values",nevBlocks_*blockSize_);
506 plist.
set(
"Print Number of Ritz Values",printNum_);
515 if (probauxvecs != Teuchos::null) {
526 int maxXtraBlocks = 0;
527 if ( dynXtraNev_ ) maxXtraBlocks = ( ( bks_solver->getMaxSubspaceDim() - nev ) / blockSize_ ) / 2;
530 if (maxRestarts_ > 0) {
531 if (inSituRestart_==
true) {
533 workMV = MVT::Clone( *problem_->getInitVec(), 1 );
536 if (problem_->isHermitian()) {
537 workMV = MVT::Clone( *problem_->getInitVec(), (nevBlocks_+maxXtraBlocks)*blockSize_ + blockSize_ );
540 workMV = MVT::Clone( *problem_->getInitVec(), (nevBlocks_+maxXtraBlocks)*blockSize_ + 1 + blockSize_ );
544 workMV = Teuchos::null;
550 problem_->setSolution(sol);
553 int cur_nevBlocks = 0;
557 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
564 bks_solver->iterate();
571 if ( ordertest->getStatus() ==
Passed ) {
589 else if ( (bks_solver->getCurSubspaceDim() == bks_solver->getMaxSubspaceDim()) ||
590 (!problem_->isHermitian() && !conjSplit_ && (bks_solver->getCurSubspaceDim()+1 == bks_solver->getMaxSubspaceDim())) ) {
593 if (!bks_solver->isSchurCurrent()) {
594 bks_solver->computeSchurForm(
true );
597 outputtest->checkStatus( &*bks_solver );
601 if ( numRestarts >= maxRestarts_ || ordertest->getStatus() ==
Passed) {
606 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
611 int numConv = ordertest->howMany();
612 cur_nevBlocks = nevBlocks_*blockSize_;
615 int moreNevBlocks = std::min( maxXtraBlocks, std::max( numConv/blockSize_, xtra_nevBlocks_) );
617 cur_nevBlocks += moreNevBlocks * blockSize_;
618 else if ( xtra_nevBlocks_ )
619 cur_nevBlocks += xtra_nevBlocks_ * blockSize_;
627 printer->stream(
Debug) <<
" Performing restart number " << numRestarts <<
" of " << maxRestarts_ << std::endl << std::endl;
628 printer->stream(
Debug) <<
" - Current NEV blocks is " << cur_nevBlocks <<
", the minimum is " << nevBlocks_*blockSize_ << std::endl;
631 ritzValues_ = bks_solver->getRitzValues();
637 int curDim = oldState.
curDim;
640 std::vector<int> ritzIndex = bks_solver->getRitzIndex();
641 if (ritzIndex[cur_nevBlocks-1]==1) {
650 if (problem_->isHermitian() && conjSplit_)
653 <<
" Eigenproblem is Hermitian, complex eigenvalues have been detected, and eigenvalues of interest split a conjugate pair!!!"
655 <<
" Block Krylov-Schur eigensolver cannot guarantee correct behavior in this situation, please turn Hermitian flag off!!!"
665 std::vector<int> curind( curDim );
666 for (
int i=0; i<curDim; i++) { curind[i] = i; }
678 if (inSituRestart_) {
685 std::vector<ScalarType> tau(cur_nevBlocks), work(cur_nevBlocks);
687 lapack.
GEQRF(curDim,cur_nevBlocks,copyQnev.values(),copyQnev.stride(),&tau[0],&work[0],work.size(),&info);
689 "Anasazi::BlockKrylovSchurSolMgr::solve(): error calling GEQRF during restarting.");
691 std::vector<ScalarType> d(cur_nevBlocks);
692 for (
int j=0; j<copyQnev.numCols(); j++) {
693 d[j] = copyQnev(j,j);
695 if (printer->isVerbosity(
Debug)) {
697 for (
int j=0; j<R.
numCols(); j++) {
698 R(j,j) = SCT::magnitude(R(j,j)) - 1.0;
699 for (
int i=j+1; i<R.
numRows(); i++) {
703 printer->stream(
Debug) <<
"||Triangular factor of Su - I||: " << R.
normFrobenius() << std::endl;
709 curind.resize(curDim);
710 for (
int i=0; i<curDim; i++) curind[i] = i;
717 curind.resize(cur_nevBlocks);
718 for (
int i=0; i<cur_nevBlocks; i++) { curind[i] = i; }
721 MVT::MvScale(*newV,d);
724 curind.resize(blockSize_);
725 for (
int i=0; i<blockSize_; i++) { curind[i] = cur_nevBlocks + i; }
726 newF = MVT::CloneViewNonConst( *solverbasis, curind );
730 curind.resize(cur_nevBlocks);
731 for (
int i=0; i<cur_nevBlocks; i++) { curind[i] = i; }
734 MVT::MvTimesMatAddMv( one, *basistemp, Qnev, zero, *tmp_newV );
735 tmp_newV = Teuchos::null;
737 curind.resize(blockSize_);
738 for (
int i=0; i<blockSize_; i++) { curind[i] = cur_nevBlocks + i; }
739 newF = MVT::CloneViewNonConst( *workMV, curind );
743 curind.resize(blockSize_);
744 for (
int i=0; i<blockSize_; i++) { curind[i] = curDim + i; }
746 for (
int i=0; i<blockSize_; i++) { curind[i] = i; }
747 MVT::SetBlock( *oldF, curind, *newF );
748 newF = Teuchos::null;
774 if (inSituRestart_) {
775 newstate.
V = oldState.
V;
780 newstate.
curDim = cur_nevBlocks;
781 bks_solver->initialize(newstate);
791 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Anasazi::BlockKrylovSchurSolMgr::solve(): Invalid return from bks_solver::iterate().");
796 <<
"Anasazi::BlockKrylovSchurSolMgr::solve() caught unexpected exception from Anasazi::BlockKrylovSchur::iterate() at iteration " << bks_solver->getNumIters() << std::endl
797 << err.what() << std::endl
798 <<
"Anasazi::BlockKrylovSchurSolMgr::solve() returning Unconverged with no solutions." << std::endl;
805 workMV = Teuchos::null;
808 ritzValues_ = bks_solver->getRitzValues();
810 sol.
numVecs = ordertest->howMany();
811 printer->stream(
Debug) <<
"ordertest->howMany() : " << sol.
numVecs << std::endl;
812 std::vector<int> whichVecs = ordertest->whichVecs();
818 std::vector<int> tmpIndex = bks_solver->getRitzIndex();
819 for (
int i=0; i<(int)ritzValues_.size(); ++i) {
820 printer->stream(
Debug) << ritzValues_[i].realpart <<
" + i " << ritzValues_[i].imagpart <<
", Index = " << tmpIndex[i] << std::endl;
822 printer->stream(
Debug) <<
"Number of converged eigenpairs (before) = " << sol.
numVecs << std::endl;
823 for (
int i=0; i<sol.
numVecs; ++i) {
824 printer->stream(
Debug) <<
"whichVecs[" << i <<
"] = " << whichVecs[i] <<
", tmpIndex[" << whichVecs[i] <<
"] = " << tmpIndex[whichVecs[i]] << std::endl;
826 if (tmpIndex[whichVecs[sol.
numVecs-1]]==1) {
827 printer->stream(
Debug) <<
"There is a conjugate pair on the boundary, resizing sol.numVecs" << std::endl;
828 whichVecs.push_back(whichVecs[sol.
numVecs-1]+1);
830 for (
int i=0; i<sol.
numVecs; ++i) {
831 printer->stream(
Debug) <<
"whichVecs[" << i <<
"] = " << whichVecs[i] <<
", tmpIndex[" << whichVecs[i] <<
"] = " << tmpIndex[whichVecs[i]] << std::endl;
835 bool keepMore =
false;
837 printer->stream(
Debug) <<
"Number of converged eigenpairs (after) = " << sol.
numVecs << std::endl;
838 printer->stream(
Debug) <<
"whichVecs[sol.numVecs-1] > sol.numVecs-1 : " << whichVecs[sol.
numVecs-1] <<
" > " << sol.
numVecs-1 << std::endl;
841 numEvecs = whichVecs[sol.
numVecs-1]+1;
842 printer->stream(
Debug) <<
"keepMore = true; numEvecs = " << numEvecs << std::endl;
846 bks_solver->setNumRitzVectors(numEvecs);
847 bks_solver->computeRitzVectors();
853 sol.
index = bks_solver->getRitzIndex();
854 sol.
Evals = bks_solver->getRitzValues();
855 sol.
Evecs = MVT::CloneCopy( *(bks_solver->getRitzVectors()) );
865 std::vector<Anasazi::Value<ScalarType> > tmpEvals = bks_solver->getRitzValues();
866 for (
int vec_i=0; vec_i<sol.
numVecs; ++vec_i) {
867 sol.
index[vec_i] = tmpIndex[whichVecs[vec_i]];
868 sol.
Evals[vec_i] = tmpEvals[whichVecs[vec_i]];
870 sol.
Evecs = MVT::CloneCopy( *(bks_solver->getRitzVectors()), whichVecs );
879 bks_solver->currentStatus(printer->stream(
FinalSummary));
882 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
888 problem_->setSolution(sol);
889 printer->stream(
Debug) <<
"Returning " << sol.
numVecs <<
" eigenpairs to eigenproblem." << std::endl;
892 numIters_ = bks_solver->getNumIters();
901 template <
class ScalarType,
class MV,
class OP>
906 globalTest_ = global;
909 template <
class ScalarType,
class MV,
class OP>
916 template <
class ScalarType,
class MV,
class OP>
924 template <
class ScalarType,
class MV,
class OP>
ScalarType * values() const
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. ...
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > H
The current Hessenberg matrix.
std::vector< Value< ScalarType > > Evals
The computed eigenvalues.
A special StatusTest for printing other status tests.
This class defines the interface required by an eigensolver and status test class to compute solution...
An implementation of the Anasazi::SortManager that performs a collection of common sorting techniques...
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
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...
ReturnType solve()
This method performs possibly repeated calls to the underlying eigensolver's iterate() routine until ...
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 setDebugStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &debug)
Set the status test for debugging.
Basic implementation of the Anasazi::SortManager class.
An implementation of the Anasazi::MatOrthoManager that performs orthogonalization using the SVQB iter...
Structure to contain pointers to BlockKrylovSchur state variables.
virtual ~BlockKrylovSchurSolMgr()
Destructor.
void GEMM(ETransp transa, ETransp transb, const OrdinalType &m, const OrdinalType &n, const OrdinalType &k, const alpha_type alpha, const A_type *A, const OrdinalType &lda, const B_type *B, const OrdinalType &ldb, const beta_type beta, ScalarType *C, const OrdinalType &ldc) const
An exception class parent to all Anasazi exceptions.
Output managers remove the need for the eigensolver to know any information about the required output...
ScalarTraits< ScalarType >::magnitudeType normFrobenius() const
The Anasazi::BlockKrylovSchurSolMgr provides a flexible solver manager over the BlockKrylovSchur eige...
A status test for testing the norm of the eigenvectors residuals along with a set of auxiliary eigenv...
bool isParameter(const std::string &name) const
int numVecs
The number of computed eigenpairs.
std::vector< Value< ScalarType > > getRitzValues() const
Return the Ritz values from the most recent solve.
void setGlobalStatusTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &global)
Set the status test defining global convergence.
BlockKrylovSchurSolMgr(const Teuchos::RCP< Eigenproblem< ScalarType, MV, OP > > &problem, Teuchos::ParameterList &pl)
Basic constructor for BlockKrylovSchurSolMgr.
Teuchos::RCP< MV > Espace
An orthonormal basis for the computed eigenspace.
Abstract class definition for Anasazi Output Managers.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Abstract base class which defines the interface required by an eigensolver and status test class to c...
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
static magnitudeType prec()
static void applyHouse(int k, MV &V, const Teuchos::SerialDenseMatrix< int, ScalarType > &H, const std::vector< ScalarType > &tau, Teuchos::RCP< MV > workMV=Teuchos::null)
Apply a sequence of Householder reflectors (from GEQRF) to a multivector, using minimal workspace...
ReturnType
Enumerated type used to pass back information from a solver manager.
Output managers remove the need for the eigensolver to know any information about the required output...
A status test for testing the norm of the eigenvectors residuals.
Traits class which defines basic operations on multivectors.
std::vector< int > index
An index into Evecs to allow compressed storage of eigenvectors for real, non-Hermitian problems...
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Return the eigenvalue problem.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
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...
Struct for storing an eigenproblem solution.
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > & getGlobalStatusTest() const
Get the status test defining global convergence.
OrdinalType numCols() const
void push_back(const value_type &x)
void GEQRF(const OrdinalType &m, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, ScalarType *TAU, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *info) const
Teuchos::RCP< const MulVec > V
The current Krylov basis.
Special StatusTest for printing status tests.
A status test for testing the norm of the eigenvectors residuals along with a set of auxiliary eigenv...
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.
Abstract class definition for Anasazi output stream.
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > Q
The current Schur vectors of the valid part of H.
Implementation of a block Krylov-Schur eigensolver.
This class implements the block Krylov-Schur iteration, for solving linear eigenvalue problems...
int curDim
The current dimension of the reduction.
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.
const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > & getDebugStatusTest() const
Get the status test for debugging.
Basic implementation of the Anasazi::OrthoManager class.
Teuchos::RCP< const Teuchos::SerialDenseMatrix< int, ScalarType > > S
The current Schur form reduction of the valid part of H.
OrdinalType stride() const
int getNumIters() const
Get the iteration count for the most recent call to solve().
OrdinalType numRows() const
Class which provides internal utilities for the Anasazi solvers.