1029 Teuchos::LAPACK<int,ScalarType> lapack;
1030 std::vector<int> index(recycleBlocks_);
1031 ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
1032 ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
1045 "Belos::RCGSolMgr::solve(): Linear problem is not a valid object.");
1047 "Belos::RCGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called.");
1048 TEUCHOS_TEST_FOR_EXCEPTION((problem_->getLeftPrec() != Teuchos::null)&&(problem_->getRightPrec() != Teuchos::null),
1050 "Belos::RCGSolMgr::solve(): RCG does not support split preconditioning, only set left or right preconditioner.");
1053 Teuchos::RCP<OP> precObj;
1054 if (problem_->getLeftPrec() != Teuchos::null) {
1055 precObj = Teuchos::rcp_const_cast<OP>(problem_->getLeftPrec());
1057 else if (problem_->getRightPrec() != Teuchos::null) {
1058 precObj = Teuchos::rcp_const_cast<OP>(problem_->getRightPrec());
1063 std::vector<int> currIdx(1);
1067 problem_->setLSIndex( currIdx );
1071 if (numBlocks_ > dim) {
1072 numBlocks_ = Teuchos::asSafe<int>(dim);
1073 params_->set(
"Num Blocks", numBlocks_);
1075 "Warning! Requested Krylov subspace dimension is larger than operator dimension!" << std::endl <<
1076 " The maximum number of blocks allowed for the Krylov subspace will be adjusted to " << numBlocks_ << std::endl;
1080 initializeStateStorage();
1083 Teuchos::ParameterList plist;
1084 plist.set(
"Num Blocks",numBlocks_);
1085 plist.set(
"Recycled Blocks",recycleBlocks_);
1088 outputTest_->reset();
1091 bool isConverged =
true;
1095 index.resize(recycleBlocks_);
1096 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1098 index.resize(recycleBlocks_);
1099 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1102 problem_->applyOp( *Utmp, *AUtmp );
1104 Teuchos::SerialDenseMatrix<int,ScalarType> UTAUtmp( Teuchos::View, *UTAU_, recycleBlocks_, recycleBlocks_ );
1107 Teuchos::SerialDenseMatrix<int,ScalarType> AUTAUtmp( Teuchos::View, *AUTAU_, recycleBlocks_, recycleBlocks_ );
1108 if ( precObj != Teuchos::null ) {
1109 index.resize(recycleBlocks_);
1110 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1111 index.resize(recycleBlocks_);
1112 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1124 Teuchos::RCP<RCGIter<ScalarType,MV,OP> > rcg_iter;
1129#ifdef BELOS_TEUCHOS_TIME_MONITOR
1130 Teuchos::TimeMonitor slvtimer(*timerSolve_);
1133 while ( numRHS2Solve > 0 ) {
1136 if (printer_->isVerbosity(
Debug ) ) {
1137 if (existU_) printer_->print(
Debug,
"Using recycle space generated from previous call to solve()." );
1138 else printer_->print(
Debug,
"No recycle space exists." );
1142 rcg_iter->resetNumIters();
1145 rcg_iter->setSize( recycleBlocks_, numBlocks_ );
1148 outputTest_->resetNumCalls();
1157 problem_->computeCurrResVec( &*r_ );
1162 Teuchos::SerialDenseMatrix<int,ScalarType> Utr(recycleBlocks_,1);
1163 index.resize(recycleBlocks_);
1164 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1167 Teuchos::SerialDenseMatrix<int,ScalarType> UTAUtmp( Teuchos::View, *UTAU_, recycleBlocks_, recycleBlocks_ );
1168 Teuchos::SerialDenseMatrix<int,ScalarType> LUUTAUtmp( Teuchos::View, *LUUTAU_, recycleBlocks_, recycleBlocks_ );
1169 LUUTAUtmp.assign(UTAUtmp);
1171 lapack.GESV(recycleBlocks_, 1, LUUTAUtmp.values(), LUUTAUtmp.stride(), &(*ipiv_)[0], Utr.values(), Utr.stride(), &info);
1173 "Belos::RCGSolMgr::solve(): LAPACK GESV failed to compute a solution.");
1179 index.resize(recycleBlocks_);
1180 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1185 if ( precObj != Teuchos::null ) {
1196 Teuchos::SerialDenseMatrix<int,ScalarType> mu( Teuchos::View, *Delta_, recycleBlocks_, 1);
1197 index.resize(recycleBlocks_);
1198 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1201 Teuchos::SerialDenseMatrix<int,ScalarType> LUUTAUtmp( Teuchos::View, *LUUTAU_, recycleBlocks_, recycleBlocks_ );
1204 lapack.GETRS(
TRANS, recycleBlocks_, 1, LUUTAUtmp.values(), LUUTAUtmp.stride(), &(*ipiv_)[0], mu.values(), mu.stride(), &info );
1206 "Belos::RCGSolMgr::solve(): LAPACK GETRS failed to compute a solution.");
1225 index.resize( numBlocks_+1 );
1226 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii; }
1228 index.resize( recycleBlocks_ );
1229 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1231 index.resize( recycleBlocks_ );
1232 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1234 newstate.
Alpha = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *Alpha_, numBlocks_, 1 ) );
1235 newstate.
Beta = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *Beta_, numBlocks_, 1 ) );
1236 newstate.
D = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *D_, numBlocks_, 1 ) );
1237 newstate.
Delta = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *Delta_, recycleBlocks_, numBlocks_, 0, 1 ) );
1238 newstate.
LUUTAU = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *LUUTAU_, recycleBlocks_, recycleBlocks_ ) );
1244 newstate.
existU = existU_;
1245 newstate.
ipiv = ipiv_;
1248 rcg_iter->initialize(newstate);
1254 rcg_iter->iterate();
1261 if ( convTest_->getStatus() ==
Passed ) {
1270 else if ( maxIterTest_->getStatus() ==
Passed ) {
1272 isConverged =
false;
1280 else if ( rcg_iter->getCurSubspaceDim() == rcg_iter->getMaxSubspaceDim() ) {
1285 if (recycleBlocks_ > 0) {
1289 Teuchos::SerialDenseMatrix<int,ScalarType> Ftmp( Teuchos::View, *F_, numBlocks_, numBlocks_ );
1290 Teuchos::SerialDenseMatrix<int,ScalarType> Gtmp( Teuchos::View, *G_, numBlocks_, numBlocks_ );
1291 Teuchos::SerialDenseMatrix<int,ScalarType> Dtmp( Teuchos::View, *D_, numBlocks_, 1 );
1292 Teuchos::SerialDenseMatrix<int,ScalarType> Alphatmp( Teuchos::View, *Alpha_, numBlocks_, 1 );
1293 Teuchos::SerialDenseMatrix<int,ScalarType> Betatmp( Teuchos::View, *Beta_, numBlocks_, 1 );
1294 Ftmp.putScalar(zero);
1295 Gtmp.putScalar(zero);
1296 for (
int ii=0;ii<numBlocks_;ii++) {
1297 Gtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii,0));
1299 Gtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1300 Gtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1302 Ftmp(ii,ii) = Dtmp(ii,0);
1306 Teuchos::SerialDenseMatrix<int,ScalarType> Ytmp( Teuchos::View, *Y_, numBlocks_, recycleBlocks_ );
1307 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1310 index.resize( numBlocks_ );
1311 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii; }
1313 index.resize( recycleBlocks_ );
1314 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1321 Teuchos::SerialDenseMatrix<int,ScalarType> GYtmp( Teuchos::View, *GY_, numBlocks_, recycleBlocks_ );
1322 GYtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Gtmp,Ytmp,zero);
1323 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TAU1tmp( Teuchos::View, *AU1TAU1_, recycleBlocks_, recycleBlocks_ );
1324 AU1TAU1tmp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Ytmp,GYtmp,zero);
1327 Teuchos::SerialDenseMatrix<int,ScalarType> FYtmp( Teuchos::View, *FY_, numBlocks_, recycleBlocks_ );
1328 FYtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Ftmp,Ytmp,zero);
1329 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TU1tmp( Teuchos::View, *AU1TU1_, recycleBlocks_, recycleBlocks_ );
1330 AU1TU1tmp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Ytmp,FYtmp,zero);
1332 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TAPtmp( Teuchos::View, *AU1TAP_, recycleBlocks_, 1 );
1334 AU1TAPtmp.putScalar(zero);
1336 ScalarType alphatmp = -1.0 / Alphatmp(numBlocks_-1,0);
1337 for (
int ii=0; ii<recycleBlocks_; ++ii) {
1338 AU1TAPtmp(ii,0) = Ytmp(numBlocks_-1,ii) * alphatmp;
1346 lastBeta = numBlocks_-1;
1353 Teuchos::SerialDenseMatrix<int,ScalarType> Dtmp( Teuchos::View, *D_, numBlocks_, 1 );
1354 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TAPtmp( Teuchos::View, *AU1TAP_, recycleBlocks_, numBlocks_ );
1355 AU1TAPtmp.scale(Dtmp(0,0));
1357 Teuchos::SerialDenseMatrix<int,ScalarType> Alphatmp( Teuchos::View, *Alpha_, numBlocks_, 1 );
1358 Teuchos::SerialDenseMatrix<int,ScalarType> Betatmp( Teuchos::View, *Beta_, numBlocks_+1, 1 );
1359 Teuchos::SerialDenseMatrix<int,ScalarType> APTAPtmp( Teuchos::View, *APTAP_, numBlocks_, numBlocks_ );
1360 APTAPtmp.putScalar(zero);
1361 for (
int ii=0; ii<numBlocks_; ii++) {
1362 APTAPtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii+1,0));
1364 APTAPtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1365 APTAPtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1370 Teuchos::SerialDenseMatrix<int,ScalarType> Ftmp( Teuchos::View, *F_, (numBlocks_+recycleBlocks_), (numBlocks_+recycleBlocks_) );
1371 Teuchos::SerialDenseMatrix<int,ScalarType> F11( Teuchos::View, *F_, recycleBlocks_, recycleBlocks_ );
1372 Teuchos::SerialDenseMatrix<int,ScalarType> F12( Teuchos::View, *F_, recycleBlocks_, numBlocks_, 0, recycleBlocks_ );
1373 Teuchos::SerialDenseMatrix<int,ScalarType> F21( Teuchos::View, *F_, numBlocks_, recycleBlocks_, recycleBlocks_, 0 );
1374 Teuchos::SerialDenseMatrix<int,ScalarType> F22( Teuchos::View, *F_, numBlocks_, numBlocks_, recycleBlocks_, recycleBlocks_ );
1375 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TU1tmp( Teuchos::View, *AU1TU1_, recycleBlocks_, recycleBlocks_ );
1376 F11.assign(AU1TU1tmp);
1377 F12.putScalar(zero);
1378 F21.putScalar(zero);
1379 F22.putScalar(zero);
1380 for(
int ii=0;ii<numBlocks_;ii++) {
1381 F22(ii,ii) = Dtmp(ii,0);
1385 Teuchos::SerialDenseMatrix<int,ScalarType> Gtmp( Teuchos::View, *G_, (numBlocks_+recycleBlocks_), (numBlocks_+recycleBlocks_) );
1386 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TAU1tmp( Teuchos::View, *AU1TAU1_, recycleBlocks_, recycleBlocks_ );
1387 Teuchos::SerialDenseMatrix<int,ScalarType> G11( Teuchos::View, *G_, recycleBlocks_, recycleBlocks_ );
1388 Teuchos::SerialDenseMatrix<int,ScalarType> G12( Teuchos::View, *G_, recycleBlocks_, numBlocks_, 0, recycleBlocks_ );
1389 Teuchos::SerialDenseMatrix<int,ScalarType> G21( Teuchos::View, *G_, numBlocks_, recycleBlocks_, recycleBlocks_, 0 );
1390 Teuchos::SerialDenseMatrix<int,ScalarType> G22( Teuchos::View, *G_, numBlocks_, numBlocks_, recycleBlocks_, recycleBlocks_ );
1391 G11.assign(AU1TAU1tmp);
1392 G12.assign(AU1TAPtmp);
1394 for (
int ii=0;ii<recycleBlocks_;++ii)
1395 for (
int jj=0;jj<numBlocks_;++jj)
1396 G21(jj,ii) = G12(ii,jj);
1397 G22.assign(APTAPtmp);
1400 Teuchos::SerialDenseMatrix<int,ScalarType> Ytmp( Teuchos::View, *Y_, (recycleBlocks_+numBlocks_), recycleBlocks_ );
1401 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1404 index.resize( numBlocks_ );
1405 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii+1; }
1407 index.resize( recycleBlocks_ );
1408 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1410 Teuchos::SerialDenseMatrix<int,ScalarType> Y2( Teuchos::View, *Y_, numBlocks_, recycleBlocks_, recycleBlocks_, 0 );
1411 index.resize( recycleBlocks_ );
1412 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1414 index.resize( recycleBlocks_ );
1415 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1417 Teuchos::SerialDenseMatrix<int,ScalarType> Y1( Teuchos::View, *Y_, recycleBlocks_, recycleBlocks_ );
1425 Teuchos::SerialDenseMatrix<int,ScalarType> GYtmp( Teuchos::View, *GY_, (numBlocks_+recycleBlocks_), recycleBlocks_ );
1426 GYtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Gtmp,Ytmp,zero);
1427 AU1TAU1tmp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Ytmp,GYtmp,zero);
1431 AU1TAPtmp.putScalar(zero);
1432 ScalarType alphatmp = -1.0 / Alphatmp(numBlocks_-1,0);
1433 for (
int ii=0; ii<recycleBlocks_; ++ii) {
1434 AU1TAPtmp(ii,0) = Ytmp(numBlocks_+recycleBlocks_-1,ii) * alphatmp;
1438 Teuchos::SerialDenseMatrix<int,ScalarType> FYtmp( Teuchos::View, *FY_, (numBlocks_+recycleBlocks_), recycleBlocks_ );
1439 FYtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Ftmp,Ytmp,zero);
1441 AU1TU1tmp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Ytmp,FYtmp,zero);
1444 lastp = numBlocks_+1;
1445 lastBeta = numBlocks_;
1451 Teuchos::SerialDenseMatrix<int,ScalarType> Alphatmp( Teuchos::View, *Alpha_, numBlocks_, 1 );
1452 Teuchos::SerialDenseMatrix<int,ScalarType> Betatmp( Teuchos::View, *Beta_, numBlocks_, 1 );
1453 Teuchos::SerialDenseMatrix<int,ScalarType> Dtmp( Teuchos::View, *D_, numBlocks_, 1 );
1454 Teuchos::SerialDenseMatrix<int,ScalarType> APTAPtmp( Teuchos::View, *APTAP_, numBlocks_, numBlocks_ );
1455 APTAPtmp.putScalar(zero);
1456 for (
int ii=0; ii<numBlocks_; ii++) {
1457 APTAPtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii,0));
1459 APTAPtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1460 APTAPtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1464 Teuchos::SerialDenseMatrix<int,ScalarType> L2tmp( Teuchos::View, *L2_, numBlocks_+1, numBlocks_ );
1465 L2tmp.putScalar(zero);
1466 for(
int ii=0;ii<numBlocks_;ii++) {
1467 L2tmp(ii,ii) = 1./Alphatmp(ii,0);
1468 L2tmp(ii+1,ii) = -1./Alphatmp(ii,0);
1472 Teuchos::SerialDenseMatrix<int,ScalarType> AUTAPtmp( Teuchos::View, *AUTAP_, recycleBlocks_, numBlocks_ );
1473 Teuchos::SerialDenseMatrix<int,ScalarType> UTAUtmp( Teuchos::View, *UTAU_, recycleBlocks_, recycleBlocks_ );
1474 Teuchos::SerialDenseMatrix<int,ScalarType> Deltatmp( Teuchos::View, *Delta_, recycleBlocks_, numBlocks_+1 );
1475 Teuchos::SerialDenseMatrix<int,ScalarType> DeltaL2tmp( Teuchos::View, *DeltaL2_, recycleBlocks_, numBlocks_ );
1476 DeltaL2tmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Deltatmp,L2tmp,zero);
1477 AUTAPtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,UTAUtmp,DeltaL2tmp,zero);
1480 Teuchos::SerialDenseMatrix<int,ScalarType> Ftmp( Teuchos::View, *F_, (numBlocks_+recycleBlocks_), (numBlocks_+recycleBlocks_) );
1481 Teuchos::SerialDenseMatrix<int,ScalarType> F11( Teuchos::View, *F_, recycleBlocks_, recycleBlocks_ );
1482 Teuchos::SerialDenseMatrix<int,ScalarType> F12( Teuchos::View, *F_, recycleBlocks_, numBlocks_, 0, recycleBlocks_ );
1483 Teuchos::SerialDenseMatrix<int,ScalarType> F21( Teuchos::View, *F_, numBlocks_, recycleBlocks_, recycleBlocks_, 0 );
1484 Teuchos::SerialDenseMatrix<int,ScalarType> F22( Teuchos::View, *F_, numBlocks_, numBlocks_, recycleBlocks_, recycleBlocks_ );
1485 F11.assign(UTAUtmp);
1486 F12.putScalar(zero);
1487 F21.putScalar(zero);
1488 F22.putScalar(zero);
1489 for(
int ii=0;ii<numBlocks_;ii++) {
1490 F22(ii,ii) = Dtmp(ii,0);
1494 Teuchos::SerialDenseMatrix<int,ScalarType> Gtmp( Teuchos::View, *G_, (numBlocks_+recycleBlocks_), (numBlocks_+recycleBlocks_) );
1495 Teuchos::SerialDenseMatrix<int,ScalarType> G11( Teuchos::View, *G_, recycleBlocks_, recycleBlocks_ );
1496 Teuchos::SerialDenseMatrix<int,ScalarType> G12( Teuchos::View, *G_, recycleBlocks_, numBlocks_, 0, recycleBlocks_ );
1497 Teuchos::SerialDenseMatrix<int,ScalarType> G21( Teuchos::View, *G_, numBlocks_, recycleBlocks_, recycleBlocks_, 0 );
1498 Teuchos::SerialDenseMatrix<int,ScalarType> G22( Teuchos::View, *G_, numBlocks_, numBlocks_, recycleBlocks_, recycleBlocks_ );
1499 Teuchos::SerialDenseMatrix<int,ScalarType> AUTAUtmp( Teuchos::View, *AUTAU_, recycleBlocks_, recycleBlocks_ );
1500 G11.assign(AUTAUtmp);
1501 G12.assign(AUTAPtmp);
1503 for (
int ii=0;ii<recycleBlocks_;++ii)
1504 for (
int jj=0;jj<numBlocks_;++jj)
1505 G21(jj,ii) = G12(ii,jj);
1506 G22.assign(APTAPtmp);
1509 Teuchos::SerialDenseMatrix<int,ScalarType> Ytmp( Teuchos::View, *Y_, (recycleBlocks_+numBlocks_), recycleBlocks_ );
1510 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1513 index.resize( recycleBlocks_ );
1514 for (
int ii=0; ii<(recycleBlocks_); ++ii) { index[ii] = ii; }
1516 index.resize( numBlocks_ );
1517 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii; }
1519 index.resize( recycleBlocks_ );
1520 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1522 Teuchos::SerialDenseMatrix<int,ScalarType> Y2( Teuchos::View, *Y_, numBlocks_, recycleBlocks_, recycleBlocks_, 0 );
1523 index.resize( recycleBlocks_ );
1524 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1526 Teuchos::SerialDenseMatrix<int,ScalarType> Y1( Teuchos::View, *Y_, recycleBlocks_, recycleBlocks_ );
1527 index.resize( recycleBlocks_ );
1528 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1537 Teuchos::SerialDenseMatrix<int,ScalarType> GYtmp( Teuchos::View, *GY_, (numBlocks_+recycleBlocks_), recycleBlocks_ );
1538 GYtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Gtmp,Ytmp,zero);
1539 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TAU1tmp( Teuchos::View, *AU1TAU1_, recycleBlocks_, recycleBlocks_ );
1540 AU1TAU1tmp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Ytmp,GYtmp,zero);
1543 Teuchos::SerialDenseMatrix<int,ScalarType> FYtmp( Teuchos::View, *FY_, (numBlocks_+recycleBlocks_), recycleBlocks_ );
1544 FYtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Ftmp,Ytmp,zero);
1545 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TU1tmp( Teuchos::View, *AU1TU1_, recycleBlocks_, recycleBlocks_ );
1546 AU1TU1tmp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Ytmp,FYtmp,zero);
1549 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TUtmp( Teuchos::View, *AU1TU_, recycleBlocks_, recycleBlocks_ );
1550 AU1TUtmp.assign(UTAUtmp);
1553 dold = Dtmp(numBlocks_-1,0);
1560 lastBeta = numBlocks_-1;
1563 Teuchos::SerialDenseMatrix<int,ScalarType> Alphatmp( Teuchos::View, *Alpha_, numBlocks_, 1 );
1564 Teuchos::SerialDenseMatrix<int,ScalarType> Betatmp( Teuchos::View, *Beta_, numBlocks_+1, 1 );
1565 Teuchos::SerialDenseMatrix<int,ScalarType> Dtmp( Teuchos::View, *D_, numBlocks_, 1 );
1566 Teuchos::SerialDenseMatrix<int,ScalarType> APTAPtmp( Teuchos::View, *APTAP_, numBlocks_, numBlocks_ );
1567 for (
int ii=0; ii<numBlocks_; ii++) {
1568 APTAPtmp(ii,ii) = (Dtmp(ii,0) / Alphatmp(ii,0))*(1 + Betatmp(ii+1,0));
1570 APTAPtmp(ii-1,ii) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1571 APTAPtmp(ii,ii-1) = -Dtmp(ii,0)/Alphatmp(ii-1,0);
1575 Teuchos::SerialDenseMatrix<int,ScalarType> L2tmp( Teuchos::View, *L2_, numBlocks_+1, numBlocks_ );
1576 for(
int ii=0;ii<numBlocks_;ii++) {
1577 L2tmp(ii,ii) = 1./Alphatmp(ii,0);
1578 L2tmp(ii+1,ii) = -1./Alphatmp(ii,0);
1583 Teuchos::SerialDenseMatrix<int,ScalarType> DeltaL2( Teuchos::View, *DeltaL2_, recycleBlocks_, numBlocks_ );
1584 Teuchos::SerialDenseMatrix<int,ScalarType> Deltatmp( Teuchos::View, *Delta_, recycleBlocks_, numBlocks_+1 );
1585 DeltaL2.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Deltatmp,L2tmp,zero);
1586 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TUDeltaL2( Teuchos::View, *AU1TUDeltaL2_, recycleBlocks_, numBlocks_ );
1587 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TUtmp( Teuchos::View, *AU1TU_, recycleBlocks_, recycleBlocks_ );
1588 AU1TUDeltaL2.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,AU1TUtmp,DeltaL2,zero);
1589 Teuchos::SerialDenseMatrix<int,ScalarType> Y1( Teuchos::View, *Y_, recycleBlocks_, recycleBlocks_ );
1590 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TAPtmp( Teuchos::View, *AU1TAP_, recycleBlocks_, numBlocks_ );
1591 AU1TAPtmp.putScalar(zero);
1592 AU1TAPtmp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Y1,AU1TUDeltaL2,zero);
1593 Teuchos::SerialDenseMatrix<int,ScalarType> Y2( Teuchos::View, *Y_, numBlocks_, recycleBlocks_, recycleBlocks_, 0 );
1594 ScalarType val = dold * (-Betatmp(0,0)/Alphatmp(0,0));
1595 for(
int ii=0;ii<recycleBlocks_;ii++) {
1596 AU1TAPtmp(ii,0) += Y2(numBlocks_-1,ii)*val;
1600 Teuchos::SerialDenseMatrix<int,ScalarType> Y1TAU1TU( Teuchos::View, *GY_, recycleBlocks_, recycleBlocks_ );
1601 Y1TAU1TU.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Y1,AU1TUtmp,zero);
1602 AU1TUtmp.assign(Y1TAU1TU);
1605 Teuchos::SerialDenseMatrix<int,ScalarType> Ftmp( Teuchos::View, *F_, (numBlocks_+recycleBlocks_), (numBlocks_+recycleBlocks_) );
1606 Teuchos::SerialDenseMatrix<int,ScalarType> F11( Teuchos::View, *F_, recycleBlocks_, recycleBlocks_ );
1607 Teuchos::SerialDenseMatrix<int,ScalarType> F12( Teuchos::View, *F_, recycleBlocks_, numBlocks_, 0, recycleBlocks_ );
1608 Teuchos::SerialDenseMatrix<int,ScalarType> F21( Teuchos::View, *F_, numBlocks_, recycleBlocks_, recycleBlocks_, 0 );
1609 Teuchos::SerialDenseMatrix<int,ScalarType> F22( Teuchos::View, *F_, numBlocks_, numBlocks_, recycleBlocks_, recycleBlocks_ );
1610 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TU1tmp( Teuchos::View, *AU1TU1_, recycleBlocks_, recycleBlocks_ );
1611 F11.assign(AU1TU1tmp);
1612 for(
int ii=0;ii<numBlocks_;ii++) {
1613 F22(ii,ii) = Dtmp(ii,0);
1617 Teuchos::SerialDenseMatrix<int,ScalarType> Gtmp( Teuchos::View, *G_, (numBlocks_+recycleBlocks_), (numBlocks_+recycleBlocks_) );
1618 Teuchos::SerialDenseMatrix<int,ScalarType> G11( Teuchos::View, *G_, recycleBlocks_, recycleBlocks_ );
1619 Teuchos::SerialDenseMatrix<int,ScalarType> G12( Teuchos::View, *G_, recycleBlocks_, numBlocks_, 0, recycleBlocks_ );
1620 Teuchos::SerialDenseMatrix<int,ScalarType> G21( Teuchos::View, *G_, numBlocks_, recycleBlocks_, recycleBlocks_, 0 );
1621 Teuchos::SerialDenseMatrix<int,ScalarType> G22( Teuchos::View, *G_, numBlocks_, numBlocks_, recycleBlocks_, recycleBlocks_ );
1622 Teuchos::SerialDenseMatrix<int,ScalarType> AU1TAU1tmp( Teuchos::View, *AU1TAU1_, recycleBlocks_, recycleBlocks_ );
1623 G11.assign(AU1TAU1tmp);
1624 G12.assign(AU1TAPtmp);
1626 for (
int ii=0;ii<recycleBlocks_;++ii)
1627 for (
int jj=0;jj<numBlocks_;++jj)
1628 G21(jj,ii) = G12(ii,jj);
1629 G22.assign(APTAPtmp);
1632 Teuchos::SerialDenseMatrix<int,ScalarType> Ytmp( Teuchos::View, *Y_, (recycleBlocks_+numBlocks_), recycleBlocks_ );
1633 getHarmonicVecs(Ftmp,Gtmp,Ytmp);
1636 index.resize( numBlocks_ );
1637 for (
int ii=0; ii<numBlocks_; ++ii) { index[ii] = ii+1; }
1639 index.resize( recycleBlocks_ );
1640 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1642 index.resize( recycleBlocks_ );
1643 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1645 index.resize( recycleBlocks_ );
1646 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1655 Teuchos::SerialDenseMatrix<int,ScalarType> GYtmp( Teuchos::View, *GY_, (numBlocks_+recycleBlocks_), recycleBlocks_ );
1656 GYtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Gtmp,Ytmp,zero);
1657 AU1TAU1tmp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Ytmp,GYtmp,zero);
1660 Teuchos::SerialDenseMatrix<int,ScalarType> FYtmp( Teuchos::View, *FY_, (numBlocks_+recycleBlocks_), recycleBlocks_ );
1661 FYtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,Ftmp,Ytmp,zero);
1662 AU1TU1tmp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,one,Ytmp,FYtmp,zero);
1665 dold = Dtmp(numBlocks_-1,0);
1668 lastp = numBlocks_+1;
1669 lastBeta = numBlocks_;
1679 index[0] = lastp-1; index[1] = lastp;
1681 index[0] = 0; index[1] = 1;
1685 (*Beta_)(0,0) = (*Beta_)(lastBeta,0);
1689 Teuchos::SerialDenseMatrix<int,ScalarType> mu1( Teuchos::View, *Delta_, recycleBlocks_, 1, 0, 0 );
1690 Teuchos::SerialDenseMatrix<int,ScalarType> mu2( Teuchos::View, *Delta_, recycleBlocks_, 1, 0, numBlocks_ );
1695 newstate.
P = Teuchos::null;
1696 index.resize( numBlocks_+1 );
1697 for (
int ii=0; ii<(numBlocks_+1); ++ii) { index[ii] = ii+1; }
1700 newstate.
Beta = Teuchos::null;
1701 newstate.
Beta = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *Beta_, numBlocks_, 1, 1, 0 ) );
1703 newstate.
Delta = Teuchos::null;
1704 newstate.
Delta = Teuchos::rcp(
new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::View, *Delta_, recycleBlocks_, numBlocks_, 0, 1 ) );
1709 rcg_iter->initialize(newstate);
1722 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
1723 "Belos::RCGSolMgr::solve(): Invalid return from RCGIter::iterate().");
1728 achievedTol_ = MT::one();
1729 Teuchos::RCP<MV> X = problem_->getLHS();
1731 printer_->stream(
Warnings) <<
"Belos::RCGSolMgr::solve(): Warning! NaN has been detected!"
1735 catch (
const std::exception &e) {
1736 printer_->stream(
Errors) <<
"Error! Caught std::exception in RCGIter::iterate() at iteration "
1737 << rcg_iter->getNumIters() << std::endl
1738 << e.what() << std::endl;
1744 problem_->setCurrLS();
1748 if ( numRHS2Solve > 0 ) {
1751 problem_->setLSIndex( currIdx );
1754 currIdx.resize( numRHS2Solve );
1760 index.resize(recycleBlocks_);
1761 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1765 if (numRHS2Solve > 0) {
1767 newstate.
P = Teuchos::null;
1768 newstate.
Ap = Teuchos::null;
1769 newstate.
r = Teuchos::null;
1770 newstate.
z = Teuchos::null;
1771 newstate.
U = Teuchos::null;
1772 newstate.
AU = Teuchos::null;
1773 newstate.
Alpha = Teuchos::null;
1774 newstate.
Beta = Teuchos::null;
1775 newstate.
D = Teuchos::null;
1776 newstate.
Delta = Teuchos::null;
1777 newstate.
LUUTAU = Teuchos::null;
1778 newstate.
ipiv = Teuchos::null;
1779 newstate.
rTz_old = Teuchos::null;
1782 index.resize(recycleBlocks_);
1783 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1785 index.resize(recycleBlocks_);
1786 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1789 problem_->applyOp( *Utmp, *AUtmp );
1791 Teuchos::SerialDenseMatrix<int,ScalarType> UTAUtmp( Teuchos::View, *UTAU_, recycleBlocks_, recycleBlocks_ );
1794 Teuchos::SerialDenseMatrix<int,ScalarType> AUTAUtmp( Teuchos::View, *AUTAU_, recycleBlocks_, recycleBlocks_ );
1795 if ( precObj != Teuchos::null ) {
1796 index.resize(recycleBlocks_);
1797 for (
int i=0; i<recycleBlocks_; ++i) { index[i] = i; }
1798 index.resize(recycleBlocks_);
1799 for (
int ii=0; ii<recycleBlocks_; ++ii) { index[ii] = ii; }
1817#ifdef BELOS_TEUCHOS_TIME_MONITOR
1822 Teuchos::TimeMonitor::summarize( printer_->stream(
TimingDetails) );
1826 numIters_ = maxIterTest_->getNumIters();
1830 using Teuchos::rcp_dynamic_cast;
1833 const std::vector<MagnitudeType>* pTestValues =
1834 rcp_dynamic_cast<conv_test_type>(convTest_)->
getTestValue();
1836 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues == NULL, std::logic_error,
1837 "Belos::RCGSolMgr::solve(): The convergence test's getTestValue() "
1838 "method returned NULL. Please report this bug to the Belos developers.");
1840 TEUCHOS_TEST_FOR_EXCEPTION(pTestValues->size() < 1, std::logic_error,
1841 "Belos::RCGSolMgr::solve(): The convergence test's getTestValue() "
1842 "method returned a vector of length zero. Please report this bug to the "
1843 "Belos developers.");
1848 achievedTol_ = *std::max_element (pTestValues->begin(), pTestValues->end());