|
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_TFQMR_SOLMGR_HPP 00043 #define BELOS_TFQMR_SOLMGR_HPP 00044 00049 #include "BelosConfigDefs.hpp" 00050 #include "BelosTypes.hpp" 00051 00052 #include "BelosLinearProblem.hpp" 00053 #include "BelosSolverManager.hpp" 00054 00055 #include "BelosTFQMRIter.hpp" 00056 #include "BelosStatusTestMaxIters.hpp" 00057 #include "BelosStatusTestGenResNorm.hpp" 00058 #include "BelosStatusTestCombo.hpp" 00059 #include "BelosStatusTestOutputFactory.hpp" 00060 #include "BelosOutputManager.hpp" 00061 #ifdef BELOS_TEUCHOS_TIME_MONITOR 00062 #include "Teuchos_TimeMonitor.hpp" 00063 #endif 00064 00078 namespace Belos { 00079 00081 00082 00089 class TFQMRSolMgrLinearProblemFailure : public BelosError {public: 00090 TFQMRSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg) 00091 {}}; 00092 00099 class TFQMRSolMgrOrthoFailure : public BelosError {public: 00100 TFQMRSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg) 00101 {}}; 00102 00103 template<class ScalarType, class MV, class OP> 00104 class TFQMRSolMgr : public SolverManager<ScalarType,MV,OP> { 00105 00106 private: 00107 typedef MultiVecTraits<ScalarType,MV> MVT; 00108 typedef OperatorTraits<ScalarType,MV,OP> OPT; 00109 typedef Teuchos::ScalarTraits<ScalarType> SCT; 00110 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType; 00111 typedef Teuchos::ScalarTraits<MagnitudeType> MT; 00112 00113 public: 00114 00116 00117 00123 TFQMRSolMgr(); 00124 00141 TFQMRSolMgr( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem, 00142 const Teuchos::RCP<Teuchos::ParameterList> &pl ); 00143 00145 virtual ~TFQMRSolMgr() {}; 00147 00149 00150 00151 const LinearProblem<ScalarType,MV,OP>& getProblem() const { 00152 return *problem_; 00153 } 00154 00157 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const; 00158 00161 Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const { return params_; } 00162 00168 Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const { 00169 return Teuchos::tuple(timerSolve_); 00170 } 00171 00177 MagnitudeType achievedTol() const { 00178 return achievedTol_; 00179 } 00180 00182 int getNumIters() const { 00183 return numIters_; 00184 } 00185 00193 bool isLOADetected() const { return false; } 00194 00196 00198 00199 00201 void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) { problem_ = problem; } 00202 00204 void setParameters( const Teuchos::RCP<Teuchos::ParameterList> ¶ms ); 00205 00207 00209 00210 00214 void reset( const ResetType type ) { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); } 00216 00218 00219 00237 ReturnType solve(); 00238 00240 00243 00245 std::string description() const; 00246 00248 00249 private: 00250 00251 // Method for checking current status test against defined linear problem. 00252 bool checkStatusTest(); 00253 00254 // Linear problem. 00255 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_; 00256 00257 // Output manager. 00258 Teuchos::RCP<OutputManager<ScalarType> > printer_; 00259 Teuchos::RCP<std::ostream> outputStream_; 00260 00261 // Status test. 00262 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_; 00263 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_; 00264 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convTest_; 00265 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > expConvTest_, impConvTest_; 00266 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_; 00267 00268 // Current parameter list. 00269 Teuchos::RCP<Teuchos::ParameterList> params_; 00270 00271 // Default solver values. 00272 static const MagnitudeType convtol_default_; 00273 static const int maxIters_default_; 00274 static const bool expResTest_default_; 00275 static const int verbosity_default_; 00276 static const int outputStyle_default_; 00277 static const int outputFreq_default_; 00278 static const std::string impResScale_default_; 00279 static const std::string expResScale_default_; 00280 static const std::string label_default_; 00281 static const Teuchos::RCP<std::ostream> outputStream_default_; 00282 00283 // Current solver values. 00284 MagnitudeType convtol_, achievedTol_; 00285 int maxIters_, numIters_; 00286 int verbosity_, outputStyle_, outputFreq_; 00287 int blockSize_; 00288 bool expResTest_; 00289 std::string impResScale_, expResScale_; 00290 00291 // Timers. 00292 std::string label_; 00293 Teuchos::RCP<Teuchos::Time> timerSolve_; 00294 00295 // Internal state variables. 00296 bool isSet_, isSTSet_; 00297 }; 00298 00299 00300 // Default solver values. 00301 template<class ScalarType, class MV, class OP> 00302 const typename TFQMRSolMgr<ScalarType,MV,OP>::MagnitudeType TFQMRSolMgr<ScalarType,MV,OP>::convtol_default_ = 1e-8; 00303 00304 template<class ScalarType, class MV, class OP> 00305 const int TFQMRSolMgr<ScalarType,MV,OP>::maxIters_default_ = 1000; 00306 00307 template<class ScalarType, class MV, class OP> 00308 const bool TFQMRSolMgr<ScalarType,MV,OP>::expResTest_default_ = false; 00309 00310 template<class ScalarType, class MV, class OP> 00311 const int TFQMRSolMgr<ScalarType,MV,OP>::verbosity_default_ = Belos::Errors; 00312 00313 template<class ScalarType, class MV, class OP> 00314 const int TFQMRSolMgr<ScalarType,MV,OP>::outputStyle_default_ = Belos::General; 00315 00316 template<class ScalarType, class MV, class OP> 00317 const int TFQMRSolMgr<ScalarType,MV,OP>::outputFreq_default_ = -1; 00318 00319 template<class ScalarType, class MV, class OP> 00320 const std::string TFQMRSolMgr<ScalarType,MV,OP>::impResScale_default_ = "Norm of Preconditioned Initial Residual"; 00321 00322 template<class ScalarType, class MV, class OP> 00323 const std::string TFQMRSolMgr<ScalarType,MV,OP>::expResScale_default_ = "Norm of Initial Residual"; 00324 00325 template<class ScalarType, class MV, class OP> 00326 const std::string TFQMRSolMgr<ScalarType,MV,OP>::label_default_ = "Belos"; 00327 00328 template<class ScalarType, class MV, class OP> 00329 const Teuchos::RCP<std::ostream> TFQMRSolMgr<ScalarType,MV,OP>::outputStream_default_ = Teuchos::rcp(&std::cout,false); 00330 00331 00332 // Empty Constructor 00333 template<class ScalarType, class MV, class OP> 00334 TFQMRSolMgr<ScalarType,MV,OP>::TFQMRSolMgr() : 00335 outputStream_(outputStream_default_), 00336 convtol_(convtol_default_), 00337 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()), 00338 maxIters_(maxIters_default_), 00339 numIters_(0), 00340 verbosity_(verbosity_default_), 00341 outputStyle_(outputStyle_default_), 00342 outputFreq_(outputFreq_default_), 00343 blockSize_(1), 00344 expResTest_(expResTest_default_), 00345 impResScale_(impResScale_default_), 00346 expResScale_(expResScale_default_), 00347 label_(label_default_), 00348 isSet_(false), 00349 isSTSet_(false) 00350 {} 00351 00352 00353 // Basic Constructor 00354 template<class ScalarType, class MV, class OP> 00355 TFQMRSolMgr<ScalarType,MV,OP>::TFQMRSolMgr( 00356 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem, 00357 const Teuchos::RCP<Teuchos::ParameterList> &pl ) : 00358 problem_(problem), 00359 outputStream_(outputStream_default_), 00360 convtol_(convtol_default_), 00361 achievedTol_(Teuchos::ScalarTraits<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>::zero()), 00362 maxIters_(maxIters_default_), 00363 numIters_(0), 00364 verbosity_(verbosity_default_), 00365 outputStyle_(outputStyle_default_), 00366 outputFreq_(outputFreq_default_), 00367 blockSize_(1), 00368 expResTest_(expResTest_default_), 00369 impResScale_(impResScale_default_), 00370 expResScale_(expResScale_default_), 00371 label_(label_default_), 00372 isSet_(false), 00373 isSTSet_(false) 00374 { 00375 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager."); 00376 00377 // If the parameter list pointer is null, then set the current parameters to the default parameter list. 00378 if ( !is_null(pl) ) { 00379 setParameters( pl ); 00380 } 00381 } 00382 00383 template<class ScalarType, class MV, class OP> 00384 void TFQMRSolMgr<ScalarType,MV,OP>::setParameters( const Teuchos::RCP<Teuchos::ParameterList> ¶ms ) 00385 { 00386 // Create the internal parameter list if ones doesn't already exist. 00387 if (params_ == Teuchos::null) { 00388 params_ = Teuchos::rcp( new Teuchos::ParameterList(*getValidParameters()) ); 00389 } 00390 else { 00391 params->validateParameters(*getValidParameters()); 00392 } 00393 00394 // Check for maximum number of iterations 00395 if (params->isParameter("Maximum Iterations")) { 00396 maxIters_ = params->get("Maximum Iterations",maxIters_default_); 00397 00398 // Update parameter in our list and in status test. 00399 params_->set("Maximum Iterations", maxIters_); 00400 if (maxIterTest_!=Teuchos::null) 00401 maxIterTest_->setMaxIters( maxIters_ ); 00402 } 00403 00404 // Check for blocksize 00405 if (params->isParameter("Block Size")) { 00406 blockSize_ = params->get("Block Size",1); 00407 TEUCHOS_TEST_FOR_EXCEPTION(blockSize_ != 1, std::invalid_argument, 00408 "Belos::TFQMRSolMgr: \"Block Size\" must be 1."); 00409 00410 // Update parameter in our list. 00411 params_->set("Block Size", blockSize_); 00412 } 00413 00414 // Check to see if the timer label changed. 00415 if (params->isParameter("Timer Label")) { 00416 std::string tempLabel = params->get("Timer Label", label_default_); 00417 00418 // Update parameter in our list and solver timer 00419 if (tempLabel != label_) { 00420 label_ = tempLabel; 00421 params_->set("Timer Label", label_); 00422 std::string solveLabel = label_ + ": TFQMRSolMgr total solve time"; 00423 #ifdef BELOS_TEUCHOS_TIME_MONITOR 00424 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel); 00425 #endif 00426 } 00427 } 00428 00429 // Check for a change in verbosity level 00430 if (params->isParameter("Verbosity")) { 00431 if (Teuchos::isParameterType<int>(*params,"Verbosity")) { 00432 verbosity_ = params->get("Verbosity", verbosity_default_); 00433 } else { 00434 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,"Verbosity"); 00435 } 00436 00437 // Update parameter in our list. 00438 params_->set("Verbosity", verbosity_); 00439 if (printer_ != Teuchos::null) 00440 printer_->setVerbosity(verbosity_); 00441 } 00442 00443 // Check for a change in output style 00444 if (params->isParameter("Output Style")) { 00445 if (Teuchos::isParameterType<int>(*params,"Output Style")) { 00446 outputStyle_ = params->get("Output Style", outputStyle_default_); 00447 } else { 00448 outputStyle_ = (int)Teuchos::getParameter<Belos::OutputType>(*params,"Output Style"); 00449 } 00450 00451 // Reconstruct the convergence test if the explicit residual test is not being used. 00452 params_->set("Output Style", outputStyle_); 00453 isSTSet_ = false; 00454 } 00455 00456 // output stream 00457 if (params->isParameter("Output Stream")) { 00458 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,"Output Stream"); 00459 00460 // Update parameter in our list. 00461 params_->set("Output Stream", outputStream_); 00462 if (printer_ != Teuchos::null) 00463 printer_->setOStream( outputStream_ ); 00464 } 00465 00466 // frequency level 00467 if (verbosity_ & Belos::StatusTestDetails) { 00468 if (params->isParameter("Output Frequency")) { 00469 outputFreq_ = params->get("Output Frequency", outputFreq_default_); 00470 } 00471 00472 // Update parameter in out list and output status test. 00473 params_->set("Output Frequency", outputFreq_); 00474 if (outputTest_ != Teuchos::null) 00475 outputTest_->setOutputFrequency( outputFreq_ ); 00476 } 00477 00478 // Create output manager if we need to. 00479 if (printer_ == Teuchos::null) { 00480 printer_ = Teuchos::rcp( new OutputManager<ScalarType>(verbosity_, outputStream_) ); 00481 } 00482 00483 // Check for convergence tolerance 00484 if (params->isParameter("Convergence Tolerance")) { 00485 convtol_ = params->get("Convergence Tolerance",convtol_default_); 00486 00487 // Update parameter in our list and residual tests. 00488 params_->set("Convergence Tolerance", convtol_); 00489 if (impConvTest_ != Teuchos::null) 00490 impConvTest_->setTolerance( convtol_ ); 00491 if (expConvTest_ != Teuchos::null) 00492 expConvTest_->setTolerance( convtol_ ); 00493 } 00494 00495 // Check for a change in scaling, if so we need to build new residual tests. 00496 if (params->isParameter("Implicit Residual Scaling")) { 00497 std::string tempImpResScale = Teuchos::getParameter<std::string>( *params, "Implicit Residual Scaling" ); 00498 00499 // Only update the scaling if it's different. 00500 if (impResScale_ != tempImpResScale) { 00501 Belos::ScaleType impResScaleType = convertStringToScaleType( tempImpResScale ); 00502 impResScale_ = tempImpResScale; 00503 00504 // Update parameter in our list and residual tests 00505 params_->set("Implicit Residual Scaling", impResScale_); 00506 if (impConvTest_ != Teuchos::null) { 00507 try { 00508 impConvTest_->defineScaleForm( impResScaleType, Belos::TwoNorm ); 00509 } 00510 catch (std::exception& e) { 00511 // Make sure the convergence test gets constructed again. 00512 isSTSet_ = false; 00513 } 00514 } 00515 } 00516 } 00517 00518 if (params->isParameter("Explicit Residual Scaling")) { 00519 std::string tempExpResScale = Teuchos::getParameter<std::string>( *params, "Explicit Residual Scaling" ); 00520 00521 // Only update the scaling if it's different. 00522 if (expResScale_ != tempExpResScale) { 00523 Belos::ScaleType expResScaleType = convertStringToScaleType( tempExpResScale ); 00524 expResScale_ = tempExpResScale; 00525 00526 // Update parameter in our list and residual tests 00527 params_->set("Explicit Residual Scaling", expResScale_); 00528 if (expConvTest_ != Teuchos::null) { 00529 try { 00530 expConvTest_->defineScaleForm( expResScaleType, Belos::TwoNorm ); 00531 } 00532 catch (std::exception& e) { 00533 // Make sure the convergence test gets constructed again. 00534 isSTSet_ = false; 00535 } 00536 } 00537 } 00538 } 00539 00540 if (params->isParameter("Explicit Residual Test")) { 00541 expResTest_ = Teuchos::getParameter<bool>( *params,"Explicit Residual Test" ); 00542 00543 // Reconstruct the convergence test if the explicit residual test is not being used. 00544 params_->set("Explicit Residual Test", expResTest_); 00545 if (expConvTest_ == Teuchos::null) { 00546 isSTSet_ = false; 00547 } 00548 } 00549 00550 // Create the timer if we need to. 00551 if (timerSolve_ == Teuchos::null) { 00552 std::string solveLabel = label_ + ": TFQMRSolMgr total solve time"; 00553 #ifdef BELOS_TEUCHOS_TIME_MONITOR 00554 timerSolve_ = Teuchos::TimeMonitor::getNewCounter(solveLabel); 00555 #endif 00556 } 00557 00558 // Inform the solver manager that the current parameters were set. 00559 isSet_ = true; 00560 } 00561 00562 00563 // Check the status test versus the defined linear problem 00564 template<class ScalarType, class MV, class OP> 00565 bool TFQMRSolMgr<ScalarType,MV,OP>::checkStatusTest() { 00566 00567 typedef Belos::StatusTestCombo<ScalarType,MV,OP> StatusTestCombo_t; 00568 typedef Belos::StatusTestGenResNorm<ScalarType,MV,OP> StatusTestGenResNorm_t; 00569 00570 // Basic test checks maximum iterations and native residual. 00571 maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>( maxIters_ ) ); 00572 00573 if (expResTest_) { 00574 00575 // Implicit residual test, using the native residual to determine if convergence was achieved. 00576 Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest = 00577 Teuchos::rcp( new StatusTestGenResNorm_t( convtol_ ) ); 00578 tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm ); 00579 impConvTest_ = tmpImpConvTest; 00580 00581 // Explicit residual test once the native residual is below the tolerance 00582 Teuchos::RCP<StatusTestGenResNorm_t> tmpExpConvTest = 00583 Teuchos::rcp( new StatusTestGenResNorm_t( convtol_ ) ); 00584 tmpExpConvTest->defineResForm( StatusTestGenResNorm_t::Explicit, Belos::TwoNorm ); 00585 tmpExpConvTest->defineScaleForm( convertStringToScaleType(expResScale_), Belos::TwoNorm ); 00586 expConvTest_ = tmpExpConvTest; 00587 00588 // The convergence test is a combination of the "cheap" implicit test and explicit test. 00589 convTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::SEQ, impConvTest_, expConvTest_ ) ); 00590 } 00591 else { 00592 00593 // Implicit residual test, using the native residual to determine if convergence was achieved. 00594 Teuchos::RCP<StatusTestGenResNorm_t> tmpImpConvTest = 00595 Teuchos::rcp( new StatusTestGenResNorm_t( convtol_ ) ); 00596 tmpImpConvTest->defineScaleForm( convertStringToScaleType(impResScale_), Belos::TwoNorm ); 00597 impConvTest_ = tmpImpConvTest; 00598 00599 // Set the explicit and total convergence test to this implicit test that checks for accuracy loss. 00600 expConvTest_ = impConvTest_; 00601 convTest_ = impConvTest_; 00602 } 00603 sTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) ); 00604 00605 // Create the status test output class. 00606 // This class manages and formats the output from the status test. 00607 StatusTestOutputFactory<ScalarType,MV,OP> stoFactory( outputStyle_ ); 00608 outputTest_ = stoFactory.create( printer_, sTest_, outputFreq_, Passed+Failed+Undefined ); 00609 00610 // Set the solver string for the output test 00611 std::string solverDesc = " TFQMR "; 00612 outputTest_->setSolverDesc( solverDesc ); 00613 00614 00615 // The status test is now set. 00616 isSTSet_ = true; 00617 00618 return false; 00619 } 00620 00621 00622 template<class ScalarType, class MV, class OP> 00623 Teuchos::RCP<const Teuchos::ParameterList> 00624 TFQMRSolMgr<ScalarType,MV,OP>::getValidParameters() const 00625 { 00626 static Teuchos::RCP<const Teuchos::ParameterList> validPL; 00627 00628 // Set all the valid parameters and their default values. 00629 if(is_null(validPL)) { 00630 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList(); 00631 pl->set("Convergence Tolerance", convtol_default_, 00632 "The relative residual tolerance that needs to be achieved by the\n" 00633 "iterative solver in order for the linear system to be declared converged."); 00634 pl->set("Maximum Iterations", maxIters_default_, 00635 "The maximum number of block iterations allowed for each\n" 00636 "set of RHS solved."); 00637 pl->set("Verbosity", verbosity_default_, 00638 "What type(s) of solver information should be outputted\n" 00639 "to the output stream."); 00640 pl->set("Output Style", outputStyle_default_, 00641 "What style is used for the solver information outputted\n" 00642 "to the output stream."); 00643 pl->set("Output Frequency", outputFreq_default_, 00644 "How often convergence information should be outputted\n" 00645 "to the output stream."); 00646 pl->set("Output Stream", outputStream_default_, 00647 "A reference-counted pointer to the output stream where all\n" 00648 "solver output is sent."); 00649 pl->set("Explicit Residual Test", expResTest_default_, 00650 "Whether the explicitly computed residual should be used in the convergence test."); 00651 pl->set("Implicit Residual Scaling", impResScale_default_, 00652 "The type of scaling used in the implicit residual convergence test."); 00653 pl->set("Explicit Residual Scaling", expResScale_default_, 00654 "The type of scaling used in the explicit residual convergence test."); 00655 pl->set("Timer Label", label_default_, 00656 "The string to use as a prefix for the timer labels."); 00657 // pl->set("Restart Timers", restartTimers_); 00658 validPL = pl; 00659 } 00660 return validPL; 00661 } 00662 00663 00664 // solve() 00665 template<class ScalarType, class MV, class OP> 00666 ReturnType TFQMRSolMgr<ScalarType,MV,OP>::solve() { 00667 00668 // Set the current parameters if they were not set before. 00669 // NOTE: This may occur if the user generated the solver manager with the default constructor and 00670 // then didn't set any parameters using setParameters(). 00671 if (!isSet_) { 00672 setParameters(Teuchos::parameterList(*getValidParameters())); 00673 } 00674 00675 TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,TFQMRSolMgrLinearProblemFailure, 00676 "Belos::TFQMRSolMgr::solve(): Linear problem is not a valid object."); 00677 00678 TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(),TFQMRSolMgrLinearProblemFailure, 00679 "Belos::TFQMRSolMgr::solve(): Linear problem is not ready, setProblem() has not been called."); 00680 00681 if (!isSTSet_) { 00682 TEUCHOS_TEST_FOR_EXCEPTION( checkStatusTest(),TFQMRSolMgrLinearProblemFailure, 00683 "Belos::TFQMRSolMgr::solve(): Linear problem and requested status tests are incompatible."); 00684 } 00685 00686 // Create indices for the linear systems to be solved. 00687 int startPtr = 0; 00688 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) ); 00689 int numCurrRHS = blockSize_; 00690 00691 std::vector<int> currIdx, currIdx2; 00692 00693 // The index set is generated that informs the linear problem that some linear systems are augmented. 00694 currIdx.resize( blockSize_ ); 00695 currIdx2.resize( blockSize_ ); 00696 for (int i=0; i<numCurrRHS; ++i) 00697 { currIdx[i] = startPtr+i; currIdx2[i]=i; } 00698 00699 // Inform the linear problem of the current linear system to solve. 00700 problem_->setLSIndex( currIdx ); 00701 00703 // Parameter list 00704 Teuchos::ParameterList plist; 00705 plist.set("Block Size",blockSize_); 00706 00707 // Reset the status test. 00708 outputTest_->reset(); 00709 00710 // Assume convergence is achieved, then let any failed convergence set this to false. 00711 bool isConverged = true; 00712 00714 // TFQMR solver 00715 00716 Teuchos::RCP<TFQMRIter<ScalarType,MV,OP> > tfqmr_iter = 00717 Teuchos::rcp( new TFQMRIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,plist) ); 00718 00719 // Enter solve() iterations 00720 { 00721 #ifdef BELOS_TEUCHOS_TIME_MONITOR 00722 Teuchos::TimeMonitor slvtimer(*timerSolve_); 00723 #endif 00724 00725 while ( numRHS2Solve > 0 ) { 00726 // 00727 // Reset the active / converged vectors from this block 00728 std::vector<int> convRHSIdx; 00729 std::vector<int> currRHSIdx( currIdx ); 00730 currRHSIdx.resize(numCurrRHS); 00731 00732 // Reset the number of iterations. 00733 tfqmr_iter->resetNumIters(); 00734 00735 // Reset the number of calls that the status test output knows about. 00736 outputTest_->resetNumCalls(); 00737 00738 // Get the current residual for this block of linear systems. 00739 Teuchos::RCP<MV> R_0 = MVT::CloneViewNonConst( *(Teuchos::rcp_const_cast<MV>(problem_->getInitPrecResVec())), currIdx ); 00740 00741 // Set the new state and initialize the solver. 00742 TFQMRIterState<ScalarType,MV> newstate; 00743 newstate.R = R_0; 00744 tfqmr_iter->initializeTFQMR(newstate); 00745 00746 while(1) { 00747 00748 // tell tfqmr_iter to iterate 00749 try { 00750 tfqmr_iter->iterate(); 00751 00753 // 00754 // check convergence first 00755 // 00757 if ( convTest_->getStatus() == Passed ) { 00758 // We have convergence of the linear system. 00759 break; // break from while(1){tfqmr_iter->iterate()} 00760 } 00762 // 00763 // check for maximum iterations 00764 // 00766 else if ( maxIterTest_->getStatus() == Passed ) { 00767 // we don't have convergence 00768 isConverged = false; 00769 break; // break from while(1){tfqmr_iter->iterate()} 00770 } 00771 00773 // 00774 // we returned from iterate(), but none of our status tests Passed. 00775 // something is wrong, and it is probably our fault. 00776 // 00778 00779 else { 00780 TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error, 00781 "Belos::TFQMRSolMgr::solve(): Invalid return from TFQMRIter::iterate()."); 00782 } 00783 } 00784 catch (const std::exception &e) { 00785 printer_->stream(Errors) << "Error! Caught std::exception in TFQMRIter::iterate() at iteration " 00786 << tfqmr_iter->getNumIters() << std::endl 00787 << e.what() << std::endl; 00788 throw; 00789 } 00790 } 00791 00792 // Inform the linear problem that we are finished with this block linear system. 00793 problem_->setCurrLS(); 00794 00795 // Update indices for the linear systems to be solved. 00796 startPtr += numCurrRHS; 00797 numRHS2Solve -= numCurrRHS; 00798 if ( numRHS2Solve > 0 ) { 00799 numCurrRHS = blockSize_; 00800 00801 currIdx.resize( blockSize_ ); 00802 currIdx2.resize( blockSize_ ); 00803 for (int i=0; i<numCurrRHS; ++i) 00804 { currIdx[i] = startPtr+i; currIdx2[i] = i; } 00805 // Set the next indices. 00806 problem_->setLSIndex( currIdx ); 00807 00808 // Set the new blocksize for the solver. 00809 tfqmr_iter->setBlockSize( blockSize_ ); 00810 } 00811 else { 00812 currIdx.resize( numRHS2Solve ); 00813 } 00814 00815 }// while ( numRHS2Solve > 0 ) 00816 00817 } 00818 00819 // print final summary 00820 sTest_->print( printer_->stream(FinalSummary) ); 00821 00822 // print timing information 00823 #ifdef BELOS_TEUCHOS_TIME_MONITOR 00824 // Calling summarize() can be expensive, so don't call unless the 00825 // user wants to print out timing details. summarize() will do all 00826 // the work even if it's passed a "black hole" output stream. 00827 if (verbosity_ & TimingDetails) 00828 Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) ); 00829 #endif 00830 00831 // get iteration information for this solve 00832 numIters_ = maxIterTest_->getNumIters(); 00833 00834 // Save the convergence test value ("achieved tolerance") for this 00835 // solve. For this solver, convTest_ may either be a single 00836 // (implicit) residual norm test, or a combination of two residual 00837 // norm tests. In the latter case, the master convergence test 00838 // convTest_ is a SEQ combo of the implicit resp. explicit tests. 00839 // If the implicit test never passes, then the explicit test won't 00840 // ever be executed. This manifests as 00841 // expConvTest_->getTestValue()->size() < 1. We deal with this case 00842 // by using the values returned by impConvTest_->getTestValue(). 00843 { 00844 // We'll fetch the vector of residual norms one way or the other. 00845 const std::vector<MagnitudeType>* pTestValues = NULL; 00846 if (expResTest_) { 00847 pTestValues = expConvTest_->getTestValue(); 00848 if (pTestValues == NULL || pTestValues->size() < 1) { 00849 pTestValues = impConvTest_->getTestValue(); 00850 } 00851 } 00852 else { 00853 // Only the implicit residual norm test is being used. 00854 pTestValues = impConvTest_->getTestValue(); 00855 } 00856 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error, 00857 "Belos::TFQMRSolMgr::solve(): The implicit convergence test's " 00858 "getTestValue() method returned NULL. Please report this bug to the " 00859 "Belos developers."); 00860 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error, 00861 "Belos::TMQMRSolMgr::solve(): The implicit convergence test's " 00862 "getTestValue() method returned a vector of length zero. Please report " 00863 "this bug to the Belos developers."); 00864 00865 // FIXME (mfh 12 Dec 2011) Does pTestValues really contain the 00866 // achieved tolerances for all vectors in the current solve(), or 00867 // just for the vectors from the last deflation? 00868 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end()); 00869 } 00870 00871 if (!isConverged) { 00872 return Unconverged; // return from TFQMRSolMgr::solve() 00873 } 00874 return Converged; // return from TFQMRSolMgr::solve() 00875 } 00876 00877 // This method requires the solver manager to return a std::string that describes itself. 00878 template<class ScalarType, class MV, class OP> 00879 std::string TFQMRSolMgr<ScalarType,MV,OP>::description() const 00880 { 00881 std::ostringstream oss; 00882 oss << "Belos::TFQMRSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<">"; 00883 oss << "{}"; 00884 return oss.str(); 00885 } 00886 00887 } // end Belos namespace 00888 00889 #endif /* BELOS_TFQMR_SOLMGR_HPP */
1.7.6.1