Belos Version of the Day
BelosTFQMRSolMgr.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_TFQMR_SOLMGR_HPP
00043 #define BELOS_TFQMR_SOLMGR_HPP
00044 
00049 #include "BelosConfigDefs.hpp"
00050 #include "BelosTypes.hpp"
00051 
00052 #include "BelosLinearProblem.hpp"
00053 #include "BelosSolverManager.hpp"
00054 
00055 #include "BelosTFQMRIter.hpp"
00056 #include "BelosStatusTestMaxIters.hpp"
00057 #include "BelosStatusTestGenResNorm.hpp"
00058 #include "BelosStatusTestCombo.hpp"
00059 #include "BelosStatusTestOutputFactory.hpp"
00060 #include "BelosOutputManager.hpp"
00061 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00062 #include "Teuchos_TimeMonitor.hpp"
00063 #endif
00064 
00078 namespace Belos {
00079   
00081 
00082   
00089   class TFQMRSolMgrLinearProblemFailure : public BelosError {public:
00090     TFQMRSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
00091     {}};
00092   
00099   class TFQMRSolMgrOrthoFailure : public BelosError {public:
00100     TFQMRSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg)
00101     {}};
00102   
00103   template<class ScalarType, class MV, class OP>
00104   class TFQMRSolMgr : public SolverManager<ScalarType,MV,OP> {
00105     
00106   private:
00107     typedef MultiVecTraits<ScalarType,MV> MVT;
00108     typedef OperatorTraits<ScalarType,MV,OP> OPT;
00109     typedef Teuchos::ScalarTraits<ScalarType> SCT;
00110     typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00111     typedef Teuchos::ScalarTraits<MagnitudeType> MT;
00112     
00113   public:
00114     
00116 
00117 
00123      TFQMRSolMgr();
00124 
00141     TFQMRSolMgr( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00142      const Teuchos::RCP<Teuchos::ParameterList> &pl );
00143     
00145     virtual ~TFQMRSolMgr() {};
00147     
00149 
00150     
00151     const LinearProblem<ScalarType,MV,OP>& getProblem() const {
00152       return *problem_;
00153     }
00154 
00157     Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
00158     
00161     Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const { return params_; }
00162     
00168     Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
00169       return Teuchos::tuple(timerSolve_);
00170     }
00171 
00177     MagnitudeType achievedTol() const {
00178       return achievedTol_;
00179     }
00180 
00182     int getNumIters() const {
00183       return numIters_;
00184     }
00185     
00193     bool isLOADetected() const { return false; }
00194     
00196     
00198 
00199     
00201     void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) { problem_ = problem; }
00202     
00204     void setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params );
00205     
00207     
00209 
00210 
00214     void reset( const ResetType type ) { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
00216     
00218 
00219     
00237     ReturnType solve();
00238     
00240     
00243     
00245     std::string description() const;
00246     
00248     
00249   private:
00250 
00251     // Method for checking current status test against defined linear problem.
00252     bool checkStatusTest();
00253     
00254     // Linear problem.
00255     Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
00256     
00257     // Output manager.
00258     Teuchos::RCP<OutputManager<ScalarType> > printer_;
00259     Teuchos::RCP<std::ostream> outputStream_;
00260     
00261     // Status test.
00262     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
00263     Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
00264     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
00265     Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > expConvTest_, impConvTest_;
00266     Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
00267     
00268     // Current parameter list.
00269     Teuchos::RCP<Teuchos::ParameterList> params_;
00270     
00271     // Default solver values.
00272     static const MagnitudeType convtol_default_;
00273     static const int maxIters_default_;
00274     static const bool expResTest_default_;
00275     static const int verbosity_default_;
00276     static const int outputStyle_default_;
00277     static const int outputFreq_default_;
00278     static const std::string impResScale_default_; 
00279     static const std::string expResScale_default_; 
00280     static const std::string label_default_;
00281     static const Teuchos::RCP<std::ostream> outputStream_default_;
00282 
00283     // Current solver values.
00284     MagnitudeType convtol_, achievedTol_;
00285     int maxIters_, numIters_;
00286     int verbosity_, outputStyle_, outputFreq_;
00287     int blockSize_;
00288     bool expResTest_;
00289     std::string impResScale_, expResScale_;
00290     
00291     // Timers.
00292     std::string label_;
00293     Teuchos::RCP<Teuchos::Time> timerSolve_;
00294 
00295     // Internal state variables.
00296     bool isSet_, isSTSet_;
00297   };
00298 
00299 
00300 // Default solver values.
00301 template<class ScalarType, class MV, class OP>
00302 const typename TFQMRSolMgr<ScalarType,MV,OP>::MagnitudeType TFQMRSolMgr<ScalarType,MV,OP>::convtol_default_ = 1e-8;
00303 
00304 template<class ScalarType, class MV, class OP>
00305 const int TFQMRSolMgr<ScalarType,MV,OP>::maxIters_default_ = 1000;
00306 
00307 template<class ScalarType, class MV, class OP>
00308 const bool TFQMRSolMgr<ScalarType,MV,OP>::expResTest_default_ = false;
00309 
00310 template<class ScalarType, class MV, class OP>
00311 const int TFQMRSolMgr<ScalarType,MV,OP>::verbosity_default_ = Belos::Errors;
00312 
00313 template<class ScalarType, class MV, class OP>
00314 const int TFQMRSolMgr<ScalarType,MV,OP>::outputStyle_default_ = Belos::General;
00315 
00316 template<class ScalarType, class MV, class OP>
00317 const int TFQMRSolMgr<ScalarType,MV,OP>::outputFreq_default_ = -1;
00318 
00319 template<class ScalarType, class MV, class OP>
00320 const std::string TFQMRSolMgr<ScalarType,MV,OP>::impResScale_default_ = "Norm of Preconditioned Initial Residual";
00321 
00322 template<class ScalarType, class MV, class OP>
00323 const std::string TFQMRSolMgr<ScalarType,MV,OP>::expResScale_default_ = "Norm of Initial Residual";
00324 
00325 template<class ScalarType, class MV, class OP>
00326 const std::string TFQMRSolMgr<ScalarType,MV,OP>::label_default_ = "Belos";
00327 
00328 template<class ScalarType, class MV, class OP>
00329 const Teuchos::RCP<std::ostream> TFQMRSolMgr<ScalarType,MV,OP>::outputStream_default_ = Teuchos::rcp(&std::cout,false);
00330 
00331 
00332 // Empty Constructor
00333 template<class ScalarType, class MV, class OP>
00334 TFQMRSolMgr<ScalarType,MV,OP>::TFQMRSolMgr() :
00335   outputStream_(outputStream_default_),
00336   convtol_(convtol_default_),
00337   achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
00338   maxIters_(maxIters_default_),
00339   numIters_(0),
00340   verbosity_(verbosity_default_),
00341   outputStyle_(outputStyle_default_),
00342   outputFreq_(outputFreq_default_),
00343   blockSize_(1),
00344   expResTest_(expResTest_default_),
00345   impResScale_(impResScale_default_),
00346   expResScale_(expResScale_default_),
00347   label_(label_default_),
00348   isSet_(false),
00349   isSTSet_(false)
00350 {}
00351 
00352 
00353 // Basic Constructor
00354 template<class ScalarType, class MV, class OP>
00355 TFQMRSolMgr<ScalarType,MV,OP>::TFQMRSolMgr( 
00356                const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00357                const Teuchos::RCP<Teuchos::ParameterList> &pl ) : 
00358   problem_(problem),
00359   outputStream_(outputStream_default_),
00360   convtol_(convtol_default_),
00361   achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()),
00362   maxIters_(maxIters_default_),
00363   numIters_(0),
00364   verbosity_(verbosity_default_),
00365   outputStyle_(outputStyle_default_),
00366   outputFreq_(outputFreq_default_),
00367   blockSize_(1),
00368   expResTest_(expResTest_default_),
00369   impResScale_(impResScale_default_),
00370   expResScale_(expResScale_default_),
00371   label_(label_default_),
00372   isSet_(false),
00373   isSTSet_(false)
00374 {
00375   TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
00376   
00377   // If the parameter list pointer is null, then set the current parameters to the default parameter list.
00378   if ( !is_null(pl) ) {
00379     setParameters( pl );  
00380   }
00381 }
00382   
00383 template<class ScalarType, class MV, class OP>
00384 void TFQMRSolMgr<ScalarType,MV,OP>::setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params )
00385 {
00386   // Create the internal parameter list if ones doesn't already exist.
00387   if (params_ == Teuchos::null) {
00388     params_ = Teuchos::rcp( new Teuchos::ParameterList(*getValidParameters()) );
00389   }
00390   else {
00391     params->validateParameters(*getValidParameters());
00392   }
00393 
00394   // Check for maximum number of iterations
00395   if (params->isParameter("Maximum Iterations")) {
00396     maxIters_ = params->get("Maximum Iterations",maxIters_default_);
00397 
00398     // Update parameter in our list and in status test.
00399     params_->set("Maximum Iterations", maxIters_);
00400     if (maxIterTest_!=Teuchos::null)
00401       maxIterTest_->setMaxIters( maxIters_ );
00402   }
00403 
00404   // Check for blocksize
00405   if (params->isParameter("Block Size")) {
00406     blockSize_ = params->get("Block Size",1);    
00407     TEUCHOS_TEST_FOR_EXCEPTION(blockSize_ != 1, std::invalid_argument,
00408            "Belos::TFQMRSolMgr: \"Block Size\" must be 1.");
00409 
00410     // Update parameter in our list.
00411     params_->set("Block Size", blockSize_);
00412   }
00413 
00414   // Check to see if the timer label changed.
00415   if (params->isParameter("Timer Label")) {
00416     std::string tempLabel = params->get("Timer Label", label_default_);
00417 
00418     // Update parameter in our list and solver timer
00419     if (tempLabel != label_) {
00420       label_ = tempLabel;
00421       params_->set("Timer Label", label_);
00422       std::string solveLabel = label_ + ": TFQMRSolMgr total solve time";
00423 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00424       timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00425 #endif
00426     }
00427   }
00428 
00429   // Check for a change in verbosity level
00430   if (params->isParameter("Verbosity")) {
00431     if (Teuchos::isParameterType<int>(*params,"Verbosity")) {
00432       verbosity_ = params->get("Verbosity", verbosity_default_);
00433     } else {
00434       verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,"Verbosity");
00435     }
00436 
00437     // Update parameter in our list.
00438     params_->set("Verbosity", verbosity_);
00439     if (printer_ != Teuchos::null)
00440       printer_->setVerbosity(verbosity_);
00441   }
00442 
00443   // Check for a change in output style
00444   if (params->isParameter("Output Style")) {
00445     if (Teuchos::isParameterType<int>(*params,"Output Style")) {
00446       outputStyle_ = params->get("Output Style", outputStyle_default_);
00447     } else {
00448       outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,"Output Style");
00449     }
00450 
00451     // Reconstruct the convergence test if the explicit residual test is not being used.
00452     params_->set("Output Style", outputStyle_);
00453     isSTSet_ = false;
00454   }
00455 
00456   // output stream
00457   if (params->isParameter("Output Stream")) {
00458     outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,"Output Stream");
00459 
00460     // Update parameter in our list.
00461     params_->set("Output Stream", outputStream_);
00462     if (printer_ != Teuchos::null)
00463       printer_->setOStream( outputStream_ );
00464   }
00465 
00466   // frequency level
00467   if (verbosity_ & Belos::StatusTestDetails) {
00468     if (params->isParameter("Output Frequency")) {
00469       outputFreq_ = params->get("Output Frequency", outputFreq_default_);
00470     }
00471 
00472     // Update parameter in out list and output status test.
00473     params_->set("Output Frequency", outputFreq_);
00474     if (outputTest_ != Teuchos::null)
00475       outputTest_->setOutputFrequency( outputFreq_ );
00476   }
00477 
00478   // Create output manager if we need to.
00479   if (printer_ == Teuchos::null) {
00480     printer_ = Teuchos::rcp( new OutputManager<ScalarType>(verbosity_, outputStream_) );
00481   }  
00482   
00483   // Check for convergence tolerance
00484   if (params->isParameter("Convergence Tolerance")) {
00485     convtol_ = params->get("Convergence Tolerance",convtol_default_);
00486 
00487     // Update parameter in our list and residual tests.
00488     params_->set("Convergence Tolerance", convtol_);
00489     if (impConvTest_ != Teuchos::null)
00490       impConvTest_->setTolerance( convtol_ );
00491     if (expConvTest_ != Teuchos::null)
00492       expConvTest_->setTolerance( convtol_ );
00493   }
00494   
00495   // Check for a change in scaling, if so we need to build new residual tests.
00496   if (params->isParameter("Implicit Residual Scaling")) {
00497     std::string tempImpResScale = Teuchos::getParameter<std::string>( *params, "Implicit Residual Scaling" );
00498 
00499     // Only update the scaling if it's different.
00500     if (impResScale_ != tempImpResScale) {
00501       Belos::ScaleType impResScaleType = convertStringToScaleType( tempImpResScale );
00502       impResScale_ = tempImpResScale;
00503 
00504       // Update parameter in our list and residual tests
00505       params_->set("Implicit Residual Scaling", impResScale_);
00506       if (impConvTest_ != Teuchos::null) {
00507         try { 
00508           impConvTest_->defineScaleForm( impResScaleType, Belos::TwoNorm );
00509         }
00510         catch (std::exception& e) { 
00511           // Make sure the convergence test gets constructed again.
00512           isSTSet_ = false;
00513         }
00514       }
00515     }      
00516   }
00517   
00518   if (params->isParameter("Explicit Residual Scaling")) {
00519     std::string tempExpResScale = Teuchos::getParameter<std::string>( *params, "Explicit Residual Scaling" );
00520 
00521     // Only update the scaling if it's different.
00522     if (expResScale_ != tempExpResScale) {
00523       Belos::ScaleType expResScaleType = convertStringToScaleType( tempExpResScale );
00524       expResScale_ = tempExpResScale;
00525 
00526       // Update parameter in our list and residual tests
00527       params_->set("Explicit Residual Scaling", expResScale_);
00528       if (expConvTest_ != Teuchos::null) {
00529         try { 
00530           expConvTest_->defineScaleForm( expResScaleType, Belos::TwoNorm );
00531         }
00532         catch (std::exception& e) {
00533           // Make sure the convergence test gets constructed again.
00534           isSTSet_ = false;
00535         }
00536       }
00537     }      
00538   }
00539 
00540   if (params->isParameter("Explicit Residual Test")) {
00541     expResTest_ = Teuchos::getParameter<bool>( *params,"Explicit Residual Test" );
00542 
00543     // Reconstruct the convergence test if the explicit residual test is not being used.
00544     params_->set("Explicit Residual Test", expResTest_);
00545     if (expConvTest_ == Teuchos::null) {
00546       isSTSet_ = false;
00547     }
00548   }
00549 
00550   // Create the timer if we need to.
00551   if (timerSolve_ == Teuchos::null) {
00552     std::string solveLabel = label_ + ": TFQMRSolMgr total solve time";
00553 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00554     timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00555 #endif
00556   }
00557 
00558   // Inform the solver manager that the current parameters were set.
00559   isSet_ = true;
00560 }
00561 
00562 
00563 // Check the status test versus the defined linear problem
00564 template<class ScalarType, class MV, class OP>
00565 bool TFQMRSolMgr<ScalarType,MV,OP>::checkStatusTest() {
00566 
00567   typedef Belos::StatusTestCombo<ScalarType,MV,OP>  StatusTestCombo_t;
00568   typedef Belos::StatusTestGenResNorm<ScalarType,MV,OP>  StatusTestGenResNorm_t;
00569 
00570   // Basic test checks maximum iterations and native residual.
00571   maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>( maxIters_ ) );
00572 
00573   if (expResTest_) {
00574    
00575     // Implicit residual test, using the native residual to determine if convergence was achieved.
00576     Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
00577       Teuchos::rcp( new StatusTestGenResNorm_t( convtol_ ) );
00578     tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm );
00579     impConvTest_ = tmpImpConvTest;
00580 
00581     // Explicit residual test once the native residual is below the tolerance
00582     Teuchos::RCP<StatusTestGenResNorm_t> tmpExpConvTest =
00583       Teuchos::rcp( new StatusTestGenResNorm_t( convtol_ ) );
00584     tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit, Belos::TwoNorm );
00585     tmpExpConvTest->defineScaleForm( convertStringToScaleType(expResScale_), Belos::TwoNorm );
00586     expConvTest_ = tmpExpConvTest;
00587 
00588     // The convergence test is a combination of the "cheap" implicit test and explicit test.
00589     convTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) );
00590   }
00591   else {
00592 
00593     // Implicit residual test, using the native residual to determine if convergence was achieved.
00594     Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
00595       Teuchos::rcp( new StatusTestGenResNorm_t( convtol_ ) );
00596     tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm );
00597     impConvTest_ = tmpImpConvTest;
00598 
00599     // Set the explicit and total convergence test to this implicit test that checks for accuracy loss.
00600     expConvTest_ = impConvTest_;
00601     convTest_ = impConvTest_;
00602   }
00603   sTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
00604 
00605   // Create the status test output class.
00606   // This class manages and formats the output from the status test.
00607   StatusTestOutputFactory<ScalarType,MV,OP> stoFactory( outputStyle_ );
00608   outputTest_ = stoFactory.create( printer_, sTest_, outputFreq_, Passed+Failed+Undefined );
00609 
00610   // Set the solver string for the output test
00611   std::string solverDesc = " TFQMR ";
00612   outputTest_->setSolverDesc( solverDesc );
00613 
00614   
00615   // The status test is now set.
00616   isSTSet_ = true;
00617 
00618   return false;
00619 }
00620 
00621     
00622 template<class ScalarType, class MV, class OP>
00623 Teuchos::RCP<const Teuchos::ParameterList> 
00624 TFQMRSolMgr<ScalarType,MV,OP>::getValidParameters() const
00625 {
00626   static Teuchos::RCP<const Teuchos::ParameterList> validPL;
00627   
00628   // Set all the valid parameters and their default values.
00629   if(is_null(validPL)) {
00630     Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
00631     pl->set("Convergence Tolerance", convtol_default_,
00632       "The relative residual tolerance that needs to be achieved by the\n"
00633       "iterative solver in order for the linear system to be declared converged.");
00634     pl->set("Maximum Iterations", maxIters_default_,
00635       "The maximum number of block iterations allowed for each\n"
00636       "set of RHS solved.");
00637     pl->set("Verbosity", verbosity_default_,
00638       "What type(s) of solver information should be outputted\n"
00639       "to the output stream.");
00640     pl->set("Output Style", outputStyle_default_,
00641       "What style is used for the solver information outputted\n"
00642       "to the output stream.");
00643     pl->set("Output Frequency", outputFreq_default_,
00644       "How often convergence information should be outputted\n"
00645       "to the output stream.");  
00646     pl->set("Output Stream", outputStream_default_,
00647       "A reference-counted pointer to the output stream where all\n"
00648       "solver output is sent.");
00649     pl->set("Explicit Residual Test", expResTest_default_,
00650       "Whether the explicitly computed residual should be used in the convergence test.");
00651     pl->set("Implicit Residual Scaling", impResScale_default_,
00652       "The type of scaling used in the implicit residual convergence test.");
00653     pl->set("Explicit Residual Scaling", expResScale_default_,
00654       "The type of scaling used in the explicit residual convergence test.");
00655     pl->set("Timer Label", label_default_,
00656       "The string to use as a prefix for the timer labels.");
00657     //  pl->set("Restart Timers", restartTimers_);
00658     validPL = pl;
00659   }
00660   return validPL;
00661 }
00662 
00663   
00664 // solve()
00665 template<class ScalarType, class MV, class OP>
00666 ReturnType TFQMRSolMgr<ScalarType,MV,OP>::solve() {
00667 
00668   // Set the current parameters if they were not set before.
00669   // NOTE:  This may occur if the user generated the solver manager with the default constructor and 
00670   // then didn't set any parameters using setParameters().
00671   if (!isSet_) {
00672     setParameters(Teuchos::parameterList(*getValidParameters()));
00673   }
00674 
00675   TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,TFQMRSolMgrLinearProblemFailure,
00676          "Belos::TFQMRSolMgr::solve(): Linear problem is not a valid object.");
00677 
00678   TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(),TFQMRSolMgrLinearProblemFailure,
00679                      "Belos::TFQMRSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
00680 
00681   if (!isSTSet_) {
00682     TEUCHOS_TEST_FOR_EXCEPTION( checkStatusTest(),TFQMRSolMgrLinearProblemFailure,
00683       "Belos::TFQMRSolMgr::solve(): Linear problem and requested status tests are incompatible.");
00684   }
00685 
00686   // Create indices for the linear systems to be solved.
00687   int startPtr = 0;
00688   int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
00689   int numCurrRHS = blockSize_;
00690 
00691   std::vector<int> currIdx, currIdx2;
00692 
00693   //  The index set is generated that informs the linear problem that some linear systems are augmented.
00694   currIdx.resize( blockSize_ );
00695   currIdx2.resize( blockSize_ );
00696   for (int i=0; i<numCurrRHS; ++i) 
00697     { currIdx[i] = startPtr+i; currIdx2[i]=i; }
00698 
00699   // Inform the linear problem of the current linear system to solve.
00700   problem_->setLSIndex( currIdx );
00701 
00703   // Parameter list
00704   Teuchos::ParameterList plist;
00705   plist.set("Block Size",blockSize_);
00706   
00707   // Reset the status test.  
00708   outputTest_->reset();
00709 
00710   // Assume convergence is achieved, then let any failed convergence set this to false.
00711   bool isConverged = true;  
00712 
00714   // TFQMR solver
00715 
00716   Teuchos::RCP<TFQMRIter<ScalarType,MV,OP> > tfqmr_iter = 
00717     Teuchos::rcp( new TFQMRIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,plist) );
00718 
00719   // Enter solve() iterations
00720   {
00721 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00722     Teuchos::TimeMonitor slvtimer(*timerSolve_);
00723 #endif
00724 
00725     while ( numRHS2Solve > 0 ) {
00726       //
00727       // Reset the active / converged vectors from this block
00728       std::vector<int> convRHSIdx;
00729       std::vector<int> currRHSIdx( currIdx );
00730       currRHSIdx.resize(numCurrRHS);
00731 
00732       // Reset the number of iterations.
00733       tfqmr_iter->resetNumIters();
00734 
00735       // Reset the number of calls that the status test output knows about.
00736       outputTest_->resetNumCalls();
00737 
00738       // Get the current residual for this block of linear systems.
00739       Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitPrecResVec())), currIdx );
00740 
00741       // Set the new state and initialize the solver.
00742       TFQMRIterState<ScalarType,MV> newstate;
00743       newstate.R = R_0;
00744       tfqmr_iter->initializeTFQMR(newstate);
00745 
00746       while(1) {
00747   
00748   // tell tfqmr_iter to iterate
00749   try {
00750     tfqmr_iter->iterate();
00751     
00753     //
00754     // check convergence first
00755     //
00757     if ( convTest_->getStatus() == Passed ) {
00758       // We have convergence of the linear system.
00759       break;  // break from while(1){tfqmr_iter->iterate()}
00760     }
00762     //
00763     // check for maximum iterations
00764     //
00766     else if ( maxIterTest_->getStatus() == Passed ) {
00767       // we don't have convergence
00768       isConverged = false;
00769       break;  // break from while(1){tfqmr_iter->iterate()}
00770     }
00771 
00773     //
00774     // we returned from iterate(), but none of our status tests Passed.
00775     // something is wrong, and it is probably our fault.
00776     //
00778 
00779     else {
00780       TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
00781              "Belos::TFQMRSolMgr::solve(): Invalid return from TFQMRIter::iterate().");
00782     }
00783   }
00784   catch (const std::exception &e) {
00785     printer_->stream(Errors) << "Error! Caught std::exception in TFQMRIter::iterate() at iteration " 
00786            << tfqmr_iter->getNumIters() << std::endl 
00787            << e.what() << std::endl;
00788     throw;
00789   }
00790       }
00791       
00792       // Inform the linear problem that we are finished with this block linear system.
00793       problem_->setCurrLS();
00794       
00795       // Update indices for the linear systems to be solved.
00796       startPtr += numCurrRHS;
00797       numRHS2Solve -= numCurrRHS;
00798       if ( numRHS2Solve > 0 ) {
00799   numCurrRHS = blockSize_;
00800 
00801   currIdx.resize( blockSize_ );
00802   currIdx2.resize( blockSize_ );
00803   for (int i=0; i<numCurrRHS; ++i) 
00804     { currIdx[i] = startPtr+i; currIdx2[i] = i; }
00805   // Set the next indices.
00806   problem_->setLSIndex( currIdx );
00807 
00808   // Set the new blocksize for the solver.
00809   tfqmr_iter->setBlockSize( blockSize_ ); 
00810       }
00811       else {
00812         currIdx.resize( numRHS2Solve );
00813       }
00814       
00815     }// while ( numRHS2Solve > 0 )
00816     
00817   }
00818 
00819   // print final summary
00820   sTest_->print( printer_->stream(FinalSummary) );
00821  
00822   // print timing information
00823 #ifdef BELOS_TEUCHOS_TIME_MONITOR
00824   // Calling summarize() can be expensive, so don't call unless the
00825   // user wants to print out timing details.  summarize() will do all
00826   // the work even if it's passed a "black hole" output stream.
00827   if (verbosity_ & TimingDetails)
00828     Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
00829 #endif
00830  
00831   // get iteration information for this solve
00832   numIters_ = maxIterTest_->getNumIters();
00833 
00834   // Save the convergence test value ("achieved tolerance") for this
00835   // solve.  For this solver, convTest_ may either be a single
00836   // (implicit) residual norm test, or a combination of two residual
00837   // norm tests.  In the latter case, the master convergence test
00838   // convTest_ is a SEQ combo of the implicit resp. explicit tests.
00839   // If the implicit test never passes, then the explicit test won't
00840   // ever be executed.  This manifests as
00841   // expConvTest_->getTestValue()->size() < 1.  We deal with this case
00842   // by using the values returned by impConvTest_->getTestValue().
00843   {
00844     // We'll fetch the vector of residual norms one way or the other.
00845     const std::vector<MagnitudeType>* pTestValues = NULL;
00846     if (expResTest_) {
00847       pTestValues = expConvTest_->getTestValue();
00848       if (pTestValues == NULL || pTestValues->size() < 1) {
00849   pTestValues = impConvTest_->getTestValue();
00850       }
00851     } 
00852     else {
00853       // Only the implicit residual norm test is being used.
00854       pTestValues = impConvTest_->getTestValue();
00855     }
00856     TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
00857       "Belos::TFQMRSolMgr::solve(): The implicit convergence test's "
00858       "getTestValue() method returned NULL.  Please report this bug to the "
00859       "Belos developers.");
00860     TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
00861       "Belos::TMQMRSolMgr::solve(): The implicit convergence test's "
00862       "getTestValue() method returned a vector of length zero.  Please report "
00863       "this bug to the Belos developers.");
00864 
00865     // FIXME (mfh 12 Dec 2011) Does pTestValues really contain the
00866     // achieved tolerances for all vectors in the current solve(), or
00867     // just for the vectors from the last deflation?
00868     achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());
00869   }
00870  
00871   if (!isConverged) {
00872     return Unconverged; // return from TFQMRSolMgr::solve() 
00873   }
00874   return Converged; // return from TFQMRSolMgr::solve() 
00875 }
00876 
00877 //  This method requires the solver manager to return a std::string that describes itself.
00878 template<class ScalarType, class MV, class OP>
00879 std::string TFQMRSolMgr<ScalarType,MV,OP>::description() const
00880 {
00881   std::ostringstream oss;
00882   oss << "Belos::TFQMRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<">";
00883   oss << "{}";
00884   return oss.str();
00885 }
00886   
00887 } // end Belos namespace
00888 
00889 #endif /* BELOS_TFQMR_SOLMGR_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines