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 terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #ifndef BELOS_TFQMR_SOLMGR_HPP
00030 #define BELOS_TFQMR_SOLMGR_HPP
00031 
00036 #include "BelosConfigDefs.hpp"
00037 #include "BelosTypes.hpp"
00038 
00039 #include "BelosLinearProblem.hpp"
00040 #include "BelosSolverManager.hpp"
00041 
00042 #include "BelosTFQMRIter.hpp"
00043 #include "BelosStatusTestMaxIters.hpp"
00044 #include "BelosStatusTestGenResNorm.hpp"
00045 #include "BelosStatusTestCombo.hpp"
00046 #include "BelosStatusTestOutputFactory.hpp"
00047 #include "BelosOutputManager.hpp"
00048 #include "Teuchos_BLAS.hpp"
00049 #include "Teuchos_LAPACK.hpp"
00050 #include "Teuchos_TimeMonitor.hpp"
00051 
00065 namespace Belos {
00066   
00068 
00069   
00076   class TFQMRSolMgrLinearProblemFailure : public BelosError {public:
00077     TFQMRSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
00078     {}};
00079   
00086   class TFQMRSolMgrOrthoFailure : public BelosError {public:
00087     TFQMRSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg)
00088     {}};
00089   
00090   template<class ScalarType, class MV, class OP>
00091   class TFQMRSolMgr : public SolverManager<ScalarType,MV,OP> {
00092     
00093   private:
00094     typedef MultiVecTraits<ScalarType,MV> MVT;
00095     typedef OperatorTraits<ScalarType,MV,OP> OPT;
00096     typedef Teuchos::ScalarTraits<ScalarType> SCT;
00097     typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00098     typedef Teuchos::ScalarTraits<MagnitudeType> MT;
00099     
00100   public:
00101     
00103 
00104 
00110      TFQMRSolMgr();
00111 
00128     TFQMRSolMgr( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00129      const Teuchos::RCP<Teuchos::ParameterList> &pl );
00130     
00132     virtual ~TFQMRSolMgr() {};
00134     
00136 
00137     
00138     const LinearProblem<ScalarType,MV,OP>& getProblem() const {
00139       return *problem_;
00140     }
00141 
00144     Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
00145     
00148     Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const { return params_; }
00149     
00155     Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
00156       return tuple(timerSolve_);
00157     }
00158     
00160     int getNumIters() const {
00161       return numIters_;
00162     }
00163     
00166     bool isLOADetected() const { return false; }
00167     
00169     
00171 
00172     
00174     void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) { problem_ = problem; }
00175     
00177     void setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params );
00178     
00180     
00182 
00183 
00187     void reset( const ResetType type ) { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
00189     
00191 
00192     
00210     ReturnType solve();
00211     
00213     
00216     
00218     std::string description() const;
00219     
00221     
00222   private:
00223 
00224     // Method to convert std::string to enumerated type for residual.
00225     Belos::ScaleType convertStringToScaleType( std::string& scaleType ) {
00226       if (scaleType == "Norm of Initial Residual") {
00227   return Belos::NormOfInitRes;
00228       } else if (scaleType == "Norm of Preconditioned Initial Residual") {
00229   return Belos::NormOfPrecInitRes;
00230       } else if (scaleType == "Norm of RHS") {
00231   return Belos::NormOfRHS;
00232       } else if (scaleType == "None") {
00233   return Belos::None;
00234       } else 
00235   TEST_FOR_EXCEPTION( true ,std::logic_error,
00236           "Belos::TFQMRSolMgr(): Invalid residual scaling type.");
00237     }
00238 
00239     // Method for checking current status test against defined linear problem.
00240     bool checkStatusTest();
00241     
00242     // Linear problem.
00243     Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
00244     
00245     // Output manager.
00246     Teuchos::RCP<OutputManager<ScalarType> > printer_;
00247     Teuchos::RCP<std::ostream> outputStream_;
00248     
00249     // Status test.
00250     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
00251     Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
00252     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_;
00253     Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > expConvTest_, impConvTest_;
00254     Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
00255     
00256     // Current parameter list.
00257     Teuchos::RCP<ParameterList> params_;
00258     
00259     // Default solver values.
00260     static const MagnitudeType convtol_default_;
00261     static const int maxIters_default_;
00262     static const bool expResTest_default_;
00263     static const int verbosity_default_;
00264     static const int outputStyle_default_;
00265     static const int outputFreq_default_;
00266     static const std::string impResScale_default_; 
00267     static const std::string expResScale_default_; 
00268     static const std::string label_default_;
00269     static const Teuchos::RCP<std::ostream> outputStream_default_;
00270 
00271     // Current solver values.
00272     MagnitudeType convtol_;
00273     int maxIters_, numIters_;
00274     int verbosity_, outputStyle_, outputFreq_;
00275     int blockSize_;
00276     bool expResTest_;
00277     std::string impResScale_, expResScale_;
00278     
00279     // Timers.
00280     std::string label_;
00281     Teuchos::RCP<Teuchos::Time> timerSolve_;
00282 
00283     // Internal state variables.
00284     bool isSet_, isSTSet_;
00285   };
00286 
00287 
00288 // Default solver values.
00289 template<class ScalarType, class MV, class OP>
00290 const typename TFQMRSolMgr<ScalarType,MV,OP>::MagnitudeType TFQMRSolMgr<ScalarType,MV,OP>::convtol_default_ = 1e-8;
00291 
00292 template<class ScalarType, class MV, class OP>
00293 const int TFQMRSolMgr<ScalarType,MV,OP>::maxIters_default_ = 1000;
00294 
00295 template<class ScalarType, class MV, class OP>
00296 const bool TFQMRSolMgr<ScalarType,MV,OP>::expResTest_default_ = false;
00297 
00298 template<class ScalarType, class MV, class OP>
00299 const int TFQMRSolMgr<ScalarType,MV,OP>::verbosity_default_ = Belos::Errors;
00300 
00301 template<class ScalarType, class MV, class OP>
00302 const int TFQMRSolMgr<ScalarType,MV,OP>::outputStyle_default_ = Belos::General;
00303 
00304 template<class ScalarType, class MV, class OP>
00305 const int TFQMRSolMgr<ScalarType,MV,OP>::outputFreq_default_ = -1;
00306 
00307 template<class ScalarType, class MV, class OP>
00308 const std::string TFQMRSolMgr<ScalarType,MV,OP>::impResScale_default_ = "Norm of Preconditioned Initial Residual";
00309 
00310 template<class ScalarType, class MV, class OP>
00311 const std::string TFQMRSolMgr<ScalarType,MV,OP>::expResScale_default_ = "Norm of Initial Residual";
00312 
00313 template<class ScalarType, class MV, class OP>
00314 const std::string TFQMRSolMgr<ScalarType,MV,OP>::label_default_ = "Belos";
00315 
00316 template<class ScalarType, class MV, class OP>
00317 const Teuchos::RCP<std::ostream> TFQMRSolMgr<ScalarType,MV,OP>::outputStream_default_ = Teuchos::rcp(&std::cout,false);
00318 
00319 
00320 // Empty Constructor
00321 template<class ScalarType, class MV, class OP>
00322 TFQMRSolMgr<ScalarType,MV,OP>::TFQMRSolMgr() :
00323   outputStream_(outputStream_default_),
00324   convtol_(convtol_default_),
00325   maxIters_(maxIters_default_),
00326   verbosity_(verbosity_default_),
00327   outputStyle_(outputStyle_default_),
00328   outputFreq_(outputFreq_default_),
00329   blockSize_(1),
00330   expResTest_(expResTest_default_),
00331   impResScale_(impResScale_default_),
00332   expResScale_(expResScale_default_),
00333   label_(label_default_),
00334   isSet_(false),
00335   isSTSet_(false)
00336 {}
00337 
00338 
00339 // Basic Constructor
00340 template<class ScalarType, class MV, class OP>
00341 TFQMRSolMgr<ScalarType,MV,OP>::TFQMRSolMgr( 
00342                const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00343                const Teuchos::RCP<Teuchos::ParameterList> &pl ) : 
00344   problem_(problem),
00345   outputStream_(outputStream_default_),
00346   convtol_(convtol_default_),
00347   maxIters_(maxIters_default_),
00348   verbosity_(verbosity_default_),
00349   outputStyle_(outputStyle_default_),
00350   outputFreq_(outputFreq_default_),
00351   blockSize_(1),
00352   expResTest_(expResTest_default_),
00353   impResScale_(impResScale_default_),
00354   expResScale_(expResScale_default_),
00355   label_(label_default_),
00356   isSet_(false),
00357   isSTSet_(false)
00358 {
00359   TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
00360   
00361   // If the parameter list pointer is null, then set the current parameters to the default parameter list.
00362   if ( !is_null(pl) ) {
00363     setParameters( pl );  
00364   }
00365 }
00366   
00367 template<class ScalarType, class MV, class OP>
00368 void TFQMRSolMgr<ScalarType,MV,OP>::setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params )
00369 {
00370   // Create the internal parameter list if ones doesn't already exist.
00371   if (params_ == Teuchos::null) {
00372     params_ = Teuchos::rcp( new Teuchos::ParameterList(*getValidParameters()) );
00373   }
00374   else {
00375     params->validateParameters(*getValidParameters());
00376   }
00377 
00378   // Check for maximum number of iterations
00379   if (params->isParameter("Maximum Iterations")) {
00380     maxIters_ = params->get("Maximum Iterations",maxIters_default_);
00381 
00382     // Update parameter in our list and in status test.
00383     params_->set("Maximum Iterations", maxIters_);
00384     if (maxIterTest_!=Teuchos::null)
00385       maxIterTest_->setMaxIters( maxIters_ );
00386   }
00387 
00388   // Check for blocksize
00389   if (params->isParameter("Block Size")) {
00390     blockSize_ = params->get("Block Size",1);    
00391     TEST_FOR_EXCEPTION(blockSize_ != 1, std::invalid_argument,
00392            "Belos::TFQMRSolMgr: \"Block Size\" must be 1.");
00393 
00394     // Update parameter in our list.
00395     params_->set("Block Size", blockSize_);
00396   }
00397 
00398   // Check to see if the timer label changed.
00399   if (params->isParameter("Timer Label")) {
00400     std::string tempLabel = params->get("Timer Label", label_default_);
00401 
00402     // Update parameter in our list and solver timer
00403     if (tempLabel != label_) {
00404       label_ = tempLabel;
00405       params_->set("Timer Label", label_);
00406       std::string solveLabel = label_ + ": TFQMRSolMgr total solve time";
00407       timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00408     }
00409   }
00410 
00411   // Check for a change in verbosity level
00412   if (params->isParameter("Verbosity")) {
00413     if (Teuchos::isParameterType<int>(*params,"Verbosity")) {
00414       verbosity_ = params->get("Verbosity", verbosity_default_);
00415     } else {
00416       verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,"Verbosity");
00417     }
00418 
00419     // Update parameter in our list.
00420     params_->set("Verbosity", verbosity_);
00421     if (printer_ != Teuchos::null)
00422       printer_->setVerbosity(verbosity_);
00423   }
00424 
00425   // Check for a change in output style
00426   if (params->isParameter("Output Style")) {
00427     if (Teuchos::isParameterType<int>(*params,"Output Style")) {
00428       outputStyle_ = params->get("Output Style", outputStyle_default_);
00429     } else {
00430       outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,"Output Style");
00431     }
00432 
00433     // Reconstruct the convergence test if the explicit residual test is not being used.
00434     params_->set("Output Style", outputStyle_);
00435     isSTSet_ = false;
00436   }
00437 
00438   // output stream
00439   if (params->isParameter("Output Stream")) {
00440     outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,"Output Stream");
00441 
00442     // Update parameter in our list.
00443     params_->set("Output Stream", outputStream_);
00444     if (printer_ != Teuchos::null)
00445       printer_->setOStream( outputStream_ );
00446   }
00447 
00448   // frequency level
00449   if (verbosity_ & Belos::StatusTestDetails) {
00450     if (params->isParameter("Output Frequency")) {
00451       outputFreq_ = params->get("Output Frequency", outputFreq_default_);
00452     }
00453 
00454     // Update parameter in out list and output status test.
00455     params_->set("Output Frequency", outputFreq_);
00456     if (outputTest_ != Teuchos::null)
00457       outputTest_->setOutputFrequency( outputFreq_ );
00458   }
00459 
00460   // Create output manager if we need to.
00461   if (printer_ == Teuchos::null) {
00462     printer_ = Teuchos::rcp( new OutputManager<ScalarType>(verbosity_, outputStream_) );
00463   }  
00464   
00465   // Check for convergence tolerance
00466   if (params->isParameter("Convergence Tolerance")) {
00467     convtol_ = params->get("Convergence Tolerance",convtol_default_);
00468 
00469     // Update parameter in our list and residual tests.
00470     params_->set("Convergence Tolerance", convtol_);
00471     if (impConvTest_ != Teuchos::null)
00472       impConvTest_->setTolerance( convtol_ );
00473     if (expConvTest_ != Teuchos::null)
00474       expConvTest_->setTolerance( convtol_ );
00475   }
00476   
00477   // Check for a change in scaling, if so we need to build new residual tests.
00478   if (params->isParameter("Implicit Residual Scaling")) {
00479     std::string tempImpResScale = Teuchos::getParameter<std::string>( *params, "Implicit Residual Scaling" );
00480 
00481     // Only update the scaling if it's different.
00482     if (impResScale_ != tempImpResScale) {
00483       Belos::ScaleType impResScaleType = convertStringToScaleType( tempImpResScale );
00484       impResScale_ = tempImpResScale;
00485 
00486       // Update parameter in our list and residual tests
00487       params_->set("Implicit Residual Scaling", impResScale_);
00488       if (impConvTest_ != Teuchos::null) {
00489         try { 
00490           impConvTest_->defineScaleForm( impResScaleType, Belos::TwoNorm );
00491         }
00492         catch (std::exception& e) { 
00493           // Make sure the convergence test gets constructed again.
00494           isSTSet_ = false;
00495         }
00496       }
00497     }      
00498   }
00499   
00500   if (params->isParameter("Explicit Residual Scaling")) {
00501     std::string tempExpResScale = Teuchos::getParameter<std::string>( *params, "Explicit Residual Scaling" );
00502 
00503     // Only update the scaling if it's different.
00504     if (expResScale_ != tempExpResScale) {
00505       Belos::ScaleType expResScaleType = convertStringToScaleType( tempExpResScale );
00506       expResScale_ = tempExpResScale;
00507 
00508       // Update parameter in our list and residual tests
00509       params_->set("Explicit Residual Scaling", expResScale_);
00510       if (expConvTest_ != Teuchos::null) {
00511         try { 
00512           expConvTest_->defineScaleForm( expResScaleType, Belos::TwoNorm );
00513         }
00514         catch (std::exception& e) {
00515           // Make sure the convergence test gets constructed again.
00516           isSTSet_ = false;
00517         }
00518       }
00519     }      
00520   }
00521 
00522   if (params->isParameter("Explicit Residual Test")) {
00523     expResTest_ = Teuchos::getParameter<bool>( *params,"Explicit Residual Test" );
00524 
00525     // Reconstruct the convergence test if the explicit residual test is not being used.
00526     params_->set("Explicit Residual Test", expResTest_);
00527     if (expConvTest_ == Teuchos::null) {
00528       isSTSet_ = false;
00529     }
00530   }
00531 
00532   // Create the timer if we need to.
00533   if (timerSolve_ == Teuchos::null) {
00534     std::string solveLabel = label_ + ": TFQMRSolMgr total solve time";
00535     timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00536   }
00537 
00538   // Inform the solver manager that the current parameters were set.
00539   isSet_ = true;
00540 }
00541 
00542 
00543 // Check the status test versus the defined linear problem
00544 template<class ScalarType, class MV, class OP>
00545 bool TFQMRSolMgr<ScalarType,MV,OP>::checkStatusTest() {
00546 
00547   typedef Belos::StatusTestCombo<ScalarType,MV,OP>  StatusTestCombo_t;
00548   typedef Belos::StatusTestGenResNorm<ScalarType,MV,OP>  StatusTestGenResNorm_t;
00549 
00550   // Basic test checks maximum iterations and native residual.
00551   maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>( maxIters_ ) );
00552 
00553   if (expResTest_) {
00554    
00555     // Implicit residual test, using the native residual to determine if convergence was achieved.
00556     Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
00557       Teuchos::rcp( new StatusTestGenResNorm_t( convtol_ ) );
00558     tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm );
00559     impConvTest_ = tmpImpConvTest;
00560 
00561     // Explicit residual test once the native residual is below the tolerance
00562     Teuchos::RCP<StatusTestGenResNorm_t> tmpExpConvTest =
00563       Teuchos::rcp( new StatusTestGenResNorm_t( convtol_ ) );
00564     tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit, Belos::TwoNorm );
00565     tmpExpConvTest->defineScaleForm( convertStringToScaleType(expResScale_), Belos::TwoNorm );
00566     expConvTest_ = tmpExpConvTest;
00567 
00568     // The convergence test is a combination of the "cheap" implicit test and explicit test.
00569     convTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) );
00570   }
00571   else {
00572 
00573     // Implicit residual test, using the native residual to determine if convergence was achieved.
00574     Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest =
00575       Teuchos::rcp( new StatusTestGenResNorm_t( convtol_ ) );
00576     tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm );
00577     impConvTest_ = tmpImpConvTest;
00578 
00579     // Set the explicit and total convergence test to this implicit test that checks for accuracy loss.
00580     expConvTest_ = impConvTest_;
00581     convTest_ = impConvTest_;
00582   }
00583   sTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
00584 
00585   // Create the status test output class.
00586   // This class manages and formats the output from the status test.
00587   StatusTestOutputFactory<ScalarType,MV,OP> stoFactory( outputStyle_ );
00588   outputTest_ = stoFactory.create( printer_, sTest_, outputFreq_, Passed+Failed+Undefined );
00589 
00590   // Set the solver string for the output test
00591   std::string solverDesc = " TFQMR ";
00592   outputTest_->setSolverDesc( solverDesc );
00593 
00594   
00595   // The status test is now set.
00596   isSTSet_ = true;
00597 
00598   return false;
00599 }
00600 
00601     
00602 template<class ScalarType, class MV, class OP>
00603 Teuchos::RCP<const Teuchos::ParameterList> 
00604 TFQMRSolMgr<ScalarType,MV,OP>::getValidParameters() const
00605 {
00606   static Teuchos::RCP<const Teuchos::ParameterList> validPL;
00607   
00608   // Set all the valid parameters and their default values.
00609   if(is_null(validPL)) {
00610     Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
00611     pl->set("Convergence Tolerance", convtol_default_,
00612       "The relative residual tolerance that needs to be achieved by the\n"
00613       "iterative solver in order for the linear system to be declared converged.");
00614     pl->set("Maximum Iterations", maxIters_default_,
00615       "The maximum number of block iterations allowed for each\n"
00616       "set of RHS solved.");
00617     pl->set("Verbosity", verbosity_default_,
00618       "What type(s) of solver information should be outputted\n"
00619       "to the output stream.");
00620     pl->set("Output Style", outputStyle_default_,
00621       "What style is used for the solver information outputted\n"
00622       "to the output stream.");
00623     pl->set("Output Frequency", outputFreq_default_,
00624       "How often convergence information should be outputted\n"
00625       "to the output stream.");  
00626     pl->set("Output Stream", outputStream_default_,
00627       "A reference-counted pointer to the output stream where all\n"
00628       "solver output is sent.");
00629     pl->set("Explicit Residual Test", expResTest_default_,
00630       "Whether the explicitly computed residual should be used in the convergence test.");
00631     pl->set("Implicit Residual Scaling", impResScale_default_,
00632       "The type of scaling used in the implicit residual convergence test.");
00633     pl->set("Explicit Residual Scaling", expResScale_default_,
00634       "The type of scaling used in the explicit residual convergence test.");
00635     pl->set("Timer Label", label_default_,
00636       "The string to use as a prefix for the timer labels.");
00637     //  pl->set("Restart Timers", restartTimers_);
00638     validPL = pl;
00639   }
00640   return validPL;
00641 }
00642 
00643   
00644 // solve()
00645 template<class ScalarType, class MV, class OP>
00646 ReturnType TFQMRSolMgr<ScalarType,MV,OP>::solve() {
00647 
00648   // Set the current parameters if they were not set before.
00649   // NOTE:  This may occur if the user generated the solver manager with the default constructor and 
00650   // then didn't set any parameters using setParameters().
00651   if (!isSet_) {
00652     setParameters(Teuchos::parameterList(*getValidParameters()));
00653   }
00654 
00655   Teuchos::BLAS<int,ScalarType> blas;
00656   Teuchos::LAPACK<int,ScalarType> lapack;
00657 
00658   TEST_FOR_EXCEPTION(problem_ == Teuchos::null,TFQMRSolMgrLinearProblemFailure,
00659          "Belos::TFQMRSolMgr::solve(): Linear problem is not a valid object.");
00660 
00661   TEST_FOR_EXCEPTION(!problem_->isProblemSet(),TFQMRSolMgrLinearProblemFailure,
00662                      "Belos::TFQMRSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
00663 
00664   if (!isSTSet_) {
00665     TEST_FOR_EXCEPTION( checkStatusTest(),TFQMRSolMgrLinearProblemFailure,
00666       "Belos::TFQMRSolMgr::solve(): Linear problem and requested status tests are incompatible.");
00667   }
00668 
00669   // Create indices for the linear systems to be solved.
00670   int startPtr = 0;
00671   int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
00672   int numCurrRHS = blockSize_;
00673 
00674   std::vector<int> currIdx, currIdx2;
00675 
00676   //  The index set is generated that informs the linear problem that some linear systems are augmented.
00677   currIdx.resize( blockSize_ );
00678   currIdx2.resize( blockSize_ );
00679   for (int i=0; i<numCurrRHS; ++i) 
00680     { currIdx[i] = startPtr+i; currIdx2[i]=i; }
00681 
00682   // Inform the linear problem of the current linear system to solve.
00683   problem_->setLSIndex( currIdx );
00684 
00686   // Parameter list
00687   Teuchos::ParameterList plist;
00688   plist.set("Block Size",blockSize_);
00689   
00690   // Reset the status test.  
00691   outputTest_->reset();
00692 
00693   // Assume convergence is achieved, then let any failed convergence set this to false.
00694   bool isConverged = true;  
00695 
00697   // TFQMR solver
00698 
00699   Teuchos::RCP<TFQMRIter<ScalarType,MV,OP> > tfqmr_iter = 
00700     Teuchos::rcp( new TFQMRIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,plist) );
00701 
00702   // Enter solve() iterations
00703   {
00704     Teuchos::TimeMonitor slvtimer(*timerSolve_);
00705 
00706     while ( numRHS2Solve > 0 ) {
00707       //
00708       // Reset the active / converged vectors from this block
00709       std::vector<int> convRHSIdx;
00710       std::vector<int> currRHSIdx( currIdx );
00711       currRHSIdx.resize(numCurrRHS);
00712 
00713       // Reset the number of iterations.
00714       tfqmr_iter->resetNumIters();
00715 
00716       // Reset the number of calls that the status test output knows about.
00717       outputTest_->resetNumCalls();
00718 
00719       // Get the current residual for this block of linear systems.
00720       Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitPrecResVec())), currIdx );
00721 
00722       // Set the new state and initialize the solver.
00723       TFQMRIterState<ScalarType,MV> newstate;
00724       newstate.R = R_0;
00725       tfqmr_iter->initializeTFQMR(newstate);
00726 
00727       while(1) {
00728   
00729   // tell tfqmr_iter to iterate
00730   try {
00731     tfqmr_iter->iterate();
00732     
00734     //
00735     // check convergence first
00736     //
00738     if ( convTest_->getStatus() == Passed ) {
00739       // We have convergence of the linear system.
00740       break;  // break from while(1){tfqmr_iter->iterate()}
00741     }
00743     //
00744     // check for maximum iterations
00745     //
00747     else if ( maxIterTest_->getStatus() == Passed ) {
00748       // we don't have convergence
00749       isConverged = false;
00750       break;  // break from while(1){tfqmr_iter->iterate()}
00751     }
00752 
00754     //
00755     // we returned from iterate(), but none of our status tests Passed.
00756     // something is wrong, and it is probably our fault.
00757     //
00759 
00760     else {
00761       TEST_FOR_EXCEPTION(true,std::logic_error,
00762              "Belos::TFQMRSolMgr::solve(): Invalid return from TFQMRIter::iterate().");
00763     }
00764   }
00765   catch (const std::exception &e) {
00766     printer_->stream(Errors) << "Error! Caught std::exception in TFQMRIter::iterate() at iteration " 
00767            << tfqmr_iter->getNumIters() << std::endl 
00768            << e.what() << std::endl;
00769     throw;
00770   }
00771       }
00772       
00773       // Inform the linear problem that we are finished with this block linear system.
00774       problem_->setCurrLS();
00775       
00776       // Update indices for the linear systems to be solved.
00777       startPtr += numCurrRHS;
00778       numRHS2Solve -= numCurrRHS;
00779       if ( numRHS2Solve > 0 ) {
00780   numCurrRHS = blockSize_;
00781 
00782   currIdx.resize( blockSize_ );
00783   currIdx2.resize( blockSize_ );
00784   for (int i=0; i<numCurrRHS; ++i) 
00785     { currIdx[i] = startPtr+i; currIdx2[i] = i; }
00786   // Set the next indices.
00787   problem_->setLSIndex( currIdx );
00788 
00789   // Set the new blocksize for the solver.
00790   tfqmr_iter->setBlockSize( blockSize_ ); 
00791       }
00792       else {
00793         currIdx.resize( numRHS2Solve );
00794       }
00795       
00796     }// while ( numRHS2Solve > 0 )
00797     
00798   }
00799 
00800   // print final summary
00801   sTest_->print( printer_->stream(FinalSummary) );
00802  
00803   // print timing information
00804   Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
00805  
00806   // get iteration information for this solve
00807   numIters_ = maxIterTest_->getNumIters();
00808  
00809   if (!isConverged) {
00810     return Unconverged; // return from TFQMRSolMgr::solve() 
00811   }
00812   return Converged; // return from TFQMRSolMgr::solve() 
00813 }
00814 
00815 //  This method requires the solver manager to return a std::string that describes itself.
00816 template<class ScalarType, class MV, class OP>
00817 std::string TFQMRSolMgr<ScalarType,MV,OP>::description() const
00818 {
00819   std::ostringstream oss;
00820   oss << "Belos::TFQMRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<">";
00821   oss << "{}";
00822   return oss.str();
00823 }
00824   
00825 } // end Belos namespace
00826 
00827 #endif /* BELOS_TFQMR_SOLMGR_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 10:05:07 2011 for Belos by  doxygen 1.6.3