Anasazi  Version of the Day
AnasaziRTRSolMgr.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Anasazi: Block Eigensolvers Package
5 // Copyright 2004 Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef ANASAZI_RTR_SOLMGR_HPP
43 #define ANASAZI_RTR_SOLMGR_HPP
44 
50 #include "AnasaziConfigDefs.hpp"
51 #include "AnasaziTypes.hpp"
52 
53 #include "AnasaziEigenproblem.hpp"
54 #include "AnasaziSolverManager.hpp"
55 #include "AnasaziSolverUtils.hpp"
56 
57 #include "AnasaziIRTR.hpp"
58 #include "AnasaziSIRTR.hpp"
59 #include "AnasaziBasicSort.hpp"
67 
68 #include <Teuchos_TimeMonitor.hpp>
69 #include <Teuchos_FancyOStream.hpp>
70 
80 namespace Anasazi {
81 
82 template<class ScalarType, class MV, class OP>
83 class RTRSolMgr : public SolverManager<ScalarType,MV,OP> {
84 
85  private:
88  typedef Teuchos::ScalarTraits<ScalarType> SCT;
89  typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
90  typedef Teuchos::ScalarTraits<MagnitudeType> MT;
91 
92  public:
93 
95 
96 
112  RTRSolMgr( const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
113  Teuchos::ParameterList &pl );
114 
116  virtual ~RTRSolMgr() {};
118 
120 
121 
124  return *problem_;
125  }
126 
132  Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
133  return Teuchos::tuple(_timerSolve);
134  }
135 
137  int getNumIters() const {
138  return numIters_;
139  }
140 
141 
143 
145 
146 
155  ReturnType solve();
157 
158  private:
159  Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
160  std::string whch_;
161  std::string ortho_;
162 
163  bool skinny_;
164  MagnitudeType convtol_;
165  int maxIters_;
166  bool relconvtol_;
167  enum ResType convNorm_;
168  int numIters_;
169  int numICGS_;
170 
171  Teuchos::RCP<Teuchos::Time> _timerSolve;
172  Teuchos::RCP<BasicOutputManager<ScalarType> > printer_;
173  Teuchos::ParameterList pl_;
174 };
175 
176 
178 template<class ScalarType, class MV, class OP>
180  const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
181  Teuchos::ParameterList &pl ) :
182  problem_(problem),
183  whch_("SR"),
184  skinny_(true),
185  convtol_(MT::prec()),
186  maxIters_(100),
187  relconvtol_(true),
188  numIters_(-1),
189 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
190  _timerSolve(Teuchos::TimeMonitor::getNewTimer("Anasazi: RTRSolMgr::solve()")),
191 #endif
192  pl_(pl)
193 {
194  TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
195  TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(), std::invalid_argument, "Problem not set.");
196  TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isHermitian(), std::invalid_argument, "Problem not symmetric.");
197  TEUCHOS_TEST_FOR_EXCEPTION(problem_->getInitVec() == Teuchos::null,std::invalid_argument, "Problem does not contain initial vectors to clone from.");
198 
199  std::string strtmp;
200 
201  whch_ = pl_.get("Which","SR");
202  TEUCHOS_TEST_FOR_EXCEPTION(whch_ != "SR" && whch_ != "LR",
203  std::invalid_argument, "Anasazi::RTRSolMgr: Invalid sorting string. RTR solvers compute only LR or SR.");
204 
205  // convergence tolerance
206  convtol_ = pl_.get("Convergence Tolerance",convtol_);
207  relconvtol_ = pl_.get("Relative Convergence Tolerance",relconvtol_);
208  strtmp = pl_.get("Convergence Norm",std::string("2"));
209  if (strtmp == "2") {
210  convNorm_ = RES_2NORM;
211  }
212  else if (strtmp == "M") {
213  convNorm_ = RES_ORTH;
214  }
215  else {
216  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
217  "Anasazi::RTRSolMgr: Invalid Convergence Norm.");
218  }
219 
220 
221  // maximum number of (outer) iterations
222  maxIters_ = pl_.get("Maximum Iterations",maxIters_);
223 
224  // skinny solver or not
225  skinny_ = pl_.get("Skinny Solver",skinny_);
226 
227  // number if ICGS iterations
228  numICGS_ = pl_.get("Num ICGS",2);
229 
230  // output stream
231  std::string fntemplate = "";
232  bool allProcs = false;
233  if (pl_.isParameter("Output on all processors")) {
234  if (Teuchos::isParameterType<bool>(pl_,"Output on all processors")) {
235  allProcs = pl_.get("Output on all processors",allProcs);
236  } else {
237  allProcs = ( Teuchos::getParameter<int>(pl_,"Output on all processors") != 0 );
238  }
239  }
240  fntemplate = pl_.get("Output filename template",fntemplate);
241  int MyPID;
242 # ifdef HAVE_MPI
243  // Initialize MPI
244  int mpiStarted = 0;
245  MPI_Initialized(&mpiStarted);
246  if (mpiStarted) MPI_Comm_rank(MPI_COMM_WORLD, &MyPID);
247  else MyPID=0;
248 # else
249  MyPID = 0;
250 # endif
251  if (fntemplate != "") {
252  std::ostringstream MyPIDstr;
253  MyPIDstr << MyPID;
254  // replace %d in fntemplate with MyPID
255  int pos, start=0;
256  while ( (pos = fntemplate.find("%d",start)) != -1 ) {
257  fntemplate.replace(pos,2,MyPIDstr.str());
258  start = pos+2;
259  }
260  }
261  Teuchos::RCP<ostream> osp;
262  if (fntemplate != "") {
263  osp = Teuchos::rcp( new std::ofstream(fntemplate.c_str(),std::ios::out | std::ios::app) );
264  if (!*osp) {
265  osp = Teuchos::rcpFromRef(std::cout);
266  std::cout << "Anasazi::RTRSolMgr::constructor(): Could not open file for write: " << fntemplate << std::endl;
267  }
268  }
269  else {
270  osp = Teuchos::rcpFromRef(std::cout);
271  }
272  // Output manager
273  int verbosity = Anasazi::Errors;
274  if (pl_.isParameter("Verbosity")) {
275  if (Teuchos::isParameterType<int>(pl_,"Verbosity")) {
276  verbosity = pl_.get("Verbosity", verbosity);
277  } else {
278  verbosity = (int)Teuchos::getParameter<Anasazi::MsgType>(pl_,"Verbosity");
279  }
280  }
281  if (allProcs) {
282  // print on all procs
283  printer_ = Teuchos::rcp( new BasicOutputManager<ScalarType>(verbosity,osp,MyPID) );
284  }
285  else {
286  // print only on proc 0
287  printer_ = Teuchos::rcp( new BasicOutputManager<ScalarType>(verbosity,osp,0) );
288  }
289 }
290 
291 
292 // solve()
293 template<class ScalarType, class MV, class OP>
296 
297  using std::endl;
298 
299  // typedef SolverUtils<ScalarType,MV,OP> msutils; // unused
300 
301  const int nev = problem_->getNEV();
302 
303  // clear num iters
304  numIters_ = -1;
305 
306 #ifdef TEUCHOS_DEBUG
307  Teuchos::RCP<Teuchos::FancyOStream>
308  out = Teuchos::getFancyOStream(Teuchos::rcpFromRef(printer_->stream(Debug)));
309  out->setShowAllFrontMatter(false).setShowProcRank(true);
310  *out << "Entering Anasazi::RTRSolMgr::solve()\n";
311 #endif
312 
314  // Sort manager
315  Teuchos::RCP<BasicSort<MagnitudeType> > sorter = Teuchos::rcp( new BasicSort<MagnitudeType>(whch_) );
316 
318  // Status tests
319  //
320  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > maxtest;
321  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > ordertest;
322  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > combotest;
323  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convtest;
324  // maximum iters
325  if (maxIters_ > 0) {
326  maxtest = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>(maxIters_) );
327  }
328  else {
329  maxtest = Teuchos::null;
330  }
331  //
332  // convergence
333  convtest = Teuchos::rcp( new StatusTestResNorm<ScalarType,MV,OP>(convtol_,nev,convNorm_,relconvtol_) );
334  ordertest = Teuchos::rcp( new StatusTestWithOrdering<ScalarType,MV,OP>(convtest,sorter,nev) );
335  //
336  // combo
337  Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests;
338  alltests.push_back(ordertest);
339  if (maxtest != Teuchos::null) alltests.push_back(maxtest);
340  combotest = Teuchos::rcp( new StatusTestCombo<ScalarType,MV,OP>( StatusTestCombo<ScalarType,MV,OP>::OR, alltests) );
341  //
342  // printing StatusTest
343  Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest;
344  if ( printer_->isVerbosity(Debug) ) {
345  outputtest = Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer_,combotest,1,Passed+Failed+Undefined ) );
346  }
347  else {
348  outputtest = Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer_,combotest,1,Passed ) );
349  }
350 
352  // Orthomanager
353  Teuchos::RCP<ICGSOrthoManager<ScalarType,MV,OP> > ortho
354  = Teuchos::rcp( new ICGSOrthoManager<ScalarType,MV,OP>(problem_->getM(),numICGS_) );
355 
357  // create an RTR solver
358  // leftmost or rightmost?
359  bool leftMost = true;
360  if (whch_ == "LR" || whch_ == "LM") {
361  leftMost = false;
362  }
363  pl_.set<bool>("Leftmost",leftMost);
364  Teuchos::RCP<RTRBase<ScalarType,MV,OP> > rtr_solver;
365  if (skinny_ == false) {
366  // "hefty" IRTR
367  rtr_solver = Teuchos::rcp( new IRTR<ScalarType,MV,OP>(problem_,sorter,printer_,outputtest,ortho,pl_) );
368  }
369  else {
370  // "skinny" IRTR
371  rtr_solver = Teuchos::rcp( new SIRTR<ScalarType,MV,OP>(problem_,sorter,printer_,outputtest,ortho,pl_) );
372  }
373  // set any auxiliary vectors defined in the problem
374  Teuchos::RCP< const MV > probauxvecs = problem_->getAuxVecs();
375  if (probauxvecs != Teuchos::null) {
376  rtr_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs) );
377  }
378 
379  TEUCHOS_TEST_FOR_EXCEPTION(rtr_solver->getBlockSize() < problem_->getNEV(),std::logic_error,
380  "Anasazi::RTRSolMgr requires block size >= requested number of eigenvalues.");
381 
382  int numfound = 0;
383  Teuchos::RCP<MV> foundvecs;
384  std::vector<MagnitudeType> foundvals;
385 
386  // tell the solver to iterate
387  try {
388 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
389  Teuchos::TimeMonitor slvtimer(*_timerSolve);
390 #endif
391  rtr_solver->iterate();
392  numIters_ = rtr_solver->getNumIters();
393  }
394  catch (const std::exception &e) {
395  // we are a simple solver manager. we don't catch exceptions. set solution empty, then rethrow.
396  printer_->stream(Anasazi::Errors) << "Exception: " << e.what() << endl;
398  sol.numVecs = 0;
399  problem_->setSolution(sol);
400  throw;
401  }
402 
403  // check the status tests
404  if (convtest->getStatus() == Passed || (maxtest != Teuchos::null && maxtest->getStatus() == Passed))
405  {
406  int num = convtest->howMany();
407  if (num > 0) {
408  std::vector<int> ind = convtest->whichVecs();
409  // copy the converged eigenvectors
410  foundvecs = MVT::CloneCopy(*rtr_solver->getRitzVectors(),ind);
411  // copy the converged eigenvalues
412  foundvals.resize(num);
413  std::vector<Value<ScalarType> > all = rtr_solver->getRitzValues();
414  for (int i=0; i<num; i++) {
415  foundvals[i] = all[ind[i]].realpart;
416  }
417  numfound = num;
418  }
419  }
420  else {
421  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"Anasazi::RTRSolMgr::solve(): solver returned without satisfy status test.");
422  }
423 
424  // create contiguous storage for all eigenvectors, eigenvalues
426  sol.numVecs = numfound;
427  sol.Evecs = foundvecs;
428  sol.Espace = sol.Evecs;
429  sol.Evals.resize(sol.numVecs);
430  for (int i=0; i<sol.numVecs; i++) {
431  sol.Evals[i].realpart = foundvals[i];
432  }
433  // all real eigenvalues: set index vectors [0,...,numfound-1]
434  sol.index.resize(numfound,0);
435 
436  // print final summary
437  rtr_solver->currentStatus(printer_->stream(FinalSummary));
438 
439  // print timing information
440 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR
441  if ( printer_->isVerbosity( TimingDetails ) ) {
442  Teuchos::TimeMonitor::summarize( printer_->stream( TimingDetails ) );
443  }
444 #endif
445 
446  // send the solution to the eigenproblem
447  problem_->setSolution(sol);
448  printer_->stream(Debug) << "Returning " << sol.numVecs << " eigenpairs to eigenproblem." << endl;
449 
450  // return from SolMgr::solve()
451  if (sol.numVecs < nev) return Unconverged;
452  return Converged;
453 }
454 
455 
456 
457 
458 } // end Anasazi namespace
459 
460 #endif /* ANASAZI_RTR_SOLMGR_HPP */
Pure virtual base class which describes the basic interface for a solver manager. ...
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
Return the timers for this object.
std::vector< Value< ScalarType > > Evals
The computed eigenvalues.
ResType
Enumerated type used to specify which residual norm used by residual norm status tests.
A special StatusTest for printing other status tests.
This class defines the interface required by an eigensolver and status test class to compute solution...
RTRSolMgr(const Teuchos::RCP< Eigenproblem< ScalarType, MV, OP > > &problem, Teuchos::ParameterList &pl)
Basic constructor for RTRSolMgr.
An implementation of the Anasazi::SortManager that performs a collection of common sorting techniques...
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...
int getNumIters() const
Get the iteration count for the most recent call to solve.
The Anasazi::RTRSolMgr provides a simple solver manager over the RTR eigensolver. For more informatio...
virtual ~RTRSolMgr()
Destructor.
Basic implementation of the Anasazi::SortManager class.
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...
const Eigenproblem< ScalarType, MV, OP > & getProblem() const
Return the eigenvalue problem.
int numVecs
The number of computed eigenpairs.
Basic output manager for sending information of select verbosity levels to the appropriate output str...
ReturnType solve()
This method performs possibly repeated calls to the underlying eigensolver&#39;s iterate() routine until ...
Teuchos::RCP< MV > Espace
An orthonormal basis for the computed eigenspace.
Anasazi&#39;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).
std::vector< int > index
An index into Evecs to allow compressed storage of eigenvectors for real, non-Hermitian problems...
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
Struct for storing an eigenproblem solution.
A status test for testing the number of iterations.
Status test for testing the number of iterations.
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.
Types and exceptions used within Anasazi solvers and interfaces.
A status test for testing the norm of the eigenvectors residuals.
Basic implementation of the Anasazi::OrthoManager class.
Class which provides internal utilities for the Anasazi solvers.