From fc241636081fa3323f60008d2ccea1e86955322d Mon Sep 17 00:00:00 2001
From: Peter Bastian <peter@dune-project.org>
Date: Fri, 22 Oct 2004 17:18:51 +0000
Subject: [PATCH] ILU(n) works (as far as I could test it). Unfortunately only
 n=0 and n=1 are practically useful. n=2 is already a direct solver. (May I
 have still something wrong ...)

[[Imported from SVN: r978]]
---
 istl/ilu.hh              | 54 ++++++++++++++++++++++++----------------
 istl/tutorial/example.cc | 14 +++++++----
 2 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/istl/ilu.hh b/istl/ilu.hh
index 7c65a46d4..3cbab2e7e 100644
--- a/istl/ilu.hh
+++ b/istl/ilu.hh
@@ -160,7 +160,7 @@ namespace Dune {
     createiterator ci=ILU.createbegin();
     for (crowiterator i=A.begin(); i!=endi; ++i)
     {
-      std::cout << "symbolic factorization, row " << i.index() << std::endl;
+      //		std::cout << "in row " << i.index() << std::endl;
       map rowpattern;           // maps column index to generation
 
       // initialize pattern with row of A
@@ -170,22 +170,27 @@ namespace Dune {
       // eliminate entries in row which are to the left of the diagonal
       for (mapiterator ik=rowpattern.begin(); (*ik).first<i.index(); ++ik)
       {
-        std::cout << "eliminating " << i.index() << "," << (*ik).first
-                  << std::endl;
-        coliterator endk = ILU[(*ik).first].end();                 // end of row k
-        coliterator kj = ILU[(*ik).first].find((*ik).first);                 // diagonal in k
-        for (++kj; kj!=endk; ++kj)                 // row k eliminates in row i
+        if ((*ik).second<n)
         {
-          int generation = static_cast<int>(firstmatrixelement(*kj));
-          mapiterator ij = rowpattern.find(kj.index());
-          if (ij==rowpattern.end())
-          {                         // new entry
+          //                            std::cout << "  eliminating " << i.index() << "," << (*ik).first
+          //                                              << " level " << (*ik).second << std::endl;
+
+          coliterator endk = ILU[(*ik).first].end();                       // end of row k
+          coliterator kj = ILU[(*ik).first].find((*ik).first);                       // diagonal in k
+          for (++kj; kj!=endk; ++kj)                       // row k eliminates in row i
+          {
+            int generation = (int) firstmatrixelement(*kj);
             if (generation<n)
-              rowpattern[kj.index()] = generation+1;
-          }
-          else
-          {                         // entry exists already
-            (*ij).second = std::min((*ij).second,generation+1);
+            {
+              mapiterator ij = rowpattern.find(kj.index());
+              if (ij==rowpattern.end())
+              {
+                //std::cout << "    new entry " << i.index() << "," << kj.index()
+                //                                                << " level " << (*ik).second+1 << std::endl;
+
+                rowpattern[kj.index()] = generation+1;
+              }
+            }
           }
         }
       }
@@ -195,17 +200,19 @@ namespace Dune {
         ci.insert((*ik).first);
       ++ci;           // now row i exist
 
-      // set generation index on new row
-      coliterator endik=ILU[i.index()].end();
-      for (coliterator ik=ILU[i.index()].begin(); ik!=endik; ++ik)
-        firstmatrixelement(*ik) = static_cast<K>(rowpattern[ik.index()]);
+      // write generation index into entries
+      coliterator endILUij = ILU[i.index()].end();;
+      for (coliterator ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
+        firstmatrixelement(*ILUij) = (K) rowpattern[ILUij.index()];
     }
 
-    // initialize new matrix with A
+    //	printmatrix(std::cout,ILU,"ilu pattern","row",10,2);
+
+    // copy entries of A
     for (crowiterator i=A.begin(); i!=endi; ++i)
     {
-      coliterator ILUij = ILU[i.index()].begin();
-      coliterator endILUij;
+      coliterator ILUij;
+      coliterator endILUij = ILU[i.index()].end();;
       for (ILUij=ILU[i.index()].begin(); ILUij!=endILUij; ++ILUij)
         (*ILUij) = 0;           // clear row
       ccoliterator Aij = (*i).begin();
@@ -214,7 +221,10 @@ namespace Dune {
       while (Aij!=endAij && ILUij!=endILUij)
       {
         if (Aij.index()==ILUij.index())
+        {
           *ILUij = *Aij;
+          ++Aij; ++ILUij;
+        }
         else
         {
           if (Aij.index()<ILUij.index())
diff --git a/istl/tutorial/example.cc b/istl/tutorial/example.cc
index 65a4ef3e0..ac76300a0 100644
--- a/istl/tutorial/example.cc
+++ b/istl/tutorial/example.cc
@@ -435,7 +435,7 @@ void test_Iter ()
 void test_Interface ()
 {
   // define Types
-  const int BlockSize = 1;
+  const int BlockSize = 6;
   typedef Dune::FieldVector<double,BlockSize> VB;
   typedef Dune::FieldMatrix<double,BlockSize,BlockSize> MB;
   typedef Dune::BlockVector<VB> Vector;
@@ -452,7 +452,7 @@ void test_Interface ()
     E[i][i] = -1;
 
   // make a block compressed row matrix with five point stencil
-  const int BW2=64, BW1=1, N=BW2*BW2;
+  const int BW2=100, BW1=1, N=BW2*BW2;
   Matrix A(N,N,5*N,Dune::BCRSMatrix<MB>::row_wise);
   for (Matrix::CreateIterator i=A.createbegin(); i!=A.createend(); ++i)
   {
@@ -469,6 +469,8 @@ void test_Interface ()
       else
         (*j) = E;
 
+  //  printmatrix(std::cout,A,"system matrix","row",10,2);
+
   // set up system
   Vector x(N),b(N);
   x=0; x[0]=1; x[N-1]=2; // prescribe known solution
@@ -477,10 +479,12 @@ void test_Interface ()
 
   // set up the high-level solver objects
   Dune::MatrixAdapter<Matrix,Vector,Vector> op(A);        // make linear operator from A
-  Dune::SeqSSOR<Matrix,Vector,Vector> ssor(A,1,1.78);     // SSOR preconditioner
+  Dune::SeqSSOR<Matrix,Vector,Vector> ssor(A,1,1);     // SSOR preconditioner
   Dune::SeqILU0<Matrix,Vector,Vector> ilu0(A);            // preconditioner object
-  Dune::CGSolver<Vector> cg(op,ilu0,1E-8,8000,2);         // an inverse operator
-  Dune::BiCGSTABSolver<Vector> bcgs(op,ilu0,1E-8,8000,2); // an inverse operator
+  Dune::SeqILUn<Matrix,Vector,Vector> ilun(A,1);          // preconditioner object
+  Dune::LoopSolver<Vector> loop(op,ilun,1E-8,8000,2);     // an inverse operator
+  Dune::CGSolver<Vector> cg(op,ilun,1E-8,8000,2);         // an inverse operator
+  Dune::BiCGSTABSolver<Vector> bcgs(op,ilun,1E-8,8000,2); // an inverse operator
 
   // call the solver
   Dune::InverseOperatorResult r;
-- 
GitLab