43 #include "Ifpack_ConfigDefs.h"
44 #include "Ifpack_CondestType.h"
45 #include "Ifpack_ILU.h"
46 #include "Epetra_ConfigDefs.h"
47 #include "Epetra_Comm.h"
48 #include "Epetra_Map.h"
49 #include "Epetra_RowMatrix.h"
50 #include "Epetra_Vector.h"
51 #include "Epetra_MultiVector.h"
52 #include "Epetra_CrsGraph.h"
53 #include "Epetra_CrsMatrix.h"
54 #include "Teuchos_ParameterList.hpp"
55 #include "Teuchos_RefCountPtr.hpp"
57 using Teuchos::RefCountPtr;
60 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
61 # include "Teuchos_TimeMonitor.hpp"
66 A_(rcp(Matrix_in,false)),
67 Comm_(Matrix_in->Comm()),
75 IsInitialized_(false),
82 ApplyInverseTime_(0.0),
84 ApplyInverseFlops_(0.0),
87 Teuchos::ParameterList List;
92 void Ifpack_ILU::Destroy()
102 RelaxValue_ = List.get(
"fact: relax value", RelaxValue_);
103 Athresh_ = List.get(
"fact: absolute threshold", Athresh_);
104 Rthresh_ = List.get(
"fact: relative threshold", Rthresh_);
105 LevelOfFill_ = List.get(
"fact: level-of-fill", LevelOfFill_);
108 sprintf(Label_,
"IFPACK ILU (fill=%d, relax=%f, athr=%f, rthr=%f)",
109 LevelOfFill(), RelaxValue(), AbsoluteThreshold(),
110 RelativeThreshold());
115 int Ifpack_ILU::ComputeSetup()
118 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
119 TEUCHOS_FUNC_TIME_MONITOR(
"Ifpack_ILU::ComputeSetup");
125 if ((L_.get() == 0) || (U_.get() == 0) || (D_.get() == 0))
138 int NumIn, NumL, NumU;
140 int NumNonzeroDiags = 0;
142 std::vector<int> InI(MaxNumEntries);
143 std::vector<int> LI(MaxNumEntries);
144 std::vector<int> UI(MaxNumEntries);
145 std::vector<double> InV(MaxNumEntries);
146 std::vector<double> LV(MaxNumEntries);
147 std::vector<double> UV(MaxNumEntries);
149 bool ReplaceValues = (L_->StaticGraph() || L_->IndicesAreLocal());
158 IFPACK_CHK_ERR(D_->ExtractView(&DV));
162 for (i=0; i< NumMyRows(); i++) {
164 IFPACK_CHK_ERR(
Matrix().ExtractMyRowCopy(i, MaxNumEntries, NumIn, &InV[0], &InI[0]));
172 for (j=0; j< NumIn; j++) {
177 DV[i] += Rthresh_ * InV[j] + EPETRA_SGN(InV[j]) * Athresh_;
180 else if (k < 0) {IFPACK_CHK_ERR(-4);}
187 else if (k<NumMyRows()) {
196 if (DiagFound) NumNonzeroDiags++;
197 else DV[i] = Athresh_;
201 (L_->ReplaceMyValues(i, NumL, &LV[0], &LI[0]));
204 IFPACK_CHK_ERR(L_->InsertMyValues(i, NumL, &LV[0], &LI[0]));
210 (U_->ReplaceMyValues(i, NumU, &UV[0], &UI[0]));
213 IFPACK_CHK_ERR(U_->InsertMyValues(i, NumU, &UV[0], &UI[0]));
219 if (!ReplaceValues) {
224 IFPACK_CHK_ERR(L_->FillComplete((L_->RowMatrixColMap()), *L_RangeMap_));
225 IFPACK_CHK_ERR(U_->FillComplete(*U_DomainMap_, U_->RowMatrixRowMap()));
229 int TotalNonzeroDiags = 0;
230 IFPACK_CHK_ERR(Graph().L_Graph().RowMap().
Comm().SumAll(&NumNonzeroDiags, &TotalNonzeroDiags, 1));
231 NumMyDiagonals_ = NumNonzeroDiags;
232 if (NumNonzeroDiags != NumMyRows()) ierr = 1;
234 IFPACK_CHK_ERR(ierr);
242 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
243 TEUCHOS_FUNC_TIME_MONITOR(
"Ifpack_ILU::Initialize");
247 IsInitialized_ =
false;
253 CrsMatrix = dynamic_cast<Epetra_CrsMatrix*>(&*A_);
254 if (CrsMatrix == 0) {
259 int size = A_->MaxNumEntries();
261 if (CrsGraph_.get() == 0)
264 std::vector<double> Values(size);
266 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
267 if(A_->RowMatrixRowMap().GlobalIndicesInt()) {
268 std::vector<int> Indices(size);
271 for (
int i = 0 ; i < A_->NumMyRows() ; ++i) {
273 int GlobalRow = A_->RowMatrixRowMap().GID(i);
274 IFPACK_CHK_ERR(A_->ExtractMyRowCopy(i, size, NumEntries,
275 &Values[0], &Indices[0]));
277 for (
int j = 0 ; j < NumEntries ; ++j) {
278 Indices[j] = A_->RowMatrixColMap().GID(Indices[j]);
280 IFPACK_CHK_ERR(CrsGraph_->InsertGlobalIndices(GlobalRow,NumEntries,
286 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
287 if(A_->RowMatrixRowMap().GlobalIndicesLongLong()) {
288 std::vector<int> Indices_local(size);
289 std::vector<long long> Indices(size);
292 for (
int i = 0 ; i < A_->NumMyRows() ; ++i) {
294 long long GlobalRow = A_->RowMatrixRowMap().GID64(i);
295 IFPACK_CHK_ERR(A_->ExtractMyRowCopy(i, size, NumEntries,
296 &Values[0], &Indices_local[0]));
298 for (
int j = 0 ; j < NumEntries ; ++j) {
299 Indices[j] = A_->RowMatrixColMap().GID64(Indices_local[j]);
301 IFPACK_CHK_ERR(CrsGraph_->InsertGlobalIndices(GlobalRow,NumEntries,
307 throw "Ifpack_ILU::Initialize: GlobalIndices type unknown";
309 IFPACK_CHK_ERR(CrsGraph_->FillComplete(A_->RowMatrixRowMap(),
310 A_->RowMatrixRowMap()));
322 if (Graph_.get() == 0)
324 IFPACK_CHK_ERR(Graph_->ConstructFilledGraph());
326 IsInitialized_ =
true;
337 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
338 TEUCHOS_FUNC_TIME_MONITOR(
"Ifpack_ILU::Compute");
348 IFPACK_CHK_ERR(ComputeSetup());
353 double MinDiagonalValue = Epetra_MinDouble;
354 double MaxDiagonalValue = 1.0/MinDiagonalValue;
360 int NumIn, NumL, NumU;
363 int MaxNumEntries = L_->MaxNumEntries() + U_->MaxNumEntries() + 1;
365 std::vector<int> InI(MaxNumEntries+1);
366 std::vector<double> InV(MaxNumEntries+1);
367 std::vector<int> colflag(NumMyCols());
370 ierr = D_->ExtractView(&DV);
372 #ifdef IFPACK_FLOPCOUNTERS
373 int current_madds = 0;
384 for (j = 0; j < NumMyCols(); ++j) colflag[j] = - 1;
386 for (i = 0; i < NumMyRows(); ++i) {
390 NumIn = MaxNumEntries;
391 IFPACK_CHK_ERR(L_->ExtractMyRowCopy(i, NumIn, NumL, &InV[0], &InI[0]));
398 IFPACK_CHK_ERR(U_->ExtractMyRowCopy(i, NumIn-NumL-1, NumU, &InV[NumL+1], &InI[NumL+1]));
404 for (j=0; j<NumIn; j++) colflag[InI[j]] = j;
406 double diagmod = 0.0;
408 for (
int jj=0; jj<NumL; jj++) {
410 double multiplier = InV[jj];
414 IFPACK_CHK_ERR(U_->ExtractMyRowView(j, NumUU, UUV, UUI));
416 if (RelaxValue_==0.0) {
417 for (k=0; k<NumUU; k++) {
418 int kk = colflag[UUI[k]];
420 InV[kk] -= multiplier*UUV[k];
421 #ifdef IFPACK_FLOPCOUNTERS
428 for (k=0; k<NumUU; k++) {
429 int kk = colflag[UUI[k]];
430 if (kk>-1) InV[kk] -= multiplier*UUV[k];
431 else diagmod -= multiplier*UUV[k];
432 #ifdef IFPACK_FLOPCOUNTERS
439 IFPACK_CHK_ERR(L_->ReplaceMyValues(i, NumL, LV, LI));
444 if (RelaxValue_!=0.0) {
445 DV[i] += RelaxValue_*diagmod;
449 if (fabs(DV[i]) > MaxDiagonalValue) {
450 if (DV[i] < 0) DV[i] = - MinDiagonalValue;
451 else DV[i] = MinDiagonalValue;
456 for (j=0; j<NumU; j++) UV[j] *= DV[i];
459 IFPACK_CHK_ERR(U_->ReplaceMyValues(i, NumU, UV, UI));
463 for (j=0; j<NumIn; j++) colflag[InI[j]] = -1;
468 if (!L_->LowerTriangular())
470 if (!U_->UpperTriangular())
473 #ifdef IFPACK_FLOPCOUNTERS
476 double current_flops = 2 * current_madds;
477 double total_flops = 0;
479 IFPACK_CHK_ERR(Graph().L_Graph().RowMap().
Comm().SumAll(¤t_flops, &total_flops, 1));
482 total_flops += (double) L_->NumGlobalNonzeros();
483 total_flops += (double) D_->GlobalLength();
484 if (RelaxValue_!=0.0) total_flops += 2 * (double)D_->GlobalLength();
487 ComputeFlops_ += total_flops;
504 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
505 TEUCHOS_FUNC_TIME_MONITOR(
"Ifpack_ILU::ApplyInverse - Solve");
511 bool UnitDiagonal =
true;
515 IFPACK_CHK_ERR(L_->Solve(Lower, Trans, UnitDiagonal, X, Y));
517 IFPACK_CHK_ERR(Y.
Multiply(1.0, *D_, Y, 0.0));
519 IFPACK_CHK_ERR(U_->Solve(Upper, Trans, UnitDiagonal, Y, Y));
523 IFPACK_CHK_ERR(U_->Solve(Upper, Trans, UnitDiagonal, X, Y));
525 IFPACK_CHK_ERR(Y.
Multiply(1.0, *D_, Y, 0.0));
526 IFPACK_CHK_ERR(L_->Solve(Lower, Trans, UnitDiagonal, Y, Y));
539 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
540 TEUCHOS_FUNC_TIME_MONITOR(
"Ifpack_ILU::Multiply");
547 IFPACK_CHK_ERR(U_->Multiply(Trans, X, Y));
549 IFPACK_CHK_ERR(Y.
Update(1.0, X, 1.0));
553 IFPACK_CHK_ERR(L_->Multiply(Trans, Y1temp, Y));
555 IFPACK_CHK_ERR(Y.
Update(1.0, Y1temp, 1.0));
559 IFPACK_CHK_ERR(L_->Multiply(Trans, X, Y));
561 IFPACK_CHK_ERR(Y.
Update(1.0, X, 1.0));
565 IFPACK_CHK_ERR(U_->Multiply(Trans, Y1temp, Y));
567 IFPACK_CHK_ERR(Y.
Update(1.0, Y1temp, 1.0));
579 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
580 TEUCHOS_FUNC_TIME_MONITOR(
"Ifpack_ILU::ApplyInverse");
593 Teuchos::RefCountPtr< const Epetra_MultiVector > Xcopy;
597 Xcopy = Teuchos::rcp( &X,
false );
602 #ifdef IFPACK_FLOPCOUNTERS
604 (L_->NumGlobalNonzeros() + U_->NumGlobalNonzeros());
616 const int MaxIters,
const double Tol,
620 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
621 TEUCHOS_FUNC_TIME_MONITOR(
"Ifpack_ILU::Condest");
627 Condest_ = Ifpack_Condest(*
this, CT, MaxIters, Tol, Matrix_in);
638 if (!
Comm().MyPID()) {
640 os <<
"================================================================================" << endl;
641 os <<
"Ifpack_ILU: " <<
Label() << endl << endl;
642 os <<
"Level-of-fill = " << LevelOfFill() << endl;
643 os <<
"Absolute threshold = " << AbsoluteThreshold() << endl;
644 os <<
"Relative threshold = " << RelativeThreshold() << endl;
645 os <<
"Relax value = " << RelaxValue() << endl;
646 os <<
"Condition number estimate = " <<
Condest() << endl;
647 os <<
"Global number of rows = " << A_->NumGlobalRows64() << endl;
649 os <<
"Number of rows of L, D, U = " << L_->NumGlobalRows64() << endl;
650 os <<
"Number of nonzeros of L + U = " << NumGlobalNonzeros64() << endl;
651 os <<
"nonzeros / rows = "
652 << 1.0 * NumGlobalNonzeros64() / U_->NumGlobalRows64() << endl;
655 os <<
"Phase # calls Total Time (s) Total MFlops MFlops/s" << endl;
656 os <<
"----- ------- -------------- ------------ --------" << endl;
659 <<
" 0.0 0.0" << endl;
660 os <<
"Compute() " << std::setw(5) <<
NumCompute()
666 os <<
" " << std::setw(15) << 0.0 << endl;
673 os <<
" " << std::setw(15) << 0.0 << endl;
674 os <<
"================================================================================" << endl;