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