From 53f54f998a77f75c77a3f205891f9c4f42357608 Mon Sep 17 00:00:00 2001
From: Markus Blatt <markus@dr-blatt.de>
Date: Wed, 12 Jun 2013 12:30:42 +0200
Subject: [PATCH] Adds an adapter that turns an InverseOperator into a
 Preconditioner.

This fixes FS #1224
---
 dune/istl/preconditioners.hh  | 51 +++++++++++++++++++++++++++++++++++
 dune/istl/test/CMakeLists.txt |  2 ++
 dune/istl/test/Makefile.am    |  3 +++
 3 files changed, 56 insertions(+)

diff --git a/dune/istl/preconditioners.hh b/dune/istl/preconditioners.hh
index 5cb894bee..b38c03f15 100644
--- a/dune/istl/preconditioners.hh
+++ b/dune/istl/preconditioners.hh
@@ -122,6 +122,57 @@ namespace Dune {
     virtual ~Preconditioner () {}
   };
 
+  template<class X, class Y> class InverseOperator;
+
+  class InverseOperatorResult;
+
+  /**
+   * @brief Turns an InverseOperator into a Preconditioner.
+   * @tparam O The type of the inverse operator to wrap.
+   */
+  template<class O, int c>
+  class InverseOperator2Preconditioner :
+    public Preconditioner<typename O::domain_type, typename O::range_type>
+  {
+  public:
+    //! \brief The domain type of the preconditioner.
+    typedef typename O::domain_type domain_type;
+    //! \brief The range type of the preconditioner.
+    typedef typename O::range_type range_type;
+    //! \brief The field type of the preconditioner.
+    typedef typename range_type::field_type field_type;
+    typedef O InverseOperator;
+
+    // define the category
+    enum {
+      //! \brief The category the preconditioner is part of.
+      category=c
+    };
+
+    /**
+     * @brief Construct the preconditioner from the solver
+     * @param inverse_operator The inverse operator to wrap.
+     */
+    InverseOperator2Preconditioner(InverseOperator& inverse_operator)
+    : inverse_operator_(inverse_operator)
+    {}
+
+    void pre(domain_type&,range_type&)
+    {}
+
+    void apply(domain_type& v, const range_type& d)
+    {
+      InverseOperatorResult res;
+      range_type copy(d);
+      inverse_operator_.apply(v, copy, res);
+    }
+
+    void post(domain_type&)
+    {}
+
+  private:
+    InverseOperator& inverse_operator_;
+  };
 
   //=====================================================================
   // Implementation of this interface for sequential ISTL-preconditioners
diff --git a/dune/istl/test/CMakeLists.txt b/dune/istl/test/CMakeLists.txt
index 9ea18d131..60b3dfed0 100644
--- a/dune/istl/test/CMakeLists.txt
+++ b/dune/istl/test/CMakeLists.txt
@@ -4,6 +4,7 @@ set(NORMALTEST
   bcrsbuildtest
   dotproducttest
   iotest
+  inverseoperator2prectest
   matrixiteratortest
   matrixtest
   matrixutilstest
@@ -50,6 +51,7 @@ add_executable(matrixiteratortest "matrixiteratortest.cc")
 add_executable(mmtest mmtest.cc)
 add_executable(mv "mv.cc")
 add_executable(iotest "iotest.cc")
+add_executable(inverseoperator2prectest "inverseoperator2prectest.cc")
 add_executable(scaledidmatrixtest "scaledidmatrixtest.cc")
 add_executable(seqmatrixmarkettest "matrixmarkettest.cc")
 #set_target_properties(seqmatrixmarkettest PROPERTIES COMPILE_FLAGS
diff --git a/dune/istl/test/Makefile.am b/dune/istl/test/Makefile.am
index f6d05b075..c0de4632f 100644
--- a/dune/istl/test/Makefile.am
+++ b/dune/istl/test/Makefile.am
@@ -23,6 +23,7 @@ NORMALTESTS = basearraytest \
               complexrhstest \
               dotproducttest \
               iotest \
+              inverseoperator2prectest \
               matrixiteratortest \
               matrixtest \
               matrixutilstest \
@@ -103,6 +104,8 @@ mv_SOURCES = mv.cc
 
 iotest_SOURCES = iotest.cc
 
+inverseoperator2prectest_SOURCES = inverseoperator2prectest.cc
+
 scaledidmatrixtest_SOURCES = scaledidmatrixtest.cc
 
 if MPI
-- 
GitLab