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"
67 Comm_(Matrix_in->Comm()),
75 IsInitialized_(
false),
82 ApplyInverseTime_(0.0),
84 ApplyInverseFlops_(0.0),
108 sprintf(
Label_,
"IFPACK ILU (fill=%d, relax=%f, athr=%f, rthr=%f)",
118 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
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());
172 for (j=0; j< NumIn; j++) {
196 if (DiagFound) NumNonzeroDiags++;
201 (
L_->ReplaceMyValues(i, NumL, &LV[0], &LI[0]));
210 (
U_->ReplaceMyValues(i, NumU, &UV[0], &UI[0]));
219 if (!ReplaceValues) {
229 int TotalNonzeroDiags = 0;
232 if (NumNonzeroDiags !=
NumMyRows()) ierr = 1;
242 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
253 CrsMatrix = dynamic_cast<Epetra_CrsMatrix*>(&*
A_);
254 if (CrsMatrix == 0) {
259 int size =
A_->MaxNumEntries();
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);
275 &Values[0], &Indices[0]));
277 for (
int j = 0 ; j < NumEntries ; ++j) {
278 Indices[j] =
A_->RowMatrixColMap().GID(Indices[j]);
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);
296 &Values[0], &Indices_local[0]));
298 for (
int j = 0 ; j < NumEntries ; ++j) {
299 Indices[j] =
A_->RowMatrixColMap().GID64(Indices_local[j]);
307 throw "Ifpack_ILU::Initialize: GlobalIndices type unknown";
310 A_->RowMatrixRowMap()));
337 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
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);
370 ierr =
D_->ExtractView(&DV);
372 #ifdef IFPACK_FLOPCOUNTERS
373 int current_madds = 0;
384 for (j = 0; j <
NumMyCols(); ++j) colflag[j] = - 1;
390 NumIn = MaxNumEntries;
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];
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
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];
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;
482 total_flops += (double)
L_->NumGlobalNonzeros();
483 total_flops += (double)
D_->GlobalLength();
484 if (
RelaxValue_!=0.0) total_flops += 2 * (double)
D_->GlobalLength();
504 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
511 bool UnitDiagonal =
true;
539 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
579 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
593 Teuchos::RefCountPtr< const Epetra_MultiVector > Xcopy;
602 #ifdef IFPACK_FLOPCOUNTERS
604 (
L_->NumGlobalNonzeros() +
U_->NumGlobalNonzeros());
616 const int MaxIters,
const double Tol,
620 #ifdef IFPACK_TEUCHOS_TIME_MONITOR
638 if (!
Comm().MyPID()) {
640 os <<
"================================================================================" << endl;
641 os <<
"Ifpack_ILU: " <<
Label() << endl << 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;
651 os <<
"nonzeros / rows = "
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;