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

Generated on Wed May 12 21:30:09 2010 for Belos by  doxygen 1.4.7