diff --git a/examples/heat-equation/heatEquationConfig.h b/examples/heat-equation/heatEquationConfig.h
index 1997d4b95717d717cbf1ac94aa48b777dc5e8e5b..e0c6fb0675aa6ab32c9ee9041233d99610c875ba 100644
--- a/examples/heat-equation/heatEquationConfig.h
+++ b/examples/heat-equation/heatEquationConfig.h
@@ -19,6 +19,7 @@
 #define HEATEQUATIONCONFIG_H_
 
 #include <config/tnlConfigDescription.h>
+#include <functions/tnlTestFunction.h>
 
 template< typename ConfigTag >
 class heatEquationConfig
@@ -30,29 +31,7 @@ class heatEquationConfig
          config.addDelimiter( "Tests setting::" );
          config.addEntry     < bool >( "approximation-test", "Test of the Laplace operator approximation.", false );
          config.addEntry     < bool >( "eoc-test", "Test of the numerical scheme convergence.", false );
-         config.addEntry     < tnlString >( "test-function", "Testing function.", "sin-wave" );
-            config.addEntryEnum( "sin-wave" );
-            config.addEntryEnum( "sin-bumps" );
-            config.addEntryEnum( "exp-bump" );
-         config.addEntry     < double >( "wave-length", "Wave length of the sine based test functions.", 1.0 );
-         config.addEntry     < double >( "wave-length-x", "Wave length of the sine based test functions.", 1.0 );
-         config.addEntry     < double >( "wave-length-y", "Wave length of the sine based test functions.", 1.0 );
-         config.addEntry     < double >( "wave-length-z", "Wave length of the sine based test functions.", 1.0 );
-         config.addEntry     < double >( "phase", "Phase of the sine based test functions.", 0.0 );
-         config.addEntry     < double >( "phase-x", "Phase of the sine based test functions.", 0.0 );
-         config.addEntry     < double >( "phase-y", "Phase of the sine based test functions.", 0.0 );
-         config.addEntry     < double >( "phase-z", "Phase of the sine based test functions.", 0.0 );
-         config.addEntry     < double >( "amplitude", "Amplitude length of the sine based test functions.", 1.0 );
-         config.addEntry     < double >( "waves-number", "Cut-off for the sine based test functions.", 0.0 );
-         config.addEntry     < double >( "waves-number-x", "Cut-off for the sine based test functions.", 0.0 );
-         config.addEntry     < double >( "waves-number-y", "Cut-off for the sine based test functions.", 0.0 );
-         config.addEntry     < double >( "waves-number-z", "Cut-off for the sine based test functions.", 0.0 );
-         config.addEntry     < double >( "sigma", "Sigma for the exp based test functions.", 1.0 );
-         config.addEntry     < tnlString >( "test-function-time-dependence", "Time dependence of the test function.", "none" );
-            config.addEntryEnum( "none" );
-            config.addEntryEnum( "linear" );
-            config.addEntryEnum( "quadratic" );
-            config.addEntryEnum( "cosine" );
+         tnlTestFunction< 3, double >::configSetup( config );
       }
 };
 
diff --git a/src/functions/tnlTestFunction.h b/src/functions/tnlTestFunction.h
index 2be7a9dc76964bec2f88a694adf9fb06adac8a66..1e5ea1da91a52577a81e99b3e0d935a8cff90617 100644
--- a/src/functions/tnlTestFunction.h
+++ b/src/functions/tnlTestFunction.h
@@ -18,10 +18,11 @@
 #ifndef TNLTESTFUNCTION_H_
 #define TNLTESTFUNCTION_H_
 
+#include <core/tnlHost.h>
 
 template< int FunctionDimensions,
           typename Real,
-          typename Device >
+          typename Device = tnlHost >
 class tnlTestFunction
 {
    protected:
@@ -41,7 +42,7 @@ class tnlTestFunction
    tnlTestFunction();
 
    static void configSetup( tnlConfigDescription& config,
-                            const tnlString& prefix );
+                            const tnlString& prefix = "" );
 
    bool init( const tnlParameterContainer& parameters );
 
