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