BelosPseudoBlockCGSolMgr.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_PSEUDO_BLOCK_CG_SOLMGR_HPP
00030 #define BELOS_PSEUDO_BLOCK_CG_SOLMGR_HPP
00031 
00036 #include "BelosConfigDefs.hpp"
00037 #include "BelosTypes.hpp"
00038 
00039 #include "BelosLinearProblem.hpp"
00040 #include "BelosSolverManager.hpp"
00041 
00042 #include "BelosPseudoBlockCGIter.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_TimeMonitor.hpp"
00050 
00067 namespace Belos {
00068   
00070 
00071   
00078   class PseudoBlockCGSolMgrLinearProblemFailure : public BelosError {public:
00079     PseudoBlockCGSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
00080     {}};
00081   
00088   class PseudoBlockCGSolMgrOrthoFailure : public BelosError {public:
00089     PseudoBlockCGSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg)
00090     {}};
00091   
00092   template<class ScalarType, class MV, class OP>
00093   class PseudoBlockCGSolMgr : public SolverManager<ScalarType,MV,OP> {
00094     
00095   private:
00096     typedef MultiVecTraits<ScalarType,MV> MVT;
00097     typedef OperatorTraits<ScalarType,MV,OP> OPT;
00098     typedef Teuchos::ScalarTraits<ScalarType> SCT;
00099     typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00100     typedef Teuchos::ScalarTraits<MagnitudeType> MT;
00101     
00102   public:
00103     
00105 
00106 
00112     PseudoBlockCGSolMgr();
00113     
00123     PseudoBlockCGSolMgr( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00124                    const Teuchos::RCP<Teuchos::ParameterList> &pl );
00125     
00127     virtual ~PseudoBlockCGSolMgr() {};
00129     
00131 
00132     
00133     const LinearProblem<ScalarType,MV,OP>& getProblem() const {
00134       return *problem_;
00135     }
00136     
00139     Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
00140    
00143     Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const { return params_; }
00144  
00150     Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
00151       return tuple(timerSolve_);
00152     }
00153 
00155     int getNumIters() const {
00156       return numIters_;
00157     }
00158   
00162     bool isLOADetected() const { return false; }
00163   
00165     
00167 
00168    
00170     void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) { problem_ = problem; }
00171    
00173     void setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params );
00174     
00176 
00178 
00179 
00183     void reset( const ResetType type ) { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
00185 
00187 
00188     
00206     ReturnType solve();
00207     
00209     
00212     
00214     std::string description() const;
00215     
00217     
00218   private:
00219 
00220     // Method to convert std::string to enumerated type for residual.
00221     Belos::ScaleType convertStringToScaleType( const std::string& scaleType ) {
00222       if (scaleType == "Norm of Initial Residual") {
00223         return Belos::NormOfInitRes;
00224       } else if (scaleType == "Norm of Preconditioned Initial Residual") {
00225         return Belos::NormOfPrecInitRes;
00226       } else if (scaleType == "Norm of RHS") {
00227         return Belos::NormOfRHS;
00228       } else if (scaleType == "None") {
00229         return Belos::None;
00230       } else 
00231         TEST_FOR_EXCEPTION( true ,std::logic_error,
00232           "Belos::PseudoBlockCGSolMgr(): Invalid residual scaling type.");
00233     }
00234 
00235     // Linear problem.
00236     Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
00237     
00238     // Output manager.
00239     Teuchos::RCP<OutputManager<ScalarType> > printer_;
00240     Teuchos::RCP<std::ostream> outputStream_;
00241 
00242     // Status test.
00243     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
00244     Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
00245     Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
00246     Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
00247 
00248     // Orthogonalization manager.
00249     Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_; 
00250 
00251      // Current parameter list.
00252     Teuchos::RCP<ParameterList> params_;
00253    
00254     // Default solver values.
00255     static const MagnitudeType convtol_default_;
00256     static const int maxIters_default_;
00257     static const bool showMaxResNormOnly_default_;
00258     static const int verbosity_default_;
00259     static const int outputStyle_default_;
00260     static const int outputFreq_default_;
00261     static const int defQuorum_default_;
00262     static const std::string resScale_default_; 
00263     static const std::string label_default_;
00264     static const Teuchos::RCP<std::ostream> outputStream_default_;
00265 
00266     // Current solver values.
00267     MagnitudeType convtol_;
00268     int maxIters_, numIters_;
00269     int verbosity_, outputStyle_, outputFreq_, defQuorum_;
00270     bool showMaxResNormOnly_;
00271     std::string resScale_;       
00272  
00273     // Timers.
00274     std::string label_;
00275     Teuchos::RCP<Teuchos::Time> timerSolve_;
00276 
00277     // Internal state variables.
00278     bool isSet_;
00279   };
00280   
00281   
00282 // Default solver values.
00283 template<class ScalarType, class MV, class OP>
00284 const typename PseudoBlockCGSolMgr<ScalarType,MV,OP>::MagnitudeType PseudoBlockCGSolMgr<ScalarType,MV,OP>::convtol_default_ = 1e-8;
00285 
00286 template<class ScalarType, class MV, class OP>
00287 const int PseudoBlockCGSolMgr<ScalarType,MV,OP>::maxIters_default_ = 1000;
00288 
00289 template<class ScalarType, class MV, class OP>
00290 const bool PseudoBlockCGSolMgr<ScalarType,MV,OP>::showMaxResNormOnly_default_ = false;
00291 
00292 template<class ScalarType, class MV, class OP>
00293 const int PseudoBlockCGSolMgr<ScalarType,MV,OP>::verbosity_default_ = Belos::Errors;
00294 
00295 template<class ScalarType, class MV, class OP>
00296 const int PseudoBlockCGSolMgr<ScalarType,MV,OP>::outputStyle_default_ = Belos::General;
00297 
00298 template<class ScalarType, class MV, class OP>
00299 const int PseudoBlockCGSolMgr<ScalarType,MV,OP>::outputFreq_default_ = -1;
00300 
00301 template<class ScalarType, class MV, class OP>
00302 const int PseudoBlockCGSolMgr<ScalarType,MV,OP>::defQuorum_default_ = 1;
00303 
00304 template<class ScalarType, class MV, class OP>
00305 const std::string PseudoBlockCGSolMgr<ScalarType,MV,OP>::resScale_default_ = "Norm of Initial Residual";
00306 
00307 template<class ScalarType, class MV, class OP>
00308 const std::string PseudoBlockCGSolMgr<ScalarType,MV,OP>::label_default_ = "Belos";
00309 
00310 template<class ScalarType, class MV, class OP>
00311 const Teuchos::RCP<std::ostream> PseudoBlockCGSolMgr<ScalarType,MV,OP>::outputStream_default_ = Teuchos::rcp(&std::cout,false);
00312 
00313 
00314 // Empty Constructor
00315 template<class ScalarType, class MV, class OP>
00316 PseudoBlockCGSolMgr<ScalarType,MV,OP>::PseudoBlockCGSolMgr() :
00317   outputStream_(outputStream_default_),
00318   convtol_(convtol_default_),
00319   maxIters_(maxIters_default_),
00320   verbosity_(verbosity_default_),
00321   outputStyle_(outputStyle_default_),
00322   outputFreq_(outputFreq_default_),
00323   defQuorum_(defQuorum_default_),
00324   showMaxResNormOnly_(showMaxResNormOnly_default_),
00325   resScale_(resScale_default_),
00326   label_(label_default_),
00327   isSet_(false)
00328 {}
00329 
00330 // Basic Constructor
00331 template<class ScalarType, class MV, class OP>
00332 PseudoBlockCGSolMgr<ScalarType,MV,OP>::PseudoBlockCGSolMgr( 
00333                const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00334                const Teuchos::RCP<Teuchos::ParameterList> &pl ) : 
00335   problem_(problem),
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   defQuorum_(defQuorum_default_),
00343   showMaxResNormOnly_(showMaxResNormOnly_default_),
00344   resScale_(resScale_default_),
00345   label_(label_default_),
00346   isSet_(false)
00347 {
00348   TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
00349 
00350   // If the parameter list pointer is null, then set the current parameters to the default parameter list.
00351   if (!is_null(pl)) {
00352     // Set the parameters using the list that was passed in.
00353     setParameters( pl );  
00354   }
00355 }
00356 
00357 template<class ScalarType, class MV, class OP>
00358 void PseudoBlockCGSolMgr<ScalarType,MV,OP>::setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params )
00359 {
00360   // Create the internal parameter list if ones doesn't already exist.
00361   if (params_ == Teuchos::null) {
00362     params_ = Teuchos::rcp( new Teuchos::ParameterList(*getValidParameters()) );
00363   }
00364   else {
00365     params->validateParameters(*getValidParameters());
00366   }
00367 
00368   // Check for maximum number of iterations
00369   if (params->isParameter("Maximum Iterations")) {
00370     maxIters_ = params->get("Maximum Iterations",maxIters_default_);
00371 
00372     // Update parameter in our list and in status test.
00373     params_->set("Maximum Iterations", maxIters_);
00374     if (maxIterTest_!=Teuchos::null)
00375       maxIterTest_->setMaxIters( maxIters_ );
00376   }
00377 
00378   // Check to see if the timer label changed.
00379   if (params->isParameter("Timer Label")) {
00380     std::string tempLabel = params->get("Timer Label", label_default_);
00381 
00382     // Update parameter in our list and solver timer
00383     if (tempLabel != label_) {
00384       label_ = tempLabel;
00385       params_->set("Timer Label", label_);
00386       std::string solveLabel = label_ + ": PseudoBlockCGSolMgr total solve time";
00387       timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00388     }
00389   }
00390 
00391   // Check for a change in verbosity level
00392   if (params->isParameter("Verbosity")) {
00393     if (Teuchos::isParameterType<int>(*params,"Verbosity")) {
00394       verbosity_ = params->get("Verbosity", verbosity_default_);
00395     } else {
00396       verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,"Verbosity");
00397     }
00398 
00399     // Update parameter in our list.
00400     params_->set("Verbosity", verbosity_);
00401     if (printer_ != Teuchos::null)
00402       printer_->setVerbosity(verbosity_);
00403   }
00404 
00405   // Check for a change in output style
00406   if (params->isParameter("Output Style")) {
00407     if (Teuchos::isParameterType<int>(*params,"Output Style")) {
00408       outputStyle_ = params->get("Output Style", outputStyle_default_);
00409     } else {
00410       outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,"Output Style");
00411     }
00412 
00413     // Reconstruct the convergence test if the explicit residual test is not being used.
00414     params_->set("Output Style", outputStyle_);
00415     outputTest_ = Teuchos::null;
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   // Convergence
00446   typedef Belos::StatusTestCombo<ScalarType,MV,OP>  StatusTestCombo_t;
00447   typedef Belos::StatusTestGenResNorm<ScalarType,MV,OP>  StatusTestResNorm_t;
00448 
00449   // Check for convergence tolerance
00450   if (params->isParameter("Convergence Tolerance")) {
00451     convtol_ = params->get("Convergence Tolerance",convtol_default_);
00452 
00453     // Update parameter in our list and residual tests.
00454     params_->set("Convergence Tolerance", convtol_);
00455     if (convTest_ != Teuchos::null)
00456       convTest_->setTolerance( convtol_ );
00457   }
00458 
00459   if (params->isParameter("Show Maximum Residual Norm Only")) {
00460     showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,"Show Maximum Residual Norm Only");
00461 
00462     // Update parameter in our list and residual tests
00463     params_->set("Show Maximum Residual Norm Only", showMaxResNormOnly_);
00464     if (convTest_ != Teuchos::null)
00465       convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
00466   }
00467 
00468   // Check for a change in scaling, if so we need to build new residual tests.
00469   bool newResTest = false;
00470   if (params->isParameter("Residual Scaling")) {
00471     std::string tempResScale = Teuchos::getParameter<std::string>( *params, "Residual Scaling" );
00472 
00473     // Only update the scaling if it's different.
00474     if (resScale_ != tempResScale) {
00475       Belos::ScaleType resScaleType = convertStringToScaleType( tempResScale );
00476       resScale_ = tempResScale;
00477 
00478       // Update parameter in our list and residual tests
00479       params_->set("Residual Scaling", resScale_);
00480       if (convTest_ != Teuchos::null) {
00481         try {
00482           convTest_->defineScaleForm( resScaleType, Belos::TwoNorm );
00483         }
00484         catch (std::exception& e) {
00485     // Make sure the convergence test gets constructed again.
00486     newResTest = true;
00487         }
00488       }
00489     }      
00490   }
00491 
00492   // Get the deflation quorum, or number of converged systems before deflation is allowed
00493   if (params->isParameter("Deflation Quorum")) {
00494     defQuorum_ = params->get("Deflation Quorum", defQuorum_);
00495     params_->set("Deflation Quorum", defQuorum_);
00496     if (convTest_ != Teuchos::null)
00497       convTest_->setQuorum( defQuorum_ );
00498   }
00499 
00500   // Create status tests if we need to.
00501 
00502   // Basic test checks maximum iterations and native residual.
00503   if (maxIterTest_ == Teuchos::null)
00504     maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>( maxIters_ ) );
00505   
00506   // Implicit residual test, using the native residual to determine if convergence was achieved.
00507   if (convTest_ == Teuchos::null || newResTest) {
00508     convTest_ = Teuchos::rcp( new StatusTestResNorm_t( convtol_, defQuorum_, showMaxResNormOnly_ ) );
00509     convTest_->defineScaleForm( convertStringToScaleType( resScale_ ), Belos::TwoNorm );
00510   } 
00511 
00512   if (sTest_ == Teuchos::null || newResTest)
00513     sTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
00514   
00515   if (outputTest_ == Teuchos::null || newResTest) {
00516 
00517     // Create the status test output class.
00518     // This class manages and formats the output from the status test.
00519     StatusTestOutputFactory<ScalarType,MV,OP> stoFactory( outputStyle_ );
00520     outputTest_ = stoFactory.create( printer_, sTest_, outputFreq_, Passed+Failed+Undefined );
00521 
00522     // Set the solver string for the output test
00523     std::string solverDesc = " Pseudo Block CG ";
00524     outputTest_->setSolverDesc( solverDesc );
00525 
00526   }
00527 
00528   // Create the timer if we need to.
00529   if (timerSolve_ == Teuchos::null) {
00530     std::string solveLabel = label_ + ": PseudoBlockCGSolMgr total solve time";
00531     timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00532   }
00533 
00534   // Inform the solver manager that the current parameters were set.
00535   isSet_ = true;
00536 }
00537 
00538     
00539 template<class ScalarType, class MV, class OP>
00540 Teuchos::RCP<const Teuchos::ParameterList>
00541 PseudoBlockCGSolMgr<ScalarType,MV,OP>::getValidParameters() const
00542 {
00543   static Teuchos::RCP<const Teuchos::ParameterList> validPL;
00544   if (is_null(validPL)) {
00545     Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
00546     // Set all the valid parameters and their default values.
00547     pl= Teuchos::rcp( new Teuchos::ParameterList() );
00548     pl->set("Convergence Tolerance", convtol_default_,
00549       "The relative residual tolerance that needs to be achieved by the\n"
00550       "iterative solver in order for the linera system to be declared converged.");
00551     pl->set("Maximum Iterations", maxIters_default_,
00552       "The maximum number of block iterations allowed for each\n"
00553       "set of RHS solved.");
00554     pl->set("Verbosity", verbosity_default_,
00555       "What type(s) of solver information should be outputted\n"
00556       "to the output stream.");
00557     pl->set("Output Style", outputStyle_default_,
00558       "What style is used for the solver information outputted\n"
00559       "to the output stream.");
00560     pl->set("Output Frequency", outputFreq_default_,
00561       "How often convergence information should be outputted\n"
00562       "to the output stream.");  
00563     pl->set("Deflation Quorum", defQuorum_default_,
00564       "The number of linear systems that need to converge before\n"
00565       "they are deflated.  This number should be <= block size.");
00566     pl->set("Output Stream", outputStream_default_,
00567       "A reference-counted pointer to the output stream where all\n"
00568       "solver output is sent.");
00569     pl->set("Show Maximum Residual Norm Only", showMaxResNormOnly_default_,
00570       "When convergence information is printed, only show the maximum\n"
00571       "relative residual norm when the block size is greater than one.");
00572     pl->set("Residual Scaling", resScale_default_,
00573       "The type of scaling used in the residual convergence test.");
00574     pl->set("Timer Label", label_default_,
00575       "The string to use as a prefix for the timer labels.");
00576     //  defaultParams_->set("Restart Timers", restartTimers_);
00577     validPL = pl;
00578   }
00579   return validPL;
00580 }
00581 
00582 
00583 // solve()
00584 template<class ScalarType, class MV, class OP>
00585 ReturnType PseudoBlockCGSolMgr<ScalarType,MV,OP>::solve() {
00586 
00587   // Set the current parameters if they were not set before.
00588   // NOTE:  This may occur if the user generated the solver manager with the default constructor and 
00589   // then didn't set any parameters using setParameters().
00590   if (!isSet_) { setParameters( params_ ); }
00591   
00592   Teuchos::BLAS<int,ScalarType> blas;
00593   
00594   TEST_FOR_EXCEPTION(!problem_->isProblemSet(),PseudoBlockCGSolMgrLinearProblemFailure,
00595                      "Belos::PseudoBlockCGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
00596 
00597   // Create indices for the linear systems to be solved.
00598   int startPtr = 0;
00599   int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
00600   int numCurrRHS = numRHS2Solve;
00601 
00602   std::vector<int> currIdx( numRHS2Solve ), currIdx2( numRHS2Solve );
00603   for (int i=0; i<numRHS2Solve; ++i) {
00604     currIdx[i] = startPtr+i; 
00605     currIdx2[i]=i;
00606   }
00607 
00608   // Inform the linear problem of the current linear system to solve.
00609   problem_->setLSIndex( currIdx );
00610 
00612   // Parameter list
00613   Teuchos::ParameterList plist;
00614 
00615   // Reset the status test.  
00616   outputTest_->reset();
00617 
00618   // Assume convergence is achieved, then let any failed convergence set this to false.
00619   bool isConverged = true;  
00620 
00622   // Pseudo-Block CG solver
00623 
00624   Teuchos::RCP<PseudoBlockCGIter<ScalarType,MV,OP> > block_cg_iter
00625     = Teuchos::rcp( new PseudoBlockCGIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,plist) );  
00626 
00627   // Enter solve() iterations
00628   {
00629     Teuchos::TimeMonitor slvtimer(*timerSolve_);
00630 
00631     while ( numRHS2Solve > 0 ) {
00632 
00633       // Reset the active / converged vectors from this block
00634       std::vector<int> convRHSIdx;
00635       std::vector<int> currRHSIdx( currIdx );
00636       currRHSIdx.resize(numCurrRHS);
00637 
00638       // Reset the number of iterations.
00639       block_cg_iter->resetNumIters();
00640 
00641       // Reset the number of calls that the status test output knows about.
00642       outputTest_->resetNumCalls();
00643 
00644       // Get the current residual for this block of linear systems.
00645       Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
00646 
00647       // Get a new state struct and initialize the solver.
00648       CGIterationState<ScalarType,MV> newState;
00649       newState.R = R_0;
00650       block_cg_iter->initializeCG(newState);
00651 
00652       while(1) {
00653   
00654   // tell block_gmres_iter to iterate
00655   try {
00656     block_cg_iter->iterate();
00657     
00659     //
00660     // check convergence first
00661     //
00663     if ( convTest_->getStatus() == Passed ) {
00664       
00665       // Figure out which linear systems converged.
00666       std::vector<int> convIdx = Teuchos::rcp_dynamic_cast<StatusTestGenResNorm<ScalarType,MV,OP> >(convTest_)->convIndices();
00667 
00668       // If the number of converged linear systems is equal to the
00669             // number of current linear systems, then we are done with this block.
00670       if (convIdx.size() == currRHSIdx.size())
00671         break;  // break from while(1){block_cg_iter->iterate()}
00672 
00673       // Inform the linear problem that we are finished with this current linear system.
00674       problem_->setCurrLS();
00675 
00676       // Reset currRHSIdx to have the right-hand sides that are left to converge for this block.
00677       int have = 0;
00678             std::vector<int> unconvIdx(currRHSIdx.size());
00679       for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
00680         bool found = false;
00681         for (unsigned int j=0; j<convIdx.size(); ++j) {
00682     if (currRHSIdx[i] == convIdx[j]) {
00683       found = true;
00684       break;
00685     }
00686         }
00687         if (!found) {
00688                 currIdx2[have] = currIdx2[i];
00689     currRHSIdx[have++] = currRHSIdx[i];
00690         }
00691       }
00692       currRHSIdx.resize(have);
00693       currIdx2.resize(have);
00694       
00695       // Set the remaining indices after deflation.
00696       problem_->setLSIndex( currRHSIdx );
00697       
00698       // Get the current residual vector.
00699       std::vector<MagnitudeType> norms;
00700             R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
00701       for (int i=0; i<have; ++i) { currIdx2[i] = i; }
00702 
00703       // Set the new state and initialize the solver.
00704       CGIterationState<ScalarType,MV> defstate;
00705       defstate.R = R_0;
00706       block_cg_iter->initializeCG(defstate);
00707     }
00708 
00710     //
00711     // check for maximum iterations
00712     //
00714     else if ( maxIterTest_->getStatus() == Passed ) {
00715       // we don't have convergence
00716       isConverged = false;
00717       break;  // break from while(1){block_cg_iter->iterate()}
00718     }
00719 
00721     //
00722     // we returned from iterate(), but none of our status tests Passed.
00723     // something is wrong, and it is probably our fault.
00724     //
00726 
00727     else {
00728       TEST_FOR_EXCEPTION(true,std::logic_error,
00729              "Belos::PseudoBlockCGSolMgr::solve(): Invalid return from PseudoBlockCGIter::iterate().");
00730     }
00731   } 
00732   catch (const std::exception &e) {
00733     printer_->stream(Errors) << "Error! Caught std::exception in PseudoBlockCGIter::iterate() at iteration " 
00734            << block_cg_iter->getNumIters() << std::endl 
00735            << e.what() << std::endl;
00736     throw;
00737   }
00738       }
00739       
00740       // Inform the linear problem that we are finished with this block linear system.
00741       problem_->setCurrLS();
00742       
00743       // Update indices for the linear systems to be solved.
00744       startPtr += numCurrRHS;
00745       numRHS2Solve -= numCurrRHS;
00746 
00747       if ( numRHS2Solve > 0 ) { 
00748 
00749   numCurrRHS = numRHS2Solve;  
00750   currIdx.resize( numCurrRHS );
00751   currIdx2.resize( numCurrRHS );
00752   for (int i=0; i<numCurrRHS; ++i) 
00753     { currIdx[i] = startPtr+i; currIdx2[i] = i; }
00754   
00755   // Set the next indices.
00756   problem_->setLSIndex( currIdx );  
00757       }
00758       else {
00759   currIdx.resize( numRHS2Solve );
00760       }
00761       
00762     }// while ( numRHS2Solve > 0 )
00763     
00764   }
00765                      
00766   // print final summary
00767   sTest_->print( printer_->stream(FinalSummary) );
00768  
00769   // print timing information
00770   Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
00771  
00772   // get iteration information for this solve
00773   numIters_ = maxIterTest_->getNumIters();
00774  
00775   if (!isConverged ) {
00776     return Unconverged; // return from PseudoBlockCGSolMgr::solve() 
00777   }
00778   return Converged; // return from PseudoBlockCGSolMgr::solve() 
00779 }
00780 
00781 //  This method requires the solver manager to return a std::string that describes itself.
00782 template<class ScalarType, class MV, class OP>
00783 std::string PseudoBlockCGSolMgr<ScalarType,MV,OP>::description() const
00784 {
00785   std::ostringstream oss;
00786   oss << "Belos::PseudoBlockCGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<">";
00787   oss << "{";
00788   oss << "}";
00789   return oss.str();
00790 }
00791   
00792 } // end Belos namespace
00793 
00794 #endif /* BELOS_PSEUDO_BLOCK_CG_SOLMGR_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 10:05:06 2011 for Belos by  doxygen 1.6.3