diff --git a/src/implementation/functions/tnlTestFunction_impl.h b/src/implementation/functions/tnlTestFunction_impl.h
index fdf2da76ed883a6a97d231cfda0edc649c9356c6..ea5e3872220042e02c122cfea3e3ba8a3e8ee005 100644
--- a/src/implementation/functions/tnlTestFunction_impl.h
+++ b/src/implementation/functions/tnlTestFunction_impl.h
@@ -41,18 +41,31 @@ tnlTestFunction< FunctionDimensions, Real, Device >::
 configSetup( tnlConfigDescription& config,
              const tnlString& prefix )
 {
-   config.addEntry< double >( prefix + "value", "Value of the constant function.", 0.0 );
-   config.addEntry< double >( prefix + "amplitude", "Amplitude of the sine and exp functions.", 1.0 );
-   config.addEntry< double >( prefix + "sigma", "Sigma parameter of the exp-bump function.", 1.0 );
-   config.addEntry< double >( prefix + "waves-number", "Number of waves of the sine functions.", 0.0 );
-   config.addEntry< double >( prefix + "wave-length", "Wave length of the sine functions.", 1.0 );
-   config.addEntry< double >( prefix + "wave-length-x", "Wave length of the sin-bumps function.", 1.0 );
-   config.addEntry< double >( prefix + "wave-length-y", "Wave length of the sin-bumps functions.", 1.0 );
-   config.addEntry< double >( prefix + "wave-length-z", "Wave length of the sin-bumps functions.", 1.0 );
-   config.addEntry< double >( prefix + "phase", "Phase of the sine functions.", 0.0 );
-   config.addEntry< double >( prefix + "phase-x", "Phase of the sin-bumps function.", 0.0 );
-   config.addEntry< double >( prefix + "phase-y", "Phase of the sin-bumps function.", 0.0 );
-   config.addEntry< double >( prefix + "phase-z", "Phase of the sin-bumps function.", 0.0 );
+   config.addEntry     < tnlString >( "test-function", "Testing function.", "sin-wave" );
+      config.addEntryEnum( "sin-wave" );
+      config.addEntryEnum( "sin-bumps" );
+      config.addEntryEnum( "exp-bump" );
+   config.addEntry     < double >( prefix + "value", "Value of the constant function.", 0.0 );
+   config.addEntry     < double >( prefix + "wave-length", "Wave length of the sine based test functions.", 1.0 );
+   config.addEntry     < double >( prefix + "wave-length-x", "Wave length of the sine based test functions.", 1.0 );
+   config.addEntry     < double >( prefix + "wave-length-y", "Wave length of the sine based test functions.", 1.0 );
+   config.addEntry     < double >( prefix + "wave-length-z", "Wave length of the sine based test functions.", 1.0 );
+   config.addEntry     < double >( prefix + "phase", "Phase of the sine based test functions.", 0.0 );
+   config.addEntry     < double >( prefix + "phase-x", "Phase of the sine based test functions.", 0.0 );
+   config.addEntry     < double >( prefix + "phase-y", "Phase of the sine based test functions.", 0.0 );
+   config.addEntry     < double >( prefix + "phase-z", "Phase of the sine based test functions.", 0.0 );
+   config.addEntry     < double >( prefix + "amplitude", "Amplitude length of the sine based test functions.", 1.0 );
+   config.addEntry     < double >( prefix + "waves-number", "Cut-off for the sine based test functions.", 0.0 );
+   config.addEntry     < double >( prefix + "waves-number-x", "Cut-off for the sine based test functions.", 0.0 );
+   config.addEntry     < double >( prefix + "waves-number-y", "Cut-off for the sine based test functions.", 0.0 );
+   config.addEntry     < double >( prefix + "waves-number-z", "Cut-off for the sine based test functions.", 0.0 );
+   config.addEntry     < double >( prefix + "sigma", "Sigma for the exp based test functions.", 1.0 );
+   config.addEntry     < tnlString >( "test-function-time-dependence", "Time dependence of the test function.", "none" );
+      config.addEntryEnum( "none" );
+      config.addEntryEnum( "linear" );
+      config.addEntryEnum( "quadratic" );
+      config.addEntryEnum( "cosine" );
+
 }
 
 template< int FunctionDimensions,
