00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef BELOS_BLOCK_CG_SOLMGR_HPP
00030 #define BELOS_BLOCK_CG_SOLMGR_HPP
00031
00036 #include "BelosConfigDefs.hpp"
00037 #include "BelosTypes.hpp"
00038
00039 #include "BelosLinearProblem.hpp"
00040 #include "BelosSolverManager.hpp"
00041
00042 #include "BelosCGIter.hpp"
00043 #include "BelosBlockCGIter.hpp"
00044 #include "BelosDGKSOrthoManager.hpp"
00045 #include "BelosICGSOrthoManager.hpp"
00046 #include "BelosIMGSOrthoManager.hpp"
00047 #include "BelosStatusTestMaxIters.hpp"
00048 #include "BelosStatusTestGenResNorm.hpp"
00049 #include "BelosStatusTestCombo.hpp"
00050 #include "BelosStatusTestOutput.hpp"
00051 #include "BelosOutputManager.hpp"
00052 #include "Teuchos_BLAS.hpp"
00053 #include "Teuchos_LAPACK.hpp"
00054 #include "Teuchos_TimeMonitor.hpp"
00055
00069 namespace Belos {
00070
00072
00073
00080 class BlockCGSolMgrLinearProblemFailure : public BelosError {public:
00081 BlockCGSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg)
00082 {}};
00083
00090 class BlockCGSolMgrOrthoFailure : public BelosError {public:
00091 BlockCGSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg)
00092 {}};
00093
00094 template<class ScalarType, class MV, class OP>
00095 class BlockCGSolMgr : public SolverManager<ScalarType,MV,OP> {
00096
00097 private:
00098 typedef MultiVecTraits<ScalarType,MV> MVT;
00099 typedef OperatorTraits<ScalarType,MV,OP> OPT;
00100 typedef Teuchos::ScalarTraits<ScalarType> SCT;
00101 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00102 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
00103
00104 public:
00105
00107
00108
00114 BlockCGSolMgr();
00115
00143 BlockCGSolMgr( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00144 const Teuchos::RCP<Teuchos::ParameterList> &pl );
00145
00147 virtual ~BlockCGSolMgr() {};
00149
00151
00152
00153 const LinearProblem<ScalarType,MV,OP>& getProblem() const {
00154 return *problem_;
00155 }
00156
00159 Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const;
00160
00163 Teuchos::RCP<const Teuchos::ParameterList> getCurrentParameters() const { return params_; }
00164
00170 Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
00171 return tuple(timerSolve_);
00172 }
00173
00175 int getNumIters() const {
00176 return numIters_;
00177 }
00178
00181 bool isLOADetected() const { return false; }
00182
00184
00186
00187
00189 void setProblem( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem ) { problem_ = problem; }
00190
00192 void setParameters( const Teuchos::RCP<Teuchos::ParameterList> ¶ms );
00193
00195
00197
00198
00202 void reset( const ResetType type ) { if ((type & Belos::Problem) && !Teuchos::is_null(problem_)) problem_->setProblem(); }
00204
00206
00207
00225 ReturnType solve();
00226
00228
00231
00233 std::string description() const;
00234
00236
00237 private:
00238
00239
00240 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
00241
00242
00243 Teuchos::RCP<OutputManager<ScalarType> > printer_;
00244 Teuchos::RCP<std::ostream> outputStream_;
00245
00246
00247 Teuchos::RCP<StatusTest<ScalarType,MV,OP> > sTest_;
00248 Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxIterTest_;
00249 Teuchos::RCP<StatusTestGenResNorm<ScalarType,MV,OP> > convTest_;
00250 Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputTest_;
00251
00252
00253 Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho_;
00254
00255
00256 Teuchos::RCP<ParameterList> params_;
00257
00258
00259 static const MagnitudeType convtol_default_;
00260 static const MagnitudeType orthoKappa_default_;
00261 static const int maxIters_default_;
00262 static const bool adaptiveBlockSize_default_;
00263 static const bool showMaxResNormOnly_default_;
00264 static const int blockSize_default_;
00265 static const int verbosity_default_;
00266 static const int outputFreq_default_;
00267 static const std::string label_default_;
00268 static const std::string orthoType_default_;
00269 static const Teuchos::RCP<std::ostream> outputStream_default_;
00270
00271
00272 MagnitudeType convtol_, orthoKappa_;
00273 int maxIters_, numIters_;
00274 int blockSize_, verbosity_, outputFreq_;
00275 bool adaptiveBlockSize_, showMaxResNormOnly_;
00276 std::string orthoType_;
00277
00278
00279 std::string label_;
00280 Teuchos::RCP<Teuchos::Time> timerSolve_;
00281
00282
00283 bool isSet_;
00284 };
00285
00286
00287
00288 template<class ScalarType, class MV, class OP>
00289 const typename Teuchos::ScalarTraits<ScalarType>::magnitudeType BlockCGSolMgr<ScalarType,MV,OP>::convtol_default_ = 1e-8;
00290
00291 template<class ScalarType, class MV, class OP>
00292 const typename Teuchos::ScalarTraits<ScalarType>::magnitudeType BlockCGSolMgr<ScalarType,MV,OP>::orthoKappa_default_ = -1.0;
00293
00294 template<class ScalarType, class MV, class OP>
00295 const int BlockCGSolMgr<ScalarType,MV,OP>::maxIters_default_ = 1000;
00296
00297 template<class ScalarType, class MV, class OP>
00298 const bool BlockCGSolMgr<ScalarType,MV,OP>::adaptiveBlockSize_default_ = true;
00299
00300 template<class ScalarType, class MV, class OP>
00301 const bool BlockCGSolMgr<ScalarType,MV,OP>::showMaxResNormOnly_default_ = false;
00302
00303 template<class ScalarType, class MV, class OP>
00304 const int BlockCGSolMgr<ScalarType,MV,OP>::blockSize_default_ = 1;
00305
00306 template<class ScalarType, class MV, class OP>
00307 const int BlockCGSolMgr<ScalarType,MV,OP>::verbosity_default_ = Belos::Errors;
00308
00309 template<class ScalarType, class MV, class OP>
00310 const int BlockCGSolMgr<ScalarType,MV,OP>::outputFreq_default_ = -1;
00311
00312 template<class ScalarType, class MV, class OP>
00313 const std::string BlockCGSolMgr<ScalarType,MV,OP>::label_default_ = "Belos";
00314
00315 template<class ScalarType, class MV, class OP>
00316 const std::string BlockCGSolMgr<ScalarType,MV,OP>::orthoType_default_ = "DGKS";
00317
00318 template<class ScalarType, class MV, class OP>
00319 const Teuchos::RCP<std::ostream> BlockCGSolMgr<ScalarType,MV,OP>::outputStream_default_ = Teuchos::rcp(&std::cout,false);
00320
00321
00322
00323 template<class ScalarType, class MV, class OP>
00324 BlockCGSolMgr<ScalarType,MV,OP>::BlockCGSolMgr() :
00325 outputStream_(outputStream_default_),
00326 convtol_(convtol_default_),
00327 orthoKappa_(orthoKappa_default_),
00328 maxIters_(maxIters_default_),
00329 blockSize_(blockSize_default_),
00330 verbosity_(verbosity_default_),
00331 outputFreq_(outputFreq_default_),
00332 adaptiveBlockSize_(adaptiveBlockSize_default_),
00333 showMaxResNormOnly_(showMaxResNormOnly_default_),
00334 orthoType_(orthoType_default_),
00335 label_(label_default_),
00336 isSet_(false)
00337 {}
00338
00339
00340
00341 template<class ScalarType, class MV, class OP>
00342 BlockCGSolMgr<ScalarType,MV,OP>::BlockCGSolMgr(
00343 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > &problem,
00344 const Teuchos::RCP<Teuchos::ParameterList> &pl ) :
00345 problem_(problem),
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 outputFreq_(outputFreq_default_),
00353 adaptiveBlockSize_(adaptiveBlockSize_default_),
00354 showMaxResNormOnly_(showMaxResNormOnly_default_),
00355 orthoType_(orthoType_default_),
00356 label_(label_default_),
00357 isSet_(false)
00358 {
00359 TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
00360
00361
00362 if ( !is_null(pl) ) {
00363 setParameters( pl );
00364 }
00365 }
00366
00367 template<class ScalarType, class MV, class OP>
00368 void BlockCGSolMgr<ScalarType,MV,OP>::setParameters( const Teuchos::RCP<Teuchos::ParameterList> ¶ms )
00369 {
00370
00371 if (params_ == Teuchos::null) {
00372 params_ = Teuchos::rcp( new Teuchos::ParameterList(*getValidParameters()) );
00373 }
00374 else {
00375 params->validateParameters(*getValidParameters());
00376 }
00377
00378
00379 if (params->isParameter("Maximum Iterations")) {
00380 maxIters_ = params->get("Maximum Iterations",maxIters_default_);
00381
00382
00383 params_->set("Maximum Iterations", maxIters_);
00384 if (maxIterTest_!=Teuchos::null)
00385 maxIterTest_->setMaxIters( maxIters_ );
00386 }
00387
00388
00389 if (params->isParameter("Block Size")) {
00390 blockSize_ = params->get("Block Size",blockSize_default_);
00391 TEST_FOR_EXCEPTION(blockSize_ <= 0, std::invalid_argument,
00392 "Belos::BlockCGSolMgr: \"Block Size\" must be strictly positive.");
00393
00394
00395 params_->set("Block Size", blockSize_);
00396 }
00397
00398
00399 if (params->isParameter("Adapative Block Size")) {
00400 adaptiveBlockSize_ = params->get("Adaptive Block Size",adaptiveBlockSize_default_);
00401
00402
00403 params_->set("Adaptive Block Size", adaptiveBlockSize_);
00404 }
00405
00406
00407 if (params->isParameter("Timer Label")) {
00408 std::string tempLabel = params->get("Timer Label", label_default_);
00409
00410
00411 if (tempLabel != label_) {
00412 label_ = tempLabel;
00413 params_->set("Timer Label", label_);
00414 std::string solveLabel = label_ + ": BlockCGSolMgr total solve time";
00415 timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00416 }
00417 }
00418
00419
00420 if (params->isParameter("Orthogonalization")) {
00421 std::string tempOrthoType = params->get("Orthogonalization",orthoType_default_);
00422 TEST_FOR_EXCEPTION( tempOrthoType != "DGKS" && tempOrthoType != "ICGS" && tempOrthoType != "IMGS",
00423 std::invalid_argument,
00424 "Belos::BlockCGSolMgr: \"Orthogonalization\" must be either \"DGKS\", \"ICGS\", or \"IMGS\".");
00425 if (tempOrthoType != orthoType_) {
00426 orthoType_ = tempOrthoType;
00427
00428 if (orthoType_=="DGKS") {
00429 if (orthoKappa_ <= 0) {
00430 ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
00431 }
00432 else {
00433 ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
00434 Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
00435 }
00436 }
00437 else if (orthoType_=="ICGS") {
00438 ortho_ = Teuchos::rcp( new ICGSOrthoManager<ScalarType,MV,OP>( label_ ) );
00439 }
00440 else if (orthoType_=="IMGS") {
00441 ortho_ = Teuchos::rcp( new IMGSOrthoManager<ScalarType,MV,OP>( label_ ) );
00442 }
00443 }
00444 }
00445
00446
00447 if (params->isParameter("Orthogonalization Constant")) {
00448 orthoKappa_ = params->get("Orthogonalization Constant",orthoKappa_default_);
00449
00450
00451 params_->set("Orthogonalization Constant",orthoKappa_);
00452 if (orthoType_=="DGKS") {
00453 if (orthoKappa_ > 0 && ortho_ != Teuchos::null) {
00454 Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
00455 }
00456 }
00457 }
00458
00459
00460 if (params->isParameter("Verbosity")) {
00461 if (Teuchos::isParameterType<int>(*params,"Verbosity")) {
00462 verbosity_ = params->get("Verbosity", verbosity_default_);
00463 } else {
00464 verbosity_ = (int)Teuchos::getParameter<Belos::MsgType>(*params,"Verbosity");
00465 }
00466
00467
00468 params_->set("Verbosity", verbosity_);
00469 if (printer_ != Teuchos::null)
00470 printer_->setVerbosity(verbosity_);
00471 }
00472
00473
00474 if (params->isParameter("Output Stream")) {
00475 outputStream_ = Teuchos::getParameter<Teuchos::RCP<std::ostream> >(*params,"Output Stream");
00476
00477
00478 params_->set("Output Stream", outputStream_);
00479 if (printer_ != Teuchos::null)
00480 printer_->setOStream( outputStream_ );
00481 }
00482
00483
00484 if (verbosity_ & Belos::StatusTestDetails) {
00485 if (params->isParameter("Output Frequency")) {
00486 outputFreq_ = params->get("Output Frequency", outputFreq_default_);
00487 }
00488
00489
00490 params_->set("Output Frequency", outputFreq_);
00491 if (outputTest_ != Teuchos::null)
00492 outputTest_->setOutputFrequency( outputFreq_ );
00493 }
00494
00495
00496 if (printer_ == Teuchos::null) {
00497 printer_ = Teuchos::rcp( new OutputManager<ScalarType>(verbosity_, outputStream_) );
00498 }
00499
00500
00501 typedef Belos::StatusTestCombo<ScalarType,MV,OP> StatusTestCombo_t;
00502 typedef Belos::StatusTestGenResNorm<ScalarType,MV,OP> StatusTestResNorm_t;
00503
00504
00505 if (params->isParameter("Convergence Tolerance")) {
00506 convtol_ = params->get("Convergence Tolerance",convtol_default_);
00507
00508
00509 params_->set("Convergence Tolerance", convtol_);
00510 if (convTest_ != Teuchos::null)
00511 convTest_->setTolerance( convtol_ );
00512 }
00513
00514 if (params->isParameter("Show Maximum Residual Norm Only")) {
00515 showMaxResNormOnly_ = Teuchos::getParameter<bool>(*params,"Show Maximum Residual Norm Only");
00516
00517
00518 params_->set("Show Maximum Residual Norm Only", showMaxResNormOnly_);
00519 if (convTest_ != Teuchos::null)
00520 convTest_->setShowMaxResNormOnly( showMaxResNormOnly_ );
00521 }
00522
00523
00524
00525
00526 if (maxIterTest_ == Teuchos::null)
00527 maxIterTest_ = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>( maxIters_ ) );
00528
00529
00530 if (convTest_ == Teuchos::null)
00531 convTest_ = Teuchos::rcp( new StatusTestResNorm_t( convtol_, 1 ) );
00532
00533 if (sTest_ == Teuchos::null)
00534 sTest_ = Teuchos::rcp( new StatusTestCombo_t( StatusTestCombo_t::OR, maxIterTest_, convTest_ ) );
00535
00536 if (outputTest_ == Teuchos::null) {
00537 if (outputFreq_ > 0) {
00538 outputTest_ = Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer_,
00539 sTest_,
00540 outputFreq_,
00541 Passed+Failed+Undefined ) );
00542 }
00543 else {
00544 outputTest_ = Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer_,
00545 sTest_, 1 ) );
00546 }
00547 }
00548
00549
00550 if (ortho_ == Teuchos::null) {
00551 if (orthoType_=="DGKS") {
00552 if (orthoKappa_ <= 0) {
00553 ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
00554 }
00555 else {
00556 ortho_ = Teuchos::rcp( new DGKSOrthoManager<ScalarType,MV,OP>( label_ ) );
00557 Teuchos::rcp_dynamic_cast<DGKSOrthoManager<ScalarType,MV,OP> >(ortho_)->setDepTol( orthoKappa_ );
00558 }
00559 }
00560 else if (orthoType_=="ICGS") {
00561 ortho_ = Teuchos::rcp( new ICGSOrthoManager<ScalarType,MV,OP>( label_ ) );
00562 }
00563 else if (orthoType_=="IMGS") {
00564 ortho_ = Teuchos::rcp( new IMGSOrthoManager<ScalarType,MV,OP>( label_ ) );
00565 }
00566 else {
00567 TEST_FOR_EXCEPTION(orthoType_!="ICGS"&&orthoType_!="DGKS"&&orthoType_!="IMGS",std::logic_error,
00568 "Belos::BlockCGSolMgr(): Invalid orthogonalization type.");
00569 }
00570 }
00571
00572
00573 if (timerSolve_ == Teuchos::null) {
00574 std::string solveLabel = label_ + ": BlockCGSolMgr total solve time";
00575 timerSolve_ = Teuchos::TimeMonitor::getNewTimer(solveLabel);
00576 }
00577
00578
00579 isSet_ = true;
00580 }
00581
00582
00583 template<class ScalarType, class MV, class OP>
00584 Teuchos::RCP<const Teuchos::ParameterList>
00585 BlockCGSolMgr<ScalarType,MV,OP>::getValidParameters() const
00586 {
00587 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
00588
00589
00590 if(is_null(validPL)) {
00591 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
00592 pl->set("Convergence Tolerance", convtol_default_,
00593 "The relative residual tolerance that needs to be achieved by the\n"
00594 "iterative solver in order for the linear system to be declared converged.");
00595 pl->set("Maximum Iterations", maxIters_default_,
00596 "The maximum number of block iterations allowed for each\n"
00597 "set of RHS solved.");
00598 pl->set("Block Size", blockSize_default_,
00599 "The number of vectors in each block.");
00600 pl->set("Adaptive Block Size", adaptiveBlockSize_default_,
00601 "Whether the solver manager should adapt to the block size\n"
00602 "based on the number of RHS to solve.");
00603 pl->set("Verbosity", verbosity_default_,
00604 "What type(s) of solver information should be outputted\n"
00605 "to the output stream.");
00606 pl->set("Output Frequency", outputFreq_default_,
00607 "How often convergence information should be outputted\n"
00608 "to the output stream.");
00609 pl->set("Output Stream", outputStream_default_,
00610 "A reference-counted pointer to the output stream where all\n"
00611 "solver output is sent.");
00612 pl->set("Show Maximum Residual Norm Only", showMaxResNormOnly_default_,
00613 "When convergence information is printed, only show the maximum\n"
00614 "relative residual norm when the block size is greater than one.");
00615 pl->set("Timer Label", label_default_,
00616 "The string to use as a prefix for the timer labels.");
00617
00618 pl->set("Orthogonalization", orthoType_default_,
00619 "The type of orthogonalization to use: DGKS, ICGS, or IMGS.");
00620 pl->set("Orthogonalization Constant",orthoKappa_default_,
00621 "The constant used by DGKS orthogonalization to determine\n"
00622 "whether another step of classical Gram-Schmidt is necessary.");
00623 validPL = pl;
00624 }
00625 return validPL;
00626 }
00627
00628
00629
00630 template<class ScalarType, class MV, class OP>
00631 ReturnType BlockCGSolMgr<ScalarType,MV,OP>::solve() {
00632
00633
00634
00635
00636 if (!isSet_) {
00637 setParameters(Teuchos::parameterList(*getValidParameters()));
00638 }
00639
00640 Teuchos::BLAS<int,ScalarType> blas;
00641 Teuchos::LAPACK<int,ScalarType> lapack;
00642
00643 TEST_FOR_EXCEPTION(!problem_->isProblemSet(),BlockCGSolMgrLinearProblemFailure,
00644 "Belos::BlockCGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
00645
00646
00647 int startPtr = 0;
00648 int numRHS2Solve = MVT::GetNumberVecs( *(problem_->getRHS()) );
00649 int numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
00650
00651 std::vector<int> currIdx, currIdx2;
00652
00653
00654 if ( adaptiveBlockSize_ ) {
00655 blockSize_ = numCurrRHS;
00656 currIdx.resize( numCurrRHS );
00657 currIdx2.resize( numCurrRHS );
00658 for (int i=0; i<numCurrRHS; ++i)
00659 { currIdx[i] = startPtr+i; currIdx2[i]=i; }
00660
00661 }
00662 else {
00663 currIdx.resize( blockSize_ );
00664 currIdx2.resize( blockSize_ );
00665 for (int i=0; i<numCurrRHS; ++i)
00666 { currIdx[i] = startPtr+i; currIdx2[i]=i; }
00667 for (int i=numCurrRHS; i<blockSize_; ++i)
00668 { currIdx[i] = -1; currIdx2[i] = i; }
00669 }
00670
00671
00672 problem_->setLSIndex( currIdx );
00673
00675
00676 Teuchos::ParameterList plist;
00677 plist.set("Block Size",blockSize_);
00678
00679
00680 outputTest_->reset();
00681
00682
00683 bool isConverged = true;
00684
00686
00687
00688 Teuchos::RCP<CGIteration<ScalarType,MV,OP> > block_cg_iter;
00689 if (blockSize_ == 1)
00690 block_cg_iter = Teuchos::rcp( new CGIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,plist) );
00691 else
00692 block_cg_iter = Teuchos::rcp( new BlockCGIter<ScalarType,MV,OP>(problem_,printer_,outputTest_,ortho_,plist) );
00693
00694
00695
00696 {
00697 Teuchos::TimeMonitor slvtimer(*timerSolve_);
00698
00699 while ( numRHS2Solve > 0 ) {
00700
00701
00702 std::vector<int> convRHSIdx;
00703 std::vector<int> currRHSIdx( currIdx );
00704 currRHSIdx.resize(numCurrRHS);
00705
00706
00707 block_cg_iter->resetNumIters();
00708
00709
00710 outputTest_->resetNumCalls();
00711
00712
00713 Teuchos::RCP<MV> R_0 = MVT::CloneView( *(Teuchos::rcp_const_cast<MV>(problem_->getInitResVec())), currIdx );
00714
00715
00716 CGIterationState<ScalarType,MV> newstate;
00717 newstate.R = R_0;
00718 block_cg_iter->initializeCG(newstate);
00719
00720 while(1) {
00721
00722
00723 try {
00724 block_cg_iter->iterate();
00725
00727
00728
00729
00731 if ( convTest_->getStatus() == Passed ) {
00732
00733
00734
00735 std::vector<int> convIdx = Teuchos::rcp_dynamic_cast<StatusTestGenResNorm<ScalarType,MV,OP> >(convTest_)->convIndices();
00736
00737
00738
00739 if (convIdx.size() == currRHSIdx.size())
00740 break;
00741
00742
00743 problem_->setCurrLS();
00744
00745
00746 int have = 0;
00747 std::vector<int> unconvIdx(currRHSIdx.size());
00748 for (unsigned int i=0; i<currRHSIdx.size(); ++i) {
00749 bool found = false;
00750 for (unsigned int j=0; j<convIdx.size(); ++j) {
00751 if (currRHSIdx[i] == convIdx[j]) {
00752 found = true;
00753 break;
00754 }
00755 }
00756 if (!found) {
00757 currIdx2[have] = currIdx2[i];
00758 currRHSIdx[have++] = currRHSIdx[i];
00759 }
00760 else {
00761 }
00762 }
00763 currRHSIdx.resize(have);
00764 currIdx2.resize(have);
00765
00766
00767 problem_->setLSIndex( currRHSIdx );
00768
00769
00770 std::vector<MagnitudeType> norms;
00771 R_0 = MVT::CloneCopy( *(block_cg_iter->getNativeResiduals(&norms)),currIdx2 );
00772 for (int i=0; i<have; ++i) { currIdx2[i] = i; }
00773
00774
00775 block_cg_iter->setBlockSize( have );
00776
00777
00778 CGIterationState<ScalarType,MV> defstate;
00779 defstate.R = R_0;
00780 block_cg_iter->initializeCG(defstate);
00781 }
00783
00784
00785
00787 else if ( maxIterTest_->getStatus() == Passed ) {
00788
00789 isConverged = false;
00790 break;
00791 }
00792
00794
00795
00796
00797
00799
00800 else {
00801 TEST_FOR_EXCEPTION(true,std::logic_error,
00802 "Belos::BlockCGSolMgr::solve(): Invalid return from CGIteration::iterate().");
00803 }
00804 }
00805 catch (const std::exception &e) {
00806 printer_->stream(Errors) << "Error! Caught std::exception in CGIteration::iterate() at iteration "
00807 << block_cg_iter->getNumIters() << std::endl
00808 << e.what() << std::endl;
00809 throw;
00810 }
00811 }
00812
00813
00814 problem_->setCurrLS();
00815
00816
00817 startPtr += numCurrRHS;
00818 numRHS2Solve -= numCurrRHS;
00819 if ( numRHS2Solve > 0 ) {
00820 numCurrRHS = ( numRHS2Solve < blockSize_) ? numRHS2Solve : blockSize_;
00821
00822 if ( adaptiveBlockSize_ ) {
00823 blockSize_ = numCurrRHS;
00824 currIdx.resize( numCurrRHS );
00825 currIdx2.resize( numCurrRHS );
00826 for (int i=0; i<numCurrRHS; ++i)
00827 { currIdx[i] = startPtr+i; currIdx2[i] = i; }
00828 }
00829 else {
00830 currIdx.resize( blockSize_ );
00831 currIdx2.resize( blockSize_ );
00832 for (int i=0; i<numCurrRHS; ++i)
00833 { currIdx[i] = startPtr+i; currIdx2[i] = i; }
00834 for (int i=numCurrRHS; i<blockSize_; ++i)
00835 { currIdx[i] = -1; currIdx2[i] = i; }
00836 }
00837
00838 problem_->setLSIndex( currIdx );
00839
00840
00841 block_cg_iter->setBlockSize( blockSize_ );
00842 }
00843 else {
00844 currIdx.resize( numRHS2Solve );
00845 }
00846
00847 }
00848
00849 }
00850
00851
00852 sTest_->print( printer_->stream(FinalSummary) );
00853
00854
00855 Teuchos::TimeMonitor::summarize( printer_->stream(TimingDetails) );
00856
00857
00858 numIters_ = maxIterTest_->getNumIters();
00859
00860 if (!isConverged) {
00861 return Unconverged;
00862 }
00863 return Converged;
00864 }
00865
00866
00867 template<class ScalarType, class MV, class OP>
00868 std::string BlockCGSolMgr<ScalarType,MV,OP>::description() const
00869 {
00870 std::ostringstream oss;
00871 oss << "Belos::BlockCGSolMgr<...,"<<Teuchos::ScalarTraits<ScalarType>::name()<<">";
00872 oss << "{";
00873 oss << "Ortho Type='"<<orthoType_<<"\', Block Size=" << blockSize_;
00874 oss << "}";
00875 return oss.str();
00876 }
00877
00878 }
00879
00880 #endif