43 #ifndef ANASAZI_SIMPLE_LOBPCG_SOLMGR_HPP 44 #define ANASAZI_SIMPLE_LOBPCG_SOLMGR_HPP 67 #include "Teuchos_TimeMonitor.hpp" 102 template<
class ScalarType,
class MV,
class OP>
107 typedef Teuchos::ScalarTraits<ScalarType> SCT;
108 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
109 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
127 Teuchos::ParameterList &pl );
161 Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
172 template<
class ScalarType,
class MV,
class OP>
175 Teuchos::ParameterList &pl ) :
184 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument,
"Problem not given to solver manager.");
185 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(), std::invalid_argument,
"Problem not set.");
186 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isHermitian(), std::invalid_argument,
"Problem not symmetric.");
187 TEUCHOS_TEST_FOR_EXCEPTION(problem_->getInitVec() == Teuchos::null,std::invalid_argument,
"Problem does not contain initial vectors to clone from.");
189 whch_ = pl.get(
"Which",
"SR");
190 TEUCHOS_TEST_FOR_EXCEPTION(whch_ !=
"SM" && whch_ !=
"LM" && whch_ !=
"SR" && whch_ !=
"LR",
192 "SimpleLOBPCGSolMgr: \"Which\" parameter must be SM, LM, SR or LR.");
194 tol_ = pl.get(
"Convergence Tolerance",tol_);
195 TEUCHOS_TEST_FOR_EXCEPTION(tol_ <= 0,
197 "SimpleLOBPCGSolMgr: \"Tolerance\" parameter must be strictly postiive.");
200 if (pl.isParameter(
"Verbosity")) {
201 if (Teuchos::isParameterType<int>(pl,
"Verbosity")) {
202 verb_ = pl.get(
"Verbosity", verb_);
204 verb_ = (int)Teuchos::getParameter<Anasazi::MsgType>(pl,
"Verbosity");
209 blockSize_= pl.get(
"Block Size",problem_->getNEV());
210 TEUCHOS_TEST_FOR_EXCEPTION(blockSize_ <= 0,
212 "SimpleLOBPCGSolMgr: \"Block Size\" parameter must be strictly positive.");
214 maxIters_ = pl.get(
"Maximum Iterations",maxIters_);
220 template<
class ScalarType,
class MV,
class OP>
229 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > max;
236 Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > norm
238 Teuchos::Array< Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests;
239 alltests.push_back(norm);
240 if (max != Teuchos::null) alltests.push_back(max);
241 Teuchos::RCP<StatusTestCombo<ScalarType,MV,OP> > combo
246 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest
249 Teuchos::RCP<SVQBOrthoManager<ScalarType,MV,OP> > ortho
252 Teuchos::ParameterList plist;
253 plist.set(
"Block Size",blockSize_);
254 plist.set(
"Full Ortho",
true);
257 Teuchos::RCP<LOBPCG<ScalarType,MV,OP> > lobpcg_solver
260 if (problem_->getAuxVecs() != Teuchos::null) {
261 lobpcg_solver->setAuxVecs( Teuchos::tuple<Teuchos::RCP<const MV> >(problem_->getAuxVecs()) );
265 int nev = problem_->getNEV();
266 Teuchos::Array< Teuchos::RCP<MV> > foundvecs;
267 Teuchos::Array< Teuchos::RCP< std::vector<MagnitudeType> > > foundvals;
268 while (numfound < nev) {
270 if (nev - numfound < blockSize_) {
271 norm->setQuorum(nev-numfound);
276 lobpcg_solver->iterate();
278 catch (
const std::exception &e) {
280 printer->stream(
Anasazi::Errors) <<
"Exception: " << e.what() << std::endl;
283 problem_->setSolution(sol);
288 if (norm->getStatus() ==
Passed) {
290 int num = norm->howMany();
292 TEUCHOS_TEST_FOR_EXCEPTION(num < blockSize_ && num+numfound < nev,
294 "Anasazi::SimpleLOBPCGSolMgr::solve(): logic error.");
295 std::vector<int> ind = norm->whichVecs();
297 if (num + numfound > nev) {
298 num = nev - numfound;
303 Teuchos::RCP<MV> newvecs =
MVT::CloneCopy(*lobpcg_solver->getRitzVectors(),ind);
305 foundvecs.push_back(newvecs);
307 Teuchos::Array<Teuchos::RCP<const MV> > auxvecs = lobpcg_solver->getAuxVecs();
308 auxvecs.push_back(newvecs);
310 lobpcg_solver->setAuxVecs(auxvecs);
313 Teuchos::RCP<std::vector<MagnitudeType> > newvals = Teuchos::rcp(
new std::vector<MagnitudeType>(num) );
314 std::vector<Value<ScalarType> > all = lobpcg_solver->getRitzValues();
315 for (
int i=0; i<num; i++) {
316 (*newvals)[i] = all[ind[i]].realpart;
318 foundvals.push_back(newvals);
322 else if (max != Teuchos::null && max->getStatus() ==
Passed) {
324 int num = norm->howMany();
325 std::vector<int> ind = norm->whichVecs();
329 Teuchos::RCP<MV> newvecs =
MVT::CloneCopy(*lobpcg_solver->getRitzVectors(),ind);
331 foundvecs.push_back(newvecs);
335 Teuchos::RCP<std::vector<MagnitudeType> > newvals = Teuchos::rcp(
new std::vector<MagnitudeType>(num) );
336 std::vector<Value<ScalarType> > all = lobpcg_solver->getRitzValues();
337 for (
int i=0; i<num; i++) {
338 (*newvals)[i] = all[ind[i]].realpart;
340 foundvals.push_back(newvals);
347 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Anasazi::SimpleLOBPCGSolMgr::solve(): solver returned without satisfy status test.");
351 TEUCHOS_TEST_FOR_EXCEPTION(foundvecs.size() != foundvals.size(),std::logic_error,
"Anasazi::SimpleLOBPCGSolMgr::solve(): inconsistent array sizes");
358 sol.Evecs =
MVT::Clone(*problem_->getInitVec(),numfound);
361 sol.Evecs = Teuchos::null;
363 sol.Espace = sol.Evecs;
365 std::vector<MagnitudeType> vals(numfound);
366 sol.Evals.resize(numfound);
368 sol.index.resize(numfound,0);
371 for (
unsigned int i=0; i<foundvals.size(); i++) {
372 TEUCHOS_TEST_FOR_EXCEPTION((
signed int)(foundvals[i]->size()) !=
MVT::GetNumberVecs(*foundvecs[i]), std::logic_error,
"Anasazi::SimpleLOBPCGSolMgr::solve(): inconsistent sizes");
373 unsigned int lclnum = foundvals[i]->size();
374 std::vector<int> lclind(lclnum);
375 for (
unsigned int j=0; j<lclnum; j++) lclind[j] = curttl+j;
379 std::copy( foundvals[i]->begin(), foundvals[i]->end(), vals.begin()+curttl );
383 TEUCHOS_TEST_FOR_EXCEPTION( curttl != sol.numVecs, std::logic_error,
"Anasazi::SimpleLOBPCGSolMgr::solve(): inconsistent sizes");
387 std::vector<int> order(sol.numVecs);
388 sorter->sort(vals,Teuchos::rcpFromRef(order),sol.numVecs);
390 for (
int i=0; i<sol.numVecs; i++) {
391 sol.Evals[i].realpart = vals[i];
392 sol.Evals[i].imagpart = MT::zero();
400 lobpcg_solver->currentStatus(printer->stream(
FinalSummary));
403 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 405 Teuchos::TimeMonitor::summarize( printer->stream(
TimingDetails ) );
410 problem_->setSolution(sol);
411 printer->stream(
Debug) <<
"Returning " << sol.numVecs <<
" eigenpairs to eigenproblem." << std::endl;
414 numIters_ = lobpcg_solver->getNumIters();
Pure virtual base class which describes the basic interface for a solver manager. ...
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...
This class provides the Locally Optimal Block Preconditioned Conjugate Gradient (LOBPCG) iteration...
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...
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.
Implementation of the locally-optimal block preconditioned conjugate gradient (LOBPCG) method...
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package...
Anasazi's templated, static class providing utilities for the solvers.
virtual ~SimpleLOBPCGSolMgr()
Destructor.
int numVecs
The number of computed eigenpairs.
Basic output manager for sending information of select verbosity levels to the appropriate output str...
int getNumIters() const
Get the iteration count for the most recent call to solve().
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.
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).
The Anasazi::SimpleLOBPCGSolMgr provides a simple solver manager over the LOBPCG eigensolver.
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 Eigenproblem< ScalarType, MV, OP > & getProblem() const
Return the eigenvalue problem.
ReturnType solve()
This method performs possibly repeated calls to the underlying eigensolver's iterate() routine until ...
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...
A status test for testing the number of iterations.
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv.
Status test for testing the number of iterations.
static void permuteVectors(const int n, const std::vector< int > &perm, MV &Q, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > *resids=0)
Permute the vectors in a multivector according to the permutation vector perm, and optionally the res...
Special StatusTest for printing status tests.
Status test for forming logical combinations of other status tests.
Types and exceptions used within Anasazi solvers and interfaces.
A status test for testing the norm of the eigenvectors residuals.
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
Creates a new empty MV containing numvecs columns.
SimpleLOBPCGSolMgr(const Teuchos::RCP< Eigenproblem< ScalarType, MV, OP > > &problem, Teuchos::ParameterList &pl)
Basic constructor for SimpleLOBPCGSolMgr.
Class which provides internal utilities for the Anasazi solvers.