@@ -70,11 +83,11 @@ initFunction( const tnlParameterContainer& parameters )
       return false;
    }
 
-   if( Device::DeviceType == tnlHostDevice )
+   if( Device::DeviceType == ( int ) tnlHostDevice )
    {
       function = auxFunction;
    }
-   if( Device::DeviceType == tnlCudaDevice )
+   if( Device::DeviceType == ( int ) tnlCudaDevice )
    {
       function = passToDevice( *auxFunction );
       delete auxFunction;
@@ -158,9 +171,9 @@ void
 tnlTestFunction< FunctionDimensions, Real, Device >::
 deleteFunction()
 {
-   if( Device::DeviceType == tnlHostDevice )
+   if( Device::DeviceType == ( int ) tnlHostDevice )
       delete ( FunctionType * ) function;
-   if( Device::DeviceType == tnlCudaDevice )
+   if( Device::DeviceType == ( int ) tnlCudaDevice )
       tnlCuda::freeFromDevice( ( FunctionType * ) function );
 }
 
diff --git a/src/implementation/matrices/tnlEllpackMatrix_impl.h b/src/implementation/matrices/tnlEllpackMatrix_impl.h
index 08f2e30e68b3c35b82f9e440c636f778568e6846..cbff292e1fca372932db3abf0e4fc9383dd2e3d7 100644
--- a/src/implementation/matrices/tnlEllpackMatrix_impl.h
+++ b/src/implementation/matrices/tnlEllpackMatrix_impl.h
@@ -61,7 +61,7 @@ bool tnlEllpackMatrix< Real, Device, Index >::setDimensions( const IndexType row
                    << " columns = " << columns << endl );
    this->rows = rows;
    this->columns = columns;   
-   if( Device::DeviceType == tnlCudaDevice )
+   if( Device::DeviceType == ( int ) tnlCudaDevice )
       this->alignedRows = roundToMultiple( columns, tnlCuda::getWarpSize() );
    else this->alignedRows = rows;
    if( this->rowLengths != 0 )
diff --git a/src/implementation/schemes/diffusion/tnlExactLinearDiffusion_impl.h b/src/implementation/schemes/diffusion/tnlExactLinearDiffusion_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..37f3ba112f38df1591448badcf06f5a9b628a926
--- /dev/null
+++ b/src/implementation/schemes/diffusion/tnlExactLinearDiffusion_impl.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+                          tnlExactLinearDiffusion_impl.h  -  description
+                             -------------------
+    begin                : Aug 8, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef TNLEXACTLINEARDIFFUSION_IMPL_H_
+#define TNLEXACTLINEARDIFFUSION_IMPL_H_
+
+template<>
+   template< typename Function, typename Vertex >
+typename Function::RealType
+tnlExactLinearDiffusion< 1 >::
+getValue( const Function& function,
+          const Vertex& v )
+{
+   return function.template getValue< 2 >( v );
+}
+
+template<>
+   template< typename Function, typename Vertex >
+typename Function::RealType
+tnlExactLinearDiffusion< 2 >::
+getValue( const Function& function,
+          const Vertex& v )
+{
+   return function.template getValue< 2, 0 >( v ) +
+          function.template getValue< 0, 2 >( v );
+}
+
+template<>
+   template< typename Function, typename Vertex >
+typename Function::RealType
+tnlExactLinearDiffusion< 3 >::
+getValue( const Function& function,
+          const Vertex& v )
+{
+   return function.template getValue< 2, 0, 0 >( v ) +
+          function.template getValue< 0, 2, 0 >( v ) +
+          function.template getValue< 0, 0, 2 >( v );
+
+}
+
+#endif /* TNLEXACTLINEARDIFFUSION_IMPL_H_ */
diff --git a/src/schemes/diffusion/tnlExactLinearDiffusion.h b/src/schemes/diffusion/tnlExactLinearDiffusion.h
new file mode 100644
index 0000000000000000000000000000000000000000..181957d003734737e9dfed51b51e4988414c5f9b
--- /dev/null
+++ b/src/schemes/diffusion/tnlExactLinearDiffusion.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+                          tnlExactLinearDiffusion.h  -  description
+                             -------------------
+    begin                : Aug 8, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef TNLEXACTLINEARDIFFUSION_H_
+#define TNLEXACTLINEARDIFFUSION_H_
+
+template< int Dimensions >
+class tnlExactLinearDiffusion
+{};
+
+template<>
+class tnlExactLinearDiffusion< 1 >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef typename Function::RealType RealType;
+      typedef typename Function::VertexType VertexType;
+
+      template< typename Function, typename Vertex, typename Real = Vertex::RealType >
+      static Real getValue( const Function& function,
+                            const Vertex& v );
+
+};
+
+template<>
+class tnlExactLinearDiffusion< 2 >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef typename Function::RealType RealType;
+      typedef typename Function::VertexType VertexType;
+
+      template< typename Function, typename Vertex, typename Real = Vertex::RealType >
+      static Real getValue( const Function& function,
+                            const Vertex& v );
+
+};
+
+template<>
+class tnlExactLinearDiffusion< 3 >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef typename Function::RealType RealType;
+      typedef typename Function::VertexType VertexType;
+
+      template< typename Function, typename Vertex, typename Real = Vertex::RealType >
+      static Real getValue( const Function& function,
+                            const Vertex& v );
+
+};
+
+
+
+#endif /* TNLEXACTLINEARDIFFUSION_H_ */
diff --git a/tests/approximation-tests/CMakeLists.txt b/tests/approximation-tests/CMakeLists.txt
index 2dbab42038a25ca50315871c821a1c728ca84553..25a0ff22ab1cbfe65172878b660d7d1bc7873b89 100755
--- a/tests/approximation-tests/CMakeLists.txt
+++ b/tests/approximation-tests/CMakeLists.txt
@@ -1,3 +1,5 @@
 INSTALL( FILES tnl-functions-test
          DESTINATION share/tnl-${tnlVersion} )                                                            
