From 77de06505a6e43194d3500f7dfcea040db76b2b9 Mon Sep 17 00:00:00 2001
From: Peter Bastian <peter@dune-project.org>
Date: Tue, 19 Oct 2004 08:48:59 +0000
Subject: [PATCH] cant remember..

[[Imported from SVN: r925]]
---
 istl/fmatrix.hh | 108 ++++++++++++++++++++++++++++++++++--------------
 istl/gsetc.hh   |  10 ++---
 2 files changed, 81 insertions(+), 37 deletions(-)

diff --git a/istl/fmatrix.hh b/istl/fmatrix.hh
index 42460b18c..fb83cb3ab 100644
--- a/istl/fmatrix.hh
+++ b/istl/fmatrix.hh
@@ -327,17 +327,17 @@ namespace Dune {
 
   //! compute inverse
   template<class K, int n>
-  void fm_inverse (const FieldMatrix<K,n,n>& Ain, FieldMatrix<K,n,n>& Ainv)
+  void fm_invert (FieldMatrix<K,n,n>& B)
   {
-    FieldMatrix<K,n,n> A(Ain);
+    FieldMatrix<K,n,n> A(B);
     FieldMatrix<K,n,n>& L=A;
     FieldMatrix<K,n,n>& U=A;
 
-    double norm=A.one_norm_real();     // for relative thresholds
+    double norm=A.infinity_norm_real();     // for relative thresholds
     double pivthres = std::max(ISTLPrecision::absolute_limit(),norm*ISTLPrecision::pivoting_limit());
     double singthres = std::max(ISTLPrecision::absolute_limit(),norm*ISTLPrecision::singular_limit());
 
-    // LU decomposition of A
+    // LU decomposition of A in A
     for (int i=0; i<n; i++)      // loop over all rows
     {
       double pivmax=fvmeta_absreal(A[i][i]);
@@ -345,7 +345,7 @@ namespace Dune {
       // pivoting ?
       if (pivmax<pivthres)
       {
-        // compute maximum of row
+        // compute maximum of column
         int imax=i; double abs;
         for (int k=i+1; k<n; k++)
           if ((abs=fvmeta_absreal(A[k][i]))>pivmax)
@@ -365,61 +365,60 @@ namespace Dune {
       // eliminate
       for (int k=i+1; k<n; k++)
       {
-        K factor = -A[k][i]/A[i][i];
+        K factor = A[k][i]/A[i][i];
         L[k][i] = factor;
         for (int j=i+1; j<n; j++)
-          A[k][j] += factor*A[i][j];
+          A[k][j] -= factor*A[i][j];
       }
     }
 
     // initialize inverse
-    Ainv = 0;
-    for (int i=0; i<n; i++) Ainv[i][i] = 1;
+    B = 0;
+    for (int i=0; i<n; i++) B[i][i] = 1;
 
-    // L Y = I
+    // L Y = I; multiple right hand sides
     for (int i=0; i<n; i++)
-      for (int k=0; k<n; k++)
-      {
-        for (int j=0; j<n; j++)
-          Ainv[i][k] -= L[i][j]*Ainv[j][k];
-      }
+      for (int j=0; j<i; j++)
+        for (int k=0; k<n; k++)
+          B[i][k] -= L[i][j]*B[j][k];
 
     // U A^{-1} = Y
     for (int i=n-1; i>=0; i--)
       for (int k=0; k<n; k++)
       {
         for (int j=i+1; j<n; j++)
-          Ainv[i][k] -= U[i][j]*Ainv[j][k];
-        Ainv[i][k] = Ainv[i][k]/U[i][i];
+          B[i][k] -= U[i][j]*B[j][k];
+        B[i][k] /= U[i][i];
       }
   }
 
   //! compute inverse n=1
   template<class K>
-  void fm_inverse (const FieldMatrix<K,1,1>& Ain, FieldMatrix<K,1,1>& Ainv)
+  void fm_invert (FieldMatrix<K,1,1>& A)
   {
 #ifdef DUNE_ISTL_WITH_CHECKING
-    if (fvmeta_absreal(Ain[0][0])<ISTLPrecision::absolute_limit())
+    if (fvmeta_absreal(A[0][0])<ISTLPrecision::absolute_limit())
       DUNE_THROW(ISTLError,"matrix is singular");
 #endif
-    Ainv[0][0] = 1/Ain[0][0];
+    A[0][0] = 1/A[0][0];
   }
 
   //! compute inverse n=2
   template<class K>
-  void fm_inverse (const FieldMatrix<K,2,2>& Ain, FieldMatrix<K,2,2>& Ainv)
+  void fm_invert (FieldMatrix<K,2,2>& A)
   {
-    K detinv = Ain[0][0]*Ain[1][1]-Ain[0][1]*Ain[1][0];
+    K detinv = A[0][0]*A[1][1]-A[0][1]*A[1][0];
 #ifdef DUNE_ISTL_WITH_CHECKING
     if (fvmeta_absreal(detinv)<ISTLPrecision::absolute_limit())
       DUNE_THROW(ISTLError,"matrix is singular");
 #endif
     detinv = 1/detinv;
 
-    Ainv[0][0] =  Ain[1][1]*detinv;
-    Ainv[0][1] = -Ain[0][1]*detinv;
-    Ainv[1][0] = -Ain[1][0]*detinv;
-    Ainv[1][1] =  Ain[0][0]*detinv;
+    K temp=A[0][0];
+    A[0][0] =  A[1][1]*detinv;
+    A[0][1] = -A[0][1]*detinv;
+    A[1][0] = -A[1][0]*detinv;
+    A[1][1] =  temp*detinv;
   }
 
   //! left multiplication with matrix
@@ -456,6 +455,41 @@ namespace Dune {
     A[1][1] = M[1][0]*C[0][1] + M[1][1]*C[1][1];
   }
 
+  //! right multiplication with matrix
+  template<class K, int n, int m>
+  void fm_rightmultiply (const FieldMatrix<K,m,m>& M, FieldMatrix<K,n,m>& A)
+  {
+    FieldMatrix<K,n,m> C(A);
+
+    for (int i=0; i<n; i++)
+      for (int j=0; j<m; j++)
+      {
+        A[i][j] = 0;
+        for (int k=0; k<m; k++)
+          A[i][j] += C[i][k]*M[k][j];
+      }
+  }
+
+  //! right multiplication with matrix, n=1
+  template<class K>
+  void fm_rightmultiply (const FieldMatrix<K,1,1>& M, FieldMatrix<K,1,1>& A)
+  {
+    A[0][0] *= M[0][0];
+  }
+
+  //! right multiplication with matrix, n=2
+  template<class K>
+  void fm_rightmultiply (const FieldMatrix<K,2,2>& M, FieldMatrix<K,2,2>& A)
+  {
+    FieldMatrix<K,2,2> C(A);
+
+    A[0][0] = C[0][0]*M[0][0] + C[0][1]*M[1][0];
+    A[0][1] = C[0][0]*M[0][1] + C[0][1]*M[1][1];
+    A[1][0] = C[1][0]*M[0][0] + C[1][1]*M[1][0];
+    A[1][1] = C[1][0]*M[0][1] + C[1][1]*M[1][1];
+  }
+
+
   /**! Matrices represent linear maps from a vector space V to a vector space W.
        This class represents such a linear map by storing a two-dimensional
        array of numbers of a given field type K. The number of rows and
@@ -923,9 +957,9 @@ namespace Dune {
     }
 
     //! compute inverse
-    void inverse (FieldMatrix& Ainv) const
+    void invert ()
     {
-      fm_inverse(*this,Ainv);
+      fm_invert(*this);
     }
 
     //! left multiplication
@@ -935,6 +969,13 @@ namespace Dune {
       return *this;
     }
 
+    //! left multiplication
+    FieldMatrix& rightmultiply (const FieldMatrix<K,n,n>& M)
+    {
+      fm_rightmultiply(M,*this);
+      return *this;
+    }
+
 
     //===== sizes
 
@@ -1178,9 +1219,9 @@ namespace Dune {
     }
 
     //! compute inverse
-    void inverse (K11Matrix& Ainv) const
+    void invert ()
     {
-      Ainv.a = 1/a;
+      a = 1/a;
     }
 
     //! left multiplication
@@ -1190,6 +1231,13 @@ namespace Dune {
       return *this;
     }
 
+    //! left multiplication
+    K11Matrix& rightmultiply (const K11Matrix<K>& M)
+    {
+      a *= M.a;
+      return *this;
+    }
+
 
     //===== sizes
 
diff --git a/istl/gsetc.hh b/istl/gsetc.hh
index 2e7d75eb9..6d2d35b39 100644
--- a/istl/gsetc.hh
+++ b/istl/gsetc.hh
@@ -10,8 +10,6 @@
 #include <string>
 
 #include "istlexception.hh"
-#include "fvector.hh"
-#include "fmatrix.hh"
 
 /*! \file __FILE__
 
@@ -89,12 +87,10 @@ namespace Dune {
       for (rowiterator i=A.rbegin(); i!=rendi; --i)
       {
         bblock rhs(d[i.index()]);
-        coliterator ii=(*i).find(i.index());
-        coliterator endj=(*i).end();
-        coliterator j=ii; ++j;
-        for (; j!=endj; ++j)
+        coliterator j;
+        for (j=(*i).rbegin(); j.index()>i.index(); --j)
           (*j).mmv(v[j.index()],rhs);
-        algmeta_btsolve<I-1,diag,relax>::butsolve(*ii,v[i.index()],rhs,w);
+        algmeta_btsolve<I-1,diag,relax>::butsolve(*j,v[i.index()],rhs,w);
       }
     }
   };
-- 
GitLab