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 #include "Ifpack_CrsRiluk.h"
00030 #include "Epetra_Comm.h"
00031 #include "Epetra_Map.h"
00032 #include "Epetra_CrsGraph.h"
00033 #include "Epetra_VbrMatrix.h"
00034 #include "Epetra_RowMatrix.h"
00035 #include "Epetra_MultiVector.h"
00036
00037 #include <Teuchos_ParameterList.hpp>
00038 #include <ifp_parameters.h>
00039
00040
00041 Ifpack_CrsRiluk::Ifpack_CrsRiluk(const Ifpack_IlukGraph & Graph_in)
00042 : UserMatrixIsVbr_(false),
00043 UserMatrixIsCrs_(false),
00044 Graph_(Graph_in),
00045 Comm_(Graph_in.Comm()),
00046 UseTranspose_(false),
00047 NumMyDiagonals_(0),
00048 Allocated_(false),
00049 ValuesInitialized_(false),
00050 Factored_(false),
00051 RelaxValue_(0.0),
00052 Athresh_(0.0),
00053 Rthresh_(1.0),
00054 Condest_(-1.0),
00055 OverlapMode_(Zero)
00056 {
00057
00058 IsOverlapped_ = (Graph_in.LevelOverlap()>0 && Graph_in.DomainMap().DistributedGlobal());
00059 }
00060
00061
00062 Ifpack_CrsRiluk::Ifpack_CrsRiluk(const Ifpack_CrsRiluk & FactoredMatrix)
00063 : UserMatrixIsVbr_(FactoredMatrix.UserMatrixIsVbr_),
00064 UserMatrixIsCrs_(FactoredMatrix.UserMatrixIsCrs_),
00065 IsOverlapped_(FactoredMatrix.IsOverlapped_),
00066 Graph_(FactoredMatrix.Graph_),
00067 IlukRowMap_(FactoredMatrix.IlukRowMap_),
00068 IlukDomainMap_(FactoredMatrix.IlukDomainMap_),
00069 IlukRangeMap_(FactoredMatrix.IlukRangeMap_),
00070 Comm_(FactoredMatrix.Comm_),
00071 UseTranspose_(FactoredMatrix.UseTranspose_),
00072 NumMyDiagonals_(FactoredMatrix.NumMyDiagonals_),
00073 Allocated_(FactoredMatrix.Allocated_),
00074 ValuesInitialized_(FactoredMatrix.ValuesInitialized_),
00075 Factored_(FactoredMatrix.Factored_),
00076 RelaxValue_(FactoredMatrix.RelaxValue_),
00077 Athresh_(FactoredMatrix.Athresh_),
00078 Rthresh_(FactoredMatrix.Rthresh_),
00079 Condest_(FactoredMatrix.Condest_),
00080 OverlapMode_(FactoredMatrix.OverlapMode_)
00081 {
00082 L_ = Teuchos::rcp( new Epetra_CrsMatrix(FactoredMatrix.L()) );
00083 U_ = Teuchos::rcp( new Epetra_CrsMatrix(FactoredMatrix.U()) );
00084 D_ = Teuchos::rcp( new Epetra_Vector(FactoredMatrix.D()) );
00085 if (IlukRowMap_!=Teuchos::null) IlukRowMap_ = Teuchos::rcp( new Epetra_Map(*IlukRowMap_) );
00086 if (IlukDomainMap_!=Teuchos::null) IlukDomainMap_ = Teuchos::rcp( new Epetra_Map(*IlukDomainMap_) );
00087 if (IlukRangeMap_!=Teuchos::null) IlukRangeMap_ = Teuchos::rcp( new Epetra_Map(*IlukRangeMap_) );
00088
00089 }
00090
00091 Ifpack_CrsRiluk::~Ifpack_CrsRiluk(){
00092
00093 ValuesInitialized_ = false;
00094 Factored_ = false;
00095 Allocated_ = false;
00096 }
00097
00098 int Ifpack_CrsRiluk::AllocateCrs() {
00099
00100
00101 L_ = Teuchos::rcp( new Epetra_CrsMatrix(Copy, Graph_.L_Graph()) );
00102 U_ = Teuchos::rcp( new Epetra_CrsMatrix(Copy, Graph_.U_Graph()) );
00103 D_ = Teuchos::rcp( new Epetra_Vector(Graph_.L_Graph().RowMap()) );
00104 L_Graph_ = Teuchos::null;
00105 U_Graph_ = Teuchos::null;
00106 SetAllocated(true);
00107 return(0);
00108 }
00109
00110 int Ifpack_CrsRiluk::AllocateVbr() {
00111
00112
00113
00114 EPETRA_CHK_ERR(BlockMap2PointMap(Graph_.L_Graph().RowMap(), &IlukRowMap_));
00115 EPETRA_CHK_ERR(BlockMap2PointMap(Graph_.U_Graph().DomainMap(), &IlukDomainMap_));
00116 EPETRA_CHK_ERR(BlockMap2PointMap(Graph_.L_Graph().RangeMap(), &IlukRangeMap_));
00117
00118
00119 U_DomainMap_ = IlukDomainMap_;
00120 L_RangeMap_ = IlukRangeMap_;
00121
00122 if (Graph().LevelFill()) {
00123 L_Graph_ = Teuchos::rcp( new Epetra_CrsGraph(Copy, *IlukRowMap_, *IlukRowMap_, 0) );
00124 U_Graph_ = Teuchos::rcp( new Epetra_CrsGraph(Copy, *IlukRowMap_, *IlukRowMap_, 0) );
00125 EPETRA_CHK_ERR(BlockGraph2PointGraph(Graph_.L_Graph(), *L_Graph_, false));
00126 EPETRA_CHK_ERR(BlockGraph2PointGraph(Graph_.U_Graph(), *U_Graph_, true));
00127
00128 L_Graph_->FillComplete(*IlukRowMap_, *IlukRangeMap_);
00129 U_Graph_->FillComplete(*IlukDomainMap_, *IlukRowMap_);
00130
00131 L_ = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *L_Graph_) );
00132 U_ = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *U_Graph_) );
00133 D_ = Teuchos::rcp( new Epetra_Vector(*IlukRowMap_) );
00134 }
00135 else {
00136
00137 L_ = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *IlukRowMap_, *IlukRowMap_, 0) );
00138 U_ = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *IlukRowMap_, *IlukRowMap_, 0) );
00139 D_ = Teuchos::rcp( new Epetra_Vector(*IlukRowMap_) );
00140 L_Graph_ = Teuchos::null;
00141 U_Graph_ = Teuchos::null;
00142 }
00143 SetAllocated(true);
00144 return(0);
00145 }
00146
00147
00148 int Ifpack_CrsRiluk::SetParameters(const Teuchos::ParameterList& parameterlist,
00149 bool cerr_warning_if_unused)
00150 {
00151 Ifpack::param_struct params;
00152 params.double_params[Ifpack::relax_value] = RelaxValue_;
00153 params.double_params[Ifpack::absolute_threshold] = Athresh_;
00154 params.double_params[Ifpack::relative_threshold] = Rthresh_;
00155 params.overlap_mode = OverlapMode_;
00156
00157 Ifpack::set_parameters(parameterlist, params, cerr_warning_if_unused);
00158
00159 RelaxValue_ = params.double_params[Ifpack::relax_value];
00160 Athresh_ = params.double_params[Ifpack::absolute_threshold];
00161 Rthresh_ = params.double_params[Ifpack::relative_threshold];
00162 OverlapMode_ = params.overlap_mode;
00163
00164 return(0);
00165 }
00166
00167
00168 int Ifpack_CrsRiluk::InitValues(const Epetra_CrsMatrix & A) {
00169
00170 UserMatrixIsCrs_ = true;
00171
00172 if (!Allocated()) AllocateCrs();
00173
00174 Teuchos::RefCountPtr<Epetra_CrsMatrix> OverlapA = Teuchos::rcp( (Epetra_CrsMatrix *) &A, false );
00175
00176 if (IsOverlapped_) {
00177
00178 OverlapA = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Graph_.OverlapGraph()) );
00179 EPETRA_CHK_ERR(OverlapA->Import(A, *Graph_.OverlapImporter(), Insert));
00180 EPETRA_CHK_ERR(OverlapA->FillComplete());
00181 }
00182
00183
00184 int MaxNumEntries = OverlapA->MaxNumEntries();
00185
00186
00187 U_DomainMap_ = Teuchos::rcp( &(A.DomainMap()), false );
00188 L_RangeMap_ = Teuchos::rcp( &(A.RangeMap()), false );
00189
00190
00191 EPETRA_CHK_ERR(InitAllValues(*OverlapA, MaxNumEntries));
00192
00193 return(0);
00194 }
00195
00196
00197 int Ifpack_CrsRiluk::InitValues(const Epetra_VbrMatrix & A) {
00198
00199 UserMatrixIsVbr_ = true;
00200
00201 if (!Allocated()) AllocateVbr();
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 Teuchos::RefCountPtr<Epetra_VbrMatrix> OverlapA = Teuchos::rcp( (Epetra_VbrMatrix *) &A, false );
00214
00215 if (IsOverlapped_) {
00216
00217 OverlapA = Teuchos::rcp( new Epetra_VbrMatrix(Copy, *Graph_.OverlapGraph()) );
00218 EPETRA_CHK_ERR(OverlapA->Import(A, *Graph_.OverlapImporter(), Insert));
00219 EPETRA_CHK_ERR(OverlapA->FillComplete());
00220 }
00221
00222
00223
00224
00225 int MaxNumEntries = OverlapA->MaxNumNonzeros();
00226
00227
00228
00229 EPETRA_CHK_ERR(InitAllValues(*OverlapA, MaxNumEntries));
00230
00231 return(0);
00232 }
00233
00234
00235 int Ifpack_CrsRiluk::InitAllValues(const Epetra_RowMatrix & OverlapA, int MaxNumEntries) {
00236
00237 int ierr = 0;
00238 int i, j;
00239 int NumIn, NumL, NumU;
00240 bool DiagFound;
00241 int NumNonzeroDiags = 0;
00242
00243
00244 vector<int> InI(MaxNumEntries);
00245 vector<int> LI(MaxNumEntries);
00246 vector<int> UI(MaxNumEntries);
00247 vector<double> InV(MaxNumEntries);
00248 vector<double> LV(MaxNumEntries);
00249 vector<double> UV(MaxNumEntries);
00250
00251 bool ReplaceValues = (L_->StaticGraph() || L_->IndicesAreLocal());
00252
00253 if (ReplaceValues) {
00254 L_->PutScalar(0.0);
00255 U_->PutScalar(0.0);
00256 }
00257
00258 D_->PutScalar(0.0);
00259 double *DV;
00260 EPETRA_CHK_ERR(D_->ExtractView(&DV));
00261
00262
00263
00264
00265 for (i=0; i< NumMyRows(); i++) {
00266
00267 EPETRA_CHK_ERR(OverlapA.ExtractMyRowCopy(i, MaxNumEntries, NumIn, &InV[0], &InI[0]));
00268
00269
00270
00271 NumL = 0;
00272 NumU = 0;
00273 DiagFound = false;
00274
00275 for (j=0; j< NumIn; j++) {
00276 int k = InI[j];
00277
00278 if (k==i) {
00279 DiagFound = true;
00280 DV[i] += Rthresh_ * InV[j] + EPETRA_SGN(InV[j]) * Athresh_;
00281 }
00282
00283 else if (k < 0) {EPETRA_CHK_ERR(-1);}
00284
00285 else if (k < i) {
00286 LI[NumL] = k;
00287 LV[NumL] = InV[j];
00288 NumL++;
00289 }
00290 else if (k<NumMyRows()) {
00291 UI[NumU] = k;
00292 UV[NumU] = InV[j];
00293 NumU++;
00294 }
00295 }
00296
00297
00298
00299 if (DiagFound) NumNonzeroDiags++;
00300 else DV[i] = Athresh_;
00301
00302 if (NumL) {
00303 if (ReplaceValues) {
00304 EPETRA_CHK_ERR(L_->ReplaceMyValues(i, NumL, &LV[0], &LI[0]));
00305 }
00306 else {
00307 EPETRA_CHK_ERR(L_->InsertMyValues(i, NumL, &LV[0], &LI[0]));
00308 }
00309 }
00310
00311 if (NumU) {
00312 if (ReplaceValues) {
00313 EPETRA_CHK_ERR(U_->ReplaceMyValues(i, NumU, &UV[0], &UI[0]));
00314 }
00315 else {
00316 EPETRA_CHK_ERR(U_->InsertMyValues(i, NumU, &UV[0], &UI[0]));
00317 }
00318 }
00319
00320 }
00321
00322 if (!ReplaceValues) {
00323
00324
00325
00326
00327 EPETRA_CHK_ERR(L_->FillComplete(L_->RowMatrixColMap(), *L_RangeMap_));
00328 EPETRA_CHK_ERR(U_->FillComplete(*U_DomainMap_, U_->RowMatrixRowMap()));
00329 }
00330
00331
00332
00333 SetValuesInitialized(true);
00334 SetFactored(false);
00335
00336 int TotalNonzeroDiags = 0;
00337 EPETRA_CHK_ERR(Graph_.L_Graph().RowMap().Comm().SumAll(&NumNonzeroDiags, &TotalNonzeroDiags, 1));
00338 NumMyDiagonals_ = NumNonzeroDiags;
00339 if (NumNonzeroDiags != NumMyRows()) ierr = 1;
00340
00341 return(ierr);
00342 }
00343
00344
00345 int Ifpack_CrsRiluk::Factor() {
00346
00347
00348 if (!ValuesInitialized()) return(-2);
00349 if (Factored()) return(-3);
00350
00351 SetValuesInitialized(false);
00352
00353
00354
00355
00356 double MinDiagonalValue = Epetra_MinDouble;
00357 double MaxDiagonalValue = 1.0/MinDiagonalValue;
00358
00359 int ierr = 0;
00360 int i, j, k;
00361 int * LI=0, * UI = 0;
00362 double * LV=0, * UV = 0;
00363 int NumIn, NumL, NumU;
00364
00365
00366 int MaxNumEntries = L_->MaxNumEntries() + U_->MaxNumEntries() + 1;
00367
00368 vector<int> InI(MaxNumEntries);
00369 vector<double> InV(MaxNumEntries);
00370 vector<int> colflag(NumMyCols());
00371
00372 double *DV;
00373 ierr = D_->ExtractView(&DV);
00374
00375 #ifdef IFPACK_FLOPCOUNTERS
00376 int current_madds = 0;
00377 #endif
00378
00379
00380
00381
00382 int NumUU;
00383 int * UUI;
00384 double * UUV;
00385 for (j=0; j<NumMyCols(); j++) colflag[j] = - 1;
00386
00387 for(i=0; i<NumMyRows(); i++) {
00388
00389
00390
00391 NumIn = MaxNumEntries;
00392 EPETRA_CHK_ERR(L_->ExtractMyRowCopy(i, NumIn, NumL, &InV[0], &InI[0]));
00393 LV = &InV[0];
00394 LI = &InI[0];
00395
00396 InV[NumL] = DV[i];
00397 InI[NumL] = i;
00398
00399 EPETRA_CHK_ERR(U_->ExtractMyRowCopy(i, NumIn-NumL-1, NumU, &InV[NumL+1], &InI[NumL+1]));
00400 NumIn = NumL+NumU+1;
00401 UV = &InV[NumL+1];
00402 UI = &InI[NumL+1];
00403
00404
00405 for (j=0; j<NumIn; j++) colflag[InI[j]] = j;
00406
00407 double diagmod = 0.0;
00408
00409 for (int jj=0; jj<NumL; jj++) {
00410 j = InI[jj];
00411 double multiplier = InV[jj];
00412
00413 InV[jj] *= DV[j];
00414
00415 EPETRA_CHK_ERR(U_->ExtractMyRowView(j, NumUU, UUV, UUI));
00416
00417 if (RelaxValue_==0.0) {
00418 for (k=0; k<NumUU; k++) {
00419 int kk = colflag[UUI[k]];
00420 if (kk>-1) {
00421 InV[kk] -= multiplier*UUV[k];
00422 #ifdef IFPACK_FLOPCOUNTERS
00423 current_madds++;
00424 #endif
00425 }
00426 }
00427 }
00428 else {
00429 for (k=0; k<NumUU; k++) {
00430 int kk = colflag[UUI[k]];
00431 if (kk>-1) InV[kk] -= multiplier*UUV[k];
00432 else diagmod -= multiplier*UUV[k];
00433 #ifdef IFPACK_FLOPCOUNTERS
00434 current_madds++;
00435 #endif
00436 }
00437 }
00438 }
00439 if (NumL) {
00440 EPETRA_CHK_ERR(L_->ReplaceMyValues(i, NumL, LV, LI));
00441 }
00442
00443 DV[i] = InV[NumL];
00444
00445 if (RelaxValue_!=0.0) {
00446 DV[i] += RelaxValue_*diagmod;
00447
00448 }
00449
00450 if (fabs(DV[i]) > MaxDiagonalValue) {
00451 if (DV[i] < 0) DV[i] = - MinDiagonalValue;
00452 else DV[i] = MinDiagonalValue;
00453 }
00454 else
00455 DV[i] = 1.0/DV[i];
00456
00457 for (j=0; j<NumU; j++) UV[j] *= DV[i];
00458
00459 if (NumU) {
00460 EPETRA_CHK_ERR(U_->ReplaceMyValues(i, NumU, UV, UI));
00461 }
00462
00463
00464 for (j=0; j<NumIn; j++) colflag[InI[j]] = -1;
00465 }
00466
00467
00468
00469 if( !L_->LowerTriangular() )
00470 EPETRA_CHK_ERR(-2);
00471 if( !U_->UpperTriangular() )
00472 EPETRA_CHK_ERR(-3);
00473
00474 #ifdef IFPACK_FLOPCOUNTERS
00475
00476
00477 double current_flops = 2 * current_madds;
00478 double total_flops = 0;
00479
00480 EPETRA_CHK_ERR(Graph_.L_Graph().RowMap().Comm().SumAll(¤t_flops, &total_flops, 1));
00481
00482
00483 total_flops += (double) L_->NumGlobalNonzeros();
00484 total_flops += (double) D_->GlobalLength();
00485 if (RelaxValue_!=0.0) total_flops += 2 * (double)D_->GlobalLength();
00486
00487 UpdateFlops(total_flops);
00488 #endif
00489
00490 SetFactored(true);
00491
00492 return(ierr);
00493
00494 }
00495
00496
00497 int Ifpack_CrsRiluk::Solve(bool Trans, const Epetra_MultiVector& X,
00498 Epetra_MultiVector& Y) const {
00499
00500
00501
00502
00503
00504 Teuchos::RefCountPtr<Epetra_MultiVector> X1;
00505 Teuchos::RefCountPtr<Epetra_MultiVector> Y1;
00506 EPETRA_CHK_ERR(GenerateXY(Trans, X, Y, &X1, &Y1));
00507
00508 bool Upper = true;
00509 bool Lower = false;
00510 bool UnitDiagonal = true;
00511
00512 #ifdef IFPACK_FLOPCOUNTERS
00513 Epetra_Flops * counter = this->GetFlopCounter();
00514 if (counter!=0) {
00515 L_->SetFlopCounter(*counter);
00516 Y1->SetFlopCounter(*counter);
00517 U_->SetFlopCounter(*counter);
00518 }
00519 #endif
00520
00521 if (!Trans) {
00522
00523 EPETRA_CHK_ERR(L_->Solve(Lower, Trans, UnitDiagonal, *X1, *Y1));
00524 EPETRA_CHK_ERR(Y1->Multiply(1.0, *D_, *Y1, 0.0));
00525 EPETRA_CHK_ERR(U_->Solve(Upper, Trans, UnitDiagonal, *Y1, *Y1));
00526 if (IsOverlapped_) {EPETRA_CHK_ERR(Y.Export(*Y1,*L_->Exporter(), OverlapMode_));}
00527 }
00528 else {
00529 EPETRA_CHK_ERR(U_->Solve(Upper, Trans, UnitDiagonal, *X1, *Y1));
00530 EPETRA_CHK_ERR(Y1->Multiply(1.0, *D_, *Y1, 0.0));
00531 EPETRA_CHK_ERR(L_->Solve(Lower, Trans, UnitDiagonal, *Y1, *Y1));
00532 if (IsOverlapped_) {EPETRA_CHK_ERR(Y.Export(*Y1,*U_->Importer(), OverlapMode_));}
00533 }
00534
00535 return(0);
00536 }
00537
00538 int Ifpack_CrsRiluk::Multiply(bool Trans, const Epetra_MultiVector& X,
00539 Epetra_MultiVector& Y) const {
00540
00541
00542
00543
00544
00545 Teuchos::RefCountPtr<Epetra_MultiVector> X1;
00546 Teuchos::RefCountPtr<Epetra_MultiVector> Y1;
00547 EPETRA_CHK_ERR(GenerateXY(Trans, X, Y, &X1, &Y1));
00548
00549 #ifdef IFPACK_FLOPCOUNTERS
00550 Epetra_Flops * counter = this->GetFlopCounter();
00551 if (counter!=0) {
00552 L_->SetFlopCounter(*counter);
00553 Y1->SetFlopCounter(*counter);
00554 U_->SetFlopCounter(*counter);
00555 }
00556 #endif
00557
00558 if (!Trans) {
00559 EPETRA_CHK_ERR(U_->Multiply(Trans, *X1, *Y1));
00560 EPETRA_CHK_ERR(Y1->Update(1.0, *X1, 1.0));
00561 EPETRA_CHK_ERR(Y1->ReciprocalMultiply(1.0, *D_, *Y1, 0.0));
00562 Epetra_MultiVector Y1temp(*Y1);
00563 EPETRA_CHK_ERR(L_->Multiply(Trans, Y1temp, *Y1));
00564 EPETRA_CHK_ERR(Y1->Update(1.0, Y1temp, 1.0));
00565 if (IsOverlapped_) {EPETRA_CHK_ERR(Y.Export(*Y1,*L_->Exporter(), OverlapMode_));}
00566 }
00567 else {
00568
00569 EPETRA_CHK_ERR(L_->Multiply(Trans, *X1, *Y1));
00570 EPETRA_CHK_ERR(Y1->Update(1.0, *X1, 1.0));
00571 EPETRA_CHK_ERR(Y1->ReciprocalMultiply(1.0, *D_, *Y1, 0.0));
00572 Epetra_MultiVector Y1temp(*Y1);
00573 EPETRA_CHK_ERR(U_->Multiply(Trans, Y1temp, *Y1));
00574 EPETRA_CHK_ERR(Y1->Update(1.0, Y1temp, 1.0));
00575 if (IsOverlapped_) {EPETRA_CHK_ERR(Y.Export(*Y1,*L_->Exporter(), OverlapMode_));}
00576 }
00577 return(0);
00578 }
00579
00580 int Ifpack_CrsRiluk::Condest(bool Trans, double & ConditionNumberEstimate) const {
00581
00582 if (Condest_>=0.0) {
00583 ConditionNumberEstimate = Condest_;
00584 return(0);
00585 }
00586
00587 Epetra_Vector Ones(U_->DomainMap());
00588 Epetra_Vector OnesResult(L_->RangeMap());
00589 Ones.PutScalar(1.0);
00590
00591 EPETRA_CHK_ERR(Solve(Trans, Ones, OnesResult));
00592 EPETRA_CHK_ERR(OnesResult.Abs(OnesResult));
00593 EPETRA_CHK_ERR(OnesResult.MaxValue(&ConditionNumberEstimate));
00594 Condest_ = ConditionNumberEstimate;
00595 return(0);
00596 }
00597
00598 int Ifpack_CrsRiluk::BlockGraph2PointGraph(const Epetra_CrsGraph & BG, Epetra_CrsGraph & PG, bool Upper) {
00599
00600 if (!BG.IndicesAreLocal()) {EPETRA_CHK_ERR(-1);}
00601
00602 int * ColFirstPointInElementList = BG.RowMap().FirstPointInElementList();
00603 int * ColElementSizeList = BG.RowMap().ElementSizeList();
00604 if (BG.Importer()!=0) {
00605 ColFirstPointInElementList = BG.ImportMap().FirstPointInElementList();
00606 ColElementSizeList = BG.ImportMap().ElementSizeList();
00607 }
00608
00609 int Length = (BG.MaxNumIndices()+1) * BG.ImportMap().MaxMyElementSize();
00610 vector<int> tmpIndices(Length);
00611
00612 int BlockRow, BlockOffset, NumEntries;
00613 int NumBlockEntries;
00614 int * BlockIndices;
00615
00616 int NumMyRows_tmp = PG.NumMyRows();
00617
00618 for (int i=0; i<NumMyRows_tmp; i++) {
00619 EPETRA_CHK_ERR(BG.RowMap().FindLocalElementID(i, BlockRow, BlockOffset));
00620 EPETRA_CHK_ERR(BG.ExtractMyRowView(BlockRow, NumBlockEntries, BlockIndices));
00621
00622 int * ptr = &tmpIndices[0];
00623
00624 int RowDim = BG.RowMap().ElementSize(BlockRow);
00625 NumEntries = 0;
00626
00627
00628
00629 if (Upper) {
00630 int jstart = i+1;
00631 int jstop = EPETRA_MIN(NumMyRows_tmp,i+RowDim-BlockOffset);
00632 for (int j= jstart; j< jstop; j++) {*ptr++ = j; NumEntries++;}
00633 }
00634
00635 for (int j=0; j<NumBlockEntries; j++) {
00636 int ColDim = ColElementSizeList[BlockIndices[j]];
00637 NumEntries += ColDim;
00638 assert(NumEntries<=Length);
00639 int Index = ColFirstPointInElementList[BlockIndices[j]];
00640 for (int k=0; k < ColDim; k++) *ptr++ = Index++;
00641 }
00642
00643
00644
00645 if (!Upper) {
00646 int jstart = EPETRA_MAX(0,i-RowDim+1);
00647 int jstop = i;
00648 for (int j = jstart; j < jstop; j++) {*ptr++ = j; NumEntries++;}
00649 }
00650
00651 EPETRA_CHK_ERR(PG.InsertMyIndices(i, NumEntries, &tmpIndices[0]));
00652 }
00653
00654 SetAllocated(true);
00655
00656 return(0);
00657 }
00658
00659 int Ifpack_CrsRiluk::BlockMap2PointMap(const Epetra_BlockMap & BlockMap, Teuchos::RefCountPtr<Epetra_Map>* PointMap) {
00660
00661
00662
00663
00664
00665 int MaxElementSize = BlockMap.MaxElementSize();
00666 int PtNumMyElements = BlockMap.NumMyPoints();
00667 vector<int> PtMyGlobalElements;
00668 if (PtNumMyElements>0) PtMyGlobalElements.resize(PtNumMyElements);
00669
00670 int NumMyElements = BlockMap.NumMyElements();
00671
00672 int curID = 0;
00673 for (int i=0; i<NumMyElements; i++) {
00674 int StartID = BlockMap.GID(i)*MaxElementSize;
00675 int ElementSize = BlockMap.ElementSize(i);
00676 for (int j=0; j<ElementSize; j++) PtMyGlobalElements[curID++] = StartID+j;
00677 }
00678 assert(curID==PtNumMyElements);
00679
00680 (*PointMap) = Teuchos::rcp( new Epetra_Map(-1, PtNumMyElements, &PtMyGlobalElements[0], BlockMap.IndexBase(), BlockMap.Comm()) );
00681
00682 if (!BlockMap.PointSameAs(*(*PointMap))) {EPETRA_CHK_ERR(-1);}
00683 return(0);
00684 }
00685
00686 int Ifpack_CrsRiluk::GenerateXY(bool Trans,
00687 const Epetra_MultiVector& Xin, const Epetra_MultiVector& Yin,
00688 Teuchos::RefCountPtr<Epetra_MultiVector>* Xout,
00689 Teuchos::RefCountPtr<Epetra_MultiVector>* Yout) const {
00690
00691
00692
00693 if (Xin.NumVectors()!=Yin.NumVectors()) EPETRA_CHK_ERR(-1);
00694
00695
00696 (*Xout) = Teuchos::rcp( (Epetra_MultiVector *) &Xin, false );
00697 (*Yout) = Teuchos::rcp( (Epetra_MultiVector *) &Yin, false );
00698 if (!IsOverlapped_ && UserMatrixIsCrs_) return(0);
00699
00700 if (UserMatrixIsVbr_) {
00701 if (VbrX_!=Teuchos::null) {
00702 if (VbrX_->NumVectors()!=Xin.NumVectors()) {
00703 VbrX_ = Teuchos::null;
00704 VbrY_ = Teuchos::null;
00705 }
00706 }
00707 if (VbrX_==Teuchos::null) {
00708 VbrX_ = Teuchos::rcp( new Epetra_MultiVector(View, *U_DomainMap_, (*Xout)->Pointers(), (*Xout)->NumVectors()) );
00709 VbrY_ = Teuchos::rcp( new Epetra_MultiVector(View, *L_RangeMap_, (*Yout)->Pointers(), (*Yout)->NumVectors()) );
00710 }
00711 else {
00712 EPETRA_CHK_ERR(VbrX_->ResetView((*Xout)->Pointers()));
00713 EPETRA_CHK_ERR(VbrY_->ResetView((*Yout)->Pointers()));
00714 }
00715 (*Xout) = VbrX_;
00716 (*Yout) = VbrY_;
00717 }
00718
00719 if (IsOverlapped_) {
00720
00721 if (OverlapX_!=Teuchos::null) {
00722 if (OverlapX_->NumVectors()!=Xin.NumVectors()) {
00723 OverlapX_ = Teuchos::null;
00724 OverlapY_ = Teuchos::null;
00725 }
00726 }
00727 if (OverlapX_==Teuchos::null) {
00728 OverlapX_ = Teuchos::rcp( new Epetra_MultiVector(U_->RowMatrixColMap(), (*Xout)->NumVectors()) );
00729 OverlapY_ = Teuchos::rcp( new Epetra_MultiVector(L_->RowMatrixRowMap(), (*Yout)->NumVectors()) );
00730 }
00731 if (!Trans) {
00732 EPETRA_CHK_ERR(OverlapX_->Import(*(*Xout),*U_->Importer(), Insert));
00733 }
00734 else {
00735 EPETRA_CHK_ERR(OverlapX_->Import(*(*Xout),*L_->Exporter(), Insert));
00736 }
00737 (*Xout) = OverlapX_;
00738 (*Yout) = OverlapY_;
00739
00740 }
00741
00742 return(0);
00743 }
00744
00745
00746
00747 ostream& operator << (ostream& os, const Ifpack_CrsRiluk& A)
00748 {
00749
00750
00751
00752 int LevelFill = A.Graph().LevelFill();
00753 int LevelOverlap = A.Graph().LevelOverlap();
00754 Epetra_CrsMatrix & L = (Epetra_CrsMatrix &) A.L();
00755 Epetra_CrsMatrix & U = (Epetra_CrsMatrix &) A.U();
00756 Epetra_Vector & D = (Epetra_Vector &) A.D();
00757
00758 os.width(14);
00759 os << endl;
00760 os << " Level of Fill = "; os << LevelFill;
00761 os << endl;
00762 os.width(14);
00763 os << " Level of Overlap = "; os << LevelOverlap;
00764 os << endl;
00765
00766 os.width(14);
00767 os << " Lower Triangle = ";
00768 os << endl;
00769 os << L;
00770 os << endl;
00771
00772 os.width(14);
00773 os << " Inverse of Diagonal = ";
00774 os << endl;
00775 os << D;
00776 os << endl;
00777
00778 os.width(14);
00779 os << " Upper Triangle = ";
00780 os << endl;
00781 os << U;
00782 os << endl;
00783
00784
00785
00786
00787
00788
00789
00790 return os;
00791 }