Belos Version of the Day
BelosMinresSolMgr.hpp
Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 //
00004 //                 Belos: Block Linear Solvers Package
00005 //                  Copyright 2004 Sandia Corporation
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ************************************************************************
00040 //@HEADER
00041 
00042 #ifndef BELOS_MINRES_SOLMGR_HPP
00043 #define BELOS_MINRES_SOLMGR_HPP
00044 
00047 
00048 #include "BelosConfigDefs.hpp"
00049 #include "BelosTypes.hpp"
00050 
00051 #include "BelosLinearProblem.hpp"
00052 #include "BelosSolverManager.hpp"
00053 
00054 #include "BelosMinresIter.hpp"
00055 #include "BelosStatusTestMaxIters.hpp"
00056 #include "BelosStatusTestGenResNorm.hpp"
00057 #include "BelosStatusTestCombo.hpp"
00058 #include "BelosStatusTestOutputFactory.hpp"
00059 #include "BelosOutputManager.hpp"
00060 #include "Teuchos_BLAS.hpp"
00061 #include "Teuchos_LAPACK.hpp"
00062 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00063 #include "Teuchos_TimeMonitor.hpp"
00064 #endif
00065 
00066 #include "Teuchos_StandardParameterEntryValidators.hpp"
00067 // Teuchos::ScalarTraits<int> doesn't define rmax(), alas, so we get
00068 // INT_MAX from here.
00069 #include <climits> 
00070 
00071 namespace Belos {
00072   
00074 
00075 
00085   //
00089   class MinresSolMgrLinearProblemFailure : public BelosError {
00090   public:
00091     MinresSolMgrLinearProblemFailure (const std::string& what_arg) : 
00092       BelosError(what_arg)
00093     {}
00094   };
00095 
00114   template<class ScalarType, class MV, class OP>
00115   class MinresSolMgr : public SolverManager<ScalarType,MV,OP> {
00116     
00117   private:
00118     typedef MultiVecTraits<ScalarType,MV> MVT;
00119     typedef OperatorTraits<ScalarType,MV,OP> OPT;
00120     typedef Teuchos::ScalarTraits<ScalarType> SCT;
00121     typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00122     typedef Teuchos::ScalarTraits< MagnitudeType > MT;
00123     
00124   public:
00125 
00139     static Teuchos::RCP< const Teuchos::ParameterList > defaultParameters();
00140 
00154     static void
00155     validateParameters (const Teuchos::RCP< Teuchos::ParameterList >& params);
00156     
00158 
00159 
00168     MinresSolMgr();
00169 
00196     MinresSolMgr (const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem,
00197                   const Teuchos::RCP< Teuchos::ParameterList > &params);
00198     
00200     virtual ~MinresSolMgr() {};
00202     
00204 
00205 
00207     const LinearProblem<ScalarType,MV,OP>& getProblem() const {
00208       return *problem_;
00209     }
00210 
00212     Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const {
00213       return defaultParameters();
00214     }
00215     
00217     Teuchos::RCP< const Teuchos::ParameterList > getCurrentParameters() const { 
00218       return params_; 
00219     }
00220     
00227     Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const {
00228       return Teuchos::tuple(timerSolve_);
00229     }
00230 
00232     int getNumIters() const {
00233       return numIters_;
00234     }
00235 
00241     bool isLOADetected() const { return false; }
00242  
00244     
00246 
00247    
00249     void 
00250     setProblem (const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) 
00251     { 
00252       validateProblem (problem);
00253       problem_ = problem; 
00254     }
00255    
00268     void 
00269     setParameters (const Teuchos::RCP< Teuchos::ParameterList >& params);
00270     
00272    
00274 
00275 
00282     void 
00283     reset (const ResetType type) 
00284     { 
00285       if ((type & Belos::Problem) && ! Teuchos::is_null (problem_)) 
00286   problem_->setProblem(); 
00287     }
00289  
00291 
00292     
00294     //
00318     ReturnType solve();
00319     
00321     
00324     
00326     std::string description() const;
00327     
00329     
00330   private:
00334     static void
00335     validateProblem (const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > >& problem);
00336 
00339     void 
00340     readParameters (const Teuchos::RCP< const Teuchos::ParameterList >& params);
00341 
00343     Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
00344     
00346     Teuchos::RCP<OutputManager<ScalarType> > printer_;
00347     Teuchos::RCP<std::ostream> outputStream_;
00348 
00350     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
00351 
00353     Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
00354 
00356     Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
00357 
00359     Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
00360 
00362     Teuchos::RCP< Teuchos::ParameterList > params_;
00363 
00365     MagnitudeType convtol_;
00366 
00368     int maxIters_;
00369 
00371     int numIters_;
00372 
00374     int blockSize_;
00375 
00377     int verbosity_;
00378 
00380     int outputStyle_;
00381 
00383     int outputFreq_;
00384     
00386     std::string label_;
00387 
00389     Teuchos::RCP<Teuchos::Time> timerSolve_;
00390 
00392     bool parametersSet_;
00393   };
00394 
00395 
00396   template<class ScalarType, class MV, class OP>
00397   Teuchos::RCP< const Teuchos::ParameterList > 
00398   MinresSolMgr< ScalarType, MV, OP >::defaultParameters()
00399   {
00400     using Teuchos::is_null;
00401     using Teuchos::ParameterList;
00402     using Teuchos::RCP;
00403     using Teuchos::rcp;
00404     using Teuchos::EnhancedNumberValidator;
00405     typedef Teuchos::ScalarTraits< MagnitudeType > MST;
00406     typedef Teuchos::ScalarTraits< int > IST;
00407 
00408     // List of parameters accepted by MINRES, and their default values.
00409     static RCP< const ParameterList > validPL;
00410   
00411     // If we haven't already initialized the list of accepted parameters
00412     // and their default values, do so.
00413     if (is_null (validPL)) 
00414       {
00415   // validPL is a pointer to a const ParameterList, so we need to
00416   // make a non-const ParameterList first in order to fill it with
00417   // parameters and their default values.
00418   RCP< ParameterList > pl (new ParameterList);
00419 
00420   pl->set ("Convergence Tolerance", static_cast< MagnitudeType >(1e-8),
00421      "Relative residual tolerance that needs to be achieved by "
00422      "the iterative solver, in order for the linear system to be "
00423      "declared converged.",
00424      rcp (new EnhancedNumberValidator< MagnitudeType > (MST::zero(), MST::rmax())));
00425   pl->set ("Maximum Iterations", static_cast<int>(1000),
00426      "Maximum number of iterations allowed for each right-hand "
00427      "side solved.",
00428      rcp (new EnhancedNumberValidator< int > (0, INT_MAX)));
00429   pl->set ("Block Size", static_cast<int>(1),
00430      "Number of vectors in each block.  WARNING: The current "
00431      "implementation of MINRES only accepts a block size of 1, "
00432      "since it can only solve for 1 right-hand side at a time.",
00433      rcp (new EnhancedNumberValidator< int > (1, 1)));  // [1,1] is inclusive range
00434   pl->set ("Verbosity", (int) Belos::Errors,
00435      "The type(s) of solver information that should "
00436      "be written to the output stream.");
00437   pl->set ("Output Style", (int) Belos::General,
00438      "What style is used for the solver information written "
00439      "to the output stream.");
00440   pl->set ("Output Frequency", static_cast<int>(-1),
00441      "How often (in terms of number of iterations) intermediate "
00442      "convergence information should be written to the output stream."
00443      "  -1 means never.");
00444   pl->set ("Output Stream", rcp(&std::cout, false),
00445      "A reference-counted pointer to the output stream where all "
00446      "solver output is sent.  The output stream defaults to stdout.");
00447   pl->set ("Timer Label", std::string("Belos"),
00448      "The string to use as a prefix for the timer labels.");
00449   validPL = pl;
00450       }
00451     return validPL;
00452   }
00453 
00454   //
00455   // Empty Constructor
00456   //
00457   template<class ScalarType, class MV, class OP>
00458   MinresSolMgr<ScalarType,MV,OP>::MinresSolMgr () :
00459     numIters_ (0),
00460     parametersSet_ (false)
00461   {
00462     // Pass in a null parameter list so setParameters grabs the default parameter list.
00463     Teuchos::RCP< Teuchos::ParameterList > nullParams = Teuchos::null;
00464     setParameters ( nullParams );
00465   }
00466 
00467   //
00468   // Primary constructor (use this one)
00469   //
00470   template<class ScalarType, class MV, class OP>
00471   MinresSolMgr< ScalarType, MV, OP >::
00472   MinresSolMgr (const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem,
00473     const Teuchos::RCP< Teuchos::ParameterList >& params) :
00474     problem_ (problem),
00475     numIters_ (0),
00476     parametersSet_ (false)
00477   {
00478     TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
00479 
00480     // If the parameter list pointer is null, then set the current parameters to the default parameter list.
00481     if ( !is_null(params) ) {
00482       setParameters( params );  
00483     }
00484   }
00485 
00486   template<class ScalarType, class MV, class OP>
00487   void
00488   MinresSolMgr< ScalarType, MV, OP >::
00489   validateProblem (const Teuchos::RCP< LinearProblem< ScalarType, MV, OP > > &problem) 
00490   {
00491     TEST_FOR_EXCEPTION(Teuchos::is_null(problem), std::invalid_argument, 
00492            "MINRES requires a non-null LinearProblem object,"
00493            "which represents the linear problem to solve.");
00494     TEST_FOR_EXCEPTION(Teuchos::is_null(problem->getOperator()), 
00495            std::invalid_argument, 
00496            "MINRES requires a LinearProblem object with a non-null "
00497            "operator.");
00498     TEST_FOR_EXCEPTION(Teuchos::is_null(problem->getRHS()),
00499            std::invalid_argument, 
00500            "MINRES requires a LinearProblem object with a non-null "
00501            "right-hand side.");
00502   }
00503 
00504   template< class ScalarType, class MV, class OP >
00505   void
00506   MinresSolMgr< ScalarType, MV, OP>::
00507   validateParameters (const Teuchos::RCP< Teuchos::ParameterList >& params)
00508   {
00509     using Teuchos::Exceptions::InvalidParameterName;
00510     using Teuchos::is_null;
00511     using Teuchos::ParameterList;
00512     using Teuchos::RCP;
00513     using Teuchos::rcp;
00514 
00515     if (is_null (params)) 
00516       throw std::logic_error ("MinresSolMgr::validateParameters() requires a "
00517             "non-null input, but was given a null input.  Th"
00518             "is is likely the result of a bug in the impleme"
00519             "ntation of MinresSolMgr.");
00520     // List of default, known-valid parameters.
00521     Teuchos::RCP< const Teuchos::ParameterList > defaults = defaultParameters();
00522 
00523     // Validate parameters' values in params, and add default values
00524     // for parameters that are not in params.
00525     //
00526     // NOTE (mfh 06 Dec 2010) This throws
00527     // Teuchos::Exceptions::InvalidParameterName if params has a
00528     // parameter that defaults doesn't have (not vice versa).  (That
00529     // would mean the user provided "extra" parameters.)  We should
00530     // really just let those go through, for the sake of forwards
00531     // compatibility.  We could do this by implementing a variant of
00532     // validateParametersAndSetDefaults() that ignores parameters in
00533     // params that are not in defaults.
00534     params->validateParametersAndSetDefaults(*defaults);
00535   }
00536 
00537   template<class ScalarType, class MV, class OP>
00538   void 
00539   MinresSolMgr< ScalarType, MV, OP>::
00540   readParameters (const Teuchos::RCP< const Teuchos::ParameterList >& params)
00541   {
00542     using Teuchos::RCP;
00543     using Teuchos::rcp;
00544     using Teuchos::null;
00545     using Teuchos::is_null;
00546     using std::string;
00547     using std::ostream;
00548 
00549     // Set the block size.  The only valid value is 1, for this
00550     // particular solver.
00551     blockSize_ = params->get<int> ("Block Size");
00552 
00553     // Change the timer label.
00554     {
00555       label_ = params->get< string > ("Timer Label");
00556 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00557       const string solveLabel = label_ + ": MinresSolMgr total solve time";
00558       timerSolve_ = Teuchos::TimeMonitor::getNewTimer (solveLabel);
00559 #endif
00560     }
00561 
00562     // Set verbosity level
00563     verbosity_ = params->get< int > ("Verbosity");
00564     // We may not have created the output manager yet.  If we haven't,
00565     // we will create it below and set the verbosity level
00566     // appropriately.
00567     if (! is_null (printer_))
00568       printer_->setVerbosity (verbosity_);
00569 
00570     // Set output style
00571     outputStyle_ = params->get<int> ("Output Style");
00572 
00573     // Set output stream
00574     outputStream_ = params->get< RCP< std::ostream > > ("Output Stream");
00575     // Tell the output manager about the new output stream.  We
00576     // may not yet have created the output manager yet, so check
00577     // here if it is not null.  We will create the output manager
00578     // if necessary below.
00579     if (! Teuchos::is_null (printer_))
00580       printer_->setOStream (outputStream_);
00581 
00582     // Set output frequency level
00583     if (Belos::StatusTestDetails) 
00584       {
00585   outputFreq_ = params->get<int>("Output Frequency");
00586   // We may not have created the status test output object yet.
00587   if (! is_null (outputTest_))
00588     outputTest_->setOutputFrequency (outputFreq_);
00589       }
00590 
00591     // Create output manager
00592     printer_ = rcp (new OutputManager< ScalarType >(verbosity_, outputStream_));
00593   
00594     //
00595     // Set up the convergence tests
00596     //
00597     typedef Belos::StatusTestCombo< ScalarType, MV, OP > StatusTestCombo_t;
00598     typedef Belos::StatusTestGenResNorm< ScalarType, MV, OP > StatusTestResNorm_t;
00599 
00600     // Set convergence tolerance
00601     convtol_ = params->get< MagnitudeType >("Convergence Tolerance");
00602 
00603     // Residual status test.  It uses the native residual to determine
00604     // if convergence was achieved.  Initialize it if we haven't yet
00605     // done so, otherwise tell it the new convergence tolerance.
00606     if (is_null (convTest_))
00607       convTest_ = rcp (new StatusTestResNorm_t (convtol_, -1));
00608     else
00609       convTest_->setTolerance (convtol_);
00610 
00611     // Set maximum number of iterations.
00612     maxIters_ = params->get<int>("Maximum Iterations");
00613 
00614     // Maximum number of iterations status test.  It tells the solver to
00615     // stop iteration, if the maximum number of iterations has been
00616     // exceeded.  Initialize it if we haven't yet done so, otherwise
00617     // tell it the new maximum number of iterations.
00618     if (is_null (maxIterTest_))
00619       maxIterTest_ = rcp (new StatusTestMaxIters<ScalarType,MV,OP> (maxIters_));
00620     else
00621       maxIterTest_->setMaxIters (maxIters_);
00622 
00623     // Create the full status test if we need to.  
00624     //
00625     // The full status test: maximum number of iterations reached, OR
00626     // residual has converged.
00627     //
00628     // "If we need to" means if the status test was never created
00629     // before.  The full status test has pointers to maxIterTest_ and
00630     // convTest_, so if we changed either the convergence tolerance
00631     // and/or the maximum number of iterations, the full status test
00632     // will get the results of the updates.
00633     if (is_null (sTest_))
00634       sTest_ = rcp (new StatusTestCombo_t (StatusTestCombo_t::OR, maxIterTest_, convTest_));
00635   
00636     // If necessary, create the status test output class.  This class
00637     // manages and formats the output from the status test.
00638     if (is_null (outputTest_))
00639       {
00640   StatusTestOutputFactory<ScalarType,MV,OP> stoFactory (outputStyle_);
00641   outputTest_ = stoFactory.create (printer_, sTest_, outputFreq_,
00642            Passed+Failed+Undefined);
00643   // Set the solver string for the output test
00644   outputTest_->setSolverDesc (std::string(" MINRES "));
00645       }
00646 
00647     // Create the timer if we need to.
00648     if (is_null (timerSolve_))
00649       {
00650 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00651   const std::string solveLabel = label_ + ": MinresSolMgr total solve time";
00652   timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00653 #endif
00654       }
00655     // Inform the solver manager that the current parameters were set.
00656     parametersSet_ = true;
00657   }
00658 
00659 
00660   template<class ScalarType, class MV, class OP>
00661   void 
00662   MinresSolMgr< ScalarType, MV, OP>::
00663   setParameters (const Teuchos::RCP< Teuchos::ParameterList >& params)
00664   {
00665     if (Teuchos::is_null (params))
00666       // We don't need to validate the default parameter values.
00667       // However, we do need to make a deep copy, since params_ is
00668       // const and the input params is non-const.
00669       params_ = Teuchos::rcp (new Teuchos::ParameterList (*defaultParameters()));
00670     else
00671       {
00672   // Validate params.  All the entries that should be there, are
00673   // there, with default values if the entries were not supplied in
00674   // the input parameter list, and with valid values otherwise.
00675   validateParameters (params);
00676   params_ = params; // both are non-const
00677       }
00678     readParameters (params_);
00679   }
00680 
00681 
00682   template<class ScalarType, class MV, class OP>
00683   ReturnType MinresSolMgr<ScalarType,MV,OP>::solve() 
00684   {
00685     using Teuchos::RCP;
00686     using Teuchos::rcp;
00687 
00688 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00689     Teuchos::TimeMonitor slvtimer(*timerSolve_);
00690 #endif
00691 
00692     // We need a problem to solve, else we can't solve it.
00693     TEST_FOR_EXCEPTION( !problem_->isProblemSet(),
00694       MinresSolMgrLinearProblemFailure,
00695       "Belos::MinresSolMgr::solve(): The linear problem to "
00696       "solve has not been set, so it is not valid to call the "
00697       "solve() method.  You should either provide the linear "
00698       "problem to the solver manager's constructor, or call "
00699       "setProblem() with a non-null linear problem, before "
00700       "calling solve()." );
00701 
00702     // Reset the status test for this solve.  
00703     outputTest_->reset();
00704 
00705     // The linear problem has this many right-hand sides to solve.
00706     // MINRES can solve one at a time, so we solve for each right-hand
00707     // side in succession.
00708     const int numRHS2Solve = MVT::GetNumberVecs (*(problem_->getRHS()));
00709 
00710     // Create MINRES iteration object.  Pass along the solver
00711     // manager's parameters, which have already been validated.
00712     RCP< MinresIteration< ScalarType, MV, OP > > minres_iter =
00713       rcp (new MinresIter< ScalarType, MV, OP > (problem_, printer_, outputTest_, *params_));
00714 
00715     // The index/indices of the right-hand sides for which MINRES did
00716     // _not_ converge.  Hopefully this is empty after the for loop below!
00717     // If it is not empty, at least one right-hand side did not converge.
00718     std::vector<int> notConverged;
00719     std::vector<int> currentIndices(1);
00720 
00721     numIters_ = 0;
00722 
00723     // Solve for each right-hand side in turn.
00724     for (int currentRHS = 0; currentRHS < numRHS2Solve; ++currentRHS)
00725       {
00726   // Inform the linear problem of the right-hand side(s) currently
00727   // being solved.  MINRES only knows how to solve linear problems
00728   // with one right-hand side, so we only include one index, which
00729   // is the index of the current right-hand side.
00730   currentIndices[0] = currentRHS;
00731   problem_->setLSIndex (currentIndices);
00732 
00733   // Reset the number of iterations.
00734   minres_iter->resetNumIters();
00735   // Reset the number of calls that the status test output knows about.
00736   outputTest_->resetNumCalls();
00737   // Set the new state and initialize the solver.
00738   MinresIterationState< ScalarType, MV > newstate;
00739 
00740   // Get the residual vector for the current linear system
00741   // (i.e., for the current right-hand side).
00742   
00743   newstate.Y = MVT::CloneViewNonConst (*(Teuchos::rcp_const_cast< MV > (problem_->getInitResVec())), currentIndices);
00744   minres_iter->initializeMinres (newstate);
00745 
00746   // Attempt to solve for the solution corresponding to the
00747   // current right-hand side.
00748   while(1) {
00749           try {
00750       minres_iter->iterate();
00751 
00752             // First check for convergence
00753       if (convTest_->getStatus() == Passed) {
00754         break;
00755       }
00756             // Now check for max # of iterations
00757             else if (maxIterTest_->getStatus() == Passed) {
00758         // This right-hand side didn't converge!
00759         notConverged.push_back (currentRHS);
00760               break;
00761             } else {
00762         // If we get here, we returned from iterate(), but none of
00763         // our status tests Passed.  Something is wrong, and it is
00764         // probably our fault.
00765         TEST_FOR_EXCEPTION(true, std::logic_error,
00766                                "Belos::MinresSolMgr::solve(): iterations neither"
00767                                " converged, nor reached the maximum number of "
00768                                "iterations " << maxIters_ << ".  That means someth"
00769                                "ing went wrong.");
00770         }
00771     } catch (const std::exception &e) {
00772       printer_->stream(Errors) 
00773         << "Error! Caught std::exception in "
00774         << "MinresIter::iterate() at iteration "
00775         << minres_iter->getNumIters() << std::endl
00776         << e.what() << std::endl;
00777       throw e;
00778     }
00779         }
00780   
00781         // Inform the linear problem that we are finished with the
00782         // current right-hand side.  It may or may not have converged,
00783         // but we don't try again if the first time didn't work.
00784         problem_->setCurrLS();
00785     
00786         // Get iteration information for this solve: total number of
00787         // iterations for all right-hand sides.
00788         numIters_ += maxIterTest_->getNumIters();
00789       }
00790     
00791     // Print final summary of the solution process
00792     sTest_->print( printer_->stream(FinalSummary) );
00793 
00794     // Print timing information, if the corresponding compile-time and
00795     // run-time options are enabled.
00796 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00797     // Calling summarize() can be expensive, so don't call unless the
00798     // user wants to print out timing details.  summarize() will do all
00799     // the work even if it's passed a "black hole" output stream.
00800     if (verbosity_ & TimingDetails)
00801       Teuchos::TimeMonitor::summarize (printer_->stream (TimingDetails));
00802 #endif // BELOS_TEUCHOS_TIME_MONITOR
00803  
00804     if (notConverged.size() > 0)
00805       return Unconverged;
00806     else
00807       return Converged;
00808   }
00809 
00810   //  This method requires the solver manager to return a std::string that describes itself.
00811   template<class ScalarType, class MV, class OP>
00812   std::string MinresSolMgr<ScalarType,MV,OP>::description() const
00813   {
00814     std::ostringstream oss;
00815     oss << "Belos::MinresSolMgr< " 
00816   << Teuchos::ScalarTraits<ScalarType>::name()
00817   <<", MV, OP >";
00818     // oss << "{";
00819     // oss << "Block Size=" << blockSize_;
00820     // oss << "}";
00821     return oss.str();
00822   }
00823   
00824 } // end Belos namespace
00825 
00826 #endif /* BELOS_MINRES_SOLMGR_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines