From 59ec2774bc4a7f8f1b46cecf945e631c08e56e7f Mon Sep 17 00:00:00 2001
From: Thomas Witkowski <thomas.witkowski@gmx.de>
Date: Mon, 6 Jun 2011 10:41:09 +0000
Subject: [PATCH] Word-around for a bug in solving Rosenbrock system using
 UMFPACK.

---
 AMDiS/src/DOFMatrix.cc                 |  3 +-
 AMDiS/src/Debug.cc                     |  1 +
 AMDiS/src/ITL_OEMSolver.h              | 22 ++++----
 AMDiS/src/ITL_OEMSolver.hh             | 70 +++++++++++++-------------
 AMDiS/src/MTL4Solver.h                 | 68 ++++++++++++-------------
 AMDiS/src/OEMSolver.h                  | 49 ++----------------
 AMDiS/src/ProblemStat.cc               |  2 +
 AMDiS/src/UmfPackSolver.h              | 19 ++++---
 AMDiS/src/time/RosenbrockStationary.cc |  3 +-
 9 files changed, 97 insertions(+), 140 deletions(-)

diff --git a/AMDiS/src/DOFMatrix.cc b/AMDiS/src/DOFMatrix.cc
index 6b19f136..c1cbe8ab 100644
--- a/AMDiS/src/DOFMatrix.cc
+++ b/AMDiS/src/DOFMatrix.cc
@@ -241,7 +241,8 @@ namespace AMDiS {
       } else {
 	for (int j = 0; j < nCol; j++) {
 	  DegreeOfFreedom col = colIndices[j];
-	  ins[row][col] += elMat[i][j];
+	  if (fabs(elMat[i][j]) > 1e-10)
+	    ins[row][col] += elMat[i][j];
 	}
       }
     }
