|
Belos Version of the Day
|
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> ¶ms ); 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> ¶ms ) 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 */
1.7.4