From d2aafda10727af61c5d6cc1c38428c4581b69b85 Mon Sep 17 00:00:00 2001
From: Simon Praetorius <simon.praetorius@tu-dresden.de>
Date: Fri, 26 Jun 2015 16:46:07 +0000
Subject: [PATCH] expression and DirichletBC with lambda functions

---
 AMDiS/CMakeLists.txt                          |   2 +-
 AMDiS/src/AMDiS_fwd.h                         |   8 +-
 AMDiS/src/AbstractFunction.h                  | 130 +++++++++---------
 AMDiS/src/DirichletBC.cc                      |  28 ++--
 AMDiS/src/DirichletBC.h                       | 104 ++++++++++----
 AMDiS/src/Lagrange.h                          |   2 -
 AMDiS/src/ProblemStat.cc                      |  44 +++++-
 AMDiS/src/ProblemStat.h                       |  11 ++
 AMDiS/src/expressions/expressions.h           |   6 +-
 AMDiS/src/expressions/functorN_expr.hpp       | 129 +++++++++++++++--
 AMDiS/src/expressions/functor_expr.hpp        |  10 ++
 AMDiS/src/parallel/PetscSolverGlobalMatrix.cc |   2 +-
 12 files changed, 345 insertions(+), 131 deletions(-)

diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt
index 82db8ade..3c477326 100644
--- a/AMDiS/CMakeLists.txt
+++ b/AMDiS/CMakeLists.txt
@@ -97,7 +97,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
 	      ${SOURCE_DIR}/DOFMatrix.cc
 	      ${SOURCE_DIR}/DOFVector.cc
 	      ${SOURCE_DIR}/Debug.cc
-	      ${SOURCE_DIR}/DirichletBC.cc
+# 	      ${SOURCE_DIR}/DirichletBC.cc
 	      ${SOURCE_DIR}/DualTraverse.cc
 	      ${SOURCE_DIR}/ElInfo.cc
 	      ${SOURCE_DIR}/ElInfo1d.cc
diff --git a/AMDiS/src/AMDiS_fwd.h b/AMDiS/src/AMDiS_fwd.h
index 3c030371..034443a3 100644
--- a/AMDiS/src/AMDiS_fwd.h
+++ b/AMDiS/src/AMDiS_fwd.h
@@ -28,6 +28,7 @@
 
 #include <boost/numeric/mtl/mtl.hpp>
 #include "OpenMP.h"