-                                                                       
+
+set( common_headers tnlApproximationTest.h
+                    tnlApproximationTest_impl.h )                                                                       
diff --git a/tests/approximation-tests/tnlApproximationTest.h b/tests/approximation-tests/tnlApproximationTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a7e0ee3d8083dd0ea99dc8f97c3f9c72f96d2a8
--- /dev/null
+++ b/tests/approximation-tests/tnlApproximationTest.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+                          tnlApproximationTest.h  -  description
+                             -------------------
+    begin                : Aug 7, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef TNLAPPROXIMATIONTEST_H_
+#define TNLAPPROXIMATIONTEST_H_
+
+template< typename Mesh,
+          typename ExactOperator,
+          typename ApproximateOperator,
+          typename Function >
+class tnlApproximationTest
+{
+   public:
+
+      typedef typename ExactOperator::RealType RealType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::IndexType IndexType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef typename MeshType::VertexType VertexType;
+
+      static void getEoc( const Mesh& coarserMesh,
+                          const Mesh& finerMesh,
+                          const RealType& refinement,
+                          const ExactOperator& exactOperator,
+                          const ApproximateOperator& approximateOperator,
+                          const Function& function,
+                          RealType& l1Eoc,
+                          RealType& l2Eoc,
+                          RealType& maxEoc );
+};
+
+#include <tests/approximation-tests/tnlApproximationTest_impl.h>
+
+#endif /* TNLAPPROXIMATIONTEST_H_ */
diff --git a/tests/approximation-tests/tnlApproximationTest_impl.h b/tests/approximation-tests/tnlApproximationTest_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..713755bab511fdd0be666d277e54f9d1349138c3
--- /dev/null
+++ b/tests/approximation-tests/tnlApproximationTest_impl.h
@@ -0,0 +1,91 @@
+/***************************************************************************
+                          tnlApproximationTest_impl.h  -  description
+                             -------------------
+    begin                : Aug 8, 2014
+    copyright            : (C) 2014 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef TNLAPPROXIMATIONTEST_IMPL_H_
+#define TNLAPPROXIMATIONTEST_IMPL_H_
+
+#include <mesh/tnlTraversal.h>
+#include <core/vectors/tnlVector.h>
+
+template< typename Mesh,
+          typename ExactOperator,
+          typename ApproximateOperator,
+          typename Function >
+void
+tnlApproximationTest< Mesh, ExactOperator, ApproximateOperator, Function >::
+getEoc( const Mesh& coarserMesh,
+        const Mesh& finerMesh,
+        const RealType& refinement,
+        const ExactOperator& exactOperator,
+        const ApproximateOperator& approximateOperator,
+        const Function& function,
+        RealType& l1Eoc,
+        RealType& l2Eoc,
+        RealType& maxEoc )
+{
+   tnlVector< RealType, DeviceType, IndexType > coarserExactOperator, coarserApproximateOperator,
+                                                finerExactOperator, finerApproximateOperator;
+   const IndexType coarserEntities = coarserMesh.getNumberOfCells();
+   const IndexType finerEntities = finerMesh.getNumberOfCells();
+
+   if( ! coarserExactOperator.setSize( coarserEntities ) ||
+       ! coarserApproximateOperator.setSize( coarserEntities ) ||
+       ! finerExactOperator.setSize( finerEntities ) ||
+       ! finerApproximateOperator.setSize( finerEntities ) )
+      return false;
+
+   if( DeviceType::DeviceType == ( int ) tnlHostDevice )
+   {
+      for( IndexType i = 0; i < coarserEntities; i++ )
+      {
+         if( ! coarserMesh.isBoundaryCell( i ) )
+         {
+            VertexType v = coarserMesh.getCellCenter( i );
+            coarserExactOperator[ i ] = exactOperator.getValue( function, v );
+            coarserApproximateOperator[ i ] = approximateOperator.getValue( coarserMesh, function, i );
+         }
+         else coarserExactOperator[ i ] = coarserApproximateOperator[ i ];
+      }
+      for( IndexType i = 0; i < finerEntities; i++ )
+      {
+         if( ! coarserMesh.isBoundaryCell( i ) )
+         {
+            VertexType v = finerMesh.getCellCenter( i );
+            finerExactOperator[ i ] = exactOperator.getValue( function, v );
+            finerApproximateOperator[ i ] = approximateOperator.getValue( finerMesh, function, i );
+         }
+         else finerExactOperator[ i ] = finerApproximateOperator[ i ];
+      }
+   }
+   if( DeviceType::DeviceType == ( int ) tnlCudaDevice )
+   {
+      // TODO
+   }
+   const RealType& coarserL1Error = coarserMesh.getDifferenceLpNorm( coarserExactOperator, coarserApproximateOperator, ( RealType ) 1.0 );
+   const RealType& coarserL2Error = coarserMesh.getDifferenceLpNorm( coarserExactOperator, coarserApproximateOperator, ( RealType ) 2.0 );
+   const RealType& coarserMaxError = coarserMesh.getDifferenceAbsMax( coarserExactOperator, coarserApproximateOperator, ( RealType ) );
+
+   const RealType& finerL1Error = finerMesh.getDifferenceLpNorm( finerExactOperator, finerApproximateOperator, ( RealType ) 1.0 );
+   const RealType& finerL2Error = finerMesh.getDifferenceLpNorm( finerExactOperator, finerApproximateOperator, ( RealType ) 2.0 );
+   const RealType& finerMaxError = finerMesh.getDifferenceAbsMax( finerExactOperator, finerApproximateOperator, ( RealType ) );
+
+   l1Eoc = ln( coarserL1Error / finerL1Error ) / ln( refinement );
+   l2Eoc = ln( coarserL2Error / finerL2Error ) / ln( refinement );
+   maxEoc = ln( coarserMaxError / finerMaxError ) / ln( refinement );
+}
+
+#endif /* TNLAPPROXIMATIONTEST_IMPL_H_ */