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