diff --git a/AMDiS/src/Debug.cc b/AMDiS/src/Debug.cc
index ca4f4ff1..305ae867 100644
--- a/AMDiS/src/Debug.cc
+++ b/AMDiS/src/Debug.cc
@@ -437,6 +437,7 @@ namespace AMDiS {
 
       std::ofstream out;
       out.open(filename.c_str());
+      out.precision(20);
     
       for (cursor_type cursor = begin<major>(mat.getBaseMatrix()), 
 	     cend = end<major>(mat.getBaseMatrix()); cursor != cend; ++cursor)
diff --git a/AMDiS/src/ITL_OEMSolver.h b/AMDiS/src/ITL_OEMSolver.h
index 6889a75e..853afdbf 100644
--- a/AMDiS/src/ITL_OEMSolver.h
+++ b/AMDiS/src/ITL_OEMSolver.h
@@ -45,11 +45,11 @@ namespace AMDiS {
   template <typename ITLSolver>
   class ITL_OEMSolver : public MTL4Solver< MTLTypes::MTLMatrix, MTLTypes::MTLVector, ITL_OEMSolver_runner< ITLSolver > >  {
 
-    protected:
-    public:
+  protected:
+  public:
     /// The constructor reads needed parameters and sets solvers \ref name.
     ITL_OEMSolver(std::string name) : 
-	    MTL4Solver< MTLTypes::MTLMatrix, MTLTypes::MTLVector, ITL_OEMSolver_runner< ITLSolver > >(name)  {}
+      MTL4Solver< MTLTypes::MTLMatrix, MTLTypes::MTLVector, ITL_OEMSolver_runner< ITLSolver > >(name)  {}
 
   
     ~ITL_OEMSolver() {}
@@ -77,19 +77,19 @@ namespace AMDiS {
    */
   template <typename ITLSolver>
   class ITL_OEMSolver_para
-      : public MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > > // ITL_OEMSolver<ITLSolver>
+    : public MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > > // ITL_OEMSolver<ITLSolver>
   {
   public:
-      /// The constructor reads needed parameters and sets solvers \ref name.
-      ITL_OEMSolver_para(std::string name) 
-	  : MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > >(name) 
-      {
+    /// The constructor reads needed parameters and sets solvers \ref name.
+    ITL_OEMSolver_para(std::string name) 
+      : MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > >(name) 
+    {
 
-      }
+    }
       
-      ~ITL_OEMSolver_para() {}
+    ~ITL_OEMSolver_para() {}
 
-      /// Set parameter of iterative solver
+    /// Set parameter of iterative solver
 
     class Creator : public OEMSolverCreator
     {
diff --git a/AMDiS/src/ITL_OEMSolver.hh b/AMDiS/src/ITL_OEMSolver.hh
index 248584d3..a515a62e 100644
--- a/AMDiS/src/ITL_OEMSolver.hh
+++ b/AMDiS/src/ITL_OEMSolver.hh
@@ -9,51 +9,51 @@ namespace AMDiS {
     /// Pointer to the right preconditioner
     ITL_BasePreconditioner< Vector >* r;
     PreconPair():
-	    l(NULL), r(NULL)
-	  {}
+      l(NULL), r(NULL)
+    {}
 
   };
 
   struct BaseITL_runner { 
     OEMSolver& oem;
     BaseITL_runner(OEMSolver* oemPtr):
-	    oem(*oemPtr)
+      oem(*oemPtr)
     {
       TEST_EXIT(oemPtr != NULL)("need a real oemsolver\n");
     }
 
     template< typename Vector , typename Matrix >
-      void setPrecon(PreconPair< Vector >& pair, const Matrix& matrix)
-      {
-	/// Creator for the left preconditioner
-	CreatorInterface< ITL_BasePreconditioner< Vector > >* leftCreator(NULL);
-
-	/// Creator for the right preconditioner
-	CreatorInterface< ITL_BasePreconditioner< Vector > >* rightCreator(NULL);
-
-	std::string preconType("no");
-	Parameters::get(oem.getName() + "->left precon", preconType);
-
-	leftCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType);
-	TEST_EXIT(leftCreator != NULL)
-		("there is no creator for the given left preconditioner");
-
-	preconType = "no";
-	Parameters::get(oem.getName() + "->right precon", preconType);
-	rightCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType);
-	TEST_EXIT(rightCreator != NULL)
-		("there is no creator for the given right preconditioner");
-
-	pair.l = leftCreator->create(matrix);
-	pair.r = rightCreator->create(matrix);
-      }
+    void setPrecon(PreconPair< Vector >& pair, const Matrix& matrix)
+    {
+      /// Creator for the left preconditioner
+      CreatorInterface< ITL_BasePreconditioner< Vector > >* leftCreator(NULL);
+
+      /// Creator for the right preconditioner
+      CreatorInterface< ITL_BasePreconditioner< Vector > >* rightCreator(NULL);
+
+      std::string preconType("no");
+      Parameters::get(oem.getName() + "->left precon", preconType);
+
+      leftCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType);
+      TEST_EXIT(leftCreator != NULL)
+	("there is no creator for the given left preconditioner");
+
+      preconType = "no";
+      Parameters::get(oem.getName() + "->right precon", preconType);
+      rightCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType);
+      TEST_EXIT(rightCreator != NULL)
+	("there is no creator for the given right preconditioner");
+
+      pair.l = leftCreator->create(matrix);
+      pair.r = rightCreator->create(matrix);
+    }
   };
 
   template< typename ITLSolver >
   struct ITL_OEMSolver_para_runner : BaseITL_runner {
     ITL_OEMSolver_para_runner(OEMSolver* oem_):
-	      BaseITL_runner(oem_),
-	      ell(1)
+      BaseITL_runner(oem_),
+      ell(1)
     {
       ell=oem.getMaxIterations();
       Parameters::get(oem.getName() + "->ell", ell);
@@ -63,11 +63,11 @@ namespace AMDiS {
     int solve(const Matrix& A, Vector& x, Vector& b) 
     {
       itl::cyclic_iteration<typename Matrix::value_type> iter(b, oem.getMaxIterations(), oem.getRelative(), 
-					     oem.getTolerance(), oem.getPrint_cycle());
+							      oem.getTolerance(), oem.getPrint_cycle());
 
       static PreconPair< Vector > preconPair;
       if (preconPair.l == NULL || preconPair.r == NULL || !oem.getMultipleRhs())
-	     BaseITL_runner::setPrecon(preconPair, A); 
+	BaseITL_runner::setPrecon(preconPair, A); 
 
       int error = ITLSolver()(A, x, b, *(preconPair.l), *(preconPair.r), iter, ell);
       oem.setIterations(iter.iterations());
@@ -75,7 +75,7 @@ namespace AMDiS {
       oem.setErrorCode(error);
       return error;
     }
-    private:
+  private:
     int ell;
   };
 
@@ -84,18 +84,18 @@ namespace AMDiS {
    
    
     ITL_OEMSolver_runner(OEMSolver* oem):
-	    BaseITL_runner(oem)
+      BaseITL_runner(oem)
     {}
 
     template< typename Matrix, typename Vector>
     int solve(const Matrix& A, Vector& x, Vector& b) 
     {
       itl::cyclic_iteration<typename Matrix::value_type> iter(b, oem.getMaxIterations(), oem.getRelative(), 
-					     oem.getTolerance(), oem.getPrint_cycle());
+							      oem.getTolerance(), oem.getPrint_cycle());
 
       static PreconPair< Vector > preconPair;
       if (preconPair.l == NULL || preconPair.r == NULL || !oem.getMultipleRhs())
-	     BaseITL_runner::setPrecon(preconPair, A); 
+	BaseITL_runner::setPrecon(preconPair, A); 
 
       int error = ITLSolver()(A, x, b, *(preconPair.l), *(preconPair.r), iter);
       oem.setErrorCode(error);
diff --git a/AMDiS/src/MTL4Solver.h b/AMDiS/src/MTL4Solver.h
index b6ba1907..1d26715f 100644
--- a/AMDiS/src/MTL4Solver.h
+++ b/AMDiS/src/MTL4Solver.h
@@ -25,53 +25,49 @@
 #include <iostream>
 
 namespace AMDiS {
-  template< typename MTLMatrix, typename MTLVector, typename Worker >
-  class MTL4Solver : public OEMSolver {
-
-    protected:
 
-      Worker worker;
-
-      template< typename Matrix, typename Vector, typename Mapper >
-      int solve(const Matrix& A, Vector& x, Vector& b, Mapper& mapper) 
-      {
-	 MTLMatrix matrix(mapper.nRow(), mapper.nCol());
-	 set_to_zero(matrix);
-	 MatMap< const Matrix, Mapper > matMap(A,mapper);
-	 matrix << matMap;
+  template< typename MTLMatrix, typename MTLVector, typename Worker >
+  class MTL4Solver : public OEMSolver {    
+  protected:    
+    Worker worker;
 
-         MTLVector mtl_x(mapper.nRow());
-	 set_to_zero(mtl_x);
-	 VecMap< Vector, Mapper > xVecMap(x, mapper);
-	 mtl_x << xVecMap;
+    template< typename Matrix, typename Vector, typename Mapper >
+    int solve(const Matrix& A, Vector& x, Vector& b, Mapper& mapper) 
+    {
+      MTLMatrix matrix(mapper.nRow(), mapper.nCol());
+      set_to_zero(matrix);
+      MatMap< const Matrix, Mapper > matMap(A,mapper);
+      matrix << matMap;
 
-	 MTLVector mtl_b(mapper.nRow());
-	 set_to_zero(mtl_b);
-	 VecMap< Vector, Mapper> bVecMap(b, mapper);
-	 mtl_b << bVecMap;
+      MTLVector mtl_x(mapper.nRow());
+      set_to_zero(mtl_x);
+      VecMap< Vector, Mapper > xVecMap(x, mapper);
+      mtl_x << xVecMap;
 
-	 error = worker.solve(matrix, mtl_x, mtl_b);
+      MTLVector mtl_b(mapper.nRow());
+      set_to_zero(mtl_b);
+      VecMap< Vector, Mapper> bVecMap(b, mapper);
+      mtl_b << bVecMap;
 
-	 mtl_x >> xVecMap;
-	 return error;
-      }
+      error = worker.solve(matrix, mtl_x, mtl_b);
 
-    public:
-      MTL4Solver(std::string n):
-	OEMSolver(n),
-        worker(this)
-      {
-	FUNCNAME("MTL4Solver()");
+      mtl_x >> xVecMap;
+      return error;
+    }
 
-      }
+  public:
+    MTL4Solver(std::string n):
+      OEMSolver(n),
+      worker(this)
+    {}
 
-      virtual int solveSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A,
+    virtual int solveSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A,
 			    SystemVector& x, 
 			    SystemVector& b,
 			    VectorialMapper& m)
-      {
-	return solve(A,x,b,m);
-      }
+    {
+      return solve(A,x,b,m);
+    }
 
       
   };
diff --git a/AMDiS/src/OEMSolver.h b/AMDiS/src/OEMSolver.h
index 8d30802b..329bad38 100644
--- a/AMDiS/src/OEMSolver.h
+++ b/AMDiS/src/OEMSolver.h
@@ -73,9 +73,7 @@ namespace AMDiS {
 	print_cycle(100),
 	iterations(-1),
 	error(-1),
-	multipleRhs(false)/*,
-	leftPrecon(NULL),
-	rightPrecon(NULL)*/
+	multipleRhs(false)
     {}
 
     ///
@@ -99,47 +97,13 @@ namespace AMDiS {
 			    SystemVector& x, 
 			    SystemVector& b,
 			    VectorialMapper&) = 0;
-#if 0
-    {
-      int ns = x.getSize(),  // Number of systems.
-	size = x.getUsedSize(); // Size of all DOFVectors
-
-      // Copy vectors
-      mtl::dense_vector<value_type>   xx(size), bb(size);
-      xx << x;
-      bb << b
-/*      for (int i = 0, counter = 0; i < ns; i++) {
-	DOFVector<double>::Iterator it_b(b.getDOFVector(i), USED_DOFS);	  
-	DOFVector<double>::Iterator it_x(x.getDOFVector(i), USED_DOFS);
-	
-	for (it_b.reset(), it_x.reset(); !it_b.end(); ++it_b, ++it_x) {	
-	  bb[counter] = *it_b;
-	  xx[counter] = *it_x;
-	  counter++;
-	}
-      }
-     */
-      // Solver on DOFVector for single system
-      DOFMatrix::base_matrix_type baseA;
-      baseA << A;
-      int r = solveSystem(baseA, xx, bb);
-      
-      for (int i = 0, counter = 0; i < ns; i++) {
-	DOFVector<double>::Iterator it(x.getDOFVector(i), USED_DOFS);	  
-	for (it.reset(); !it.end(); ++it)	
-	  *it = xx[counter++];	
-      }
-      
-      return r;
-    }
-#endif
 
     inline int solveSystem(const SolverMatrix< Matrix< DOFMatrix* > >& A,
 		    SystemVector& x,
 		    SystemVector& b) 
     {
-	    VectorialMapper mapper(A);
-	    return solveSystem(A, x, b, mapper);
+      VectorialMapper mapper(A);
+      return solveSystem(A, x, b, mapper);
     }
 
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
@@ -306,13 +270,6 @@ namespace AMDiS {
      * as they can do the factorization of the matrix only once.
      */
     bool multipleRhs;
-#if 0
-    /// Left preconditioner (ignored by some iterative solvers and by UmfPack)
-    PreconCreator *leftPrecon;
-
-    /// Right preconditioner (ignored by some iterative solvers and by UmfPack)
-    PreconCreator *rightPrecon;
-#endif
   };
 
   /** 
diff --git a/AMDiS/src/ProblemStat.cc b/AMDiS/src/ProblemStat.cc
index fd6dd0cd..288a6e2b 100644
--- a/AMDiS/src/ProblemStat.cc
+++ b/AMDiS/src/ProblemStat.cc
@@ -634,6 +634,8 @@ namespace AMDiS {
   {
     FUNCNAME("ProblemStat::buildAfterCoarsen()");
 
+    VtkWriter::writeFile(rhs->getDOFVector(0), "test.vtu");
+
 //     buildAfterCoarsen_sebastianMode(adaptInfo, flag);
 //     return;
 
diff --git a/AMDiS/src/UmfPackSolver.h b/AMDiS/src/UmfPackSolver.h
index 795153ce..783cdb8b 100644
--- a/AMDiS/src/UmfPackSolver.h
+++ b/AMDiS/src/UmfPackSolver.h
@@ -52,6 +52,8 @@ namespace AMDiS {
       store_symbolic(0),
       symmetric_strategy(0)
     {
+      FUNCNAME("Umfpack_runner::Umfpack_runner()");
+
       TEST_EXIT_DBG(oem_ != NULL)("Need real OEMSolver\n"); 
       Parameters::get(oem.getName() + "->store symbolic", store_symbolic);
       Parameters::get(oem.getName() + "->symmetric strategy", symmetric_strategy);
@@ -60,15 +62,14 @@ namespace AMDiS {
     template< typename Vector> 
     int solve(const Matrix& A, Vector& x, Vector& b) 
     { 
-     FUNCNAME("(UmfPackSolver.h)::solve()");
-     if (!solver) {
+      FUNCNAME("Umfpack_runner::solve()");
+      if (!solver) {
         if (!symmetric_strategy)
 	  solver = new mtl::matrix::umfpack::solver<matrix_type>(A);
 	else
 	  solver = new mtl::matrix::umfpack::solver<matrix_type>(A, UMFPACK_STRATEGY_SYMMETRIC);
       } else {
 	if (!oem.getMultipleRhs()) {
-
  	  if (store_symbolic)
  	    solver->update_numeric();
  	  else
@@ -77,16 +78,14 @@ namespace AMDiS {
       }
 
       int code = (*solver)(x, b);
-      if( oem.getInfo() > 0) {
+      if (oem.getInfo() > 0) {
         mtl::dense_vector<typename matrix_type::value_type> r(b); 
         r -= A * x; 
         double residual = two_norm(r);
         oem.setResidual(residual);
         oem.setErrorCode(code);
         std::cout << "UmfPackSolver: ||b-Ax|| = " << residual << "\n";
-	if (residual > oem.getTolerance()) {
-	    ERROR_EXIT("Tolerance tol=%e could not be reached!\n Set tolerance by '->solver->tolerance:' \n", oem.getTolerance());	  
-	}
+	TEST_EXIT(residual <= oem.getTolerance())("Tolerance tol = %e could not be reached!\n Set tolerance by '->solver->tolerance:' \n", oem.getTolerance());	
       }
       return code;
 
@@ -94,11 +93,11 @@ namespace AMDiS {
 
     ~Umfpack_runner() 
     {
-      if(!solver)
+      if (!solver)
 	delete solver;
     }
 
-    private:
+  private:
     mtl::matrix::umfpack::solver<matrix_type> *solver;
 
     int store_symbolic;
@@ -108,7 +107,7 @@ namespace AMDiS {
   using namespace MTLTypes;
   class UmfPackSolver : public MTL4Solver<MTLMatrix, MTLVector, Umfpack_runner< MTLMatrix > >
   {
-    protected:
+  protected:
 
   public:
     /// Creator class used in the OEMSolverMap.
diff --git a/AMDiS/src/time/RosenbrockStationary.cc b/AMDiS/src/time/RosenbrockStationary.cc
index 7b029b06..87ec8da9 100644
--- a/AMDiS/src/time/RosenbrockStationary.cc
+++ b/AMDiS/src/time/RosenbrockStationary.cc
@@ -14,6 +14,7 @@
 #include "ProblemStat.h"
 #include "SystemVector.h"
 #include "OEMSolver.h"
+#include "Debug.h"
 
 namespace AMDiS {
 
@@ -79,7 +80,7 @@ namespace AMDiS {
       }
       
       ProblemStatSeq::buildAfterCoarsen(adaptInfo, flag, (i == 0), asmVector);
-      solver->setMultipleRhs(i != 0);
+      //      solver->setMultipleRhs(i != 0);
       ProblemStatSeq::solve(adaptInfo);
       
       *(stageSolutions[i]) = *solution;
-- 
GitLab