Belos Package Browser (Single Doxygen Collection) Development
BelosBlockCGSolMgr.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_BLOCK_CG_SOLMGR_HPP
00043 #define BELOS_BLOCK_CG_SOLMGR_HPP
00044 
00049 #include "BelosConfigDefs.hpp"
00050 #include "BelosTypes.hpp"
00051 
00052 #include "BelosLinearProblem.hpp"
00053 #include "BelosSolverManager.hpp"
00054 
00055 #include "BelosCGIter.hpp"
00056 #include "BelosBlockCGIter.hpp"
00057 #include "BelosDGKSOrthoManager.hpp"
00058 #include "BelosICGSOrthoManager.hpp"
00059 #include "BelosIMGSOrthoManager.hpp"
00060 #include "BelosStatusTestMaxIters.hpp"
00061 #include "BelosStatusTestGenResNorm.hpp"
00062 #include "BelosStatusTestCombo.hpp"
00063 #include "BelosStatusTestOutputFactory.hpp"
00064 #include "BelosOutputManager.hpp"
00065 #include "Teuchos_BLAS.hpp"
00066 #include "Teuchos_LAPACK.hpp"
00067 #include "Teuchos_TimeMonitor.hpp"
00068 
00085 namespace Belos {
00086   
00088 
00089   
00096   class BlockCGSolMgrLinearProblemFailure : public BelosError {public:
00097     BlockCGSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
00098     {}};
00099   
00106   class BlockCGSolMgrOrthoFailure : public BelosError {public:
00107     BlockCGSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg)
00108     {}};
00109   
00110   template<class ScalarType, class MV, class OP>
00111   class BlockCGSolMgr : public SolverManager<ScalarType,MV,OP> {
00112     
00113   private:
00114     typedef MultiVecTraits<ScalarType,MV> MVT;
00115     typedef OperatorTraits<ScalarType,MV,OP> OPT;
00116     typedef Teuchos::ScalarTraits<ScalarType> SCT;
00117     typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00118     typedef Teuchos::ScalarTraits<MagnitudeType> MT;
00119     
00120   public:
00121     
00123 
00124 
00130      BlockCGSolMgr();
00131 
00160     BlockCGSolMgr( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00161        const Teuchos::RCP<Teuchos::ParameterList> &pl );
00162     
00164     virtual ~BlockCGSolMgr() {};
00166     
00168 
00169     
00170     const LinearProblem<ScalarType,MV,OP>& getProblem() const {
00171       return *problem_;
00172     }
00173 
00176     Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
00177     
00180     Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const { return params_; }
00181     
00187     Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
00188       return tuple(timerSolve_);
00189     }
00190 
00192     int getNumIters() const {
00193       return numIters_;
00194     }
00195 
00198     bool isLOADetected() const { return false; }
00199  
00201     
00203 
00204    
00206     void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) { problem_ = problem; }
00207    
00209     void setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params );
00210     
00212    
00214 
00215 
00219     void reset( const ResetType type ) { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
00221  
00223 
00224     
00242     ReturnType solve();
00243     
00245     
00248     
00250     std::string description() const;
00251     
00253     
00254   private:
00255 
00256     // Linear problem.
00257     Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
00258     
00259     // Output manager.
00260     Teuchos::RCP<OutputManager<ScalarType> > printer_;
00261     Teuchos::RCP<std::ostream> outputStream_;
00262 
00263     // Status test.
00264     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
00265     Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
00266     Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
00267     Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
00268 
00269     // Orthogonalization manager.
00270     Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_; 
00271     
00272     // Current parameter list.
00273     Teuchos::RCP<ParameterList> params_;
00274     
00275     // Default solver values.
00276     static const MagnitudeType convtol_default_;
00277     static const MagnitudeType orthoKappa_default_;
00278     static const int maxIters_default_;
00279     static const bool adaptiveBlockSize_default_;
00280     static const bool showMaxResNormOnly_default_;
00281     static const int blockSize_default_;
00282     static const int verbosity_default_;
00283     static const int outputStyle_default_;
00284     static const int outputFreq_default_;
00285     static const std::string label_default_;
00286     static const std::string orthoType_default_;
00287     static const Teuchos::RCP<std::ostream> outputStream_default_;
00288 
00289     // Current solver values.
00290     MagnitudeType convtol_, orthoKappa_;
00291     int maxIters_, numIters_;
00292     int blockSize_, verbosity_, outputStyle_, outputFreq_;
00293     bool adaptiveBlockSize_, showMaxResNormOnly_;
00294     std::string orthoType_; 
00295     
00296     // Timers.
00297     std::string label_;
00298     Teuchos::RCP<Teuchos::Time> timerSolve_;
00299 
00300     // Internal state variables.
00301     bool isSet_;
00302   };
00303 
00304 
00305 // Default solver values.
00306 template<class ScalarType, class MV, class OP>
00307 const typename BlockCGSolMgr<ScalarType,MV,OP>::MagnitudeType BlockCGSolMgr<ScalarType,MV,OP>::convtol_default_ = 1e-8;
00308 
00309 template<class ScalarType, class MV, class OP>
00310 const typename BlockCGSolMgr<ScalarType,MV,OP>::MagnitudeType BlockCGSolMgr<ScalarType,MV,OP>::orthoKappa_default_ = -1.0;
00311 
00312 template<class ScalarType, class MV, class OP>
00313 const int BlockCGSolMgr<ScalarType,MV,OP>::maxIters_default_ = 1000;
00314 
00315 template<class ScalarType, class MV, class OP>
00316 const bool BlockCGSolMgr<ScalarType,MV,OP>::adaptiveBlockSize_default_ = true;
00317 
00318 template<class ScalarType, class MV, class OP>
00319 const bool BlockCGSolMgr<ScalarType,MV,OP>::showMaxResNormOnly_default_ = false;
00320 
00321 template<class ScalarType, class MV, class OP>
00322 const int BlockCGSolMgr<ScalarType,MV,OP>::blockSize_default_ = 1;
00323 
00324 template<class ScalarType, class MV, class OP>
00325 const int BlockCGSolMgr<ScalarType,MV,OP>::verbosity_default_ = Belos::Errors;
00326 
00327 template<class ScalarType, class MV, class OP>
00328 const int BlockCGSolMgr<ScalarType,MV,OP>::outputStyle_default_ = Belos::General;
00329 
00330 template<class ScalarType, class MV, class OP>
00331 const int BlockCGSolMgr<ScalarType,MV,OP>::outputFreq_default_ = -1;
00332 
00333 template<class ScalarType, class MV, class OP>
00334 const std::string BlockCGSolMgr<ScalarType,MV,OP>::label_default_ = "Belos";
00335 
00336 template<class ScalarType, class MV, class OP>
00337 const std::string BlockCGSolMgr<ScalarType,MV,OP>::orthoType_default_ = "DGKS";
00338 
00339 template<class ScalarType, class MV, class OP>
00340 const Teuchos::RCP<std::ostream> BlockCGSolMgr<ScalarType,MV,OP>::outputStream_default_ = Teuchos::rcp(&std::cout,false);
00341 
00342 
00343 // Empty Constructor
00344 template<class ScalarType, class MV, class OP>
00345 BlockCGSolMgr<ScalarType,MV,OP>::BlockCGSolMgr() :
00346   outputStream_(outputStream_default_),
00347   convtol_(convtol_default_),
00348   orthoKappa_(orthoKappa_default_),
00349   maxIters_(maxIters_default_),
00350   blockSize_(blockSize_default_),
00351   verbosity_(verbosity_default_),
00352   outputStyle_(outputStyle_default_),
00353   outputFreq_(outputFreq_default_),
00354   adaptiveBlockSize_(adaptiveBlockSize_default_),
00355   showMaxResNormOnly_(showMaxResNormOnly_default_),
00356   orthoType_(orthoType_default_),
00357   label_(label_default_),
00358   isSet_(false)
00359 {}
00360 
00361 
00362 // Basic Constructor
00363 template<class ScalarType, class MV, class OP>
00364 BlockCGSolMgr<ScalarType,MV,OP>::BlockCGSolMgr( 
00365                  const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00366                  const Teuchos::RCP<Teuchos::ParameterList> &pl ) : 
00367   problem_(problem),
00368   outputStream_(outputStream_default_),
00369   convtol_(convtol_default_),
00370   orthoKappa_(orthoKappa_default_),
00371   maxIters_(maxIters_default_),
00372   blockSize_(blockSize_default_),
00373   verbosity_(verbosity_default_),
00374   outputStyle_(outputStyle_default_),
00375   outputFreq_(outputFreq_default_),
00376   adaptiveBlockSize_(adaptiveBlockSize_default_),
00377   showMaxResNormOnly_(showMaxResNormOnly_default_),
00378   orthoType_(orthoType_default_),
00379   label_(label_default_),
00380   isSet_(false)
00381 {
00382   TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
00383 
00384   // If the parameter list pointer is null, then set the current parameters to the default parameter list.
00385   if ( !is_null(pl) ) {
00386     setParameters( pl );  
00387   }
00388 }
00389 
00390 template<class ScalarType, class MV, class OP>
00391 void BlockCGSolMgr<ScalarType,MV,OP>::setParameters( const Teuchos::RCP<Teuchos::ParameterList> &params )
00392 {
00393   // Create the internal parameter list if ones doesn't already exist.
00394   if (params_ == Teuchos::null) {
00395     params_ = Teuchos::rcp( new Teuchos::ParameterList(*getValidParameters()) );
00396   }
00397   else {
00398     params->validateParameters(*getValidParameters());
00399   }
00400 
00401   // Check for maximum number of iterations
00402   if (params->isParameter("Maximum Iterations")) {
00403     maxIters_ = params->get("Maximum Iterations",maxIters_default_);
00404 
00405     // Update parameter in our list and in status test.
00406     params_->set("Maximum Iterations", maxIters_);
00407     if (maxIterTest_!=Teuchos::null)
00408       maxIterTest_->setMaxIters( maxIters_ );
00409   }
00410 
00411   // Check for blocksize
00412   if (params->isParameter("Block Size")) {
00413     blockSize_ = params->get("Block Size",blockSize_default_);    
00414     TEST_FOR_EXCEPTION(blockSize_ <= 0, std::invalid_argument,
00415            "Belos::BlockCGSolMgr: \"Block Size\" must be strictly positive.");
00416 
00417     // Update parameter in our list.
00418     params_->set("Block Size", blockSize_);
00419   }
00420 
00421   // Check if the blocksize should be adaptive
00422   if (params->isParameter("Adaptive Block Size")) {
00423     adaptiveBlockSize_ = params->get("Adaptive Block Size",adaptiveBlockSize_default_);
00424     
00425     // Update parameter in our list.
00426     params_->set("Adaptive Block Size", adaptiveBlockSize_);
00427   }
00428 
00429   // Check to see if the timer label changed.
00430   if (params->isParameter("Timer Label")) {
00431     std::string tempLabel = params->get("Timer Label", label_default_);
00432 
00433     // Update parameter in our list and solver timer
00434     if (tempLabel != label_) {
00435       label_ = tempLabel;
00436       params_->set("Timer Label", label_);
00437       std::string solveLabel = label_ + ": BlockCGSolMgr total solve time";
00438       timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00439     }
00440   }
00441 
00442   // Check if the orthogonalization changed.
00443   if (params->isParameter("Orthogonalization")) {
00444     std::string tempOrthoType = params->get("Orthogonalization",orthoType_default_);
00445     TEST_FOR_EXCEPTION( tempOrthoType != "DGKS" && tempOrthoType != "ICGS" && tempOrthoType != "IMGS", 
00446                         std::invalid_argument,
00447       "Belos::BlockCGSolMgr: \"Orthogonalization\" must be either \"DGKS\", \"ICGS\", or \"IMGS\".");
00448     if (tempOrthoType != orthoType_) {
00449       orthoType_ = tempOrthoType;
00450       // Create orthogonalization manager
00451       if (orthoType_=="DGKS") {
00452   if (orthoKappa_ <= 0) {
00453     ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
00454   }
00455   else {
00456     ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
00457     Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
00458   }
00459       }
00460       else if (orthoType_=="ICGS") {
00461   ortho_ = Teuchos::rcp( new ICGSOrthoManager<ScalarType,MV,OP>( label_ ) );
00462       } 
00463       else if (orthoType_=="IMGS") {
00464   ortho_ = Teuchos::rcp( new IMGSOrthoManager<ScalarType,MV,OP>( label_ ) );
00465       } 
00466     }  
00467   }
00468 
00469   // Check which orthogonalization constant to use.
00470   if (params->isParameter("Orthogonalization Constant")) {
00471     orthoKappa_ = params->get("Orthogonalization Constant",orthoKappa_default_);
00472 
00473     // Update parameter in our list.
00474     params_->set("Orthogonalization Constant",orthoKappa_);
00475     if (orthoType_=="DGKS") {
00476       if (orthoKappa_ > 0 && ortho_ != Teuchos::null) {
00477   Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
00478       }
00479     } 
00480   }
00481 
00482   // Check for a change in verbosity level
00483   if (params->isParameter("Verbosity")) {
00484     if (Teuchos::isParameterType<int>(*params,"Verbosity")) {
00485       verbosity_ = params->get("Verbosity", verbosity_default_);
00486     } else {
00487       verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,"Verbosity");
00488     }
00489 
00490     // Update parameter in our list.
00491     params_->set("Verbosity", verbosity_);
00492     if (printer_ != Teuchos::null)
00493       printer_->setVerbosity(verbosity_);
00494   }
00495 
00496   // Check for a change in output style
00497   if (params->isParameter("Output Style")) {
00498     if (Teuchos::isParameterType<int>(*params,"Output Style")) {
00499       outputStyle_ = params->get("Output Style", outputStyle_default_);
00500     } else {
00501       outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,"Output Style");
00502     }
00503 
00504     // Update parameter in our list.
00505     params_->set("Output Style", outputStyle_);
00506     outputTest_ == Teuchos::null;
00507   }
00508 
00509   // output stream
00510   if (params->isParameter("Output Stream")) {
00511     outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,"Output Stream");
00512 
00513     // Update parameter in our list.
00514     params_->set("Output Stream", outputStream_);
00515     if (printer_ != Teuchos::null)
00516       printer_->setOStream( outputStream_ );
00517   }
00518 
00519   // frequency level
00520   if (verbosity_ & Belos::StatusTestDetails) {
00521     if (params->isParameter("Output Frequency")) {
00522       outputFreq_ = params->get("Output Frequency", outputFreq_default_);
00523     }
00524 
00525     // Update parameter in out list and output status test.
00526     params_->set("Output Frequency", outputFreq_);
00527     if (outputTest_ != Teuchos::null)
00528       outputTest_->setOutputFrequency( outputFreq_ );
00529   }
00530 
00531   // Create output manager if we need to.
00532   if (printer_ == Teuchos::null) {
00533     printer_ = Teuchos::rcp( new OutputManager<ScalarType>(verbosity_, outputStream_) );
00534   }  
00535   
00536   // Convergence
00537   typedef Belos::StatusTestCombo<ScalarType,MV,OP>  StatusTestCombo_t;
00538   typedef Belos::StatusTestGenResNorm<ScalarType,MV,OP>  StatusTestResNorm_t;
00539 
00540   // Check for convergence tolerance
00541   if (params->isParameter("Convergence Tolerance")) {
00542     convtol_ = params->get("Convergence Tolerance",convtol_default_);
00543 
00544     // Update parameter in our list and residual tests.
00545     params_->set("Convergence Tolerance", convtol_);
00546     if (convTest_ != Teuchos::null)
00547       convTest_->setTolerance( convtol_ );
00548   }
00549   
00550   if (params->isParameter("Show Maximum Residual Norm Only")) {
00551     showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,"Show Maximum Residual Norm Only");
00552 
00553     // Update parameter in our list and residual tests
00554     params_->set("Show Maximum Residual Norm Only", showMaxResNormOnly_);
00555     if (convTest_ != Teuchos::null)
00556       convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
00557   }
00558 
00559   // Create status tests if we need to.
00560 
00561   // Basic test checks maximum iterations and native residual.
00562   if (maxIterTest_ == Teuchos::null)
00563     maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>( maxIters_ ) );
00564   
00565   // Implicit residual test, using the native residual to determine if convergence was achieved.
00566   if (convTest_ == Teuchos::null)
00567     convTest_ = Teuchos::rcp( new StatusTestResNorm_t( convtol_, 1 ) );
00568   
00569   if (sTest_ == Teuchos::null)
00570     sTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
00571   
00572   if (outputTest_ == Teuchos::null) {
00573 
00574     // Create the status test output class.
00575     // This class manages and formats the output from the status test.
00576     StatusTestOutputFactory<ScalarType,MV,OP> stoFactory( outputStyle_ );
00577     outputTest_ = stoFactory.create( printer_, sTest_, outputFreq_, Passed+Failed+Undefined );
00578 
00579     // Set the solver string for the output test
00580     std::string solverDesc = " Block CG ";
00581     outputTest_->setSolverDesc( solverDesc );
00582 
00583   }
00584 
00585   // Create orthogonalization manager if we need to.
00586   if (ortho_ == Teuchos::null) {
00587     if (orthoType_=="DGKS") {
00588       if (orthoKappa_ <= 0) {
00589   ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
00590       }
00591       else {
00592   ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
00593   Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
00594       }
00595     }
00596     else if (orthoType_=="ICGS") {
00597       ortho_ = Teuchos::rcp( new ICGSOrthoManager<ScalarType,MV,OP>( label_ ) );
00598     } 
00599     else if (orthoType_=="IMGS") {
00600       ortho_ = Teuchos::rcp( new IMGSOrthoManager<ScalarType,MV,OP>( label_ ) );
00601     } 
00602     else {
00603       TEST_FOR_EXCEPTION(orthoType_!="ICGS"&&orthoType_!="DGKS"&&orthoType_!="IMGS",std::logic_error,
00604        "Belos::BlockCGSolMgr(): Invalid orthogonalization type.");
00605     }  
00606   }
00607 
00608   // Create the timer if we need to.
00609   if (timerSolve_ == Teuchos::null) {
00610     std::string solveLabel = label_ + ": BlockCGSolMgr total solve time";
00611     timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00612   }
00613 
00614   // Inform the solver manager that the current parameters were set.
00615   isSet_ = true;
00616 }
00617 
00618     
00619 template<class ScalarType, class MV, class OP>
00620 Teuchos::RCP<const Teuchos::ParameterList> 
00621 BlockCGSolMgr<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("Block Size", blockSize_default_,
00635       "The number of vectors in each block.");
00636     pl->set("Adaptive Block Size", adaptiveBlockSize_default_,
00637       "Whether the solver manager should adapt to the block size\n"
00638       "based on the number of RHS to solve.");
00639     pl->set("Verbosity", verbosity_default_,
00640       "What type(s) of solver information should be outputted\n"
00641       "to the output stream.");
00642     pl->set("Output Style", outputStyle_default_,
00643       "What style is used for the solver information outputted\n"
00644       "to the output stream.");
00645     pl->set("Output Frequency", outputFreq_default_,
00646       "How often convergence information should be outputted\n"
00647       "to the output stream.");  
00648     pl->set("Output Stream", outputStream_default_,
00649       "A reference-counted pointer to the output stream where all\n"
00650       "solver output is sent.");
00651     pl->set("Show Maximum Residual Norm Only", showMaxResNormOnly_default_,
00652       "When convergence information is printed, only show the maximum\n"
00653       "relative residual norm when the block size is greater than one.");
00654     pl->set("Timer Label", label_default_,
00655       "The string to use as a prefix for the timer labels.");
00656     //  pl->set("Restart Timers", restartTimers_);
00657     pl->set("Orthogonalization", orthoType_default_,
00658       "The type of orthogonalization to use: DGKS, ICGS, or IMGS.");
00659     pl->set("Orthogonalization Constant",orthoKappa_default_,
00660       "The constant used by DGKS orthogonalization to determine\n"
00661       "whether another step of classical Gram-Schmidt is necessary.");
00662     validPL = pl;
00663   }
00664   return validPL;
00665 }
00666 
00667   
00668 // solve()
00669 template<class ScalarType, class MV, class OP>
00670 ReturnType BlockCGSolMgr<ScalarType,MV,OP>::solve() {
00671 
00672   // Set the current parameters if they were not set before.
00673   // NOTE:  This may occur if the user generated the solver manager with the default constructor and 
00674   // then didn't set any parameters using setParameters().
00675   if (!isSet_) {
00676     setParameters(Teuchos::parameterList(*getValidParameters()));
00677   }
00678 
00679   Teuchos::BLAS<int,ScalarType> blas;
00680   Teuchos::LAPACK<int,ScalarType> lapack;
00681   
00682   TEST_FOR_EXCEPTION(!problem_->isProblemSet(),BlockCGSolMgrLinearProblemFailure,
00683                      "Belos::BlockCGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
00684 
00685   // Create indices for the linear systems to be solved.
00686   int startPtr = 0;
00687   int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
00688   int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
00689 
00690   std::vector<int> currIdx, currIdx2;
00691   //  If an adaptive block size is allowed then only the linear systems that need to be solved are solved.
00692   //  Otherwise, the index set is generated that informs the linear problem that some linear systems are augmented.
00693   if ( adaptiveBlockSize_ ) {
00694     blockSize_ = numCurrRHS;
00695     currIdx.resize( numCurrRHS  );
00696     currIdx2.resize( numCurrRHS  );
00697     for (int i=0; i<numCurrRHS; ++i) 
00698       { currIdx[i] = startPtr+i; currIdx2[i]=i; }
00699     
00700   }
00701   else {
00702     currIdx.resize( blockSize_ );
00703     currIdx2.resize( blockSize_ );
00704     for (int i=0; i<numCurrRHS; ++i) 
00705       { currIdx[i] = startPtr+i; currIdx2[i]=i; }
00706     for (int i=numCurrRHS; i<blockSize_; ++i) 
00707       { currIdx[i] = -1; currIdx2[i] = i; }
00708   }
00709 
00710   // Inform the linear problem of the current linear system to solve.
00711   problem_->setLSIndex( currIdx );
00712 
00714   // Parameter list
00715   Teuchos::ParameterList plist;
00716   plist.set("Block Size",blockSize_);
00717   
00718   // Reset the status test.  
00719   outputTest_->reset();
00720 
00721   // Assume convergence is achieved, then let any failed convergence set this to false.
00722   bool isConverged = true;  
00723 
00725   // BlockCG solver
00726 
00727   Teuchos::RCP<CGIteration<ScalarType,MV,OP> > block_cg_iter;
00728   if (blockSize_ == 1)
00729     block_cg_iter = Teuchos::rcp( new CGIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,plist) );
00730   else
00731     block_cg_iter = Teuchos::rcp( new BlockCGIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,ortho_,plist) );
00732   
00733 
00734   // Enter solve() iterations
00735   {
00736     Teuchos::TimeMonitor slvtimer(*timerSolve_);
00737 
00738     while ( numRHS2Solve > 0 ) {
00739       //
00740       // Reset the active / converged vectors from this block
00741       std::vector<int> convRHSIdx;
00742       std::vector<int> currRHSIdx( currIdx );
00743       currRHSIdx.resize(numCurrRHS);
00744 
00745       // Reset the number of iterations.
00746       block_cg_iter->resetNumIters();
00747 
00748       // Reset the number of calls that the status test output knows about.
00749       outputTest_->resetNumCalls();
00750 
00751       // Get the current residual for this block of linear systems.
00752       Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
00753 
00754       // Set the new state and initialize the solver.
00755       CGIterationState<ScalarType,MV> newstate;
00756       newstate.R = R_0;
00757       block_cg_iter->initializeCG(newstate);
00758 
00759       while(1) {
00760   
00761   // tell block_cg_iter to iterate
00762   try {
00763     block_cg_iter->iterate();
00764     
00766     //
00767     // check convergence first
00768     //
00770     if ( convTest_->getStatus() == Passed ) {
00771       // We have convergence of at least one linear system.
00772 
00773       // Figure out which linear systems converged.
00774       std::vector<int> convIdx = Teuchos::rcp_dynamic_cast<StatusTestGenResNorm<ScalarType,MV,OP> >(convTest_)->convIndices();
00775 
00776       // If the number of converged linear systems is equal to the
00777             // number of current linear systems, then we are done with this block.
00778       if (convIdx.size() == currRHSIdx.size())
00779         break;  // break from while(1){block_cg_iter->iterate()}
00780 
00781       // Inform the linear problem that we are finished with this current linear system.
00782       problem_->setCurrLS();
00783 
00784       // Reset currRHSIdx to have the right-hand sides that are left to converge for this block.
00785       int have = 0;
00786             std::vector<int> unconvIdx(currRHSIdx.size());
00787       for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
00788         bool found = false;
00789         for (unsigned int j=0; j<convIdx.size(); ++j) {
00790     if (currRHSIdx[i] == convIdx[j]) {
00791       found = true;
00792       break;
00793     }
00794         }
00795         if (!found) {
00796                 currIdx2[have] = currIdx2[i];
00797     currRHSIdx[have++] = currRHSIdx[i];
00798         }
00799               else {
00800               } 
00801       }
00802       currRHSIdx.resize(have);
00803       currIdx2.resize(have);
00804 
00805       // Set the remaining indices after deflation.
00806       problem_->setLSIndex( currRHSIdx );
00807 
00808       // Get the current residual vector.
00809       std::vector<MagnitudeType> norms;
00810             R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
00811       for (int i=0; i<have; ++i) { currIdx2[i] = i; }
00812 
00813       // Set the new blocksize for the solver.
00814       block_cg_iter->setBlockSize( have );
00815 
00816       // Set the new state and initialize the solver.
00817       CGIterationState<ScalarType,MV> defstate;
00818       defstate.R = R_0;
00819       block_cg_iter->initializeCG(defstate);
00820     }
00822     //
00823     // check for maximum iterations
00824     //
00826     else if ( maxIterTest_->getStatus() == Passed ) {
00827       // we don't have convergence
00828       isConverged = false;
00829       break;  // break from while(1){block_cg_iter->iterate()}
00830     }
00831 
00833     //
00834     // we returned from iterate(), but none of our status tests Passed.
00835     // something is wrong, and it is probably our fault.
00836     //
00838 
00839     else {
00840       TEST_FOR_EXCEPTION(true,std::logic_error,
00841              "Belos::BlockCGSolMgr::solve(): Invalid return from CGIteration::iterate().");
00842     }
00843   }
00844   catch (const std::exception &e) {
00845     printer_->stream(Errors) << "Error! Caught std::exception in CGIteration::iterate() at iteration " 
00846            << block_cg_iter->getNumIters() << std::endl 
00847            << e.what() << std::endl;
00848     throw;
00849   }
00850       }
00851       
00852       // Inform the linear problem that we are finished with this block linear system.
00853       problem_->setCurrLS();
00854       
00855       // Update indices for the linear systems to be solved.
00856       startPtr += numCurrRHS;
00857       numRHS2Solve -= numCurrRHS;
00858       if ( numRHS2Solve > 0 ) {
00859   numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
00860 
00861   if ( adaptiveBlockSize_ ) {
00862           blockSize_ = numCurrRHS;
00863     currIdx.resize( numCurrRHS  );
00864     currIdx2.resize( numCurrRHS  );
00865     for (int i=0; i<numCurrRHS; ++i) 
00866       { currIdx[i] = startPtr+i; currIdx2[i] = i; }   
00867   }
00868   else {
00869     currIdx.resize( blockSize_ );
00870     currIdx2.resize( blockSize_ );
00871     for (int i=0; i<numCurrRHS; ++i) 
00872       { currIdx[i] = startPtr+i; currIdx2[i] = i; }
00873     for (int i=numCurrRHS; i<blockSize_; ++i) 
00874       { currIdx[i] = -1; currIdx2[i] = i; }
00875   }
00876   // Set the next indices.
00877   problem_->setLSIndex( currIdx );
00878 
00879   // Set the new blocksize for the solver.
00880   block_cg_iter->setBlockSize( blockSize_ );  
00881       }
00882       else {
00883         currIdx.resize( numRHS2Solve );
00884       }
00885       
00886     }// while ( numRHS2Solve > 0 )
00887     
00888   }
00889 
00890   // print final summary
00891   sTest_->print( printer_->stream(FinalSummary) );
00892  
00893   // print timing information
00894   Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
00895  
00896   // get iteration information for this solve
00897   numIters_ = maxIterTest_->getNumIters();
00898  
00899   if (!isConverged) {
00900     return Unconverged; // return from BlockCGSolMgr::solve() 
00901   }
00902   return Converged; // return from BlockCGSolMgr::solve() 
00903 }
00904 
00905 //  This method requires the solver manager to return a std::string that describes itself.
00906 template<class ScalarType, class MV, class OP>
00907 std::string BlockCGSolMgr<ScalarType,MV,OP>::description() const
00908 {
00909   std::ostringstream oss;
00910   oss << "Belos::BlockCGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<">";
00911   oss << "{";
00912   oss << "Ortho Type='"<<orthoType_<<"\', Block Size=" << blockSize_;
00913   oss << "}";
00914   return oss.str();
00915 }
00916   
00917 } // end Belos namespace
00918 
00919 #endif /* BELOS_BLOCK_CG_SOLMGR_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines