From 03c66a514bc9d716a309bcbde344f8fd344911ff Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Thu, 1 Oct 2015 12:41:24 +0200
Subject: [PATCH] Allow to use UMFPackSolver as the base solver

Our polymorphic class hierarchy is flawed.  There is no real reason why the
MultigridStep class should be needed to be patched to accommodate for a new
base solver.  However, we are lacking a proper abstract interface for classes
that provide a 'setProblem' method.
---
 dune/solvers/iterationsteps/multigridstep.cc | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/dune/solvers/iterationsteps/multigridstep.cc b/dune/solvers/iterationsteps/multigridstep.cc
index 1bd539d7..022ccf05 100644
--- a/dune/solvers/iterationsteps/multigridstep.cc
+++ b/dune/solvers/iterationsteps/multigridstep.cc
@@ -5,6 +5,7 @@
 
 #include <dune/solvers/transferoperators/multigridtransfer.hh>
 #include <dune/solvers/solvers/loopsolver.hh>
+#include <dune/solvers/solvers/umfpacksolver.hh>
 #include <dune/solvers/common/genericvectortools.hh>
 #include "blockgsstep.hh"
 
@@ -169,6 +170,9 @@ void MultigridStep<MatrixType, VectorType, BitVectorType>::preprocess()
         dynamic_cast<SmootherType*>(loopBaseSolver->iterationStep_)->ignoreNodes_ = ignoreNodesHierarchy_[0];
 
     }
+    // TODO: The following two #if-clauses do the exactly the same thing: the call setProblem
+    // However, we cannot write the code generically because there is no geral abstraction
+    // for solvers that I can call 'setProblem' for.
 #if HAVE_IPOPT
     else if (typeid(*this->basesolver_) == typeid(QuadraticIPOptSolver<MatrixType,VectorType>)) {
 
@@ -177,6 +181,15 @@ void MultigridStep<MatrixType, VectorType, BitVectorType>::preprocess()
         ipoptBaseSolver->setProblem(*(this->matrixHierarchy_[0]), *this->xHierarchy_[0], this->rhsHierarchy_[0]);
     }
 #endif
+#if HAVE_UMFPACK
+    else if (typeid(*this->basesolver_) == typeid(Dune::Solvers::UMFPackSolver<MatrixType,VectorType>)) {
+
+        Dune::Solvers::UMFPackSolver<MatrixType,VectorType>* umfpackBaseSolver
+            = dynamic_cast<Dune::Solvers::UMFPackSolver<MatrixType,VectorType>*> (this->basesolver_);
+
+        umfpackBaseSolver->setProblem(*(this->matrixHierarchy_[0]), *this->xHierarchy_[0], this->rhsHierarchy_[0]);
+    }
+#endif
 else {
         DUNE_THROW(SolverError, "You can't use " << typeid(*this->basesolver_).name()
                    << " as a base solver in a MultigridStep!");
-- 
GitLab