+#include "Config.h"
 
 namespace AMDiS {
 
@@ -133,8 +134,12 @@ namespace AMDiS {
 
   struct BoundaryObject;
   struct AtomicBoundary;
-
+  
+#if HAS_VARIADIC_TEMPLATES
+  template<typename ReturnType, typename... Args >     class AbstractFunction;
+#else
   template<typename ReturnType, typename ArgumentType> class AbstractFunction;
+#endif
   template<typename ReturnType, 
 	   typename ArgumentType1, 
 	   typename ArgumentType2>                     class BinaryAbstractFunction;
@@ -153,6 +158,7 @@ namespace AMDiS {
   template<typename T>                                 class DOFVector;
   template<typename T>                                 class DimVec;
   template<typename T>                                 class DimMat;
+  template<typename T>                                 class DirichletBC;
 //   template<typename ITLSolver>                         class ITL_LinearSolverInterface;
   template<typename T, typename MatT, typename VecT >  class ITL_Preconditioner;
   template<typename T>                                 class Matrix;
diff --git a/AMDiS/src/AbstractFunction.h b/AMDiS/src/AbstractFunction.h
index 35ec921d..df402f97 100644
--- a/AMDiS/src/AbstractFunction.h
+++ b/AMDiS/src/AbstractFunction.h
@@ -32,43 +32,6 @@
 #include <boost/preprocessor/repetition/repeat.hpp>
 
 namespace AMDiS {
-
-  /** 
-   * \ingroup Common
-   * 
-   * \brief
-   * An AbstractFunction object represents a function 
-   * f : ArgumentType -> ReturnType. 
-   *
-   * AbstractFunction is a pure virtual class interface class.
-   * To create your own function you have to derive AbstractFunction and
-   * overload operator(). 
-   */
-// #ifndef HAS_VARIADIC_TEMPLATES
-  template<typename ReturnType, typename ArgumentType>
-  class AbstractFunction
-  {
-  public:
-    /// Constructor.
-    AbstractFunction(int degree = 0) : 
-      degree_(degree) 
-    {}
-
-    virtual ~AbstractFunction() {}
-
-    /// Returns \ref degree_.
-    inline int getDegree() const 
-    { 
-      return degree_; 
-    }
-
-    /// Deligates the evaluation to overriden method f.
-    virtual ReturnType operator()(const ArgumentType& x) const = 0;
-
-  protected:
-    int degree_;
-  };
-// #endif
   
   /**
    * \ingroup Common
@@ -175,7 +138,68 @@ namespace AMDiS {
     int degree_;
   };
 
-// #ifndef HAS_VARIADIC_TEMPLATES
+#if HAS_VARIADIC_TEMPLATES
+
+  // C++11 implementation of AbstractFunction with arbitrary nr of arguments using variadic templates
+  /** 
+   * \ingroup Common
+   * 
+   * \brief
+   * An AbstractFunction object represents a function 
+   * f : ArgumentTypes... -> ReturnType. 
+   *
+   * AbstractFunction is a pure virtual class interface class.
+   * To create your own function you have to derive AbstractFunction and
+   * overload operator(). 
+   */
+  template< typename ReturnType, typename... Args >
+  class AbstractFunction
+  { 
+  public:
+    AbstractFunction(int degree = 0) 
+      : degree_(degree) 
+    {}
+
+    virtual ~AbstractFunction() {}
+
+    /// Returns \ref degree_.
+    inline int getDegree() const 
+    { 
+      return degree_; 
+    }
+
+    /// function evaluation.
+    virtual ReturnType operator()(Args const&... args) const = 0;
+
+  protected:
+    int degree_;
+  };
+  
+#else
+
+  template<typename ReturnType, typename ArgumentType>
+  class AbstractFunction
+  {
+  public:
+    /// Constructor.
+    AbstractFunction(int degree = 0) : 
+      degree_(degree) 
+    {}
+
+    virtual ~AbstractFunction() {}
+
+    /// Returns \ref degree_.
+    inline int getDegree() const 
+    { 
+      return degree_; 
+    }
+
+    /// Deligates the evaluation to overriden method f.
+    virtual ReturnType operator()(const ArgumentType& x) const = 0;
+
+  protected:
+    int degree_;
+  };
 
   ///////////////////////////////////////////////////////////////
   // test of AbstractFunction with arbitrary number of arguments
@@ -225,34 +249,8 @@ namespace AMDiS {
 #endif
   
   BOOST_PP_REPEAT_FROM_TO(1, 11, ABSTRACT_FUNCTION_MACRO, nil)
-
-// #else
-//   
-//   /// C++11 implementation of abstract functions with arbitrary nr of arguments using variadic templates
-//   template< typename ReturnType, typename... Ts >
-//   class AbstractFunction
-//   {
-//   public:
-//     AbstractFunction(int degree = 0) 
-//       : degree_(degree) 
-//     {}
-// 
-//     virtual ~AbstractFunction() {}
-// 
-//     /// Returns \ref degree_.
-//     inline int getDegree() const 
-//     { 
-//       return degree_; 
-//     }
-// 
-//     /// function evaluation.
-//     virtual ReturnType operator()(Ts const&... args) const = 0;
-// 
-//   protected:
-//     int degree_;
-//   };
-//   
-// #endif
+  
+#endif
 }
 
 #endif // AMDIS_ABSTRACTFUNCTION_H
diff --git a/AMDiS/src/DirichletBC.cc b/AMDiS/src/DirichletBC.cc
index e92c249f..1d331dba 100644
--- a/AMDiS/src/DirichletBC.cc
+++ b/AMDiS/src/DirichletBC.cc
@@ -72,21 +72,23 @@ namespace AMDiS {
 
     const BasisFunction *basFcts = rowFeSpace->getBasisFcts();
 
-    for (int i = 0; i < nBasFcts; i++) {
-      if (localBound[i] == boundaryType) {
-	double value = 0.0;
-	if (f) {
+    if (f) {
+      for (int i = 0; i < nBasFcts; i++)
+	if (localBound[i] == boundaryType) {
 	  elInfo->coordToWorld(*(basFcts->getCoords(i)), worldCoords);
-	  value = (*f)(worldCoords);
-	} else {
-	  if (dofVec)
-	    value = (*dofVec)[dofIndices[i]];
-	  else
-	    ERROR_EXIT("There is something wrong!\n");
+	  double value = (*f)(worldCoords);
+	  vector->setDirichletDofValue(dofIndices[i], value);
+	  (*vector)[dofIndices[i]] = value;
 	}
-	vector->setDirichletDofValue(dofIndices[i], value);
-	(*vector)[dofIndices[i]] = value;
-      }
+    } else if (dofVec) {
+      for (int i = 0; i < nBasFcts; i++)
+	if (localBound[i] == boundaryType) {
+	  double value = value = (*dofVec)[dofIndices[i]];
+	  vector->setDirichletDofValue(dofIndices[i], value);
+	  (*vector)[dofIndices[i]] = value;
+	}
+    } else {
+      ERROR_EXIT("No data provided to assemble DirichletBC!\n");
     }
   }
 
diff --git a/AMDiS/src/DirichletBC.h b/AMDiS/src/DirichletBC.h
index deef6f05..e30a5edb 100644
--- a/AMDiS/src/DirichletBC.h
+++ b/AMDiS/src/DirichletBC.h
@@ -30,8 +30,49 @@
 #include "AbstractFunction.h"
 #include "FixVec.h"
 
-namespace AMDiS {
+namespace AMDiS 
+{
 
+  // some tags used for tag-dispatching
+  struct _value_by_abstractfunction {};
+  struct _value_by_dofvector {};
+  struct _value_by_function {};
+  
+  namespace detail 
+  {
+    template <class Tag>
+    struct ValueContainer {};
+    
+    template <>
+    struct ValueContainer<_value_by_abstractfunction> 
+    {
+      ValueContainer(AbstractFunction<double, WorldVector<double> > *fct) : value(*fct) {};
+      ValueContainer(AbstractFunction<double, WorldVector<double> > &fct) : value(fct) {};
+      
+      AbstractFunction<double, WorldVector<double> > &value;
+    };
+    
+    template <>
+    struct ValueContainer<_value_by_dofvector> 
+    {
+      ValueContainer(DOFVectorBase<double> *vec) : value(vec) {};
+      ValueContainer(DOFVectorBase<double> &vec) : value(&vec) {};
+      
+      DOFVectorBase<double> *value;
+    };
+    
+#if __cplusplus > 199711L
+    template <>
+    struct ValueContainer<_value_by_function> 
+    {
+      ValueContainer(std::function<double(WorldVector<double>)> fct) : value(fct) {};
+      
+      std::function<double(WorldVector<double>)> value;
+    };
+#endif
+  
+  } // end namespace detail
+  
   /**
    * \ingroup Assembler
    *
@@ -41,6 +82,7 @@ namespace AMDiS {
    * the row corresponding to a Dirichlet dof is replaced by a row containing
    * only a 1.0 in the diagonal.
    */
+  template <class ValueTag>
   class DirichletBC : public BoundaryCondition
   {
   public:
@@ -50,6 +92,15 @@ namespace AMDiS {
 		const FiniteElemSpace *rowFeSpace,
 		const FiniteElemSpace *colFeSpace = NULL,
 		bool apply = true);
+		
+#if __cplusplus > 199711L
+    /// Constructor.
+    DirichletBC(BoundaryType type,
+		std::function<double(WorldVector<double>)> fct,
+		const FiniteElemSpace *rowFeSpace,
+		const FiniteElemSpace *colFeSpace = NULL,
+		bool apply = true);
+#endif
 
     /// Constructor.
     DirichletBC(BoundaryType type,
@@ -57,18 +108,18 @@ namespace AMDiS {
 		bool apply = true);
 
     /// Implementation of BoundaryCondition::fillBoundaryCondition().
-    void fillBoundaryCondition(DOFMatrix* matrix,
+    virtual void fillBoundaryCondition(DOFMatrix* matrix,
 			       ElInfo* elInfo,
 			       const DegreeOfFreedom* dofIndices,
 			       const BoundaryType* localBound,
-			       int nBasFcts);
+			       int nBasFcts) override;
   
     /// Implementation of BoundaryCondition::fillBoundaryCondition().
-    void fillBoundaryCondition(DOFVectorBase<double>* vector, 
+    virtual void fillBoundaryCondition(DOFVectorBase<double>* vector, 
 			       ElInfo* elInfo,
 			       const DegreeOfFreedom* dofIndices,
 			       const BoundaryType* localBound,
-			       int nBasFcts);
+			       int nBasFcts) override;
 
     ///
     void initVector(DOFVectorBase<double>*);
@@ -92,26 +143,31 @@ namespace AMDiS {
     {
       return applyBC;
     }
-
-    inline AbstractFunction<double, WorldVector<double> > *getF() 
-    {
-      return f;
-    }
-
-    inline DOFVectorBase<double> *getDOFVector() 
-    {
-      return dofVec;
-    }
-
+    
   protected:
-    /// Function which is evaluated at world coords of Dirichlet dofs.
-    AbstractFunction<double, WorldVector<double> > *f;
-
-    ///
-    WorldVector<double> worldCoords;
+    void fillBC(_value_by_abstractfunction,
+		DOFVectorBase<double>* vector, 
+		ElInfo* elInfo,
+		const DegreeOfFreedom* dofIndices,
+		const BoundaryType* localBound,
+		int nBasFcts);
+			       
+    void fillBC(_value_by_function,
+		DOFVectorBase<double>* vector, 
+		ElInfo* elInfo,
+		const DegreeOfFreedom* dofIndices,
+		const BoundaryType* localBound,
+		int nBasFcts);
+			       
+    void fillBC(_value_by_dofvector,
+		DOFVectorBase<double>* vector, 
+		ElInfo* elInfo,
+		const DegreeOfFreedom* dofIndices,
+		const BoundaryType* localBound,
+		int nBasFcts);
 
-    /// DOFVector containing the boundary values
-    DOFVectorBase<double> *dofVec;
+  protected:
+    detail::ValueContainer<ValueTag> container;
 
     /// Defines, if the boundary condition must be applied to the matrix. See
     /// comment of \ref BoundaryCondition::applyBoundaryCondition.
@@ -120,4 +176,6 @@ namespace AMDiS {
 
 }
 
+#include "DirichletBC.hh"
+
 #endif
diff --git a/AMDiS/src/Lagrange.h b/AMDiS/src/Lagrange.h
index c9560383..1ff25bd0 100644
--- a/AMDiS/src/Lagrange.h
+++ b/AMDiS/src/Lagrange.h
@@ -36,8 +36,6 @@ namespace AMDiS {
 #define MAX_DIM 3
 #define MAX_DEGREE 4
 
-  template<typename ReturnType, typename ArgumentType> class AbstractFunction;
-
   /** \ingroup FEMSpace
    * \brief
    * Lagrange basis functions. Sub class of BasisFunction
diff --git a/AMDiS/src/ProblemStat.cc b/AMDiS/src/ProblemStat.cc
index acc13752..3baf3a09 100644
--- a/AMDiS/src/ProblemStat.cc
+++ b/AMDiS/src/ProblemStat.cc
@@ -1383,10 +1383,10 @@ namespace AMDiS {
 
     boundaryConditionSet = true;
 
-    DirichletBC *dirichletApply = 
-      new DirichletBC(type, b, componentSpaces[row], componentSpaces[col], true);
-    DirichletBC *dirichletNotApply = 
-      new DirichletBC(type, b, componentSpaces[row], componentSpaces[col], false);
+    DirichletBC<_value_by_abstractfunction> *dirichletApply = 
+      new DirichletBC<_value_by_abstractfunction>(type, b, componentSpaces[row], componentSpaces[col], true);
+    DirichletBC<_value_by_abstractfunction> *dirichletNotApply = 
+      new DirichletBC<_value_by_abstractfunction>(type, b, componentSpaces[row], componentSpaces[col], false);
 
     for (int i = 0; i < nComponents; i++)
       if (systemMatrix && (*systemMatrix)[row][i]) {
@@ -1402,6 +1402,38 @@ namespace AMDiS {
       solution->getDOFVector(col)->getBoundaryManager()->addBoundaryCondition(dirichletApply);
   }
 
+	
+#if __cplusplus > 199711L
+  void ProblemStatSeq::addDirichletBC(BoundaryType type, int row, int col,
+				      std::function<double(WorldVector<double>)> b)
+  {
+    FUNCNAME("ProblemStat::addDirichletBC()");
+
+    TEST_EXIT(row >= 0 && row < nComponents)("Wrong row number: %d\n", row);
+    TEST_EXIT(col >= 0 && col < nComponents)("Wrong col number: %d\n", col);
+
+    boundaryConditionSet = true;
+
+    DirichletBC<_value_by_function> *dirichletApply = 
+      new DirichletBC<_value_by_function>(type, b, componentSpaces[row], componentSpaces[col], true);
+    DirichletBC<_value_by_function> *dirichletNotApply = 
+      new DirichletBC<_value_by_function>(type, b, componentSpaces[row], componentSpaces[col], false);
+
+    for (int i = 0; i < nComponents; i++)
+      if (systemMatrix && (*systemMatrix)[row][i]) {
+	if (i == col)
+	  (*systemMatrix)[row][i]->getBoundaryManager()->addBoundaryCondition(dirichletApply);
+	else
+	  (*systemMatrix)[row][i]->getBoundaryManager()->addBoundaryCondition(dirichletNotApply);
+      }	
+
+    if (rhs)
+      rhs->getDOFVector(row)->getBoundaryManager()->addBoundaryCondition(dirichletApply);
+    if (solution)
+      solution->getDOFVector(col)->getBoundaryManager()->addBoundaryCondition(dirichletApply);
+  }
+#endif
+
 
   void ProblemStatSeq::addDirichletBC(BoundaryType type, int row, int col,
 				      DOFVector<double> *vec)
@@ -1413,8 +1445,8 @@ namespace AMDiS {
 
     boundaryConditionSet = true;
 
-    DirichletBC *dirichletApply = new DirichletBC(type, vec, true);
-    DirichletBC *dirichletNotApply = new DirichletBC(type, vec, false);
+    DirichletBC<_value_by_dofvector> *dirichletApply = new DirichletBC<_value_by_dofvector>(type, vec, true);
+    DirichletBC<_value_by_dofvector> *dirichletNotApply = new DirichletBC<_value_by_dofvector>(type, vec, false);
 
     for (int i = 0; i < nComponents; i++)
       if (systemMatrix && (*systemMatrix)[row][i]) {
diff --git a/AMDiS/src/ProblemStat.h b/AMDiS/src/ProblemStat.h
index e60244d0..ffa4b863 100644
--- a/AMDiS/src/ProblemStat.h
+++ b/AMDiS/src/ProblemStat.h
@@ -27,6 +27,9 @@
 
 #include <vector>
 #include <list>
+#if __cplusplus > 199711L
+#include <functional>
+#endif
 #include "AMDiS_fwd.h"
 #include "ProblemStatBase.h"
 #include "Initfile.h"
@@ -188,6 +191,14 @@ namespace AMDiS {
     /// abstract function.
     virtual void addDirichletBC(BoundaryType type, int row, int col,
 				AbstractFunction<double, WorldVector<double> > *b);
+				
+				
+#if __cplusplus > 199711L
+    /// Adds a Dirichlet boundary condition, where the rhs is given by an 
+    /// lambda function or a std::function object
+    virtual void addDirichletBC(BoundaryType type, int row, int col,
+				std::function<double(WorldVector<double>)> b);
+#endif
 
     /// Adds a Dirichlet boundary condition, where the rhs is given by a DOF
     /// vector.
diff --git a/AMDiS/src/expressions/expressions.h b/AMDiS/src/expressions/expressions.h
index 47ddb4d9..b6393deb 100644
--- a/AMDiS/src/expressions/expressions.h
+++ b/AMDiS/src/expressions/expressions.h
@@ -34,11 +34,7 @@
 
 #include "add_expr.hpp"		// add two expressions
 #include "mult_expr.hpp"	// multiply two expressions
-#if HAS_VARIADIC_TEMPLATES && HAS_ALIAS_TEMPLATES
-  #include "functorN_expr.hpp"	// apply a functor with arbitrary nr. of arguments to expressions
-#else
-  #include "functor_expr.hpp"	// apply a functor with 1/2/3 arguments to expressions
-#endif
+#include "functor_expr.hpp"	// apply a functor with 1/2/3 arguments to expressions
 #include "cmath_expr.hpp"	// apply a cmath function to expressions
 #include "vec_functors.hpp"	// apply a vector function to expressions
 
diff --git a/AMDiS/src/expressions/functorN_expr.hpp b/AMDiS/src/expressions/functorN_expr.hpp
index 8c8d7deb..d75151ac 100644
--- a/AMDiS/src/expressions/functorN_expr.hpp
+++ b/AMDiS/src/expressions/functorN_expr.hpp
@@ -28,13 +28,14 @@
 #include "AMDiS_fwd.h"
 #include "LazyOperatorTerm.h"
 #include "Functors.h"
-#include "expressions/functor_expr.hpp"
+// #include "expressions/functor_expr.hpp"
 #include "operations/functors.hpp"
 
 #include <boost/static_assert.hpp>
 
 #include <tuple>
 #include <utility> 
+#include <functional>
 
 namespace AMDiS 
 {
@@ -71,7 +72,66 @@ namespace AMDiS
       template<typename... Int>
       static int eval(F f, Int... d) { return f.getDegree(d...); }
     };
-  }
+    
+    // specialization for abstract-functions
+    template<typename R, typename... Args>
+    struct functor_degree<AbstractFunction<R, Args...> >
+    {
+      template<typename... Int>
+      static int eval(AbstractFunction<R, Args...> const& fct, Int... d) { return fct.getDegree(); }
+    };
+    
+    template<typename R, typename Arg0, typename Arg1>
+    struct functor_degree<BinaryAbstractFunction<R, Arg0, Arg1> >
+    {
+      template<typename... Int>
+      static int eval(BinaryAbstractFunction<R, Arg0, Arg1> const& fct, Int... d) { return fct.getDegree(); }
+    };
+    
+    template<typename R, typename Arg0, typename Arg1, typename Arg2>
+    struct functor_degree<TertiaryAbstractFunction<R, Arg0, Arg1, Arg2> >
+    {
+      template<typename... Int>
+      static int eval(TertiaryAbstractFunction<R, Arg0, Arg1, Arg2> const& fct, Int... d) { return fct.getDegree(); }
+    };
+    
+  } // end namespace traits
+  
+  namespace result_of
+  {    
+    /// extract result type from function pointers
+    template <class FPtr>
+    struct Function;
+
+    template <class R, class C, class... As>
+    struct Function<R (C::*)(As...)>
+    {
+	typedef R result_type;
+    };
+
+    template<class R, class C, class... As>
+    struct Function<R (C::*)(As...) const>
+    {
+	typedef R type;
+    };
+    
+    template<class T>
+    typename Function<T>::type function_helper(T);
+
+    /// extract result type from functors
+    template <class F>
+    struct Functor
+    {
+      typedef decltype(function_helper(&F::operator())) type;
+    };
+    
+    template <class R, class... As>
+    struct Functor<std::function<R(As...)> >
+    {
+      typedef R type;
+    };
+    
+  } // end namespace result_of
   
 
   namespace detail 
@@ -167,7 +227,7 @@ namespace AMDiS
       typedef LazyOperatorTerms<Terms...> super;
       static const int N = sizeof...(Terms);
       
-      typedef typename traits::functor_result_type<F>::type value_type;    
+      typedef typename result_of::Functor<F>::type value_type;
       BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: You have to define a result_type for your Functor **********" );
       
       F f; ///< the functor
@@ -210,50 +270,93 @@ namespace AMDiS
       inline value_type operator()(const int& iq) const { return eval(iq, int_<N>()); }
     };
     
+    template<typename F, typename Term>
+    using Function1 = FunctionN<F, Term>;
+    
+    template<typename F, typename Term1, typename Term2>
+    using Function2 = FunctionN<F, Term1, Term2>;
+    
+    template<typename F, typename Term1, typename Term2, typename Term3>
+    using Function3 = FunctionN<F, Term1, Term2, Term3>;
+    
+    template<typename F, typename Term1, typename Term2, typename Term3, typename Term4>
+    using Function4 = FunctionN<F, Term1, Term2, Term3, Term4>;
+    
+    
+    /// A wrapper functor for AMDiS::AbstractFunctions
+    template<typename TOut, typename TIn>
+    struct Wrapper : public FunctorBase
+    {
+      typedef TOut result_type;
+      Wrapper(AbstractFunction<TOut, TIn>* fct_) : fct(fct_) {}
+      int getDegree(int degree) const { return fct->getDegree(); }
+      
+      TOut operator()(const TIn& x) const 
+      {
+	return (*fct)(x);
+      }
+      
+    protected:
+      AbstractFunction<TOut, TIn>* fct;
+    };
+    
   } // end namespace expressions
 
 
   namespace result_of
   {
     // result of generator-functions (used for enable_if constructs)
-    template<typename F, typename... Terms>
-    struct FunctionN : enable_if
+    template <typename F, typename... Terms>
+    struct FunctionN : std::enable_if
       <
-	typename and_< typename traits::is_valid_arg<Terms>::type... >::type,
+	and_< typename traits::is_valid_arg<Terms>::type... >::value,
 	expressions::FunctionN< F, typename traits::to_expr<Terms>::type...> 
       > {};
       
+    template <typename F, typename Term>
+    struct FunctionN<F, Term> : std::enable_if
+      <
+	traits::is_valid_arg<Term>::value,
+	expressions::FunctionN< F, typename traits::to_expr<Term>::type> 
+      > {};
+      
   } // end namespace result_of
 
-
   // generator-functions
   // _____________________________________________________________________________
 
   template<typename F, typename... Terms>
   inline typename result_of::FunctionN<F, Terms...>::type
-  function_(const F& f, Terms... ts) 
+  function_(F&& f, Terms... ts) 
   {
     return expressions::FunctionN<F, typename traits::to_expr<Terms>::to::type...>
-	    (f, traits::to_expr<Terms>::to::get(ts)...); 
+	    (std::forward<F>(f), traits::to_expr<Terms>::to::get(ts)...); 
   }
 
   template<typename F, typename... Terms>
   inline typename result_of::FunctionN<F, Terms...>::type
-  func(const F& f, Terms... ts) 
+  func(F&& f, Terms... ts) 
   {
     return expressions::FunctionN<F, typename traits::to_expr<Terms>::to::type...>
-	    (f, traits::to_expr<Terms>::to::get(ts)...); 
+	    (std::forward<F>(f), traits::to_expr<Terms>::to::get(ts)...); 
   }
 
   template<typename F, typename Term0, typename... Terms>
   inline typename result_of::FunctionN<F, Term0, Terms...>::type
-  eval(const F& f, Term0 t0, Terms... ts) 
+  eval(F&& f, Term0 t0, Terms... ts) 
   {
     return expressions::FunctionN<F, typename traits::to_expr<Term0>::to::type, 
 				     typename traits::to_expr<Terms>::to::type...>
-      (f, traits::to_expr<Term0>::to::get(t0), traits::to_expr<Terms>::to::get(ts)...); 
+      (std::forward<F>(f), traits::to_expr<Term0>::to::get(t0), traits::to_expr<Terms>::to::get(ts)...); 
   }
 
+
+  // function wrapper for abstract functions
+  // _____________________________________________________________________________
+  template<typename TOut, typename TIn>
+  inline expressions::Wrapper<TOut,TIn> wrap(AbstractFunction<TOut, TIn>* fct) 
+  { return expressions::Wrapper<TOut,TIn>(fct); }
+
 } // end namespace AMDiS
 
 #endif // AMDIS_FUNCTOR_N_EXPRESSION_HPP
diff --git a/AMDiS/src/expressions/functor_expr.hpp b/AMDiS/src/expressions/functor_expr.hpp
index 1a00ace5..f8ee4d78 100644
--- a/AMDiS/src/expressions/functor_expr.hpp
+++ b/AMDiS/src/expressions/functor_expr.hpp
@@ -25,6 +25,14 @@
 #ifndef AMDIS_FUNCTOR_EXPRESSION_HPP
 #define AMDIS_FUNCTOR_EXPRESSION_HPP
 
+
+#if HAS_VARIADIC_TEMPLATES && HAS_ALIAS_TEMPLATES
+// use c++11 variant of functors
+#include "functorN_expr.hpp"
+  
+#else
+// replacement for c++98 compilers
+
 #include "AMDiS_fwd.h"
 #include "LazyOperatorTerm.h"
 #include "Functors.h"
@@ -426,4 +434,6 @@ namespace AMDiS
 
 } // end namespace AMDiS
 
+#endif
+
 #endif // AMDIS_FUNCTOR_EXPRESSION_HPP
diff --git a/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc b/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc
index 7c29a966..6a85d730 100644
--- a/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc
+++ b/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc
@@ -19,7 +19,7 @@
  ******************************************************************************/
 
 #include <mpi.h>
-#include "DirichletBC.h"
+// #include "DirichletBC.h"
 #include "DOFVector.h"
 #include "parallel/PetscSolverGlobalMatrix.h"
 #include "parallel/StdMpi.h"
-- 
GitLab