diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6fc8d79f1980ced5e9e4e9dd98398e71e9fd86fd..7a91988178c025365634070223c5803f3fb8d892 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,7 +33,7 @@ if( CMAKE_BUILD_TYPE STREQUAL "Debug")
     set( LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Debug/lib )
     set( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Debug/bin )
     set( debugExt -dbg )
-    set( CXX_FLAGS "${CXXFLAGS} -g ")
+    set( CMAKE_CXX_FLAGS "${CXXFLAGS} -g ")
     #AddCompilerFlag( "-g" )
 else()
     set( PROJECT_BUILD_PATH ${PROJECT_SOURCE_DIR}/Release/src )
diff --git a/ChangeLog b/ChangeLog
index 00779576ae0bd830a00c370b633ceb34f713feb5..6cd710f3e54a21f934e109433f7b7ee8473459b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+
+        * tnlBoundaryConditionsSetter was implemented 
+           - it allows to set boundary conditions to given function
+           - in explicit solvers, it must be called explicitly now after calling tnlExplicitUpdater
+
 2015-12-25 Tomas Oberhuber  <tomas.oberhuber@fjfi.cvut.cz>
         * significant changes in grids
             - the central structure is now grid entity rather than grid itself
diff --git a/TODO b/TODO
index 9bc88072cb4fd5cbb90113c3da5d67cce59f153a..7619d268836f5bf97700a437fa452c3f83055ff9 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,15 @@
+TODO:
+ - implementovat tnlMixedGridBoundaryConditions, kde by se pro kazdou stranu gridu definoval jiny zvlastni typ
+   okrajovych podminek
+ - dalo by se tim resit i skladani zpetnych a doprednych diferenci u nelinearni difuze, kdy je potreba napr. dopredne diference
+   vycislit i na leve a dolni hranici 2D gridu
+
+TODO:
+ - implementovat tuple pro snazsi a snad efektoivnejsi prenos dat na GPU
+ - nebylo by nutne definovat pomocne datove structury pro traverser
+ - data by se na hostu preskupila do souvisleho bloku dat a ten se prenesl najednou
+
+
 TODO:
  - zavest namespaces
 
@@ -21,9 +33,6 @@ TODO: Mesh
  * prejmenovat Tagy v topologies na Topology zrejme
  * zrusit tnlStorageTraits
 
-TODO: v tnlMeshResolver se provadi preklad pro vsechny mozne sablonove parametry => prorezat
-
-TODO: napsat FunctionDiscretizer pro jednotne rozhrani RightHandSide
 
 TODO: implementace maticovych resicu
       * Gaussova eliminace
diff --git a/build b/build
index 23b1182280d18eb73ab987a09da10f50ce9ac4c3..60e787a6be6f91dfbda466c6d00a5dcd809f50dc 100755
--- a/build
+++ b/build
@@ -93,6 +93,11 @@ ${CMAKE} ${ROOT_DIR} \
          -DINSTANTIATE_INT=${INSTANTIATE_INT} \
          -DINSTANTIATE_LONG_INT=${INSTANTIATE_LONG_INT}
 
+if test $? != 0; then
+    echo "Error: cmake exited with error code."
+    exit 1
+fi
+
 if test ${CMAKE_ONLY} = "yes";
 then
     exit 1
@@ -101,10 +106,18 @@ fi
 echo "Building ${BUILD} $TARGET using $BUILD_JOBS processors ..."
 
 make -j${BUILD_JOBS} ${VERBOSE}
+if test $? != 0; then
+    echo "Error: Build process failed."
+    exit 1
+fi
+
 
 if test WITH_TESTS = "yes";
 then
     make -j${BUILD_JOBS} test
+    if test $? != 0; then
+        echo "Error: Some test did not pass successfuly."
+    fi
 fi
 
 exit 0
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 495f7e6e2ac6adb284ce8addbfb3cdd9d5168a15..b0d5d7f7d3f32843b3981c157aee52e5bff13fd5 100755
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,2 +1,3 @@
 add_subdirectory( heat-equation )
 add_subdirectory( navier-stokes )
+#add_subdirectory( mean-curvature-flow )
diff --git a/examples/heat-equation/tnl-heat-equation-eoc.h b/examples/heat-equation/tnl-heat-equation-eoc.h
index 04a9ade3a93831384136d08402c5358cf4d41b3c..b0f436a06e8244478174faa6e6f4ad4471b46a67 100644
--- a/examples/heat-equation/tnl-heat-equation-eoc.h
+++ b/examples/heat-equation/tnl-heat-equation-eoc.h
@@ -67,7 +67,7 @@ class heatEquationSetter
       typedef tnlTestFunction< MeshType::meshDimensions, Real, Device > TestFunction;
       typedef tnlHeatEquationEocRhs< ExactOperator, TestFunction > RightHandSide;
       typedef tnlStaticVector < MeshType::meshDimensions, Real > Vertex;
-      typedef tnlDirichletBoundaryConditions< MeshType, TestFunction, Real, Index > BoundaryConditions;
+      typedef tnlDirichletBoundaryConditions< MeshType, TestFunction, Dimensions, Real, Index > BoundaryConditions;
       typedef tnlHeatEquationEocProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
       SolverStarter solverStarter;
       return solverStarter.template run< Solver >( parameters );
diff --git a/examples/mean-curvature-flow/CMakeLists.txt b/examples/mean-curvature-flow/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..be359c10fd7f6983ae7d77e7192c402f5dc73763
--- /dev/null
+++ b/examples/mean-curvature-flow/CMakeLists.txt
@@ -0,0 +1,29 @@
+set( tnl_mean_curvature_flow_SOURCES     
+     tnl-mean-curvature-flow.cpp
+     tnl-mean-curvature-flow-eoc.cpp
+     tnl-mean-curvature-flow.cu
+     tnl-mean-curvature-flow-eoc.cu )
+               
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE(tnl-mean-curvature-flow${debugExt} tnl-mean-curvature-flow.cu)
+   CUDA_ADD_EXECUTABLE(tnl-mean-curvature-flow-eoc-test${debugExt} tnl-mean-curvature-flow-eoc.cu)
+   target_link_libraries (tnl-mean-curvature-flow${debugExt} tnl${debugExt}-${tnlVersion}  ${CUSPARSE_LIBRARY} )
+   target_link_libraries (tnl-mean-curvature-flow-eoc-test${debugExt} tnl${debugExt}-${tnlVersion}  ${CUSPARSE_LIBRARY} )
+ELSE(  BUILD_CUDA )               
+   ADD_EXECUTABLE(tnl-mean-curvature-flow${debugExt} tnl-mean-curvature-flow.cpp)     
+   ADD_EXECUTABLE(tnl-mean-curvature-flow-eoc-test${debugExt} tnl-mean-curvature-flow-eoc.cpp)   
+   target_link_libraries (tnl-mean-curvature-flow${debugExt} tnl${debugExt}-${tnlVersion} )
+   target_link_libraries (tnl-mean-curvature-flow-eoc-test${debugExt} tnl${debugExt}-${tnlVersion} )
+ENDIF( BUILD_CUDA )
+
+INSTALL( TARGETS tnl-mean-curvature-flow${debugExt}
+                 tnl-mean-curvature-flow-eoc-test${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+INSTALL( FILES tnl-run-mean-curvature-flow-eoc-test
+               tnl-run-mean-curvature-flow
+               tnl-run-mean-curvature-flow-contour-video
+               tnl-run-mean-curvature-flow-videos
+               ${tnl_mean_curvature_flow_SOURCES}
+         DESTINATION share/tnl-${tnlVersion}/examples/mean-curvature-flow )
\ No newline at end of file
diff --git a/examples/mean-curvature-flow/Makefile b/examples/mean-curvature-flow/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..71873be3fbafbf131bd8b092c7078a9dea9b167d
--- /dev/null
+++ b/examples/mean-curvature-flow/Makefile
@@ -0,0 +1,36 @@
+TNL_VERSION=0.1
+TNL_INSTALL_DIR=${HOME}/local/lib
+TNL_INCLUDE_DIR=${HOME}/local/include/tnl-${TNL_VERSION}
+
+TARGET = mean-curvature-flow-eoc
+INSTALL_DIR = ${HOME}/local
+CXX = g++
+CUDA_CXX = nvcc
+CXX_FLAGS = -std=gnu++0x -I$(TNL_INCLUDE_DIR)   -O0 -g
+LD_FLAGS = -L$(TNL_INSTALL_DIR) -ltnl-dbg-0.1
+
+SOURCES = tnl-mean-curvature-flow-eoc.cpp
+HEADERS = 
+OBJECTS = tnl-mean-curvature-flow-eoc.o
+DIST = $(SOURCES) Makefile
+
+all: $(TARGET)
+clean: 
+	rm -f $(OBJECTS)	
+
+dist: $(DIST)
+	tar zcvf $(TARGET).tgz $(DIST) 
+
+install: $(TARGET)
+	cp $(TARGET) $(INSTALL_DIR)/bin
+	cp $(INSTALL_DIR)/share/tnl-0.1/examples/mean-curvature-flow
+
+uninstall: $(TARGET)
+	rm -f $(INSTALL_DIR)/bin/$(TARGET) 
+	rm -f $(INSTALL_DIR)/share/tnl-0.1/examples/mean-curvature-flow
+
+$(TARGET): $(OBJECTS)
+	$(CXX) -o $(TARGET) $(OBJECTS) $(LD_FLAGS)
+
+%.o: %.cpp $(HEADERS)
+	$(CXX) -c -o $@ $(CXX_FLAGS) $<
diff --git a/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.cpp b/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a14c99e1f0b4f501705cc11ad6fddb7d6f6c1fcf
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.cpp
@@ -0,0 +1,20 @@
+/***************************************************************************
+                          tnl-mean-curvature-flow-eoc.cpp  -  description
+                             -------------------
+    begin                : Dec 29, 2015
+    copyright            : (C) 2015 by 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnl-mean-curvature-flow-eoc.h"
+
+
diff --git a/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.cu b/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.cu
new file mode 100644
index 0000000000000000000000000000000000000000..7a8ffe883b1e535e1859e10286e4c41aee8240a4
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.cu
@@ -0,0 +1,20 @@
+/***************************************************************************
+                          tnl-mean-curvature-flow-eoc.cu  -  description
+                             -------------------
+    begin                : Dec 29, 2015
+    copyright            : (C) 2015 by 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnl-mean-curvature-flow-eoc.h"
+
+
diff --git a/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.h b/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.h
new file mode 100644
index 0000000000000000000000000000000000000000..587eabf33ca34dea66d8e074a49ccaaf7094a827
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-mean-curvature-flow-eoc.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+                          tnl-heat-equation-eoc.h  -  description
+                             -------------------
+    begin                : Nov 29, 2014
+    copyright            : (C) 2014 by 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 TNL_MEAN_CURVATURE_FLOW_EOC_H_
+#define TNL_MEAN_CURVATURE_FLOW_EOC_H_
+
+#include <solvers/tnlSolver.h>
+#include <solvers/tnlFastBuildConfigTag.h>
+#include <solvers/tnlBuildConfigTags.h>
+#include <functions/tnlTestFunction.h>
+#include <operators/tnlDirichletBoundaryConditions.h>
+#include <operators/tnlNeumannBoundaryConditions.h>
+#include <problems/tnlMeanCurvatureFlowEocRhs.h>
+#include <problems/tnlMeanCurvatureFlowEocProblem.h>
+#include <operators/diffusion/tnlExactNonlinearDiffusion.h>
+#include <operators/diffusion/tnlNonlinearDiffusion.h>
+#include <operators/operator-Q/tnlOneSideDiffOperatorQ.h>
+#include <operators/operator-Q/tnlFiniteVolumeOperatorQ.h>
+#include <operators/diffusion/tnlExactNonlinearDiffusion.h>
+#include <operators/diffusion/nonlinear-diffusion-operators/tnlOneSideDiffNonlinearOperator.h>
+#include <operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator.h>
+#include <operators/geometric/tnlExactGradientNorm.h>
+
+//typedef tnlDefaultConfigTag BuildConfig;
+typedef tnlFastBuildConfig BuildConfig;
+
+template< typename ConfigTag >
+class meanCurvatureFlowEocConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription& config )
+      {
+         config.addDelimiter( "Mean Curvature Flow EOC settings:" );         
+         config.addEntry< tnlString >( "numerical-scheme", "Numerical scheme for the solution approximation.", "fvm" );
+            config.addEntryEnum< tnlString >( "fdm" );
+            config.addEntryEnum< tnlString >( "fvm" );
+
+         config.addEntry< double >( "eps", "This sets a eps in operator Q.", 1.0 );
+         config.addDelimiter( "Tests setting::" );         
+         tnlTestFunction< 3, double >::configSetup( config );
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename MeshType,
+          typename ConfigTag,
+          typename SolverStarter >
+class meanCurvatureFlowEocSetter
+{
+   public:
+
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   typedef typename MeshType::VertexType Vertex;
+   enum { Dimensions = MeshType::meshDimensions };
+
+   static bool run( const tnlParameterContainer& parameters )
+   {
+
+      typedef tnlFiniteVolumeOperatorQ<MeshType, Real, Index, 0> OperatorQ;
+      typedef tnlFiniteVolumeNonlinearOperator<MeshType, OperatorQ, Real, Index > NonlinearOperator;
+      typedef tnlNonlinearDiffusion< MeshType, NonlinearOperator, Real, Index > ApproximateOperator;
+      typedef tnlExactNonlinearDiffusion< tnlExactGradientNorm< Dimensions >, Dimensions > ExactOperator;
+      typedef tnlTestFunction< MeshType::meshDimensions, Real, Device > TestFunction;
+      typedef tnlMeanCurvatureFlowEocRhs< ExactOperator, TestFunction, Dimensions > RightHandSide;
+      typedef tnlStaticVector < MeshType::meshDimensions, Real > Vertex;
+      typedef tnlDirichletBoundaryConditions< MeshType, TestFunction, Dimensions, Real, Index > BoundaryConditions;
+      typedef tnlMeanCurvatureFlowEocProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
+      SolverStarter solverStarter;
+      return solverStarter.template run< Solver >( parameters );
+   };
+};
+
+int main( int argc, char* argv[] )
+{
+   tnlSolver< meanCurvatureFlowEocSetter, meanCurvatureFlowEocConfig, BuildConfig > solver;
+   if( ! solver. run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
+#endif /* TNL_MEAN_CURVATURE_FLOW_EOC_H_ */
diff --git a/examples/mean-curvature-flow/tnl-mean-curvature-flow.cpp b/examples/mean-curvature-flow/tnl-mean-curvature-flow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f45e969fec72cf9829287f7e83cce01823fcf09d
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-mean-curvature-flow.cpp
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnl-mean-cudvature-flow.cpp  -  description
+                             -------------------
+    begin                : Dec 29, 2015
+    copyright            : (C) 2015 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnl-mean-curvature-flow.h"
diff --git a/examples/mean-curvature-flow/tnl-mean-curvature-flow.cu b/examples/mean-curvature-flow/tnl-mean-curvature-flow.cu
new file mode 100644
index 0000000000000000000000000000000000000000..b3f466845ce7332b2a2771b633da98f6eeb129d4
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-mean-curvature-flow.cu
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnl-mean-curvature-flow.cu  -  description
+                             -------------------
+    begin                : Dec 29, 2015
+    copyright            : (C) 2015 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnl-mean-curvature-flow.h"
diff --git a/examples/mean-curvature-flow/tnl-mean-curvature-flow.h b/examples/mean-curvature-flow/tnl-mean-curvature-flow.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e137fba0c9c9bf1713874932e37ea0b1e15d540
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-mean-curvature-flow.h
@@ -0,0 +1,147 @@
+/***************************************************************************
+                          tnl-heat-equation.h  -  description
+                             -------------------
+    begin                : Nov 29, 2014
+    copyright            : (C) 2014 by 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 TNL_MEAN_CURVATIVE_FLOW_H_
+#define TNL_MEAN_CURVATIVE_FLOW_H_
+
+#include <solvers/tnlSolver.h>
+#include <solvers/tnlFastBuildConfigTag.h>
+#include <operators/diffusion/tnlLinearDiffusion.h>
+#include <operators/tnlDirichletBoundaryConditions.h>
+#include <operators/tnlNeumannBoundaryConditions.h>
+#include <functions/tnlConstantFunction.h>
+#include <problems/tnlMeanCurvatureFlowProblem.h>
+#include <operators/diffusion/tnlOneSidedNonlinearDiffusion.h>
+#include <operators/operator-Q/tnlOneSideDiffOperatorQ.h>
+#include <operators/operator-Q/tnlFiniteVolumeOperatorQ.h>
+#include <operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator.h>
+#include <functions/tnlMeshFunction.h>
+
+//typedef tnlDefaultConfigTag BuildConfig;
+typedef tnlFastBuildConfig BuildConfig;
+
+template< typename ConfigTag >
+class meanCurvatureFlowConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription& config )
+      {
+         config.addDelimiter( "Mean Curvature Flow settings:" );
+         config.addEntry< tnlString >( "numerical-scheme", "Numerical scheme for the solution approximation.", "fvm" );
+            config.addEntryEnum< tnlString >( "fdm" );
+            config.addEntryEnum< tnlString >( "fvm" );
+         config.addEntry< tnlString >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
+            config.addEntryEnum< tnlString >( "dirichlet" );
+            config.addEntryEnum< tnlString >( "neumann" );
+
+         config.addEntry< tnlString >( "boundary-conditions-file", "File with the values of the boundary conditions.", "boundary.tnl" );
+         config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." );
+         config.addEntry< tnlString >( "initial-condition", "File with the initial condition.", "initial.tnl");
+	      config.addEntry< double >( "right-hand-side-constant", "This sets a value in case of the constant right hand side.", 0.0 );
+	      config.addEntry< double >( "eps", "This sets a eps in operator Q.", 1.0 );
+      };
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename MeshType,
+          typename ConfigTag,
+          typename SolverStarter >
+class meanCurvatureFlowSetter
+{
+   public:
+
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   typedef typename MeshType::VertexType Vertex;
+   enum { Dimensions = MeshType::meshDimensions };
+
+   static bool run( const tnlParameterContainer& parameters )
+   {
+      return setNumericalScheme( parameters );
+   }
+   
+   static bool setNumericalScheme( const tnlParameterContainer& parameters )
+   {
+      const tnlString& numericalScheme = parameters.getParameter< tnlString >( "numerical-scheme" );
+      if( numericalScheme == "fdm" )
+      {
+         typedef tnlOneSideDiffOperatorQ<MeshType, Real, Index > QOperator;
+         typedef tnlOneSideNonlinearDiffusion<MeshType, QOperator, Real, Index > NonlinearOperator;         
+         return setBoundaryConditions< NonlinearOperator, QOperator >( parameters );
+      }
+      if( numericalScheme == "fvm" )
+      {
+         typedef tnlFiniteVolumeOperatorQ<MeshType, Real, Index, 0> QOperator;
+         typedef tnlFiniteVolumeNonlinearOperator<MeshType, QOperator, Real, Index > NonlinearOperator;         
+         return setBoundaryConditions< NonlinearOperator, QOperator >( parameters );
+      }
+      return false;
+   }
+   
+   template< typename NonlinearOperator,
+             typename QOperator >
+   static bool setBoundaryConditions( const tnlParameterContainer& parameters )
+   {
+      typedef tnlOneSidedNonlinearDiffusion< MeshType, NonlinearOperator, Real, Index > ApproximateOperator;
+      typedef tnlConstantFunction< Dimensions, Real > RightHandSide;
+      typedef tnlStaticVector< MeshType::meshDimensions, Real > Vertex;
+
+      tnlString boundaryConditionsType = parameters.getParameter< tnlString >( "boundary-conditions-type" );
+      if( parameters.checkParameter( "boundary-conditions-constant" ) )
+      {
+         typedef tnlConstantFunction< Dimensions, Real > ConstantFunction;
+         if( boundaryConditionsType == "dirichlet" )
+         {
+            typedef tnlDirichletBoundaryConditions< MeshType, ConstantFunction, Dimensions, Real, Index > BoundaryConditions;
+            typedef tnlMeanCurvatureFlowProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
+            SolverStarter solverStarter;
+            return solverStarter.template run< Solver >( parameters );
+         }
+         typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunction, Real, Index > BoundaryConditions;
+         typedef tnlMeanCurvatureFlowProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
+         SolverStarter solverStarter;
+         return solverStarter.template run< Solver >( parameters );
+      }
+      //typedef tnlVector< Real, Device, Index > VectorType;
+      typedef tnlMeshFunction< MeshType > MeshFunction;
+      if( boundaryConditionsType == "dirichlet" )
+      {
+         typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, Dimensions, Real, Index > BoundaryConditions;
+         typedef tnlMeanCurvatureFlowProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
+         SolverStarter solverStarter;
+         return solverStarter.template run< Solver >( parameters );
+      }
+      typedef tnlNeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
+      typedef tnlMeanCurvatureFlowProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
+      SolverStarter solverStarter;
+      return solverStarter.template run< Solver >( parameters );
+   };
+};
+
+int main( int argc, char* argv[] )
+{
+   tnlSolver< meanCurvatureFlowSetter, meanCurvatureFlowConfig, BuildConfig > solver;
+   if( ! solver. run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
+#endif /* TNL_MEAN_CURVATIVE_FLOW_H_ */
diff --git a/examples/mean-curvature-flow/tnl-run-mean-curvature-flow b/examples/mean-curvature-flow/tnl-run-mean-curvature-flow
new file mode 100644
index 0000000000000000000000000000000000000000..c44ad55786ea7790f1e9bacc670b917cb1faacf7
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-run-mean-curvature-flow
@@ -0,0 +1,90 @@
+#!/bin/bash
+
+dofSize=64
+dimension=2;
+proportions=1
+
+analyticFunction="exp-bump"
+timeFunction="cosinus"
+
+amplitude=1.0
+waveLength=1.0
+waveLengthX=1.0
+waveLengthY=1.0
+waveLengthZ=1.0
+wavesNumber=0.0
+wavesNumberX=0.0
+wavesNumberY=0.0
+wavesNumberZ=0.0
+phase=0.0
+phaseX=0.0
+phaseY=0.0
+phaseZ=0.0
+sigma=1.0
+
+tnl-grid-setup --dimensions ${dimension} \
+               --proportions-x ${proportions} \
+               --proportions-y ${proportions} \
+               --proportions-z ${proportions} \
+               --origin-x 0 \
+               --origin-y 0 \
+               --origin-z 0 \
+               --size-x ${dofSize} \
+               --size-y ${dofSize} \
+               --size-z ${dofSize} \
+               
+tnl-init --mesh mesh.tnl \
+         --test-function ${analyticFunction} \
+         --output-file initial.tnl \
+         --amplitude ${amplitude} \
+         --wave-length ${waveLength} \
+         --wave-length-x ${waveLengthX} \
+         --wave-length-y ${waveLengthY} \
+         --wave-length-z ${waveLengthZ} \
+             --waves-number ${wavesNumber} \
+             --waves-number-x ${wavesNumberX} \
+             --waves-number-y ${wavesNumberY} \
+             --waves-number-z ${wavesNumberZ} \
+             --phase ${phase} \
+             --phase-x ${phaseX} \
+             --phase-y ${phaseY} \
+             --phase-z ${phaseZ} \
+             --sigma ${sigma} \
+
+tnl-mean-curvature-flow --time-discretisation explicit \
+                  --boundary-conditions-type dirichlet \
+                  --boundary-conditions-constant 0.5 \
+                  --discrete-solver merson \
+                  --snapshot-period 0.0005 \
+                  --final-time 0.1 \
+              
+tnl-view --mesh mesh.tnl \
+         --input-files *.tnl \ 
+
+seznam=`ls u-*.gplt`
+
+for fname in $seznam ; do
+   echo "Drawing $fname"
+gnuplot << EOF
+    set terminal unknown
+    #set view 33,33 #3D
+    #unset xtics 
+    #unset ytics
+    #unset ztics
+    unset border
+    set output '$fname.png'
+    set yrange [-1.2:1.2]
+    set zrange [0.4:1.1]    
+    set terminal png
+    set title "Numerical solution" 
+    splot '$fname' with line 
+EOF
+done
+
+
+mencoder "mf://u-*.png" -mf fps=22 -o diffusion.avi -ovc lavc -lavcopts vcodec=mpeg4
+
+#rm *.png
+#rm *.tnl         
+#rm *.gplt      
+              
diff --git a/examples/mean-curvature-flow/tnl-run-mean-curvature-flow-contour-video b/examples/mean-curvature-flow/tnl-run-mean-curvature-flow-contour-video
new file mode 100755
index 0000000000000000000000000000000000000000..d4d1784c7a6e51945f2659d60d5dce413d508acc
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-run-mean-curvature-flow-contour-video
@@ -0,0 +1,184 @@
+#!/bin/bash
+
+device="host"
+sizes="16"
+initFunctions="sin-bumps"
+snapshotPeriod=0.001
+finalTime=0.15
+solverName="mean-curvature-flow"
+boundaryCondition="neumann"
+boundaryValue=0
+minZ=-1
+maxZ=1
+contourHeight=0.3
+
+spaceStep=$(expr 1/($sizes-2) | bc | sed 's/^\./0./')
+
+setupInitFunction()
+{
+   initFunction=$1
+      origin=0
+      proportions=1
+      amplitude=1.0
+      waveLength=1.0
+      waveLengthX=1.0
+      waveLengthY=1.0
+      waveLengthZ=1.0
+      wavesNumber=0.0
+      wavesNumberX=0.0
+      wavesNumberY=0.0
+      wavesNumberZ=0.0
+      phase=0.0
+      phaseX=0.0
+      phaseY=0.0
+      phaseZ=0.0
+      sigma=1
+}
+
+setupGrid()
+{
+   gridSize=$1
+   tnl-grid-setup --dimensions 2 \
+                  --origin-x ${origin} \
+                  --origin-y ${origin} \
+                  --origin-z ${origin} \
+                  --proportions-x ${proportions} \
+                  --proportions-y ${proportions} \
+                  --proportions-z ${proportions} \
+                  --size-x ${gridSize} \
+                  --size-y ${gridSize} \
+                  --size-z ${gridSize} 
+}
+
+setInitialCondition()
+{
+   initFunction=$1
+   tnl-init --test-function ${initFunction} \
+	    --output-file initial.tnl \
+            --amplitude ${amplitude} \
+            --wave-length ${waveLength} \
+            --wave-length-x ${waveLengthX} \
+            --wave-length-y ${waveLengthY} \
+            --wave-length-z ${waveLengthZ} \
+            --waves-number ${wavesNumber} \
+            --waves-number-x ${wavesNumberX} \
+            --waves-number-y ${wavesNumberY} \
+            --waves-number-z ${wavesNumberZ} \
+            --phase ${phase} \
+            --phase-x ${phaseX} \
+            --phase-y ${phaseY} \
+            --phase-z ${phaseZ} \
+            --sigma ${sigma} \
+            --time-dependence none
+}
+
+solve()
+{
+   timeDiscretisation=$1
+   discreteSolver=$2
+   ${solverName} --device ${device} \
+                 --mesh mesh.tnl \
+                 --initial-condition initial.tnl \
+		--snapshot-period ${snapshotPeriod} \
+                 --time-discretisation ${timeDiscretisation} \
+                 --time-step 1 \
+                 --time-step-order 2 \
+                 --discrete-solver ${discreteSolver} \
+                 --merson-adaptivity 1.0e-7 \
+                 --sor-omega 1.95 \
+                 --gmres-restarting 20 \
+                 --min-iterations 20 \
+                 --convergence-residue 1.0e-12 \
+		 --boundary-conditions-type ${boundaryCondition} \
+		 --boundary-conditions-constant ${boundaryValue} \
+		 --final-time ${finalTime}
+}
+
+view()
+{
+   tnl-view --input-files u-*.tnl
+   tnl-view --input-files initial.tnl
+}
+
+generate3DVid()
+{
+seznam=`ls u-*.gplt`
+step=0
+for fname in $seznam ; do
+step=$((${step}+1))
+time=$(expr $step*$snapshotPeriod | bc | sed 's/^\./0./')
+echo "Drawing contour $fname"
+gnuplot << EOF
+set output '${fname}.png'
+set xrange [${1}:${proportions}]
+set yrange [${1}:${proportions}]
+set zrange [${minZ}:${maxZ}]    
+unset surface
+set terminal png size 1200,600
+set view map
+set title 'Numerical solution - contour in height ${contourHeight} - T: ${time}'
+set pm3d interpolate 100,100
+set size square
+set contour base
+unset colorbox
+set cntrparam levels discrete ${contourHeight}
+splot '$fname' with pm3d notitle
+EOF
+done
+
+mencoder "mf://u-*.png" -mf fps=4 -o mean_curvature_contour_${contourHeight}_$size.avi -ovc lavc -lavcopts vcodec=mpeg4
+
+rm *.png
+rm *.tnl         
+rm *.gplt 
+rm mesh.asy
+rm computation-done
+     
+}
+
+runTest()
+{
+   for initFunction in ${initFunctions};
+   do
+      cd ${initFunction}-videos
+      setupInitFunction ${initFunction}
+         
+      for size in $sizes;
+      do
+          cd $size
+          echo ""
+          echo ""
+          echo ""
+          if test ! -f computation-done;
+          then
+             touch computation-in-progress
+             echo "========================================================================="
+             echo "===                   SETTING UP THE GRID                             ==="
+             echo "========================================================================="
+             setupGrid $size 
+             echo "========================================================================="
+             echo "===                WRITING THE EXACT SOLUTION                         ==="
+             echo "========================================================================="
+             setInitialCondition $initFunction
+             echo "========================================================================="
+             echo "===                   STARTING THE SOLVER                             ==="
+             echo "========================================================================="
+             solve explicit merson
+             #solve semi-implicit gmres
+             mv computation-in-progress computation-done
+             echo "========================================================================="
+             echo "===                     COMPUTATION DONE                              ==="            
+             echo "========================================================================="
+	     view
+	     generate3DVid $origin $proportions
+             cd ..
+             lastSize=$size
+          fi
+         cd ..
+      done
+      cd ..
+   done
+}
+
+runTest
+ 
diff --git a/examples/mean-curvature-flow/tnl-run-mean-curvature-flow-eoc-test b/examples/mean-curvature-flow/tnl-run-mean-curvature-flow-eoc-test
new file mode 100755
index 0000000000000000000000000000000000000000..c4b9057e6c0d9c598e0af8a39f07692a3c7f97a4
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-run-mean-curvature-flow-eoc-test
@@ -0,0 +1,198 @@
+#!/bin/bash
+
+device="host"
+dimensions="3D"
+sizes3D="16 32 64"
+testFunctions="exp-bump sin-wave sin-bumps"
+snapshotPeriod=0.001
+finalTime=0.01
+timeDependence="cosine"
+solverName="mean-curvature-flow-eoc"
+#solverName="gdb --args tnl-heat-equation-eoc-test-dbg"
+
+setupTestFunction()
+{
+   testFunction=$1
+#   if test x${testFunction} = "xexp-bump";
+#   then
+      origin=2
+      proportions=2
+      amplitude=1.0
+      waveLength=1.0
+      waveLengthX=1.0
+      waveLengthY=1.0
+      waveLengthZ=1.0
+      wavesNumber=0.0
+      wavesNumberX=0.0
+      wavesNumberY=0.0
+      wavesNumberZ=0.0
+      phase=0.0
+      phaseX=0.0
+      phaseY=0.0
+      phaseZ=0.0
+      sigma=1
+#   fi
+}
+
+setupGrid()
+{
+   dimensions=$1
+   gridSize=$2
+   tnl-grid-setup --dimensions ${dimensions} \
+                  --origin-x ${origin} \
+                  --origin-y ${origin} \
+                  --origin-z ${origin} \
+                  --proportions-x ${proportions} \
+                  --proportions-y ${proportions} \
+                  --proportions-z ${proportions} \
+                  --size-x ${gridSize} \
+                  --size-y ${gridSize} \
+                  --size-z ${gridSize} 
+}
+
+setInitialCondition()
+{
+   testFunction=$1
+   tnl-init --test-function ${testFunction} \
+            --output-file exact-u.tnl \
+            --amplitude ${amplitude} \
+            --wave-length ${waveLength} \
+            --wave-length-x ${waveLengthX} \
+            --wave-length-y ${waveLengthY} \
+            --wave-length-z ${waveLengthZ} \
+            --waves-number ${wavesNumber} \
+            --waves-number-x ${wavesNumberX} \
+            --waves-number-y ${wavesNumberY} \
+            --waves-number-z ${wavesNumberZ} \
+            --phase ${phase} \
+            --phase-x ${phaseX} \
+            --phase-y ${phaseY} \
+            --phase-z ${phaseZ} \
+            --sigma ${sigma} \
+            --time-dependence ${timeDependence} \
+            --snapshot-period ${snapshotPeriod} \
+            --final-time ${finalTime}
+}
+
+solve()
+{
+   timeDiscretisation=$1
+   discreteSolver=$2
+   ${solverName} --device ${device} \
+                 --mesh mesh.tnl \
+                 --initial-condition exact-u-00000.tnl \
+                 --time-discretisation ${timeDiscretisation} \
+                 --time-step 1 \
+                 --time-step-order 2 \
+                 --discrete-solver ${discreteSolver} \
+                 --merson-adaptivity 1.0e-10 \
+                 --sor-omega 1.95 \
+                 --gmres-restarting 20  \
+                 --min-iterations 50 \
+                 --convergence-residue 1.0e-14 \
+                 --test-function ${testFunction}\
+                 --amplitude ${amplitude} \
+                 --wave-length ${waveLength} \
+                 --wave-length-x ${waveLengthX} \
+                 --wave-length-y ${waveLengthY} \
+                 --wave-length-z ${waveLengthZ} \
+                 --waves-number ${wavesNumber} \
+                 --waves-number-x ${wavesNumberX} \
+                 --waves-number-y ${wavesNumberY} \
+                 --waves-number-z ${wavesNumberZ} \
+                 --phase ${phase} \
+                 --phase-x ${phaseX} \
+                 --phase-y ${phaseY} \
+                 --phase-z ${phaseZ} \
+                 --sigma ${sigma} \
+                 --time-dependence ${timeDependence} \
+                 --snapshot-period ${snapshotPeriod} \
+                 --final-time ${finalTime}
+}
+               
+computeError()
+{
+   tnl-diff --mesh mesh.tnl \
+            --input-files exact-u-*.tnl u-*.tnl \
+            --mode halves \
+            --snapshot-period ${snapshotPeriod} \
+            --output-file errors.txt \
+            --write-difference yes
+}
+
+runTest()
+{
+   for testFunction in ${testFunctions};
+   do
+      mkdir -p ${testFunction}
+      cd ${testFunction}
+      setupTestFunction ${testFunction}
+      
+      for dim in ${dimensions};
+      do
+         mkdir -p $dim
+         cd ${dim}
+         if test $dim = 1D;
+         then 
+            sizes=$sizes1D
+         fi
+         if test $dim = 2D;
+         then 
+            sizes=$sizes2D
+         fi
+         if test $dim = 3D;
+         then 
+            sizes=$sizes3D
+         fi
+         
+         lastSize=""
+         for size in $sizes;
+         do
+            mkdir -p $size
+            cd $size
+            echo ""
+            echo ""
+            echo ""
+            if test ! -f computation-done;
+            then
+               touch computation-in-progress
+               echo "========================================================================="
+               echo "===                   SETTING UP THE GRID                             ==="
+               echo "========================================================================="
+               setupGrid $dim $size 
+               echo "========================================================================="
+               echo "===                WRITING THE EXACT SOLUTION                         ==="
+               echo "========================================================================="
+               setInitialCondition $testFunction
+               echo "========================================================================="
+               echo "===                   STARTING THE SOLVER                             ==="
+               echo "========================================================================="
+               #solve explicit merson
+               solve semi-implicit gmres
+               mv computation-in-progress computation-done
+            fi            
+            echo "========================================================================="
+            echo "===                   COMPUTING THE ERROR                             ==="
+            echo "========================================================================="
+            computeError
+            echo "========================================================================="
+            echo "===                     COMPUTING THE EOC                             ==="            
+            echo "========================================================================="
+            if test ! x$lastSize = x;
+            then
+               tnl-err2eoc ../$lastSize/errors.txt errors.txt
+            fi
+            echo "========================================================================="
+            echo "===                     COMPUTATION DONE                              ==="            
+            echo "========================================================================="
+            cd ..
+            lastSize=$size
+         done
+
+         cd ..
+      done
+      cd ..
+   done
+}
+
+runTest
diff --git a/examples/mean-curvature-flow/tnl-run-mean-curvature-flow-videos b/examples/mean-curvature-flow/tnl-run-mean-curvature-flow-videos
new file mode 100755
index 0000000000000000000000000000000000000000..a64efdcb9611bd8852fc45ea1a29d05073e31937
--- /dev/null
+++ b/examples/mean-curvature-flow/tnl-run-mean-curvature-flow-videos
@@ -0,0 +1,247 @@
+#!/bin/bash
+
+device="host"
+sizes="64"
+initFunctions="pseudoSquare"
+snapshotPeriod=0.001
+finalTime=0.1
+solverName="mean-curvature-flow"
+boundaryCondition="neumann"
+boundaryValue=0
+minZ=-3
+maxZ=6
+contourHeight=0
+numberOfContours=8
+numberOfInterpolations=10
+eps=0.00001
+
+setupInitFunction()
+{
+   initFunction=$1
+      origin=-2
+      proportions=4
+      amplitude=1.0
+      waveLength=1.0
+      waveLengthX=1.0
+      waveLengthY=1.0
+      waveLengthZ=1.0
+      wavesNumber=0.0
+      wavesNumberX=0.0
+      wavesNumberY=0.0
+      wavesNumberZ=0.0
+      phase=0.0
+      phaseX=0.0
+      phaseY=0.0
+      phaseZ=0.0
+      sigma=1.0
+      diameter=0.6
+      height=1.2
+}
+
+setupGrid()
+{
+   gridSize=$1
+   tnl-grid-setup --dimensions 2 \
+                  --origin-x ${origin} \
+                  --origin-y ${origin} \
+                  --origin-z ${origin} \
+                  --proportions-x ${proportions} \
+                  --proportions-y ${proportions} \
+                  --proportions-z ${proportions} \
+                  --size-x ${gridSize} \
+                  --size-y ${gridSize} \
+                  --size-z ${gridSize} 
+}
+
+setInitialCondition()
+{
+   initFunction=$1
+   tnl-init --test-function ${initFunction} \
+	    --output-file initial.tnl \
+            --amplitude ${amplitude} \
+            --wave-length ${waveLength} \
+            --wave-length-x ${waveLengthX} \
+            --wave-length-y ${waveLengthY} \
+            --wave-length-z ${waveLengthZ} \
+            --waves-number ${wavesNumber} \
+            --waves-number-x ${wavesNumberX} \
+            --waves-number-y ${wavesNumberY} \
+            --waves-number-z ${wavesNumberZ} \
+            --phase ${phase} \
+            --phase-x ${phaseX} \
+            --phase-y ${phaseY} \
+            --phase-z ${phaseZ} \
+            --sigma ${sigma} \
+	    --diameter ${diameter} \
+	    --height ${height} \
+            --time-dependence none
+}
+
+solve()
+{
+   timeDiscretisation=$1
+   discreteSolver=$2
+   ${solverName} --device ${device} \
+                 --mesh mesh.tnl \
+                 --initial-condition initial.tnl \
+		--snapshot-period ${snapshotPeriod} \
+                 --time-discretisation ${timeDiscretisation} \
+                 --time-step 1 \
+                 --time-step-order 2 \
+                 --discrete-solver ${discreteSolver} \
+                 --merson-adaptivity 1.0e-7 \
+                 --sor-omega 1.95 \
+                 --gmres-restarting 20 \
+                 --min-iterations 20 \
+                 --convergence-residue 1.0e-12 \
+		 --boundary-conditions-type ${boundaryCondition} \
+		 --boundary-conditions-constant ${boundaryValue} \
+		 --eps ${eps} \
+		 --final-time ${finalTime}
+}
+
+view()
+{
+   tnl-view --input-files u-*.tnl
+   tnl-view --input-files initial.tnl
+}
+
+generate3DVid()
+{
+domainEnd=$( expr ${origin}+${proportions} | bc | sed 's/^\./0./' | sed 's/^-\./-0./' )
+
+seznam=`ls u-*.gplt`
+step=0
+for fname in $seznam ; do
+time=$(expr $step*$snapshotPeriod | bc | sed 's/^\./0./')
+echo "Drawing $fname"
+gnuplot << EOF
+set output '$fname.png'
+set xrange [${1}:${domainEnd}]
+set yrange [${1}:${domainEnd}]
+set zrange [${minZ}:${maxZ}]    
+set pm3d
+unset surface
+set terminal png size 1200,600
+set cbrange [-1:1]
+set view 22,33,0.8,3
+set title 'Numerical solution - T: ${time}'
+set pm3d interpolate ${numberOfInterpolations},${numberOfInterpolations}
+splot '$fname' with pm3d notitle
+EOF
+step=$((${step}+1))
+done
+
+mencoder "mf://u-*.png" -mf fps=4 -o mean_curvature_$size.avi -ovc lavc -lavcopts vcodec=mpeg4
+rm *.png
+
+seznam=`ls u-*.gplt`
+step=0
+for fname in $seznam ; do
+time=$(expr $step*$snapshotPeriod | bc | sed 's/^\./0./')
+echo "Drawing map $fname"
+gnuplot << EOF
+set output '${fname}.png'
+set xrange [${1}:${domainEnd}]
+set yrange [${1}:${domainEnd}]
+set zrange [${minZ}:${maxZ}]    
+set pm3d
+unset surface
+set terminal png size 1200,600
+set cbrange [-1:1]
+set view map
+set title 'Numerical solution - map - T: ${time}'
+set pm3d interpolate 100,100
+set size square
+set contour base
+set cntrparam levels ${numberOfContours}
+splot '$fname' with pm3d notitle
+EOF
+step=$((${step}+1))
+done
+
+mencoder "mf://u-*.png" -mf fps=4 -o mean_curvature_map_$size.avi -ovc lavc -lavcopts vcodec=mpeg4
+rm *.png
+
+seznam=`ls u-*.gplt`
+step=0
+for fname in $seznam ; do
+time=$(expr $step*$snapshotPeriod | bc | sed 's/^\./0./')
+echo "Drawing contour $fname"
+gnuplot << EOF
+set output '${fname}.png'
+set xrange [${1}:${domainEnd}]
+set yrange [${1}:${domainEnd}]
+set zrange [${minZ}:${maxZ}]    
+unset surface
+set terminal png size 1200,600
+set view map
+set title 'Numerical solution - contour in height ${contourHeight} - T: ${time}'
+set pm3d interpolate 100,100
+set size square
+set contour base
+unset colorbox
+set cntrparam levels discrete ${contourHeight}
+splot '$fname' with pm3d notitle
+EOF
+step=$((${step}+1))
+done
+
+mencoder "mf://u-*.png" -mf fps=4 -o mean_curvature_contour_${contourHeight}_$size.avi -ovc lavc -lavcopts vcodec=mpeg4
+
+rm *.png
+rm *.tnl         
+rm *.gplt 
+rm mesh.asy
+rm computation-done
+     
+}
+
+runTest()
+{
+   for initFunction in ${initFunctions};
+   do
+      mkdir -p ${initFunction}-videos
+      cd ${initFunction}-videos
+      setupInitFunction ${initFunction}
+         
+      for size in $sizes;
+      do
+          mkdir -p $size
+          cd $size
+          echo ""
+          echo ""
+          echo ""
+          if test ! -f computation-done;
+          then
+             touch computation-in-progress
+             echo "========================================================================="
+             echo "===                   SETTING UP THE GRID                             ==="
+             echo "========================================================================="
+             setupGrid $size 
+             echo "========================================================================="
+             echo "===                WRITING THE EXACT SOLUTION                         ==="
+             echo "========================================================================="
+             setInitialCondition $initFunction
+             echo "========================================================================="
+             echo "===                   STARTING THE SOLVER                             ==="
+             echo "========================================================================="
+             solve explicit merson
+             #solve semi-implicit gmres
+             mv computation-in-progress computation-done
+             echo "========================================================================="
+             echo "===                     COMPUTATION DONE                              ==="            
+             echo "========================================================================="
+	     view
+	     generate3DVid $origin $proportions
+             cd ..
+             lastSize=$size
+          fi
+         cd ..
+      done
+      cd ..
+   done
+}
+
+runTest
+ 
diff --git a/install b/install
index 3783de1528b8ef036c2b51331f3ac59b2bc58586..88637e1cdedac34c902de372566d82085dc95cf4 100755
--- a/install
+++ b/install
@@ -35,12 +35,12 @@ then
        mkdir Debug
     fi
     cd Debug
-    ../build --root-dir=.. --build=Debug ${OPTIONS}
-    if test $? != 0;
+    if ../build --root-dir=.. --build=Debug ${OPTIONS};
     then
+        make install
+    else    
        exit 1
     fi
-    make install
     cd ..
 fi
 
@@ -51,12 +51,12 @@ then
        mkdir Release
     fi
     cd Release
-    ../build --root-dir=.. --build=Release ${OPTIONS}
-    if test $? != 0;
+    if ../build --root-dir=.. --build=Release ${OPTIONS};
     then
+        make install
+    else
         exit 1
     fi
-    make install
     cd ..
 fi
 
diff --git a/src/config/tnlParameterContainer.cpp b/src/config/tnlParameterContainer.cpp
index 6483d3dbe2faed4763eea4dd230bcb9540bd9e0c..91599b03078339b5c62cb679788d59b4694f5fc9 100644
--- a/src/config/tnlParameterContainer.cpp
+++ b/src/config/tnlParameterContainer.cpp
@@ -18,7 +18,9 @@
 #include <ctype.h>
 #include <cstring>
 #include <stdio.h>
+
 #include "tnlParameterContainer.h"
+#include <core/tnlObject.h>
 
 bool matob( const char* value, bool& ret_val )
 {
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 0670eed7f98eec266ba9409247c658aa94adc03e..942dc176e05bcc5dd6db68afba49015699a6f1ba 100755
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -8,10 +8,10 @@ ADD_SUBDIRECTORY( multimaps )
 set (headers tnlAssert.h               
              tnlConstants.h
              tnlCurve.h
-      	     tnlCuda.h
+             tnlCuda.h
              tnlCudaDeviceInfo.h
              tnlDataElement.h
-  	     tnlDevice.h
+             tnlDevice.h
              tnlDynamicTypeTag.h
              tnlFeature.h
              tnlFile.h 
@@ -42,7 +42,7 @@ set( common_SOURCES
      ${CURRENT_DIR}/tnlFile.cpp
      ${CURRENT_DIR}/tnlFlopsCounter.cpp 
      ${CURRENT_DIR}/tnlLogger.cpp 
-     ${CURRENT_DIR}/tnlObject.cpp 
+     ${CURRENT_DIR}/tnlObject.cpp
      ${CURRENT_DIR}/tnlStatistics.cpp
      ${CURRENT_DIR}/tnlString.cpp 
      ${CURRENT_DIR}/tnlTimerCPU.cpp      
diff --git a/src/core/arrays/tnlArray.h b/src/core/arrays/tnlArray.h
index 9418308906706daebb4b9ee4a4ae300a5c0156ca..afb85e3a751afc37ee9acb9d75173a2fe91738dd 100644
--- a/src/core/arrays/tnlArray.h
+++ b/src/core/arrays/tnlArray.h
@@ -77,7 +77,7 @@ class tnlArray : public virtual tnlObject
       void bind( Element* _data,
                  const Index _size );
 
-      void bind( tnlArray< Element, Device, Index >& array,
+      void bind( const tnlArray< Element, Device, Index >& array,
                  const IndexType& begin = 0,
                  const IndexType& size = 0 );
 
@@ -139,6 +139,17 @@ class tnlArray : public virtual tnlObject
       //! Method for loading the object from a file as a binary data.
       bool load( tnlFile& file );
       
+      //! This method loads data without reallocation. 
+      /****
+       * This is useful for loading data into shared arrays.
+       * If the array was not initialize yet, common load is
+       * performed. Otherwise, the array size must fit with
+       * the size of array being loaded.
+       */
+      bool boundLoad( tnlFile& file );
+      
+      bool boundLoad( const tnlString& fileName );
+      
       using tnlObject::load;
 
       using tnlObject::save;
diff --git a/src/core/arrays/tnlArrayOperations.h b/src/core/arrays/tnlArrayOperations.h
index 1aae8c265074863720dbf51465474798ccb7aa34..c769ed33bb2928fa5012bec7af5bc712d989f050 100644
--- a/src/core/arrays/tnlArrayOperations.h
+++ b/src/core/arrays/tnlArrayOperations.h
@@ -157,21 +157,6 @@ class tnlArrayOperations< tnlHost, tnlCuda >
                               const Index size );
 };
 
-template< typename Type1, typename Type2 >
-struct tnlFastArrayOperations
-{
-   enum{ enabled = false };
-};
-
-template<> struct tnlFastArrayOperations< char,              char >{ enum{ enabled = true }; };
-template<> struct tnlFastArrayOperations< int,               int  >{ enum{ enabled = true }; };
-template<> struct tnlFastArrayOperations< unsigned int,      unsigned int  >{ enum{ enabled = true }; };
-template<> struct tnlFastArrayOperations< long int,          long int  >{ enum{ enabled = true }; };
-template<> struct tnlFastArrayOperations< long unsigned int, long unsigned int  >{ enum{ enabled = true }; };
-template<> struct tnlFastArrayOperations< float,             float  >{ enum{ enabled = true }; };
-template<> struct tnlFastArrayOperations< double,            double  >{ enum{ enabled = true }; };
-
-
 #include <core/arrays/tnlArrayOperationsHost_impl.h>
 #include <core/arrays/tnlArrayOperationsCuda_impl.h>
 
diff --git a/src/core/arrays/tnlArrayOperationsCuda_impl.h b/src/core/arrays/tnlArrayOperationsCuda_impl.h
index af554d395776935218d9608ec0f11294fb2b11b4..01b649c81c4bd8d6775854bbfcf64386bd187f4c 100644
--- a/src/core/arrays/tnlArrayOperationsCuda_impl.h
+++ b/src/core/arrays/tnlArrayOperationsCuda_impl.h
@@ -148,7 +148,7 @@ bool tnlArrayOperations< tnlCuda >::copyMemory( DestinationElement* destination,
    tnlAssert( destination, );
    tnlAssert( source, );
    #ifdef HAVE_CUDA
-      if( tnlFastArrayOperations< DestinationElement, SourceElement >::enabled )
+      if( std::is_same< DestinationElement, SourceElement >::value )
       {
          if( cudaMemcpy( destination,
                          source,
@@ -201,7 +201,7 @@ bool tnlArrayOperations< tnlHost, tnlCuda >::copyMemory( DestinationElement* des
    tnlAssert( destination, );
    tnlAssert( source, );
    #ifdef HAVE_CUDA
-   if( tnlFastArrayOperations< DestinationElement, SourceElement >::enabled )
+   if( std::is_same< DestinationElement, SourceElement >::value )
    {
       cudaMemcpy( destination,
                   source,
@@ -312,7 +312,7 @@ bool tnlArrayOperations< tnlCuda, tnlHost >::copyMemory( DestinationElement* des
    tnlAssert( source, );
    tnlAssert( size >= 0, cerr << "size = " << size );
    #ifdef HAVE_CUDA
-   if( tnlFastArrayOperations< DestinationElement, SourceElement >::enabled )
+   if( std::is_same< DestinationElement, SourceElement >::value )
    {
       cudaMemcpy( destination,
                   source,
diff --git a/src/core/arrays/tnlArrayOperationsHost_impl.h b/src/core/arrays/tnlArrayOperationsHost_impl.h
index 27ee9093ff21854ab9aff2ba573f0209af10ef13..dbf4818a915315e3f161cb474bb4b3deb501a4c9 100644
--- a/src/core/arrays/tnlArrayOperationsHost_impl.h
+++ b/src/core/arrays/tnlArrayOperationsHost_impl.h
@@ -17,6 +17,8 @@
 
 #ifndef TNLARRAYOPERATIONSHOST_IMPL_H_
 #define TNLARRAYOPERATIONSHOST_IMPL_H_
+
+#include <type_traits>
 #include <tnlConfig.h>
 #include <string.h>
 
@@ -79,7 +81,7 @@ bool tnlArrayOperations< tnlHost >::copyMemory( DestinationElement* destination,
                                                 const SourceElement* source,
                                                 const Index size )
 {
-   if( tnlFastArrayOperations< DestinationElement, SourceElement >::enabled )
+   if( std::is_same< DestinationElement, SourceElement >::value )
       memcpy( destination, source, size * sizeof( DestinationElement ) );
    else
       for( Index i = 0; i < size; i ++ )
@@ -94,7 +96,7 @@ bool tnlArrayOperations< tnlHost >::compareMemory( const DestinationElement* des
                                                    const SourceElement* source,
                                                    const Index size )
 {
-   if( tnlFastArrayOperations< DestinationElement, SourceElement >::enabled )
+   if( std::is_same< DestinationElement, SourceElement >::value )
    {
       if( memcmp( destination, source, size * sizeof( DestinationElement ) ) != 0 )
          return false;
diff --git a/src/core/arrays/tnlArray_impl.h b/src/core/arrays/tnlArray_impl.h
index d8618f70a74a600ddcc6e3d2629ec574f6d57901..06bbc013c31faa86885b0e72fc25e52749cf7c61 100644
--- a/src/core/arrays/tnlArray_impl.h
+++ b/src/core/arrays/tnlArray_impl.h
@@ -158,11 +158,12 @@ releaseData() const
       {
          tnlArrayOperations< Device >::freeMemory( this->allocationPointer );
          delete this->referenceCounter;
+         //std::cerr << "Deallocating reference counter " << this->referenceCounter << std::endl;
       }
    }
    else
-      if( allocationPointer )
-         tnlArrayOperations< Device >::freeMemory( this->allocationPointer );
+      if( allocationPointer )      
+         tnlArrayOperations< Device >::freeMemory( this->allocationPointer );   
    this->allocationPointer = 0;
    this->data = 0;
    this->size = 0;
@@ -226,13 +227,13 @@ template< typename Element,
            typename Index >
 void
 tnlArray< Element, Device, Index >::
-bind( tnlArray< Element, Device, Index >& array,
+bind( const tnlArray< Element, Device, Index >& array,
       const IndexType& begin,
       const IndexType& size )
 {
-   tnlAssert( begin < array.getSize(),
+   tnlAssert( begin <= array.getSize(),
               std::cerr << " begin = " << begin << " array.getSize() = " << array.getSize() );
-   tnlAssert( begin + size  < array.getSize(),
+   tnlAssert( begin + size  <= array.getSize(),
               std::cerr << " begin = " << begin << " size = " << size <<  " array.getSize() = " << array.getSize() );
    
    this->releaseData();
@@ -240,19 +241,20 @@ bind( tnlArray< Element, Device, Index >& array,
       this->size = size;
    else
       this->size = array.getSize() - begin;
-   this->data = &array.getData()[ begin ];
+   this->data = const_cast< Element* >( &array.getData()[ begin ] );
    this->allocationPointer = array.allocationPointer;
    if( array.allocationPointer )
    {
       if( array.referenceCounter )
       {
          this->referenceCounter = array.referenceCounter;
-         *this->referenceCounter++;
+         ( *this->referenceCounter )++;
       }
       else
       {
          this->referenceCounter = array.referenceCounter = new int;
-         *this->referenceCounter = 2;            
+         *this->referenceCounter = 2;
+         //std::cerr << "Allocating reference counter " << this->referenceCounter << std::endl;
       }
    }   
 }
@@ -538,6 +540,73 @@ load( tnlFile& file )
    return true;
 }
 
+template< typename Element,
+          typename Device,
+          typename Index >
+bool
+tnlArray< Element, Device, Index >::
+boundLoad( tnlFile& file )
+{
+   if( ! tnlObject :: load( file ) )
+      return false;
+   Index _size;
+#ifdef HAVE_NOT_CXX11
+   if( ! file. read< Index, tnlHost >( &_size ) )
+      return false;
+#else   
+   if( ! file. read( &_size ) )
+      return false;
+#endif      
+   if( _size < 0 )
+   {
+      cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << endl;
+      return false;
+   }
+   if( this->getSize() != 0 )
+   {
+      if( this->getSize() != _size )
+      {
+         std::cerr << "Error: The current array size is not zero and it is different from the size of" << std::endl
+                   << "the array being loaded. This is not possible. Call method reset() before." << std::endl;
+         return false;
+      }
+   }
+   else setSize( _size );
+   if( _size )
+   {
+      if( ! tnlArrayIO< Element, Device, Index >::load( file, this -> data, this -> size ) )
+      {
+         cerr << "I was not able to load " << this->getType()
+                    << " with size " << this -> getSize() << endl;
+         return false;
+      }
+   }
+   return true;
+}
+
+template< typename Element,
+          typename Device,
+          typename Index >
+bool
+tnlArray< Element, Device, Index >::
+boundLoad( const tnlString& fileName )
+{
+   tnlFile file;
+   if( ! file. open( fileName, tnlReadMode ) )
+   {
+      cerr << "I am not bale to open the file " << fileName << " for reading." << endl;
+      return false;
+   }
+   if( ! this->boundLoad( file ) )
+      return false;
+   if( ! file. close() )
+   {
+      cerr << "An error occurred when I was closing the file " << fileName << "." << endl;
+      return false;
+   }
+   return true;   
+}
+
 template< typename Element,
           typename Device,
           typename Index >
diff --git a/src/core/arrays/tnlSharedArray.h b/src/core/arrays/tnlSharedArray.h
index 865affd0b8707edd51d3488eaacf72c0c8de7b8f..a18fe9dae7cde32d3ee3374557187364ddd9a930 100644
--- a/src/core/arrays/tnlSharedArray.h
+++ b/src/core/arrays/tnlSharedArray.h
@@ -44,13 +44,17 @@ class tnlSharedArray : public tnlObject
    typedef tnlSharedArray< Element, tnlHost, Index > HostType;
    typedef tnlSharedArray< Element, tnlCuda, Index > CudaType;
 
+   __cuda_callable__
    tnlSharedArray();
 
+   __cuda_callable__
    tnlSharedArray( Element* _data,
                    const Index _size );
 
+   __cuda_callable__
    tnlSharedArray( tnlArray< Element, Device, Index >& array );
 
+   __cuda_callable__
    tnlSharedArray( tnlSharedArray< Element, Device, Index >& array );
 
    static tnlString getType();
@@ -61,17 +65,21 @@ class tnlSharedArray : public tnlObject
 
    virtual tnlString getSerializationTypeVirtual() const;
 
+   __cuda_callable__
    void bind( Element* _data,
               const Index _size );
 
    template< typename Array >
+   __cuda_callable__
    void bind( Array& array,
               IndexType index = 0,
               IndexType size = 0 );
 
    template< int Size >
+   __cuda_callable__
    void bind( tnlStaticArray< Size, Element >& array );
 
+   __cuda_callable__
    void bind( tnlSharedArray< Element, Device, Index >& array );
 
    void swap( tnlSharedArray< Element, Device, Index >& array );
diff --git a/src/core/arrays/tnlSharedArray_impl.h b/src/core/arrays/tnlSharedArray_impl.h
index e35959ed17bdd1074c6257a0513eb865519edde0..3aad6dd486edc45ff944823be9b9dfe35156a46f 100644
--- a/src/core/arrays/tnlSharedArray_impl.h
+++ b/src/core/arrays/tnlSharedArray_impl.h
@@ -31,6 +31,7 @@ using namespace std;
 template< typename Element,
           typename Device,
           typename Index >
+__cuda_callable__
 tnlSharedArray< Element, Device, Index >::tnlSharedArray()
 : size( 0 ), data( 0 )
 {
@@ -39,6 +40,7 @@ tnlSharedArray< Element, Device, Index >::tnlSharedArray()
 template< typename Element,
           typename Device,
           typename Index >
+__cuda_callable__
 tnlSharedArray< Element, Device, Index >::tnlSharedArray( Element* _data,
                                                           const Index _size )
 {
@@ -48,6 +50,7 @@ tnlSharedArray< Element, Device, Index >::tnlSharedArray( Element* _data,
 template< typename Element,
           typename Device,
           typename Index >
+__cuda_callable__
 tnlSharedArray< Element, Device, Index >::tnlSharedArray( tnlArray< Element, Device, Index >& array )
 {
    this->bind( array );
@@ -56,6 +59,7 @@ tnlSharedArray< Element, Device, Index >::tnlSharedArray( tnlArray< Element, Dev
 template< typename Element,
           typename Device,
           typename Index >
+__cuda_callable__
 tnlSharedArray< Element, Device, Index >::tnlSharedArray( tnlSharedArray< Element, Device, Index >& array )
 {
    this->bind( array );
@@ -99,6 +103,7 @@ tnlString tnlSharedArray< Element, Device, Index > :: getSerializationTypeVirtua
 template< typename Element,
           typename Device,
           typename Index >
+__cuda_callable__
 void tnlSharedArray< Element, Device, Index > :: bind( Element* data,
                                                        const Index size )
 {
@@ -116,6 +121,7 @@ template< typename Element,
           typename Device,
           typename Index >
    template< typename Array >
+__cuda_callable__
 void tnlSharedArray< Element, Device, Index > :: bind( Array& array,
                                                        IndexType index,
                                                        IndexType size )
@@ -135,6 +141,7 @@ template< typename Element,
           typename Device,
           typename Index >
    template< int Size >
+__cuda_callable__
 void tnlSharedArray< Element, Device, Index >::bind( tnlStaticArray< Size, Element >& array )
 {
    this->size = Size;
@@ -144,6 +151,7 @@ void tnlSharedArray< Element, Device, Index >::bind( tnlStaticArray< Size, Eleme
 template< typename Element,
           typename Device,
           typename Index >
+__cuda_callable__
 void tnlSharedArray< Element, Device, Index > :: bind( tnlSharedArray< Element, Device, Index >& array )
 {
    this -> size = array. getSize();
diff --git a/src/core/arrays/tnlStaticArray.h b/src/core/arrays/tnlStaticArray.h
index eac27dcf9d331be8057d85120e1aa2af7e29c517..2288058804c51aad1b3579e09becd10976a4bd2e 100644
--- a/src/core/arrays/tnlStaticArray.h
+++ b/src/core/arrays/tnlStaticArray.h
@@ -256,7 +256,7 @@ class tnlStaticArray< 2, Element >
    template< typename OtherElement >
    __cuda_callable__
    operator tnlStaticArray< 2, OtherElement >() const;   
-
+   
    __cuda_callable__
    inline void setValue( const ElementType& val );
 
diff --git a/src/core/arrays/tnlStaticArray3D_impl.h b/src/core/arrays/tnlStaticArray3D_impl.h
index f7aa365aae96cdaa030e077cd6e55e82d4705012..b663fd24e278e00fca902e0d4e6deade6ac953a9 100644
--- a/src/core/arrays/tnlStaticArray3D_impl.h
+++ b/src/core/arrays/tnlStaticArray3D_impl.h
@@ -73,7 +73,6 @@ tnlString tnlStaticArray< 3, Element >::getType()
 }
 
 template< typename Element >
-__cuda_callable__
 inline int tnlStaticArray< 3, Element >::getSize() const
 {
    return size;
diff --git a/src/core/mfuncs.h b/src/core/mfuncs.h
index 4958a8c84ed1f97cb8bc8b8405012c718da1cff4..db1ad50fbd6c882900048100ebbab5877bb5b7d3 100644
--- a/src/core/mfuncs.h
+++ b/src/core/mfuncs.h
@@ -63,16 +63,19 @@ T tnlAbs( const T& n )
    return n;
 };
 
+__cuda_callable__
 inline int tnlAbs( const int& n )
 {
    return abs( n );
 };
 
+__cuda_callable__
 inline float tnlAbs( const float& f )
 {
    return fabs( f );
 };
 
+__cuda_callable__
 inline double tnlAbs( const double& d )
 {
    return fabs( d );
@@ -101,13 +104,13 @@ inline int roundToMultiple( int number, int multiple )
 __cuda_callable__
 inline bool isPow2( int x )
 {
-   return ( x & ( x - 1 ) == 0 );
+   return ( ( x & ( x - 1 ) ) == 0 );
 }
 
 __cuda_callable__
 inline bool isPow2( long int x )
 {
-   return ( x & ( x - 1 ) == 0 );
+   return ( ( x & ( x - 1 ) ) == 0 );
 }
 
 
diff --git a/src/core/terminal-colors.h b/src/core/terminal-colors.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c67d00c51a06e57f0300f8a0b9d7a73cb61eda9
--- /dev/null
+++ b/src/core/terminal-colors.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+                          terminal-colors.h  -  description
+                             -------------------
+    begin                : Feb 7, 2015
+    copyright            : (C) 2015 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 TERMINAL_COLORS_H
+#define	TERMINAL_COLORS_H
+
+const std::string red( "\033[0;31m" );
+const std::string green( "\033[1;32m" );
+const std::string yellow( "\033[1;33m" );
+const std::string cyan( "\033[0;36m" );
+const std::string magenta( "\033[0;35m" );
+const std::string reset( "\033[0m" );
+
+
+#endif	/* TERMINAL_COLORS_H */
+
diff --git a/src/core/tnlCuda_impl.h b/src/core/tnlCuda_impl.h
index f0be3240751648548ae2a9bf1704f5d7832305d4..42ec1165994f66a55f0c0512795e4cf719b62d3d 100644
--- a/src/core/tnlCuda_impl.h
+++ b/src/core/tnlCuda_impl.h
@@ -92,6 +92,9 @@ ObjectType* tnlCuda::passToDevice( const ObjectType& object )
       return 0;
    }
    return deviceObject;
+#else
+   tnlAssert( false, cerr << "CUDA support is missing." );
+   return 0;
 #endif
 }
 
diff --git a/src/core/tnlCurve.h b/src/core/tnlCurve.h
index dce343e3ee02435933fd6599427ce1f66e9b31a3..60150d0cc4649b65051cb4f6ced123d694a10c10 100644
--- a/src/core/tnlCurve.h
+++ b/src/core/tnlCurve.h
@@ -82,7 +82,9 @@ template< class T > class tnlCurve : public tnlObject, public tnlList< tnlCurveE
    public:
    //! Basic contructor
    tnlCurve( const char* name )
-   : tnlObject( name )
+   : tnlObject()
+// FIXME: name property has been removed from tnlObject
+//   : tnlObject( name )
    {
    };
 
diff --git a/src/core/tnlFile.h b/src/core/tnlFile.h
index 0b29b633418c2f2c693b3e7224cbc632749507ed..5accc399c1afc1e586a497eb5e3b48f94aa0d3a2 100644
--- a/src/core/tnlFile.h
+++ b/src/core/tnlFile.h
@@ -29,7 +29,6 @@
 #include <core/mfuncs.h>
 #include <core/tnlAssert.h>
 #include <core/tnlString.h>
-#include <core/tnlObject.h>
 #include <core/tnlHost.h>
 #include <core/tnlCuda.h>
 
diff --git a/src/core/tnlObject.cpp b/src/core/tnlObject.cpp
index f4b2ed0f13184a20c3fb421b90fb04876f088a18..e8157c1393552b8f298617576e63fe57f39ec7f0 100644
--- a/src/core/tnlObject.cpp
+++ b/src/core/tnlObject.cpp
@@ -27,15 +27,6 @@
 
 const char magic_number[] = "TNLMN";
 
-tnlObject :: tnlObject()
-{
-}
-
-
-tnlObject :: tnlObject( const tnlString& _name )
-{
-}
-
 tnlString tnlObject :: getType()
 {
    return tnlString( "tnlObject" );
@@ -58,8 +49,6 @@ tnlString tnlObject :: getSerializationTypeVirtual() const
 
 bool tnlObject :: save( tnlFile& file ) const
 {
-   dbgFunctionName( "tnlObject", "Save" );
-   dbgCout( "Writing magic number." );
 #ifdef HAVE_NOT_CXX11
    if( ! file. write< const char, tnlHost, int >( magic_number, strlen( magic_number ) ) )
 #else      
@@ -72,8 +61,6 @@ bool tnlObject :: save( tnlFile& file ) const
 
 bool tnlObject :: load( tnlFile& file )
 {
-   dbgFunctionName( "tnlObject", "Load" );
-   dbgCout( "Reading object type " );
    tnlString objectType;
    if( ! getObjectType( file, objectType ) )
       return false;
@@ -85,6 +72,11 @@ bool tnlObject :: load( tnlFile& file )
    return true;
 }
 
+bool tnlObject :: boundLoad( tnlFile& file )
+{
+   return load( file );
+}
+
 bool tnlObject :: save( const tnlString& fileName ) const
 {
    tnlFile file;
@@ -97,7 +89,7 @@ bool tnlObject :: save( const tnlString& fileName ) const
       return false;
    if( ! file. close() )
    {
-      cerr << "An error occured when I was closing the file " << fileName << "." << endl;
+      cerr << "An error occurred when I was closing the file " << fileName << "." << endl;
       return false;
    }
    return true;
@@ -115,12 +107,31 @@ bool tnlObject :: load( const tnlString& fileName )
       return false;
    if( ! file. close() )
    {
-      cerr << "An error occured when I was closing the file " << fileName << "." << endl;
+      cerr << "An error occurred when I was closing the file " << fileName << "." << endl;
       return false;
    }
    return true;
 }
 
+bool tnlObject :: boundLoad( const tnlString& fileName )
+{
+   tnlFile file;
+   if( ! file. open( fileName, tnlReadMode ) )
+   {
+      cerr << "I am not bale to open the file " << fileName << " for reading." << endl;
+      return false;
+   }
+   if( ! this->boundLoad( file ) )
+      return false;
+   if( ! file. close() )
+   {
+      cerr << "An error occurred when I was closing the file " << fileName << "." << endl;
+      return false;
+   }
+   return true;
+}
+
+
 bool getObjectType( tnlFile& file, tnlString& type )
 {
    dbgFunctionName( "", "getObjectType" );
@@ -207,4 +218,3 @@ bool parseObjectType( const tnlString& objectType,
    return true;
 }
 
-
diff --git a/src/core/tnlObject.h b/src/core/tnlObject.h
index be9f0f26d7cc4b7969978aab0d407dd8fda5db72..349db04e23f88804f03593086a60866dad22ed13 100644
--- a/src/core/tnlObject.h
+++ b/src/core/tnlObject.h
@@ -18,6 +18,7 @@
 #ifndef tnlObjectH
 #define tnlObjectH
 
+#include <core/tnlCuda.h>
 #include <core/tnlString.h>
 
 class tnlFile;
@@ -39,10 +40,8 @@ class tnlObject
    public:
 
    //! Basic constructor
-   tnlObject();
-
-   //! Constructor with name
-   tnlObject( const tnlString& name );
+   __cuda_callable__
+   tnlObject() {};
 
    /****
     * Type getter. This returns the type in C++ style - for example the returned value
@@ -66,12 +65,20 @@ class tnlObject
 
    //! Method for restoring the object from a file
    virtual bool load( tnlFile& file );
+   
+   //! Method for restoring the object from a file
+   virtual bool boundLoad( tnlFile& file );
 
    bool save( const tnlString& fileName ) const;
 
    bool load( const tnlString& fileName );
+   
+   bool boundLoad( const tnlString& fileName );
 
    //! Destructor
+   // FIXME: __cuda_callable__ would have to be added to every overriding destructor,
+   // even if the object's constructor is not __cuda_callable__
+//   __cuda_callable__
    virtual ~tnlObject(){};
 
 };
diff --git a/src/core/tnlString.cpp b/src/core/tnlString.cpp
index e39a869e3da4bb7bc624c012e79d7a851a793b20..7ccf68a36a2245d96696798a877d032530533d15 100644
--- a/src/core/tnlString.cpp
+++ b/src/core/tnlString.cpp
@@ -446,6 +446,11 @@ int tnlString :: parse( tnlList< tnlString >& list, const char separator ) const
    return list. getSize();
 }
 
+tnlString operator + ( const char* string1, const tnlString& string2 )
+{
+   return tnlString( string1 ) + string2;
+}
+
 ostream& operator << ( ostream& stream, const tnlString& str )
 {
    stream << str. getString();
diff --git a/src/core/tnlString.h b/src/core/tnlString.h
index 812e3b7f183708f96f2ed4d7c4a6a2b78beea3aa..42bfa9cabc197f0083d91aa9ef22493d4ea335f6 100644
--- a/src/core/tnlString.h
+++ b/src/core/tnlString.h
@@ -157,6 +157,8 @@ class tnlString
    friend ostream& operator << ( ostream& stream, const tnlString& str );
 };
 
+tnlString operator + ( const char* string1, const tnlString& string2 );
+
 ostream& operator << ( ostream& stream, const tnlString& str );
 
 template< typename T >
diff --git a/src/core/vectors/tnlSharedVector.h b/src/core/vectors/tnlSharedVector.h
index 25eeed52b45f25ec307066c7d41746382427944c..1d973ed3894205682d143580911224fdeb12629a 100644
--- a/src/core/vectors/tnlSharedVector.h
+++ b/src/core/vectors/tnlSharedVector.h
@@ -20,7 +20,7 @@
 
 #include <core/arrays/tnlSharedArray.h>
 #include <core/vectors/tnlVector.h>
-#include <functions/tnlFunction.h>
+#include <functions/tnlDomain.h>
 
 class tnlHost;
 
@@ -37,13 +37,18 @@ class tnlSharedVector : public tnlSharedArray< Real, Device, Index >
    typedef tnlSharedVector< Real, tnlHost, Index > HostType;
    typedef tnlSharedVector< Real, tnlCuda, Index > CudaType;
 
+
+   __cuda_callable__
    tnlSharedVector();
 
+   __cuda_callable__
    tnlSharedVector( Real* data,
                     const Index size );
 
+   __cuda_callable__
    tnlSharedVector( tnlVector< Real, Device, Index >& vector );
 
+   __cuda_callable__
    tnlSharedVector( tnlSharedVector< Real, Device, Index >& vector );
 
    static tnlString getType();
diff --git a/src/core/vectors/tnlSharedVector_impl.h b/src/core/vectors/tnlSharedVector_impl.h
index 8efd8ab7331947493072695f5569b191295c35ac..6b3c8155a9d318786cd06a225aa59fcc4d08033e 100644
--- a/src/core/vectors/tnlSharedVector_impl.h
+++ b/src/core/vectors/tnlSharedVector_impl.h
@@ -23,6 +23,7 @@
 template< typename Real,
           typename Device,
           typename Index >
+__cuda_callable__
 tnlSharedVector< Real, Device, Index >::tnlSharedVector()
 {
 }
@@ -30,6 +31,7 @@ tnlSharedVector< Real, Device, Index >::tnlSharedVector()
 template< typename Real,
           typename Device,
           typename Index >
+__cuda_callable__
 tnlSharedVector< Real, Device, Index >::tnlSharedVector( Real* data,
                                                          const Index size )
 : tnlSharedArray< Real, Device, Index >( data, size )
@@ -39,6 +41,7 @@ tnlSharedVector< Real, Device, Index >::tnlSharedVector( Real* data,
 template< typename Real,
           typename Device,
           typename Index >
+__cuda_callable__
 tnlSharedVector< Real, Device, Index >::tnlSharedVector( tnlVector< Real, Device, Index >& vector )
 : tnlSharedArray< Real, Device, Index >( vector )
 {
@@ -47,6 +50,7 @@ tnlSharedVector< Real, Device, Index >::tnlSharedVector( tnlVector< Real, Device
 template< typename Real,
           typename Device,
           typename Index >
+__cuda_callable__
 tnlSharedVector< Real, Device, Index >::tnlSharedVector( tnlSharedVector< Real, Device, Index >& vector )
 : tnlSharedArray< Real, Device, Index >( vector )
 {
diff --git a/src/core/vectors/tnlVector.h b/src/core/vectors/tnlVector.h
index 84b8a8159a8a5b444e487ee8f234b293a6aa51dc..27eedc04fbd5ed7a3086e9d4809cfd4e6bc64eef 100644
--- a/src/core/vectors/tnlVector.h
+++ b/src/core/vectors/tnlVector.h
@@ -19,7 +19,7 @@
 #define TNLVECTOR_H_
 
 #include <core/arrays/tnlArray.h>
-#include <functions/tnlFunction.h>
+#include <functions/tnlDomain.h>
 
 class tnlHost;
 
diff --git a/src/core/vectors/tnlVector_impl.h b/src/core/vectors/tnlVector_impl.h
index 1a5b3a4ec25023eea34969d68c11b42a142bd576..180eb7bdad221a2498f7f0b36ce0ca9239a225a7 100644
--- a/src/core/vectors/tnlVector_impl.h
+++ b/src/core/vectors/tnlVector_impl.h
@@ -23,7 +23,7 @@
 template< typename Real,
           typename Device,
           typename Index >
-tnlVector< Real, Device, Index > :: tnlVector()
+tnlVector< Real, Device, Index >::tnlVector()
 {
 
 }
@@ -31,7 +31,7 @@ tnlVector< Real, Device, Index > :: tnlVector()
 template< typename Real,
           typename Device,
           typename Index >
-tnlVector< Real, Device, Index > :: tnlVector( const Index size )
+tnlVector< Real, Device, Index >::tnlVector( const Index size )
 {
    this -> setSize( size );
 }
@@ -40,18 +40,18 @@ tnlVector< Real, Device, Index > :: tnlVector( const Index size )
 template< typename Real,
           typename Device,
           typename Index >
-tnlString tnlVector< Real, Device, Index > :: getType()
+tnlString tnlVector< Real, Device, Index >::getType()
 {
    return tnlString( "tnlVector< " ) +
                      ::getType< Real >() + ", " +
-                     Device :: getDeviceType() + ", " +
+                     Device::getDeviceType() + ", " +
                      ::getType< Index >() + " >";
 };
 
 template< typename Real,
           typename Device,
           typename Index >
-tnlString tnlVector< Real, Device, Index > :: getTypeVirtual() const
+tnlString tnlVector< Real, Device, Index >::getTypeVirtual() const
 {
    return this->getType();
 };
@@ -59,7 +59,7 @@ tnlString tnlVector< Real, Device, Index > :: getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-tnlString tnlVector< Real, Device, Index > :: getSerializationType()
+tnlString tnlVector< Real, Device, Index >::getSerializationType()
 {
    return HostType::getType();
 };
@@ -67,7 +67,7 @@ tnlString tnlVector< Real, Device, Index > :: getSerializationType()
 template< typename Real,
           typename Device,
           typename Index >
-tnlString tnlVector< Real, Device, Index > :: getSerializationTypeVirtual() const
+tnlString tnlVector< Real, Device, Index >::getSerializationTypeVirtual() const
 {
    return this->getSerializationType();
 };
@@ -95,9 +95,9 @@ template< typename Real,
            typename Device,
            typename Index >
 tnlVector< Real, Device, Index >&
-   tnlVector< Real, Device, Index > :: operator = ( const tnlVector< Real, Device, Index >& vector )
+   tnlVector< Real, Device, Index >::operator = ( const tnlVector< Real, Device, Index >& vector )
 {
-   tnlArray< Real, Device, Index > :: operator = ( vector );
+   tnlArray< Real, Device, Index >::operator = ( vector );
    return ( *this );
 };
 
@@ -106,9 +106,9 @@ template< typename Real,
            typename Index >
    template< typename Vector >
 tnlVector< Real, Device, Index >&
-   tnlVector< Real, Device, Index > :: operator = ( const Vector& vector )
+   tnlVector< Real, Device, Index >::operator = ( const Vector& vector )
 {
-   tnlArray< Real, Device, Index > :: operator = ( vector );
+   tnlArray< Real, Device, Index >::operator = ( vector );
    return ( *this );
 };
 
@@ -116,25 +116,25 @@ template< typename Real,
           typename Device,
           typename Index >
    template< typename Vector >
-bool tnlVector< Real, Device, Index > :: operator == ( const Vector& vector ) const
+bool tnlVector< Real, Device, Index >::operator == ( const Vector& vector ) const
 {
-   return tnlArray< Real, Device, Index > :: operator == ( vector );
+   return tnlArray< Real, Device, Index >::operator == ( vector );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
    template< typename Vector >
-bool tnlVector< Real, Device, Index > :: operator != ( const Vector& vector ) const
+bool tnlVector< Real, Device, Index >::operator != ( const Vector& vector ) const
 {
-   return tnlArray< Real, Device, Index > :: operator != ( vector );
+   return tnlArray< Real, Device, Index >::operator != ( vector );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
    template< typename Vector >
-tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index > :: operator -= ( const Vector& vector )
+tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index >::operator -= ( const Vector& vector )
 {
    this->addVector( vector, -1.0 );
    return *this;
@@ -144,7 +144,7 @@ template< typename Real,
           typename Device,
           typename Index >
    template< typename Vector >
-tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index > :: operator += ( const Vector& vector )
+tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index >::operator += ( const Vector& vector )
 {
    this->addVector( vector );
    return *this;
@@ -153,7 +153,7 @@ tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index > :: operator +
 template< typename Real,
           typename Device,
           typename Index >
-tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index > :: operator *= ( const RealType& c )
+tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index >::operator *= ( const RealType& c )
 {
    tnlVectorOperations< Device >::vectorScalarMultiplication( *this, c );
    return *this;
@@ -162,7 +162,7 @@ tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index > :: operator *
 template< typename Real,
           typename Device,
           typename Index >
-tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index > :: operator /= ( const RealType& c )
+tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index >::operator /= ( const RealType& c )
 {
    tnlVectorOperations< Device >::vectorScalarMultiplication( *this, 1.0 / c );
    return *this;
@@ -172,51 +172,51 @@ tnlVector< Real, Device, Index >& tnlVector< Real, Device, Index > :: operator /
 template< typename Real,
           typename Device,
           typename Index >
-Real tnlVector< Real, Device, Index > :: max() const
+Real tnlVector< Real, Device, Index >::max() const
 {
-   return tnlVectorOperations< Device > :: getVectorMax( *this );
+   return tnlVectorOperations< Device >::getVectorMax( *this );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-Real tnlVector< Real, Device, Index > :: min() const
+Real tnlVector< Real, Device, Index >::min() const
 {
-   return tnlVectorOperations< Device > :: getVectorMin( *this );
+   return tnlVectorOperations< Device >::getVectorMin( *this );
 }
 
 
 template< typename Real,
           typename Device,
           typename Index >
-Real tnlVector< Real, Device, Index > :: absMax() const
+Real tnlVector< Real, Device, Index >::absMax() const
 {
-   return tnlVectorOperations< Device > :: getVectorAbsMax( *this );
+   return tnlVectorOperations< Device >::getVectorAbsMax( *this );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-Real tnlVector< Real, Device, Index > :: absMin() const
+Real tnlVector< Real, Device, Index >::absMin() const
 {
-   return tnlVectorOperations< Device > :: getVectorAbsMin( *this );
+   return tnlVectorOperations< Device >::getVectorAbsMin( *this );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-Real tnlVector< Real, Device, Index > :: lpNorm( const Real& p ) const
+Real tnlVector< Real, Device, Index >::lpNorm( const Real& p ) const
 {
-   return tnlVectorOperations< Device > :: getVectorLpNorm( *this, p );
+   return tnlVectorOperations< Device >::getVectorLpNorm( *this, p );
 }
 
 
 template< typename Real,
           typename Device,
           typename Index >
-Real tnlVector< Real, Device, Index > :: sum() const
+Real tnlVector< Real, Device, Index >::sum() const
 {
-   return tnlVectorOperations< Device > :: getVectorSum( *this );
+   return tnlVectorOperations< Device >::getVectorSum( *this );
 }
 
 
@@ -224,9 +224,9 @@ template< typename Real,
           typename Device,
           typename Index >
 template< typename Vector >
-Real tnlVector< Real, Device, Index > :: differenceMax( const Vector& v ) const
+Real tnlVector< Real, Device, Index >::differenceMax( const Vector& v ) const
 {
-   return tnlVectorOperations< Device > :: getVectorDifferenceMax( *this, v );
+   return tnlVectorOperations< Device >::getVectorDifferenceMax( *this, v );
 }
 
 
@@ -234,9 +234,9 @@ template< typename Real,
           typename Device,
           typename Index >
 template< typename Vector >
-Real tnlVector< Real, Device, Index > :: differenceMin( const Vector& v ) const
+Real tnlVector< Real, Device, Index >::differenceMin( const Vector& v ) const
 {
-   return tnlVectorOperations< Device > :: getVectorDifferenceMin( *this, v );
+   return tnlVectorOperations< Device >::getVectorDifferenceMin( *this, v );
 }
 
 
@@ -244,27 +244,27 @@ template< typename Real,
           typename Device,
           typename Index >
 template< typename Vector >
-Real tnlVector< Real, Device, Index > :: differenceAbsMax( const Vector& v ) const
+Real tnlVector< Real, Device, Index >::differenceAbsMax( const Vector& v ) const
 {
-   return tnlVectorOperations< Device > :: getVectorDifferenceAbsMax( *this, v );
+   return tnlVectorOperations< Device >::getVectorDifferenceAbsMax( *this, v );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
 template< typename Vector >
-Real tnlVector< Real, Device, Index > :: differenceAbsMin( const Vector& v ) const
+Real tnlVector< Real, Device, Index >::differenceAbsMin( const Vector& v ) const
 {
-   return tnlVectorOperations< Device > :: getVectorDifferenceAbsMin( *this, v );
+   return tnlVectorOperations< Device >::getVectorDifferenceAbsMin( *this, v );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
 template< typename Vector >
-Real tnlVector< Real, Device, Index > :: differenceLpNorm( const Vector& v, const Real& p ) const
+Real tnlVector< Real, Device, Index >::differenceLpNorm( const Vector& v, const Real& p ) const
 {
-   return tnlVectorOperations< Device > :: getVectorDifferenceLpNorm( *this, v, p );
+   return tnlVectorOperations< Device >::getVectorDifferenceLpNorm( *this, v, p );
 }
 
 
@@ -272,18 +272,18 @@ template< typename Real,
           typename Device,
           typename Index >
 template< typename Vector >
-Real tnlVector< Real, Device, Index > :: differenceSum( const Vector& v ) const
+Real tnlVector< Real, Device, Index >::differenceSum( const Vector& v ) const
 {
-   return tnlVectorOperations< Device > :: getVectorDifferenceSum( *this, v );
+   return tnlVectorOperations< Device >::getVectorDifferenceSum( *this, v );
 }
 
 
 template< typename Real,
           typename Device,
           typename Index >
-void tnlVector< Real, Device, Index > :: scalarMultiplication( const Real& alpha )
+void tnlVector< Real, Device, Index >::scalarMultiplication( const Real& alpha )
 {
-   tnlVectorOperations< Device > :: vectorScalarMultiplication( *this, alpha );
+   tnlVectorOperations< Device >::vectorScalarMultiplication( *this, alpha );
 }
 
 
@@ -291,20 +291,20 @@ template< typename Real,
           typename Device,
           typename Index >
 template< typename Vector >
-Real tnlVector< Real, Device, Index > :: scalarProduct( const Vector& v )
+Real tnlVector< Real, Device, Index >::scalarProduct( const Vector& v )
 {
-   return tnlVectorOperations< Device > :: getScalarProduct( *this, v );
+   return tnlVectorOperations< Device >::getScalarProduct( *this, v );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
 template< typename Vector >
-void tnlVector< Real, Device, Index > :: addVector( const Vector& x,
+void tnlVector< Real, Device, Index >::addVector( const Vector& x,
                                                     const Real& multiplicator,
                                                     const Real& thisMultiplicator )
 {
-   tnlVectorOperations< Device > :: addVector( *this, x, multiplicator, thisMultiplicator );
+   tnlVectorOperations< Device >::addVector( *this, x, multiplicator, thisMultiplicator );
 }
 
 template< typename Real,
@@ -325,35 +325,35 @@ addVectors( const Vector& v1,
 template< typename Real,
           typename Device,
           typename Index >
-void tnlVector< Real, Device, Index > :: computePrefixSum()
+void tnlVector< Real, Device, Index >::computePrefixSum()
 {
-   tnlVectorOperations< Device > :: computePrefixSum( *this, 0, this->getSize() );
+   tnlVectorOperations< Device >::computePrefixSum( *this, 0, this->getSize() );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-void tnlVector< Real, Device, Index > :: computePrefixSum( const IndexType begin,
+void tnlVector< Real, Device, Index >::computePrefixSum( const IndexType begin,
                                                            const IndexType end )
 {
-   tnlVectorOperations< Device > :: computePrefixSum( *this, begin, end );
+   tnlVectorOperations< Device >::computePrefixSum( *this, begin, end );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-void tnlVector< Real, Device, Index > :: computeExclusivePrefixSum()
+void tnlVector< Real, Device, Index >::computeExclusivePrefixSum()
 {
-   tnlVectorOperations< Device > :: computeExclusivePrefixSum( *this, 0, this->getSize() );
+   tnlVectorOperations< Device >::computeExclusivePrefixSum( *this, 0, this->getSize() );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-void tnlVector< Real, Device, Index > :: computeExclusivePrefixSum( const IndexType begin,
+void tnlVector< Real, Device, Index >::computeExclusivePrefixSum( const IndexType begin,
                                                                     const IndexType end )
 {
-   tnlVectorOperations< Device > :: computeExclusivePrefixSum( *this, begin, end );
+   tnlVectorOperations< Device >::computeExclusivePrefixSum( *this, begin, end );
 }
 
 
diff --git a/src/functions/CMakeLists.txt b/src/functions/CMakeLists.txt
index 16b7e41311036d2f1f5cc25efae3127b97fe2422..f809c63dcebaafefd1263c0a1750c334f4d0a2ea 100755
--- a/src/functions/CMakeLists.txt
+++ b/src/functions/CMakeLists.txt
@@ -1,18 +1,29 @@
-SET( headers tnlFunctionDiscretizer.h
-             tnlFunctionDiscretizer_impl.h
-             tnlFunctionEnumerator.h
-             tnlFunctionEnumerator_impl.h
-             tnlFunctionAdapter.h
-             tnlConstantFunction.h
+ADD_SUBDIRECTORY( initial_conditions )
+
+SET( headers tnlConstantFunction.h
              tnlConstantFunction_impl.h
+             tnlDomain.h
+             tnlExactOperatorFunction.h
              tnlExpBumpFunction.h
              tnlExpBumpFunction_impl.h
+             tnlFunctionAdapter.h
+             tnlFunctionEvaluator.h
+             tnlFunctionEvaluator_impl.h
+             tnlMeshFunction.h
+             tnlMeshFunction_impl.h
+             tnlMeshFunctionEvaluator.h
+             tnlMeshFunctionEvaluator_impl.h
+             tnlMeshFunctionGnuplotWriter.h
+             tnlMeshFunctionGnuplotWriter_impl.h
+             tnlMeshFunctionNormGetter.h
+             tnlMeshFunctionVTKWriter.h
+             tnlMeshFunctionVTKWriter_impl.h             
+             tnlOperatorFunction.h
              tnlSinBumpsFunction.h
              tnlSinBumpsFunction_impl.h
              tnlSinWaveFunction.h
              tnlSinWaveFunction_impl.h
-             tnlTestFunction.h
-             tnlFunction.h
+             tnlTestFunction.h             
              tnlTestFunction_impl.h )
 
 SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/functions )
@@ -30,4 +41,4 @@ set( tnl_functions_SOURCES
      ${common_SOURCES}
      PARENT_SCOPE )
         
-INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/functions )
\ No newline at end of file
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/functions )
diff --git a/src/functions/initial_conditions/CMakeLists.txt b/src/functions/initial_conditions/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..461bde7bceb385b74b0d264953ce9fb7f289ec18
--- /dev/null
+++ b/src/functions/initial_conditions/CMakeLists.txt
@@ -0,0 +1,11 @@
+ADD_SUBDIRECTORY( level_set_functions )
+
+SET( headers tnlCylinderFunction.h
+             tnlCylinderFunction_impl.h  
+	     tnlFlowerpotFunction.h
+             tnlFlowerpotFunction_impl.h 
+	     tnlTwinsFunction.h
+             tnlTwinsFunction_impl.h             
+   )
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/functors/initial_conditions )
diff --git a/src/functions/initial_conditions/CMakeLists.txt~ b/src/functions/initial_conditions/CMakeLists.txt~
new file mode 100755
index 0000000000000000000000000000000000000000..fcfe293ea4d8d756d7bb371b56a6088166554123
--- /dev/null
+++ b/src/functions/initial_conditions/CMakeLists.txt~
@@ -0,0 +1,5 @@
+SET( headers tnlCylinderFunction.h
+             tnlCylinderFunction_impl.h            
+   )
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/problems )
diff --git a/src/functions/initial_conditions/level_set_functions/CMakeLists.txt b/src/functions/initial_conditions/level_set_functions/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..45ab723961fa2421b0824db1550f22b6643998d0
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/CMakeLists.txt
@@ -0,0 +1,7 @@
+SET( headers tnlBlobFunction.h
+             tnlBlobFunction_impl.h  
+	     tnlPseudoSquareFunction.h
+             tnlPseudoSquareFunction_impl.h          
+   )
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/functors/initial_conditions/level_set_functions )
diff --git a/src/functions/initial_conditions/level_set_functions/CMakeLists.txt~ b/src/functions/initial_conditions/level_set_functions/CMakeLists.txt~
new file mode 100755
index 0000000000000000000000000000000000000000..aaac57306c17920568010efc120817e452c73af3
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/CMakeLists.txt~
@@ -0,0 +1,11 @@
+ADD_SUBDIRECTORY( level_set_conditions )
+
+SET( headers tnlCylinderFunction.h
+             tnlCylinderFunction_impl.h  
+	     tnlFlowerpotFunction.h
+             tnlFlowerpotFunction_impl.h 
+	     tnlTwinsFunction.h
+             tnlTwinsFunction_impl.h             
+   )
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/functions/initial_conditions )
diff --git a/src/functions/initial_conditions/level_set_functions/tnlBlobFunction.h b/src/functions/initial_conditions/level_set_functions/tnlBlobFunction.h
new file mode 100644
index 0000000000000000000000000000000000000000..00ddc009986b0483bae7ea7c8e29670576915fc1
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/tnlBlobFunction.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLBLOBFUNCTION_H_
+#define TNLBLOBFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functions/tnlDomain.h>
+#include <core/tnlCuda.h>
+
+template< typename Real,
+          int Dimensions >
+class tnlBlobFunctionBase : public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+
+     protected:
+
+      RealType height;
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlBlobFunction
+{
+};
+
+template< typename Real >
+class tnlBlobFunction< 1, Real > : public tnlBlobFunctionBase< Real, 1 >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlBlobFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;      
+};
+
+template< typename Real >
+class tnlBlobFunction< 2, Real > : public tnlBlobFunctionBase< Real, 2 >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlBlobFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< typename Real >
+class tnlBlobFunction< 3, Real > : public tnlBlobFunctionBase< Real, 3 >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlBlobFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;      
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlBlobFunction< Dimensions, Real >& f )
+{
+   str << "Level-set pseudo square function.";
+   return str;
+}
+
+#include <functions/initial_conditions/level_set_functions/tnlBlobFunction_impl.h>
+
+
+#endif /* TNLBLOBFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/level_set_functions/tnlBlobFunction.h~ b/src/functions/initial_conditions/level_set_functions/tnlBlobFunction.h~
new file mode 100644
index 0000000000000000000000000000000000000000..c085289494fb4d25b5e0abe78e707d266f833be2
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/tnlBlobFunction.h~
@@ -0,0 +1,160 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLBLOBFUNCTION_H_
+#define TNLBLOBFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functors/tnlFunctionType.h>
+
+template< typename Real >
+class tnlBlobFunctionBase
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+
+     protected:
+
+      RealType height;
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlBlobFunction
+{
+};
+
+template< typename Real >
+class tnlBlobFunction< 1, Real > : public tnlBlobFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlBlobFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlBlobFunction< 2, Real > : public tnlBlobFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlBlobFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlBlobFunction< 3, Real > : public tnlBlobFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlBlobFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlBlobFunction< Dimensions, Real >& f )
+{
+   str << "Level-set pseudo square function.";
+   return str;
+}
+
+template< int FunctionDimensions,
+          typename Real >
+class tnlFunctionType< tnlBlobFunction< FunctionDimensions, Real > >
+{
+   public:
+
+      enum { Type = tnlAnalyticFunction };
+};
+
+
+#include <functions/initial_conditions/level_set_functions/tnlBlobFunction_impl.h>
+
+
+#endif /* TNLBLOBFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/level_set_functions/tnlBlobFunction_impl.h b/src/functions/initial_conditions/level_set_functions/tnlBlobFunction_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..90652ae26dbe7aa02ecf78fa52692dc389416307
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/tnlBlobFunction_impl.h
@@ -0,0 +1,167 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLBLOBFUNCTION_IMPL_H_
+#define TNLBLOBFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/level_set_functions/tnlBlobFunction.h>
+
+template< typename Real,
+          int Dimensions >
+bool
+tnlBlobFunctionBase< Real, Dimensions >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   this->height = parameters.getParameter< double >( prefix + "height" );
+   
+   return true;
+}
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlBlobFunction< 1, Real >::getType()
+{
+   return "tnlBlobFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlBlobFunction< 1, Real >::tnlBlobFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder >
+__cuda_callable__
+Real
+tnlBlobFunction< 1, Real >::
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlBlobFunction< 1, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+/****
+ * 2D
+ */
+template< typename Real >
+tnlString
+tnlBlobFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlBlobFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlBlobFunction< 2, Real >::tnlBlobFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder >
+__cuda_callable__
+Real
+tnlBlobFunction< 2, Real >::
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return x * x + y * y - this->height - sin( cos ( 2 * x + y ) * sin ( 2 * x + y ) );
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlBlobFunction< 2, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+/****
+ * 3D
+ */
+template< typename Real >
+tnlString
+tnlBlobFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlBlobFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlBlobFunction< 3, Real >::tnlBlobFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder >
+__cuda_callable__
+Real
+tnlBlobFunction< 3, Real >::
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlBlobFunction< 3, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
+#endif /* TNLBLOBFUNCTION_IMPL_H_ */
diff --git a/src/functions/initial_conditions/level_set_functions/tnlBlobFunction_impl.h~ b/src/functions/initial_conditions/level_set_functions/tnlBlobFunction_impl.h~
new file mode 100644
index 0000000000000000000000000000000000000000..6e05320396a2f903146eb82e44730ca8c2a349b7
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/tnlBlobFunction_impl.h~
@@ -0,0 +1,147 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLBLOBFUNCTION_IMPL_H_
+#define TNLBLOBFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/level_set_functions/tnlBlobFunction.h>
+
+template< typename Real >
+bool
+tnlBlobFunctionBase< Real >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   this->height = parameters.getParameter< double >( prefix + "height" );
+   
+   return true;
+}
+
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlBlobFunction< 1, Real >::getType()
+{
+   return "tnlBlobFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlBlobFunction< 1, Real >::tnlBlobFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlBlobFunction< 1, Real >::getValue( const Vertex& v,
+                                         const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+/****
+ * 2D
+ */
+
+template< typename Real >
+tnlString
+tnlBlobFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlBlobFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlBlobFunction< 2, Real >::tnlBlobFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlBlobFunction< 2, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return x * x + y * y - this->height - sin( cos ( 2 * x + y ) * sin ( 2 * x + y ) );
+   return 0.0;
+}
+
+/****
+ * 3D
+ */
+
+template< typename Real >
+tnlString
+tnlBlobFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlBlobFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlBlobFunction< 3, Real >::tnlBlobFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlBlobFunction< 3, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+
+#endif /* TNLBLOBFUNCTION_IMPL_H_ */
diff --git a/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h b/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h
new file mode 100644
index 0000000000000000000000000000000000000000..ffcc671f6293c088f5bfe8e385b23cf8197ed7ab
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLPSEUDOSQUAREFUNCTION_H_
+#define TNLPSEUDOSQUAREFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functions/tnlDomain.h>
+#include <core/tnlCuda.h>
+
+template< typename Real,
+          int Dimensions >
+class tnlPseudoSquareFunctionBase : public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+
+   protected:
+
+      RealType height;
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlPseudoSquareFunction
+{
+};
+
+template< typename Real >
+class tnlPseudoSquareFunction< 1, Real > : public tnlPseudoSquareFunctionBase< Real, 1 >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlPseudoSquareFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;      
+};
+
+template< typename Real >
+class tnlPseudoSquareFunction< 2, Real > : public tnlPseudoSquareFunctionBase< Real, 2 >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlPseudoSquareFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;      
+};
+
+template< typename Real >
+class tnlPseudoSquareFunction< 3, Real > : public tnlPseudoSquareFunctionBase< Real, 3 >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlPseudoSquareFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0 >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlPseudoSquareFunction< Dimensions, Real >& f )
+{
+   str << "Level-set pseudo square function.";
+   return str;
+}
+
+#include <functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction_impl.h>
+
+
+#endif /* TNLPSEUDOSQUAREFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h~ b/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h~
new file mode 100644
index 0000000000000000000000000000000000000000..5c2350e9bbbbd2cd01834d99ffc4589b85b21913
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h~
@@ -0,0 +1,160 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLPSEUDOSQUAREFUNCTION_H_
+#define TNLPSEUDOSQUAREFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functors/tnlFunctionType.h>
+
+template< typename Real >
+class tnlPseudoSquareFunctionBase
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+
+   protected:
+
+      RealType height;
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlPseudoSquareFunction
+{
+};
+
+template< typename Real >
+class tnlPseudoSquareFunction< 1, Real > : public tnlPseudoSquareFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlPseudoSquareFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlPseudoSquareFunction< 2, Real > : public tnlPseudoSquareFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlPseudoSquareFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlPseudoSquareFunction< 3, Real > : public tnlPseudoSquareFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlPseudoSquareFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlPseudoSquareFunction< Dimensions, Real >& f )
+{
+   str << "Level-set pseudo square function.";
+   return str;
+}
+
+template< int FunctionDimensions,
+          typename Real >
+class tnlFunctionType< tnlPseudoSquareFunction< FunctionDimensions, Real > >
+{
+   public:
+
+      enum { Type = tnlAnalyticFunction };
+};
+
+
+#include <functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction_impl.h>
+
+
+#endif /* TNLPSEUDOSQUAREFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction_impl.h b/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b15177f6bc63852ba2d059a6bd51291df7b071d
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction_impl.h
@@ -0,0 +1,167 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLPSEUDOSQUAREFUNCTION_IMPL_H_
+#define TNLPSEUDOSQUAREFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h>
+
+template< typename Real,
+          int Dimensions >
+bool
+tnlPseudoSquareFunctionBase< Real, Dimensions >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   this->height = parameters.getParameter< double >( prefix + "height" );
+   
+   return true;
+}
+
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlPseudoSquareFunction< 1, Real >::getType()
+{
+   return "tnlPseudoSquareFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlPseudoSquareFunction< 1, Real >::tnlPseudoSquareFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder >
+__cuda_callable__
+Real
+tnlPseudoSquareFunction< 1, Real >::
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlPseudoSquareFunction< 1, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+/****
+ * 2D
+ */
+template< typename Real >
+tnlString
+tnlPseudoSquareFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlPseudoSquareFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlPseudoSquareFunction< 2, Real >::tnlPseudoSquareFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder >
+__cuda_callable__
+Real
+tnlPseudoSquareFunction< 2, Real >::
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return x * x + y * y - this->height - cos( 2 * x * y ) * cos( 2 * x * y );
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlPseudoSquareFunction< 2, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+/****
+ * 3D
+ */
+template< typename Real >
+tnlString
+tnlPseudoSquareFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlPseudoSquareFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlPseudoSquareFunction< 3, Real >::tnlPseudoSquareFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder >
+__cuda_callable__
+Real
+tnlPseudoSquareFunction< 3, Real >::
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlPseudoSquareFunction< 3, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+#endif /* TNLPSEUDOSQUAREFUNCTION_IMPL_H_ */
diff --git a/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction_impl.h~ b/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction_impl.h~
new file mode 100644
index 0000000000000000000000000000000000000000..7fb79c33ca0d36b38daf76c49cfbda89a9878b42
--- /dev/null
+++ b/src/functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction_impl.h~
@@ -0,0 +1,147 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLPSEUDOSQUAREFUNCTION_IMPL_H_
+#define TNLPSEUDOSQUAREFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h>
+
+template< typename Real >
+bool
+tnlPseudoSquareFunctionBase< Real >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   this->height = parameters.getParameter< double >( prefix + "height" );
+   
+   return true;
+}
+
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlPseudoSquareFunction< 1, Real >::getType()
+{
+   return "tnlPseudoSquareFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlPseudoSquareFunction< 1, Real >::tnlPseudoSquareFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlPseudoSquareFunction< 1, Real >::getValue( const Vertex& v,
+                                         const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+/****
+ * 2D
+ */
+
+template< typename Real >
+tnlString
+tnlPseudoSquareFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlPseudoSquareFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlPseudoSquareFunction< 2, Real >::tnlPseudoSquareFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlPseudoSquareFunction< 2, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return x * x + y * y - this->height - cos( 2 * x * y ) * cos( 2 * x * y );
+   return 0.0;
+}
+
+/****
+ * 3D
+ */
+
+template< typename Real >
+tnlString
+tnlPseudoSquareFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlPseudoSquareFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlPseudoSquareFunction< 3, Real >::tnlPseudoSquareFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlPseudoSquareFunction< 3, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+
+#endif /* TNLPSEUDOSQUAREFUNCTION_IMPL_H_ */
diff --git a/src/functions/initial_conditions/tnlCylinderFunction.h b/src/functions/initial_conditions/tnlCylinderFunction.h
new file mode 100644
index 0000000000000000000000000000000000000000..babd74e0ea976146a9c260520193db7a390ac0c5
--- /dev/null
+++ b/src/functions/initial_conditions/tnlCylinderFunction.h
@@ -0,0 +1,165 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLCYLINDERFUNCTION_H_
+#define TNLCYLINDERFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functions/tnlDomain.h>
+#include <core/tnlCuda.h>
+
+template< typename Real,
+          int Dimensions >
+class tnlCylinderFunctionBase : public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+
+      void setDiameter( const RealType& sigma );
+
+      const RealType& getDiameter() const;
+
+   protected:
+
+      RealType diameter;
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlCylinderFunction
+{
+};
+
+template< typename Real >
+class tnlCylinderFunction< 1, Real > : public tnlCylinderFunctionBase< Real, 1 >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlCylinderFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const Vertex& v,
+                                     const Real& time = 0.0 ) const;
+
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< typename Real >
+class tnlCylinderFunction< 2, Real > : public tnlCylinderFunctionBase< Real, 2 >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlCylinderFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const Vertex& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< typename Real >
+class tnlCylinderFunction< 3, Real > : public tnlCylinderFunctionBase< Real, 3 >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlCylinderFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const Vertex& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlCylinderFunction< Dimensions, Real >& f )
+{
+   str << "Cylinder function.";
+   return str;
+}
+
+#include <functions/initial_conditions/tnlCylinderFunction_impl.h>
+
+
+#endif /* TNLEXPBUMPFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/tnlCylinderFunction.h~ b/src/functions/initial_conditions/tnlCylinderFunction.h~
new file mode 100644
index 0000000000000000000000000000000000000000..ce90d3f447ebc63929ca07dbdd0c03193d159a8d
--- /dev/null
+++ b/src/functions/initial_conditions/tnlCylinderFunction.h~
@@ -0,0 +1,164 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLCYLINDERFUNCTION_H_
+#define TNLCYLINDERFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functors/tnlFunctionType.h>
+
+template< typename Real >
+class tnlCylinderFunctionBase
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+
+      void setDiameter( const RealType& sigma );
+
+      const RealType& getDiameter() const;
+
+   protected:
+
+      RealType diameter;
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlCylinderFunction
+{
+};
+
+template< typename Real >
+class tnlCylinderFunction< 1, Real > : public tnlCylinderFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlCylinderFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlCylinderFunction< 2, Real > : public tnlCylinderFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlCylinderFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlCylinderFunction< 3, Real > : public tnlCylinderFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlCylinderFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlCylinderFunction< Dimensions, Real >& f )
+{
+   str << "Cylinder function.";
+   return str;
+}
+
+template< int FunctionDimensions,
+          typename Real >
+class tnlFunctionType< tnlCylinderFunction< FunctionDimensions, Real > >
+{
+   public:
+
+      enum { Type = tnlAnalyticFunction };
+};
+
+
+#include <functions/initial_conditions/tnlCylinderFunction_impl.h>
+
+
+#endif /* TNLEXPBUMPFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/tnlCylinderFunction_impl.h b/src/functions/initial_conditions/tnlCylinderFunction_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf4e2f7f8638c9c366f734734313288b6d23b9b3
--- /dev/null
+++ b/src/functions/initial_conditions/tnlCylinderFunction_impl.h
@@ -0,0 +1,187 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLCYLINDERFUNCTION_IMPL_H_
+#define TNLCYLINDERFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/tnlCylinderFunction.h>
+
+template< typename Real,
+          int Dimensions >
+bool
+tnlCylinderFunctionBase< Real, Dimensions >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   this->diameter = parameters.getParameter< double >( prefix + "diameter" );
+   return true;
+}
+
+template< typename Real,
+          int Dimensions >
+void
+tnlCylinderFunctionBase< Real, Dimensions >::
+setDiameter( const Real& sigma )
+{
+   this->diameter = diameter;
+}
+
+template< typename Real,
+          int Dimensions >
+const Real& tnlCylinderFunctionBase< Real, Dimensions >::getDiameter() const
+{
+   return this->diameter;
+}
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlCylinderFunction< 1, Real >::getType()
+{
+   return "tnlCylinderFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlCylinderFunction< 1, Real >::tnlCylinderFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+__cuda_callable__
+Real
+tnlCylinderFunction< 1, Real >::getPartialDerivative( const Vertex& v,
+                                                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return ( ( x*x - this->diameter ) < 0 ) - ( ( x*x - this->diameter ) > 0 ) + 1;
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlCylinderFunction< 1, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+/****
+ * 2D
+ */
+
+template< typename Real >
+tnlString
+tnlCylinderFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlCylinderFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlCylinderFunction< 2, Real >::tnlCylinderFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+__cuda_callable__
+Real
+tnlCylinderFunction< 2, Real >::
+getPartialDerivative( const Vertex& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return ( ( x*x + y*y - this->diameter ) < 0 ) - ( ( x*x + y*y - this->diameter ) > 0 ) + 1;
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlCylinderFunction< 2, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
+/****
+ * 3D
+ */
+
+template< typename Real >
+tnlString
+tnlCylinderFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlCylinderFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlCylinderFunction< 3, Real >::tnlCylinderFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+__cuda_callable__
+Real
+tnlCylinderFunction< 3, Real >::
+getPartialDerivative( const Vertex& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return ( ( x*x + y*y + z*z - this->diameter ) < 0 ) - ( ( x*x + y*y + z*z - this->diameter ) > 0 ) + 1;
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlCylinderFunction< 3, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
+#endif /* TNLCYLINDERFUNCTION_IMPL_H_ */
diff --git a/src/functions/initial_conditions/tnlCylinderFunction_impl.h~ b/src/functions/initial_conditions/tnlCylinderFunction_impl.h~
new file mode 100644
index 0000000000000000000000000000000000000000..90c250ad33356cabe14f004e60aeb771256c1612
--- /dev/null
+++ b/src/functions/initial_conditions/tnlCylinderFunction_impl.h~
@@ -0,0 +1,157 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLCYLINDERFUNCTION_IMPL_H_
+#define TNLCYLINDERFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/tnlCylinderFunction.h>
+
+template< typename Real >
+bool
+tnlCylinderFunctionBase< Real >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   this->diameter = parameters.getParameter< double >( prefix + "diameter" );
+   return true;
+}
+
+template< typename Real >
+void tnlCylinderFunctionBase< Real >::setDiameter( const Real& sigma )
+{
+   this->diameter = diameter;
+}
+
+template< typename Real >
+const Real& tnlCylinderFunctionBase< Real >::getDiameter() const
+{
+   return this->diameter;
+}
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlCylinderFunction< 1, Real >::getType()
+{
+   return "tnlCylinderFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlCylinderFunction< 1, Real >::tnlCylinderFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlCylinderFunction< 1, Real >::getValue( const Vertex& v,
+                                         const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return ( ( x*x - this->diameter ) < 0 ) - ( ( x*x - this->diameter ) > 0 ) + 1;
+   return 0.0;
+}
+
+/****
+ * 2D
+ */
+
+template< typename Real >
+tnlString
+tnlCylinderFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlCylinderFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlCylinderFunction< 2, Real >::tnlCylinderFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlCylinderFunction< 2, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return ( ( x*x + y*y - this->diameter ) < 0 ) - ( ( x*x + y*y - this->diameter ) > 0 ) + 1;
+   return 0.0;
+}
+
+/****
+ * 3D
+ */
+
+template< typename Real >
+tnlString
+tnlCylinderFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlCylinderFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlCylinderFunction< 3, Real >::tnlCylinderFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlCylinderFunction< 3, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return ( ( x*x + y*y + z*z - this->diameter ) < 0 ) - ( ( x*x + y*y + z*z - this->diameter ) > 0 ) + 1;
+   return 0.0;
+}
+
+
+#endif /* TNLCYLINDERFUNCTION_IMPL_H_ */
diff --git a/src/functions/initial_conditions/tnlFlowerpotFunction.h b/src/functions/initial_conditions/tnlFlowerpotFunction.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f0e8a0a41e543af8ac925316c77fa102039ac4d
--- /dev/null
+++ b/src/functions/initial_conditions/tnlFlowerpotFunction.h
@@ -0,0 +1,165 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLFLOWERPOTFUNCTION_H_
+#define TNLFLOWERPOTFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functions/tnlDomain.h>
+#include <core/tnlCuda.h>
+
+template< typename Real,
+          int Dimensions >
+class tnlFlowerpotFunctionBase : public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+
+      void setDiameter( const RealType& sigma );
+
+      const RealType& getDiameter() const;
+
+   protected:
+
+      RealType diameter;
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlFlowerpotFunction
+{
+};
+
+template< typename Real >
+class tnlFlowerpotFunction< 1, Real > : public tnlFlowerpotFunctionBase< Real, 1 >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlFlowerpotFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const Vertex& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< typename Real >
+class tnlFlowerpotFunction< 2, Real > : public tnlFlowerpotFunctionBase< Real, 2 >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlFlowerpotFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const Vertex& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< typename Real >
+class tnlFlowerpotFunction< 3, Real > : public tnlFlowerpotFunctionBase< Real, 3 >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlFlowerpotFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const Vertex& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlFlowerpotFunction< Dimensions, Real >& f )
+{
+   str << "Flowerpot function.";
+   return str;
+}
+
+#include <functions/initial_conditions/tnlFlowerpotFunction_impl.h>
+
+
+#endif /* TNLFLOWERPOTFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/tnlFlowerpotFunction.h~ b/src/functions/initial_conditions/tnlFlowerpotFunction.h~
new file mode 100644
index 0000000000000000000000000000000000000000..04fc344a6d61112bb15b6b807edc90ed60871de6
--- /dev/null
+++ b/src/functions/initial_conditions/tnlFlowerpotFunction.h~
@@ -0,0 +1,164 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLFLOWERPOTFUNCTION_H_
+#define TNLFLOWERPOTFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functors/tnlFunctionType.h>
+
+template< typename Real >
+class tnlFlowerpotFunctionBase
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+
+      void setDiameter( const RealType& sigma );
+
+      const RealType& getDiameter() const;
+
+   protected:
+
+      RealType diameter;
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlFlowerpotFunction
+{
+};
+
+template< typename Real >
+class tnlFlowerpotFunction< 1, Real > : public tnlFlowerpotFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlFlowerpotFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlFlowerpotFunction< 2, Real > : public tnlFlowerpotFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlFlowerpotFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlFlowerpotFunction< 3, Real > : public tnlFlowerpotFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlFlowerpotFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlFlowerpotFunction< Dimensions, Real >& f )
+{
+   str << "Flowerpot function.";
+   return str;
+}
+
+template< int FunctionDimensions,
+          typename Real >
+class tnlFunctionType< tnlFlowerpotFunction< FunctionDimensions, Real > >
+{
+   public:
+
+      enum { Type = tnlAnalyticFunction };
+};
+
+
+#include <functions/initial_conditions/tnlFlowerpotFunction_impl.h>
+
+
+#endif /* TNLFLOWERPOTFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/tnlFlowerpotFunction_impl.h b/src/functions/initial_conditions/tnlFlowerpotFunction_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..0b5b08d3b98e108d4b8c3289e007a1cca3495396
--- /dev/null
+++ b/src/functions/initial_conditions/tnlFlowerpotFunction_impl.h
@@ -0,0 +1,184 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLFLOWERPOTFUNCTION_IMPL_H_
+#define TNLFLOWERPOTFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/tnlFlowerpotFunction.h>
+
+template< typename Real,
+          int Dimensions >
+bool
+tnlFlowerpotFunctionBase< Real, Dimensions >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   this->diameter = parameters.getParameter< double >( prefix + "diameter" );
+   return true;
+}
+
+template< typename Real, 
+          int Dimensions >
+void tnlFlowerpotFunctionBase< Real, Dimensions >::setDiameter( const Real& sigma )
+{
+   this->diameter = diameter;
+}
+
+template< typename Real,
+          int Dimensions >
+const Real& tnlFlowerpotFunctionBase< Real, Dimensions >::getDiameter() const
+{
+   return this->diameter;
+}
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlFlowerpotFunction< 1, Real >::getType()
+{
+   return "tnlFlowerpotFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlFlowerpotFunction< 1, Real >::tnlFlowerpotFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+__cuda_callable__
+Real
+tnlFlowerpotFunction< 1, Real >::getPartialDerivative( const Vertex& v,
+                                                       const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return sin( M_PI * tanh( 5 * ( x * x - this->diameter ) ) );
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlFlowerpotFunction< 1, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
+/****
+ * 2D
+ */
+template< typename Real >
+tnlString
+tnlFlowerpotFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlFlowerpotFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlFlowerpotFunction< 2, Real >::tnlFlowerpotFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+__cuda_callable__
+Real
+tnlFlowerpotFunction< 2, Real >::
+getPartialDerivative( const Vertex& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return sin( M_PI * tanh( 5 * ( x * x + y * y - this->diameter ) ) );
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlFlowerpotFunction< 2, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
+/****
+ * 3D
+ */
+
+template< typename Real >
+tnlString
+tnlFlowerpotFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlFlowerpotFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlFlowerpotFunction< 3, Real >::tnlFlowerpotFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+__cuda_callable__
+Real
+tnlFlowerpotFunction< 3, Real >::
+getPartialDerivative( const Vertex& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return sin( M_PI * tanh( 5 * ( x * x + y * y + z * z - 0.25 ) ) );
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlFlowerpotFunction< 3, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+#endif /* TNLFLOWERPOTFUNCTION_IMPL_H_ */
diff --git a/src/functions/initial_conditions/tnlFlowerpotFunction_impl.h~ b/src/functions/initial_conditions/tnlFlowerpotFunction_impl.h~
new file mode 100644
index 0000000000000000000000000000000000000000..9cf6f58945596a4246186da0ea6364fc91bf41bc
--- /dev/null
+++ b/src/functions/initial_conditions/tnlFlowerpotFunction_impl.h~
@@ -0,0 +1,157 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLFLOWERPOTFUNCTION_IMPL_H_
+#define TNLFLOWERPOTFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/tnlFlowerpotFunction.h>
+
+template< typename Real >
+bool
+tnlFlowerpotFunctionBase< Real >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   this->diameter = parameters.getParameter< double >( prefix + "diameter" );
+   return true;
+}
+
+template< typename Real >
+void tnlFlowerpotFunctionBase< Real >::setDiameter( const Real& sigma )
+{
+   this->diameter = diameter;
+}
+
+template< typename Real >
+const Real& tnlFlowerpotFunctionBase< Real >::getDiameter() const
+{
+   return this->diameter;
+}
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlFlowerpotFunction< 1, Real >::getType()
+{
+   return "tnlFlowerpotFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlFlowerpotFunction< 1, Real >::tnlFlowerpotFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlFlowerpotFunction< 1, Real >::getValue( const Vertex& v,
+                                         const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return sin( M_PI * tanh( 5 * ( x * x - this->diameter ) ) );
+   return 0.0;
+}
+
+/****
+ * 2D
+ */
+
+template< typename Real >
+tnlString
+tnlFlowerpotFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlFlowerpotFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlFlowerpotFunction< 2, Real >::tnlFlowerpotFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlFlowerpotFunction< 2, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return sin( M_PI * tanh( 5 * ( x * x + y * y - this->diameter ) ) );
+   return 0.0;
+}
+
+/****
+ * 3D
+ */
+
+template< typename Real >
+tnlString
+tnlFlowerpotFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlFlowerpotFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlFlowerpotFunction< 3, Real >::tnlFlowerpotFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlFlowerpotFunction< 3, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return sin( M_PI * tanh( 5 * ( x * x + y * y + z * z - 0.25 ) ) );
+   return 0.0;
+}
+
+
+#endif /* TNLFLOWERPOTFUNCTION_IMPL_H_ */
diff --git a/src/functions/initial_conditions/tnlTwinsFunction.h b/src/functions/initial_conditions/tnlTwinsFunction.h
new file mode 100644
index 0000000000000000000000000000000000000000..b3e0af47620c98dd59d136b77120d9b590074ac8
--- /dev/null
+++ b/src/functions/initial_conditions/tnlTwinsFunction.h
@@ -0,0 +1,157 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLTWINSFUNCTION_H_
+#define TNLTWINSFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functions/tnlDomain.h>
+#include <core/tnlCuda.h>
+
+template< typename Real,
+          int Dimensions >
+class tnlTwinsFunctionBase : public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlTwinsFunction
+{
+};
+
+template< typename Real >
+class tnlTwinsFunction< 1, Real > : public tnlTwinsFunctionBase< Real, 1 >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlTwinsFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const Vertex& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< typename Real >
+class tnlTwinsFunction< 2, Real > : public tnlTwinsFunctionBase< Real, 2 >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlTwinsFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif
+      __cuda_callable__
+      RealType getPartialDerivative( const Vertex& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< typename Real >
+class tnlTwinsFunction< 3, Real > : public tnlTwinsFunctionBase< Real, 3 >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlTwinsFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+      __cuda_callable__
+      RealType getPartialDerivative( const Vertex& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlTwinsFunction< Dimensions, Real >& f )
+{
+   str << "Twins function.";
+   return str;
+}
+
+#include <functions/initial_conditions/tnlTwinsFunction_impl.h>
+
+
+#endif /* TNLTWINSFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/tnlTwinsFunction.h~ b/src/functions/initial_conditions/tnlTwinsFunction.h~
new file mode 100644
index 0000000000000000000000000000000000000000..e91c1f0e998689a657417f96d7907cb50d7c9716
--- /dev/null
+++ b/src/functions/initial_conditions/tnlTwinsFunction.h~
@@ -0,0 +1,156 @@
+/***************************************************************************
+                          tnlExpBumpFunction.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLTWINSFUNCTION_H_
+#define TNLTWINSFUNCTION_H_
+
+#include <config/tnlParameterContainer.h>
+#include <core/vectors/tnlStaticVector.h>
+#include <functors/tnlFunctionType.h>
+
+template< typename Real >
+class tnlTwinsFunctionBase
+{
+   public:
+
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                 const tnlString& prefix = "" );
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlTwinsFunction
+{
+};
+
+template< typename Real >
+class tnlTwinsFunction< 1, Real > : public tnlTwinsFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 1 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlTwinsFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlTwinsFunction< 2, Real > : public tnlTwinsFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 2 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlTwinsFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< typename Real >
+class tnlTwinsFunction< 3, Real > : public tnlTwinsFunctionBase< Real >
+{
+   public:
+
+      enum { Dimensions = 3 };
+      typedef Real RealType;
+      typedef tnlStaticVector< Dimensions, Real > VertexType;
+
+      static tnlString getType();
+
+      tnlTwinsFunction();
+
+#ifdef HAVE_NOT_CXX11
+      template< int XDiffOrder,
+                int YDiffOrder,
+                int ZDiffOrder,
+                typename Vertex >
+#else
+      template< int XDiffOrder = 0,
+                int YDiffOrder = 0,
+                int ZDiffOrder = 0,
+                typename Vertex = VertexType >
+#endif   
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      RealType getValue( const Vertex& v,
+                         const Real& time = 0.0 ) const;
+};
+
+template< int Dimensions,
+          typename Real >
+ostream& operator << ( ostream& str, const tnlTwinsFunction< Dimensions, Real >& f )
+{
+   str << "Twins function.";
+   return str;
+}
+
+template< int FunctionDimensions,
+          typename Real >
+class tnlFunctionType< tnlTwinsFunction< FunctionDimensions, Real > >
+{
+   public:
+
+      enum { Type = tnlAnalyticFunction };
+};
+
+
+#include <functions/initial_conditions/tnlTwinsFunction_impl.h>
+
+
+#endif /* TNLTWINSFUNCTION_H_ */
diff --git a/src/functions/initial_conditions/tnlTwinsFunction_impl.h b/src/functions/initial_conditions/tnlTwinsFunction_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..da6bb603617b0cb2920f0b83fc3ae49c0a841839
--- /dev/null
+++ b/src/functions/initial_conditions/tnlTwinsFunction_impl.h
@@ -0,0 +1,169 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLTWINSFUNCTION_IMPL_H_
+#define TNLTWINSFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/tnlTwinsFunction.h>
+
+template< typename Real,
+          int Dimensions >
+bool
+tnlTwinsFunctionBase< Real, Dimensions >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   return true;
+}
+
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlTwinsFunction< 1, Real >::getType()
+{
+   return "tnlTwinsFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlTwinsFunction< 1, Real >::tnlTwinsFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+__cuda_callable__
+Real
+tnlTwinsFunction< 1, Real >::getPartialDerivative( const Vertex& v,
+                                                   const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlTwinsFunction< 1, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
+/****
+ * 2D
+ */
+template< typename Real >
+tnlString
+tnlTwinsFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlTwinsFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlTwinsFunction< 2, Real >::tnlTwinsFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+__cuda_callable__
+Real
+tnlTwinsFunction< 2, Real >::
+getPartialDerivative( const Vertex& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return -0.5 * sin( M_PI * x) * sin( M_PI * x) * ( 1 - ( y - 2 ) * ( y - 2 ) ) * ( 1 - tanh ( 10 * ( sqrt( x * x + y * y ) - 0.6 ) ) );
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlTwinsFunction< 2, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
+/****
+ * 3D
+ */
+template< typename Real >
+tnlString
+tnlTwinsFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlTwinsFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlTwinsFunction< 3, Real >::tnlTwinsFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+__cuda_callable__
+Real
+tnlTwinsFunction< 3, Real >::
+getPartialDerivative( const Vertex& v,
+                      const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+template< typename Real >
+__cuda_callable__
+Real
+tnlTwinsFunction< 3, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+#endif /* TNLTWINSFUNCTION_IMPL_H_ */
diff --git a/src/functions/initial_conditions/tnlTwinsFunction_impl.h~ b/src/functions/initial_conditions/tnlTwinsFunction_impl.h~
new file mode 100644
index 0000000000000000000000000000000000000000..a89dd007fe5ec0fc6665c69a9f2ef2521f1c8dea
--- /dev/null
+++ b/src/functions/initial_conditions/tnlTwinsFunction_impl.h~
@@ -0,0 +1,145 @@
+/***************************************************************************
+                          tnlExpBumpFunction_impl.h  -  description
+                             -------------------
+    begin                : Dec 5, 2013
+    copyright            : (C) 2013 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 TNLTWINSFUNCTION_IMPL_H_
+#define TNLTWINSFUNCTION_IMPL_H_
+
+#include <functions/initial_conditions/tnlTwinsFunction.h>
+
+template< typename Real >
+bool
+tnlTwinsFunctionBase< Real >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+   return true;
+}
+
+
+/***
+ * 1D
+ */
+
+template< typename Real >
+tnlString
+tnlTwinsFunction< 1, Real >::getType()
+{
+   return "tnlTwinsFunction< 1, " + ::getType< Real >() + tnlString( " >" );
+}
+
+template< typename Real >
+tnlTwinsFunction< 1, Real >::tnlTwinsFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder, 
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlTwinsFunction< 1, Real >::getValue( const Vertex& v,
+                                         const Real& time ) const
+{
+   const RealType& x = v.x();
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+/****
+ * 2D
+ */
+
+template< typename Real >
+tnlString
+tnlTwinsFunction< 2, Real >::getType()
+{
+   return tnlString( "tnlTwinsFunction< 2, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlTwinsFunction< 2, Real >::tnlTwinsFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlTwinsFunction< 2, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   if( ZDiffOrder != 0 )
+      return 0.0;
+   if( XDiffOrder == 0 && YDiffOrder == 0 )
+      return -0.5 * sin( M_PI * x) * sin( M_PI * x) * ( 1 - ( y - 2 ) * ( y - 2 ) ) * ( 1 - tanh ( 10 * ( sqrt( x * x + y * y ) - 0.6 ) ) );
+   return 0.0;
+}
+
+/****
+ * 3D
+ */
+
+template< typename Real >
+tnlString
+tnlTwinsFunction< 3, Real >::getType()
+{
+   return tnlString( "tnlTwinsFunction< 3, " ) + ::getType< Real >() + " >";
+}
+
+template< typename Real >
+tnlTwinsFunction< 3, Real >::tnlTwinsFunction()
+{
+}
+
+template< typename Real >
+   template< int XDiffOrder,
+             int YDiffOrder,
+             int ZDiffOrder,
+             typename Vertex >
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+Real
+tnlTwinsFunction< 3, Real >::
+getValue( const Vertex& v,
+          const Real& time ) const
+{
+   const RealType& x = v.x();
+   const RealType& y = v.y();
+   const RealType& z = v.z();
+   if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 )
+      return 0.0;
+   return 0.0;
+}
+
+
+#endif /* TNLTWINSFUNCTION_IMPL_H_ */
diff --git a/src/functions/tnlConstantFunction.h b/src/functions/tnlConstantFunction.h
index c023e7553132a2f31deafeaa42688faff5164b16..381bf3cae3119d199b1b6dec3b15144cf98adc71 100644
--- a/src/functions/tnlConstantFunction.h
+++ b/src/functions/tnlConstantFunction.h
@@ -20,11 +20,11 @@
 
 #include <iostream>
 #include <core/vectors/tnlStaticVector.h>
-#include <functions/tnlFunction.h>
+#include <functions/tnlDomain.h>
 
 template< int dimensions,
           typename Real = double >
-class tnlConstantFunction : public tnlFunction< dimensions, AnalyticConstantFunction >
+class tnlConstantFunction : public tnlDomain< dimensions, NonspaceDomain >
 {
    public:
       
@@ -46,24 +46,21 @@ class tnlConstantFunction : public tnlFunction< dimensions, AnalyticConstantFunc
    #ifdef HAVE_NOT_CXX11
       template< int XDiffOrder,
                 int YDiffOrder,
-                int ZDiffOrder,
-                typename Vertex >
+                int ZDiffOrder >
    #else
       template< int XDiffOrder,
                 int YDiffOrder = 0,
-                int ZDiffOrder = 0,
-                typename Vertex = VertexType >
+                int ZDiffOrder = 0 >
    #endif
       __cuda_callable__ inline
-      RealType getValue( const Vertex& v,
-                         const Real& time = 0.0 ) const;
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
 
-      template< typename Vertex >
       __cuda_callable__ inline
-      RealType getValue( const Vertex& v,
-                         const Real& time = 0.0 ) const
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const
       {
-         return getValue< 0, 0, 0, Vertex >( v, time );
+         return constant;
       }
       
        __cuda_callable__ inline
diff --git a/src/functions/tnlConstantFunction_impl.h b/src/functions/tnlConstantFunction_impl.h
index a03b89f70a60609320e80405857134d703be93f7..bb841744c05b97fdd41f0ee974141e6d931424bd 100644
--- a/src/functions/tnlConstantFunction_impl.h
+++ b/src/functions/tnlConstantFunction_impl.h
@@ -69,12 +69,11 @@ template< int Dimensions,
           typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
-             int ZDiffOrder,
-             typename Vertex >
+             int ZDiffOrder >
 Real
 tnlConstantFunction< Dimensions, Real >::
-getValue( const Vertex& v,
-          const Real& time ) const
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    if( XDiffOrder || YDiffOrder || ZDiffOrder )
       return 0.0;
diff --git a/src/functions/tnlDomain.h b/src/functions/tnlDomain.h
new file mode 100644
index 0000000000000000000000000000000000000000..ddc32173cfe5573d36127876f8beca1c09d74b3e
--- /dev/null
+++ b/src/functions/tnlDomain.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+                          tnlDomain.h  -  description
+                             -------------------
+    begin                : Nov 8, 2015
+    copyright            : (C) 2015 by 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 TNLFUNCTION_H
+#define	TNLFUNCTION_H
+
+enum tnlDomainType { NonspaceDomain, SpaceDomain, MeshDomain, MeshInteriorDomain, MeshBoundaryDomain };
+
+template< int Dimensions,
+          tnlDomainType DomainType = SpaceDomain >
+class tnlDomain
+{
+   public:
+      
+      typedef void DeviceType;
+      
+      static const int dimensions = Dimensions;
+      static constexpr int getDimensions() { return Dimensions; }
+      
+      static constexpr tnlDomainType getDomainType() { return DomainType; }
+};
+
+#endif	/* TNLFUNCTION_H */
+
diff --git a/src/functions/tnlExactOperatorFunction.h b/src/functions/tnlExactOperatorFunction.h
new file mode 100644
index 0000000000000000000000000000000000000000..20bd39184af9d206e100701728f8fcca71df272d
--- /dev/null
+++ b/src/functions/tnlExactOperatorFunction.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+                          tnlExactOperatorFunction.h  -  description
+                             -------------------
+    begin                : Jan 5, 2016
+    copyright            : (C) 2016 by 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 TNLEXACTOPERATORFUNCTION_H
+#define	TNLEXACTOPERATORFUNCTION_H
+
+#include <functions/tnlDomain.h>
+
+template< typename Operator,
+          typename Function >
+class tnlExactOperatorFunction : public tnlDomain< Operator::getDimensions(), SpaceDomain >
+{   
+   static_assert( Operator::getDimensions() == Function::getDimensions(),
+      "Operator and function have different number of domain dimensions." );
+   
+   public:      
+      
+      typedef Operator OperatorType;
+      typedef Function FunctionType;
+      typedef typename FunctionType::RealType RealType;
+      typedef typename FunctionType::VertexType VertexType;
+      
+      static constexpr int getDimensions(){ return Operator::getDimensions(); };
+      
+      tnlExactOperatorFunction(
+         const OperatorType& operator_,
+         const FunctionType& function )
+      : operator_( operator_ ), function( function ) {};
+      
+      __cuda_callable__
+      RealType operator()(
+         const VertexType& vertex,
+         const RealType& time ) const
+      {
+         return this->operator_( function, vertex, time );
+      }
+      
+   protected:
+      
+      const OperatorType& operator_;
+      
+      const FunctionType& function;               
+};
+
+#endif	/* TNLEXACTOPERATORFUNCTION_H */
+
diff --git a/src/functions/tnlExpBumpFunction.h b/src/functions/tnlExpBumpFunction.h
index c6f3ffa8512919896ea4818f1e85db99a2706e43..f32aba0e0804a0724536c7ba04fbbda8ac78972c 100644
--- a/src/functions/tnlExpBumpFunction.h
+++ b/src/functions/tnlExpBumpFunction.h
@@ -20,16 +20,18 @@
 
 #include <config/tnlParameterContainer.h>
 #include <core/vectors/tnlStaticVector.h>
-#include <functions/tnlFunction.h>
+#include <functions/tnlDomain.h>
 
 template< int dimensions,
           typename Real >
-class tnlExpBumpFunctionBase : public tnlFunction< dimensions, AnalyticFunction >
+class tnlExpBumpFunctionBase : public tnlDomain< dimensions, SpaceDomain >
 {
    public:
      
       typedef Real RealType;
       
+      tnlExpBumpFunctionBase();
+      
       bool setup( const tnlParameterContainer& parameters,
                  const tnlString& prefix = "" );
 
@@ -73,8 +75,13 @@ class tnlExpBumpFunction< 1, Real > : public tnlExpBumpFunctionBase< 1, Real >
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
 #endif   
-   __cuda_callable__ RealType getValue( const VertexType& v,
-                                        const Real& time = 0.0 ) const;
+   __cuda_callable__ 
+   RealType getPartialDerivative( const VertexType& v,
+                                  const Real& time = 0.0 ) const;
+      
+   __cuda_callable__
+   RealType operator()( const VertexType& v,
+                        const RealType& time = 0.0 ) const;
 };
 
 template< typename Real >
@@ -99,8 +106,12 @@ class tnlExpBumpFunction< 2, Real > : public tnlExpBumpFunctionBase< 2, Real >
                 int ZDiffOrder = 0 >
 #endif
    __cuda_callable__ inline
-   RealType getValue( const VertexType& v,
-                      const Real& time = 0.0 ) const;
+   RealType getPartialDerivative( const VertexType& v,
+                                  const Real& time = 0.0 ) const;
+      
+   __cuda_callable__
+   RealType operator()( const VertexType& v,
+                        const Real& time = 0.0 ) const;                            
 };
 
 template< typename Real >
@@ -125,8 +136,14 @@ class tnlExpBumpFunction< 3, Real > : public tnlExpBumpFunctionBase< 3, Real >
                 int YDiffOrder = 0,
                 int ZDiffOrder = 0 >
 #endif   
-   __cuda_callable__    RealType getValue( const VertexType& v,
-                                           const Real& time = 0.0 ) const;
+   __cuda_callable__
+   RealType getPartialDerivative( const VertexType& v,
+                                  const Real& time = 0.0 ) const;
+      
+   __cuda_callable__
+   RealType operator()( const VertexType& v,
+                        const Real& time = 0.0 ) const;
+      
 };
 
 template< int Dimensions,
diff --git a/src/functions/tnlExpBumpFunction_impl.h b/src/functions/tnlExpBumpFunction_impl.h
index 3990902b860eeaf98281781b22d42ff98073237e..cb1d8c758ca1975e5f562c67c0bfd5080749181f 100644
--- a/src/functions/tnlExpBumpFunction_impl.h
+++ b/src/functions/tnlExpBumpFunction_impl.h
@@ -20,6 +20,13 @@
 
 #include <functions/tnlExpBumpFunction.h>
 
+template< int dimensions, typename Real >
+tnlExpBumpFunctionBase< dimensions, Real >::
+tnlExpBumpFunctionBase()
+   : amplitude( 1.0 ), sigma( 1.0 )
+{
+}
+
 template< int dimensions, typename Real >
 bool
 tnlExpBumpFunctionBase< dimensions, Real >::
@@ -77,8 +84,9 @@ template< typename Real >
              int ZDiffOrder >
 __cuda_callable__
 Real
-tnlExpBumpFunction< 1, Real >::getValue( const VertexType& v,
-                                         const Real& time ) const
+tnlExpBumpFunction< 1, Real >::
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    const RealType& x = v.x();
    if( YDiffOrder != 0 || ZDiffOrder != 0 )
@@ -92,6 +100,17 @@ tnlExpBumpFunction< 1, Real >::getValue( const VertexType& v,
    return 0.0;
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+tnlExpBumpFunction< 1, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
 /****
  * 2D
  */
@@ -115,8 +134,8 @@ template< typename Real >
 __cuda_callable__ inline
 Real
 tnlExpBumpFunction< 2, Real >::
-getValue( const VertexType& v,
-          const Real& time ) const
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    const RealType& x = v.x();
    const RealType& y = v.y();
@@ -132,9 +151,21 @@ getValue( const VertexType& v,
       return -2.0 * y / ( this->sigma * this->sigma ) * this->amplitude * exp( (-x * x - y * y)/ ( this->sigma * this->sigma ) );
    if( XDiffOrder == 0 && YDiffOrder == 2 )
       return -2.0 / ( this->sigma * this->sigma ) * this->amplitude * exp( (-x*x - y*y) / ( this->sigma * this->sigma ) ) + 4.0 * y * y / ( this->sigma * this->sigma * this->sigma * this->sigma ) * this->amplitude * exp( (-x*x - y*y) / ( this->sigma * this->sigma ) );
+   if( XDiffOrder == 1 && YDiffOrder == 1 )
+      return 4.0 * x * y / ( ( this->sigma * this->sigma ) * ( this->sigma * this->sigma ) ) * this->amplitude * exp( (-x * x - y * y)/ ( this->sigma * this->sigma ) );
    return 0.0;
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+tnlExpBumpFunction< 2, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
 /****
  * 3D
  */
@@ -158,8 +189,8 @@ template< typename Real >
 __cuda_callable__
 Real
 tnlExpBumpFunction< 3, Real >::
-getValue( const VertexType& v,
-          const Real& time ) const
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    const RealType& x = v.x();
    const RealType& y = v.y();
@@ -178,8 +209,25 @@ getValue( const VertexType& v,
       return -2.0 * z / ( this->sigma * this->sigma ) * this->amplitude * exp( ( -x*x - y*y -z*z ) / ( this->sigma * this->sigma ) );
    if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 2 )
       return -2.0 / ( this->sigma * this->sigma ) * this->amplitude * exp( ( -x*x - y*y -z*z ) / ( this->sigma * this->sigma ) ) + 4.0 * z * z / ( this->sigma * this->sigma * this->sigma * this->sigma ) * this->amplitude * exp( ( -x*x - y*y -z*z ) / ( this->sigma * this->sigma ) );
+   if( XDiffOrder == 1 && YDiffOrder == 1 && ZDiffOrder == 0 )
+      return 4.0 * x * y / ( ( this->sigma * this->sigma ) * ( this->sigma * this->sigma ) ) * this->amplitude * exp( ( -x*x - y*y -z*z ) / ( this->sigma * this->sigma ) );
+   if( XDiffOrder == 1 && YDiffOrder == 0 && ZDiffOrder == 1 )
+      return 4.0 * x * z / ( ( this->sigma * this->sigma ) * ( this->sigma * this->sigma ) ) * this->amplitude * exp( ( -x*x - y*y -z*z ) / ( this->sigma * this->sigma ) );
+   if( XDiffOrder == 0 && YDiffOrder == 1 && ZDiffOrder == 1 )
+      return 4.0 * y * z / ( ( this->sigma * this->sigma ) * ( this->sigma * this->sigma ) ) * this->amplitude * exp( ( -x*x - y*y -z*z ) / ( this->sigma * this->sigma ) );
    return 0.0;
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+tnlExpBumpFunction< 3, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
 
 #endif /* TNLEXPBUMPFUNCTION_IMPL_H_ */
diff --git a/src/functions/tnlFunction.h b/src/functions/tnlFunction.h
deleted file mode 100644
index 4ddaf58ac6c23129d3b1f3f74f5bd17b6239dbe4..0000000000000000000000000000000000000000
--- a/src/functions/tnlFunction.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/***************************************************************************
-                          tnlFunction.h  -  description
-                             -------------------
-    begin                : Nov 8, 2015
-    copyright            : (C) 2015 by 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 TNLFUNCTION_H
-#define	TNLFUNCTION_H
-
-#include <core/vectors/tnlStaticVector.h>
-
-enum tnlFunctionType { GeneralFunction, 
-                       MeshFunction,
-                       AnalyticFunction,
-                       AnalyticConstantFunction };
-
-template< int Dimensions,
-          tnlFunctionType FunctionType = GeneralFunction >
-class tnlFunction
-{
-   public:
-      
-      static const int dimensions = Dimensions;
-      static constexpr int getDimensions() { return Dimensions; }
-      
-      static constexpr tnlFunctionType getFunctionType() { return FunctionType; }
-};
-
-
-/*
- * Funkce jsou bud analyticke nebo sitove( diskretni )
- *  - analyticke jsou dane vzorcem
- *    - zavisi na prostorove promenne Vertex a casu 
- *    - 
- *  - sitove jsou dane hodnotama na sitovych entitach
- *    - jejich hodnota zavisi pouze na indexu sitove entity
- * 
- * Dale jsou hybrydni funkce, ktere zavisi na vertexu, casu a indexu sitove entity.
- *   - jejich typ se urci meotdou getFunctionType
- *   - ta je def. v tnlFunction a vraci tnlHybridFunction / tnlGeneralFunction.
- *   - jde o defaultni nastaveni, ktere neni superoptimalni, ale jednoduche pro uzivatele
- * 
- */
-
-/*
-muzeme rozlisovat tnlMeshFunction a tnl(Analytic)Function
-   -ta druha ma typ site void
-   - chtelo by to naimplementovat tnlMeshFunction, aby se videlo, co tim lze vyresit
-   - mesh-function bude mit ukazatel na mesh a dimenzi mesh entit, na nichz je definovana
-   - asi nebude zaviset na case
-   - mohl by pro ni byt definovany operator =, ktery by slouzil k projekci spojitych funkci na sit
-   - tim bysme se zbavili enumeratoru
-   - nad mesh function pak lze implementovat interpolanty - mozna vhodne i pro multigrid
-      =====>>>> IMPLEMENTOVAT tnlMeshFunction
-   - prozkoumat moznost lamda funkci pro mesh functions pro snazsi inicializaci sitove funkce
-   nejakou pocatecni podminkou ==> mozna by to mohlo nahradit i ty analyticke funkce ???
- */
-#endif	/* TNLFUNCTION_H */
-
diff --git a/src/functions/tnlFunctionAdapter.h b/src/functions/tnlFunctionAdapter.h
index 351c9f58fa206b76f6372b47573327000764087b..71e14b30ef00a5404b5767941fb3148475a999b6 100644
--- a/src/functions/tnlFunctionAdapter.h
+++ b/src/functions/tnlFunctionAdapter.h
@@ -19,28 +19,68 @@
 #define	TNLFUNCTIONADAPTER_H
 
 /***
- *  MeshType is a type of mesh on which we evaluate the function
- *  FunctionType is a type of function which we want to evaluate
- *  FunctionMeshType is a type mesh on which the function is "defined"
- *   - it can be void for analytic function given by a formula or
- *     MeshType for mesh functions
- *   - this adapter passes a vertex as a space variable to analytic functions
- *     and mesh entity index for mesh functions.
+ * MeshType is a type of mesh on which we evaluate the function.
+ * DomainType (defined in functions/tnlDomain.h) defines a domain of
+ * the function. In TNL, we mostly work with mesh functions. In this case
+ * mesh entity and time is passed to the function...
  */
 template< typename Mesh,
           typename Function,
-          //tnlFunctionType functionType = Function::functionType >
-          int functionType = Function::getFunctionType() >
+          int domainType = Function::getDomainType() >
 class tnlFunctionAdapter
 {
+      public:
+      
+      typedef Function FunctionType;
+      typedef Mesh MeshType;
+      typedef typename FunctionType::RealType  RealType;
+      typedef typename MeshType::IndexType     IndexType;      
+      //typedef typename FunctionType::VertexType VertexType;
+      
+      template< typename EntityType >
+      __cuda_callable__ inline
+      static RealType getValue( const FunctionType& function,
+                                const EntityType& meshEntity,
+                                const RealType& time )
+      {         
+         return function( meshEntity, time );
+      }
+};
+
+/***
+ * Specialization for analytic functions. In this case
+ * we pass vertex and time to the function ...
+ */
+template< typename Mesh,
+          typename Function >
+class tnlFunctionAdapter< Mesh, Function, SpaceDomain >
+{
+   public:
+      
+      typedef Function FunctionType;
+      typedef Mesh MeshType;
+      typedef typename FunctionType::RealType  RealType;
+      typedef typename MeshType::IndexType     IndexType;      
+      typedef typename FunctionType::VertexType VertexType;
+      
+      template< typename EntityType >
+      __cuda_callable__ inline
+      static RealType getValue( const FunctionType& function,
+                                const EntityType& meshEntity,
+                                const RealType& time )
+      {         
+         return function( meshEntity.getCenter(), time );
+      }
 };
 
 /***
- * Specialization for general functions
+ * Specialization for analytic space independent functions.
+ * Such function does not depend on any space variable and so
+ * we pass only time.
  */
 template< typename Mesh,
           typename Function >
-class tnlFunctionAdapter< Mesh, Function, GeneralFunction >
+class tnlFunctionAdapter< Mesh, Function, NonspaceDomain >
 {
    public:
       
@@ -56,10 +96,12 @@ class tnlFunctionAdapter< Mesh, Function, GeneralFunction >
                                 const EntityType& meshEntity,
                                 const RealType& time )
       {         
-         return function.getValue( meshEntity, time );
+         return function.getValue( time );
       }
 };
 
+#ifdef UNDEF
+
 /***
  * Specialization for mesh functions
  */
@@ -80,7 +122,7 @@ class tnlFunctionAdapter< Mesh, Function, MeshFunction >
                                 const EntityType& meshEntity,
                                 const RealType& time )
       {         
-         return function( meshEntity );
+         return function( meshEntity, time );
       }
 };
 
@@ -89,7 +131,7 @@ class tnlFunctionAdapter< Mesh, Function, MeshFunction >
  */
 template< typename Mesh,
           typename Function >
-class tnlFunctionAdapter< Mesh, Function, AnalyticFunction >
+class tnlFunctionAdapter< Mesh, Function, SpaceDomain >
 {
    public:
       
@@ -114,7 +156,7 @@ class tnlFunctionAdapter< Mesh, Function, AnalyticFunction >
  */
 template< typename Mesh,
           typename Function >
-class tnlFunctionAdapter< Mesh, Function, AnalyticConstantFunction >
+class tnlFunctionAdapter< Mesh, Function, SpaceDomain >
 {
    public:
       
@@ -133,7 +175,7 @@ class tnlFunctionAdapter< Mesh, Function, AnalyticConstantFunction >
          return function.getValue( time );
       }
 };
-
+#endif
 
 #endif	/* TNLFUNCTIONADAPTER_H */
 
diff --git a/src/functions/tnlFunctionDiscretizer.h b/src/functions/tnlFunctionDiscretizer.h
deleted file mode 100644
index bceebb646351176dfd27e265397ce19205ce8991..0000000000000000000000000000000000000000
--- a/src/functions/tnlFunctionDiscretizer.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/***************************************************************************
-                          tnlFunctionDiscretizer.h  -  description
-                             -------------------
-    begin                : Nov 24, 2013
-    copyright            : (C) 2013 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 TNLFUNCTIONDISCRETIZER_H_
-#define TNLFUNCTIONDISCRETIZER_H_
-
-template< typename Mesh, typename Function, typename Vector >
-class tnlFunctionDiscretizer
-{
-   public:
-
-      typedef typename Vector::DeviceType DeviceType;
-      typedef typename Mesh::IndexType IndexType;
-      typedef typename Function::VertexType VertexType;
-      typedef typename Mesh::CoordinatesType CoordinatesType;
-
-#ifdef HAVE_NOT_CXX11
-   template< int XDiffOrder,
-             int YDiffOrder,
-             int ZDiffOrder >
-   static void discretize( const Mesh& mesh,
-                           const Function& function,
-                           Vector& discreteFunction,
-                           const typename Vector::RealType& time = 0 );
-#else
-   template< int XDiffOrder = 0,
-             int YDiffOrder = 0,
-             int ZDiffOrder = 0 >
-   static void discretize( const Mesh& mesh,
-                           const Function& function,
-                           Vector& discreteFunction,
-                           const typename Vector::RealType& time = 0 );
-#endif   
-   
-};
-
-#include <functions/tnlFunctionDiscretizer_impl.h>
-
-#endif /* TNLFUNCTIONDISCRETIZER_H_ */
diff --git a/src/functions/tnlFunctionDiscretizer_impl.h b/src/functions/tnlFunctionDiscretizer_impl.h
deleted file mode 100644
index 30a0058b76c707e8f703db1f5be3419055e5d35b..0000000000000000000000000000000000000000
--- a/src/functions/tnlFunctionDiscretizer_impl.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***************************************************************************
-                          tnlFunctionDiscretizer_impl.h  -  description
-                             -------------------
-    begin                : Nov 24, 2013
-    copyright            : (C) 2013 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 TNLFUNCTIONDISCRETIZER_IMPL_H_
-#define TNLFUNCTIONDISCRETIZER_IMPL_H_
-
-template< typename Mesh, typename Function, typename Vector >
-   template< int XDiffOrder, int YDiffOrder, int ZDiffOrder >
-void tnlFunctionDiscretizer< Mesh, Function, Vector >::discretize( const Mesh& mesh,
-                                                                   const Function& function,
-                                                                   Vector& discreteFunction,
-                                                                   const typename Vector::RealType& time )
-{
-   //tnlAssert( Mesh::Dimensions == Function::Dimensions, ); // TODO: change this to tnlStaticAssert
-   IndexType i = 0;
-   discreteFunction.setSize( mesh.template getEntitiesCount< typename Mesh::Cell >() );
-   if( DeviceType::DeviceType == ( int ) tnlHostDevice )
-   {
-      while( i < mesh.template getEntitiesCount< typename Mesh::Cell >() )
-      {
-         VertexType v = static_cast< VertexType >( mesh.template getEntity< typename Mesh::Cell >( i ).getCenter() );
-         discreteFunction[ i ] = function.template getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( v, time );
-         i++;
-      }
-   }
-   if( DeviceType::DeviceType == ( int ) tnlCudaDevice )
-   {
-      // TODO: implement
-   }
-}
-
-
-
-#endif /* TNLFUNCTIONDISCRETIZER_IMPL_H_ */
diff --git a/src/functions/tnlFunctionEnumerator.h b/src/functions/tnlFunctionEnumerator.h
deleted file mode 100644
index 57e2e39b5a47fa230280c6709d9b0473edd30b4b..0000000000000000000000000000000000000000
--- a/src/functions/tnlFunctionEnumerator.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/***************************************************************************
-                          tnlFunctionEnumerator.h  -  description
-                             -------------------
-    begin                : Mar 5, 2015
-    copyright            : (C) 2015 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 SRC_FUNCTIONS_TNLFUNCTIONENUMERATOR_H_
-#define SRC_FUNCTIONS_TNLFUNCTIONENUMERATOR_H_
-
-#include <functions/tnlFunctionAdapter.h>
-
-template< typename Function,
-          typename DofVector >
-class tnlFunctionEnumeratorTraverserUserData
-{
-   public:
-
-      typedef typename DofVector::RealType RealType;
-
-      const RealType *time;
-
-      const Function* function;
-
-      DofVector *u;
-
-      const RealType* functionCoefficient;
-
-      const RealType* dofVectorCoefficient;
-
-      tnlFunctionEnumeratorTraverserUserData( const RealType& time,
-                                              const Function& function,
-                                              DofVector& u,
-                                              const RealType& functionCoefficient,
-                                              const RealType& dofVectorCoefficient )
-      : time( &time ),
-        function( &function ),
-        u( &u ),
-        functionCoefficient( &functionCoefficient ),
-        dofVectorCoefficient( &dofVectorCoefficient )
-      {};
-};
-
-
-template< typename Mesh,
-          typename Function,
-          typename DofVector >
-class tnlFunctionEnumerator
-{
-   public:
-      typedef Mesh MeshType;
-      typedef typename DofVector::RealType RealType;
-      typedef typename DofVector::DeviceType DeviceType;
-      typedef typename DofVector::IndexType IndexType;
-      typedef tnlFunctionEnumeratorTraverserUserData< Function,
-                                                      DofVector > TraverserUserData;
-
-      template< int EntityDimensions >
-      void enumerate( const MeshType& mesh,
-                      const Function& function,
-                      DofVector& u,
-                      const RealType& functionCoefficient = 1.0,
-                      const RealType& dofVectorCoefficient = 0.0,
-                      const RealType& time = 0.0 ) const;
-
-
-      class TraverserEntitiesProcessor
-      {
-         public:
-
-            template< int EntityDimensions >
-#ifdef HAVE_CUDA
-            __host__ __device__
-#endif
-            static void processEntity( const MeshType& mesh,
-                                       TraverserUserData& userData,
-                                       const IndexType index )
-            {
-               typedef tnlFunctionAdapter< MeshType, Function > FunctionAdapter;
-               if( ! *userData.dofVectorCoefficient  )
-                  ( *userData.u )[ index ] =
-                     ( *userData.functionCoefficient ) * FunctionAdapter::getValue( mesh,
-                                                                                    *userData.function,
-                                                                                    index,
-                                                                                    *userData.time );
-               else                                                                                            
-                 ( *userData.u )[ index ] =
-                             ( *userData.dofVectorCoefficient ) * ( *userData.u )[ index ] +
-                             ( *userData.functionCoefficient ) * FunctionAdapter::getValue( mesh,
-                                                                                            *userData.function,
-                                                                                            index,
-                                                                                            *userData.time );
-            }
-
-      };
-
-};
-
-template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index,
-          typename Function,
-          typename DofVector >
-class tnlFunctionEnumerator< tnlGrid< Dimensions, Real, Device, Index >,
-                             Function,
-                             DofVector >
-{
-   public:
-
-      typedef tnlGrid< Dimensions, Real, Device, Index > MeshType;
-      typedef typename MeshType::RealType RealType;
-      typedef typename MeshType::DeviceType DeviceType;
-      typedef typename MeshType::IndexType IndexType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef tnlFunctionEnumeratorTraverserUserData< Function,
-                                                      DofVector > TraverserUserData;
-
-      template< int EntityDimensions >
-      void enumerate( const MeshType& mesh,
-                      const Function& function,
-                      DofVector& u,
-                      const RealType& functionCoefficient = 1.0,
-                      const RealType& dofVectorCoefficient = 0.0,
-                      const RealType& time = 0.0 ) const;
-
-      class TraverserEntitiesProcessor
-      {
-         public:
-
-         typedef typename MeshType::VertexType VertexType;
-
-#ifdef HAVE_CUDA
-            __host__ __device__
-#endif
-            static void processCell( const MeshType& mesh,
-                                     TraverserUserData& userData,
-                                     const IndexType index,
-                                     const CoordinatesType& coordinates )
-            {
-               //printf( "Enumerator::processCell mesh =%p \n", &mesh );
-               typedef tnlFunctionAdapter< MeshType, Function > FunctionAdapter;
-               if( ! ( *userData.dofVectorCoefficient ) )
-                  ( *userData.u )[ index ] =
-                     ( *userData.functionCoefficient ) * FunctionAdapter::getValue( mesh,
-                                                                                    *userData.function,
-                                                                                    index,
-                                                                                    coordinates,
-                                                                                    *userData.time );
-               else
-                  ( *userData.u )[ index ] =
-                           ( *userData.dofVectorCoefficient ) * ( *userData.u )[ index ] +
-                           ( *userData.functionCoefficient ) * FunctionAdapter::getValue( mesh,
-                                                                                          *userData.function,
-                                                                                          index,
-                                                                                          coordinates,
-                                                                                          *userData.time );
-
-            }
-
-#ifdef HAVE_CUDA
-            __host__ __device__
-#endif
-            static void processFace( const MeshType& mesh,
-                                     TraverserUserData& userData,
-                                     const IndexType index,
-                                     const CoordinatesType& coordinates )
-            {
-               typedef tnlFunctionAdapter< MeshType, Function > FunctionAdapter;
-               if( ! ( *userData.dofVectorCoefficient ) )
-                  ( *userData.u )[ index ] =
-                     ( *userData.functionCoefficient ) * FunctionAdapter::getValue( mesh,
-                                                                                    *userData.function,
-                                                                                    index,
-                                                                                    coordinates,
-                                                                                    *userData.time );
-               else
-                  ( *userData.u )[ index ] =
-                           ( *userData.dofVectorCoefficient ) * ( *userData.u )[ index ] +
-                           ( *userData.functionCoefficient ) * FunctionAdapter::getValue( mesh,
-                                                                                          *userData.function,
-                                                                                          index,
-                                                                                          coordinates,
-                                                                                          *userData.time );
-            }
-      };
-
-};
-
-#include <functions/tnlFunctionEnumerator_impl.h>
-
-
-
-#endif /* SRC_FUNCTIONS_TNLFUNCTIONENUMERATOR_H_ */
diff --git a/src/functions/tnlFunctionEnumerator_impl.h b/src/functions/tnlFunctionEnumerator_impl.h
deleted file mode 100644
index fb15ab2253bc9223648de0137e6127ba6efa1ee2..0000000000000000000000000000000000000000
--- a/src/functions/tnlFunctionEnumerator_impl.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/***************************************************************************
-                          tnlFunctionEnumerator_impl.h  -  description
-                             -------------------
-    begin                : Mar 5, 2015
-    copyright            : (C) 2015 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 SRC_FUNCTIONS_TNLFUNCTIONENUMERATOR_IMPL_H_
-#define SRC_FUNCTIONS_TNLFUNCTIONENUMERATOR_IMPL_H_
-
-#include <functions/tnlFunctionEnumerator.h>
-#include <mesh/tnlTraverser_Grid1D.h>
-#include <mesh/tnlTraverser_Grid2D.h>
-#include <mesh/tnlTraverser_Grid3D.h>
-
-template< typename Mesh,
-          typename Function,
-          typename DofVector >
-   template< int EntityDimensions >
-void
-tnlFunctionEnumerator< Mesh, Function, DofVector >::
-enumerate( const MeshType& mesh,
-           const Function& function,
-           DofVector& u,
-           const RealType& functionCoefficient,
-           const RealType& dofVectorCoefficient,
-           const RealType& time ) const
-
-{
-   if( DeviceType::DeviceType == tnlHostDevice )
-   {
-      TraverserUserData userData( time, function, u, functionCoefficient, dofVectorCoefficient );
-      tnlTraverser< MeshType, EntityDimensions > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-
-   }
-   if( DeviceType::DeviceType == tnlCudaDevice )
-   {
-      RealType* kernelTime = tnlCuda::passToDevice( time );
-      Function* kernelFunction = tnlCuda::passToDevice( function );
-      DofVector* kernelU = tnlCuda::passToDevice( u );
-      RealType* kernelFunctionCoefficient = tnlCuda::passToDevice( functionCoefficient );
-      RealType* kernelDofVectorCoefficient = tnlCuda::passToDevice( dofVectorCoefficient );
-      TraverserUserData userData( *kernelTime, *kernelFunction, *kernelU, *kernelFunctionCoefficient, *kernelDofVectorCoefficient );
-      checkCudaDevice;
-      tnlTraverser< MeshType, EntityDimensions > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-
-      checkCudaDevice;
-      tnlCuda::freeFromDevice( kernelTime );
-      tnlCuda::freeFromDevice( kernelFunction );
-      tnlCuda::freeFromDevice( kernelU );
-      tnlCuda::freeFromDevice( kernelFunctionCoefficient );
-      tnlCuda::freeFromDevice( kernelDofVectorCoefficient );
-      checkCudaDevice;
-   }
-}
-
-template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index,
-          typename Function,
-          typename DofVector >
-   template< int EntityDimensions >
-void
-tnlFunctionEnumerator< tnlGrid< Dimensions, Real, Device, Index >, Function, DofVector  >::
-enumerate( const tnlGrid< Dimensions, Real, Device, Index >& mesh,
-           const Function& function,
-           DofVector& u,
-           const RealType& functionCoefficient,
-           const RealType& dofVectorCoefficient,
-           const RealType& time ) const
-{
-   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlHostDevice )
-   {
-      TraverserUserData userData( time, function, u, functionCoefficient, dofVectorCoefficient );
-      tnlTraverser< MeshType, EntityDimensions > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-
-   }
-   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlCudaDevice )
-   {
-      RealType* kernelTime = tnlCuda::passToDevice( time );
-      Function* kernelFunction = tnlCuda::passToDevice( function );
-      DofVector* kernelU = tnlCuda::passToDevice( u );
-      RealType* kernelFunctionCoefficient = tnlCuda::passToDevice( functionCoefficient );
-      RealType* kernelDofVectorCoefficient = tnlCuda::passToDevice( dofVectorCoefficient );
-      TraverserUserData userData( *kernelTime, *kernelFunction, *kernelU, *kernelFunctionCoefficient, *kernelDofVectorCoefficient );
-      checkCudaDevice;
-      tnlTraverser< MeshType, EntityDimensions > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-
-      checkCudaDevice;
-      tnlCuda::freeFromDevice( kernelTime );
-      tnlCuda::freeFromDevice( kernelFunction );
-      tnlCuda::freeFromDevice( kernelU );
-      tnlCuda::freeFromDevice( kernelFunctionCoefficient );
-      tnlCuda::freeFromDevice( kernelDofVectorCoefficient );
-      checkCudaDevice;
-   }
-}
-
-
-
-#endif /* SRC_FUNCTIONS_TNLFUNCTIONENUMERATOR_IMPL_H_ */
diff --git a/src/functions/tnlFunctionEvaluator.h b/src/functions/tnlFunctionEvaluator.h
new file mode 100644
index 0000000000000000000000000000000000000000..d57175d535eec690749534d0dcef355750db332b
--- /dev/null
+++ b/src/functions/tnlFunctionEvaluator.h
@@ -0,0 +1,112 @@
+/***************************************************************************
+                          tnlFunctionEvaluator.h  -  description
+                             -------------------
+    begin                : Mar 5, 2015
+    copyright            : (C) 2015 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 SRC_FUNCTIONS_TNLFUNCTIONEVALUATOR_H_
+#define SRC_FUNCTIONS_TNLFUNCTIONEVALUATOR_H_
+
+#include <functions/tnlFunctionAdapter.h>
+
+template< typename MeshFunction,
+          typename Function >
+class tnlFunctionEvaluatorTraverserUserData
+{
+   public:
+
+      typedef typename MeshFunction::RealType RealType;
+
+      const RealType *time;
+
+      const Function* function;
+
+      MeshFunction *u;
+
+      const RealType* functionCoefficient;
+
+      const RealType* dofVectorCoefficient;
+
+      tnlFunctionEvaluatorTraverserUserData( const RealType& time,
+                                              const Function& function,
+                                              MeshFunction& u,
+                                              const RealType& functionCoefficient,
+                                              const RealType& dofVectorCoefficient )
+      : time( &time ),
+        function( &function ),
+        u( &u ),
+        functionCoefficient( &functionCoefficient ),
+        dofVectorCoefficient( &dofVectorCoefficient )
+      {};
+            
+};
+
+
+template< typename MeshFunction,
+          typename Function >
+class tnlFunctionEvaluator
+{
+   public:
+      typedef typename MeshFunction::MeshType MeshType;
+      typedef typename MeshFunction::RealType RealType;
+      typedef typename MeshFunction::DeviceType DeviceType;
+      typedef typename MeshFunction::IndexType IndexType;
+      typedef tnlFunctionEvaluatorTraverserUserData< MeshFunction,
+                                                     Function > TraverserUserData;
+
+      void assignment( const Function& function,
+                       MeshFunction& u,
+                       const RealType& functionCoefficient = 1.0,
+                       const RealType& meshFunctionCoefficient = 0.0,
+                       const RealType& time = 0.0 ) const;
+
+      //void addition( ... );
+      
+      //void subtruction( .... );
+      
+      //void multiplication( .... );
+
+      class TraverserEntitiesProcessor
+      {
+         public:
+
+            template< typename EntityType >
+            __cuda_callable__
+            static void processEntity( const MeshType& mesh,
+                                       TraverserUserData& userData,
+                                       const EntityType& entity )
+            {
+               typedef tnlFunctionAdapter< MeshType, Function > FunctionAdapter;
+               if( ! *userData.dofVectorCoefficient  )
+                  ( *userData.u )( entity ) =
+                     ( *userData.functionCoefficient ) * FunctionAdapter::getValue( *userData.function,
+                                                                                    entity,
+                                                                                    *userData.time );
+               else                                                                                            
+                 ( *userData.u )( entity ) =
+                             ( *userData.dofVectorCoefficient ) * ( *userData.u )( entity ) +
+                             ( *userData.functionCoefficient ) * FunctionAdapter::getValue( *userData.function,
+                                                                                            entity,
+                                                                                            *userData.time );
+            }
+
+      };
+
+};
+
+#include <functions/tnlFunctionEvaluator_impl.h>
+
+
+
+#endif /* SRC_FUNCTIONS_TNLFUNCTIONEVALUATOR_H_ */
diff --git a/src/functions/tnlFunctionEvaluator_impl.h b/src/functions/tnlFunctionEvaluator_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..756f6e584c656882788164bcf9c1d5d9a8cca64d
--- /dev/null
+++ b/src/functions/tnlFunctionEvaluator_impl.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+                          tnlFunctionEvaluator_impl.h  -  description
+                             -------------------
+    begin                : Mar 5, 2015
+    copyright            : (C) 2015 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 SRC_FUNCTIONS_TNLFUNCTIONEVALUATOR_IMPL_H_
+#define SRC_FUNCTIONS_TNLFUNCTIONEVALUATOR_IMPL_H_
+
+#include <type_traits>
+#include <functions/tnlFunctionEvaluator.h>
+#include <mesh/grids/tnlTraverser_Grid1D.h>
+#include <mesh/grids/tnlTraverser_Grid2D.h>
+#include <mesh/grids/tnlTraverser_Grid3D.h>
+
+template< typename MeshFunction,
+          typename Function >
+void
+tnlFunctionEvaluator< MeshFunction, Function >::
+assignment( const Function& function,
+            MeshFunction& u,
+            const RealType& functionCoefficient,
+            const RealType& dofVectorCoefficient,
+            const RealType& time ) const
+
+{
+   typedef typename MeshType::template MeshEntity< MeshFunction::EntityDimensions > MeshEntityType;
+   if( std::is_same< DeviceType, tnlHost >::value )
+   {
+      TraverserUserData userData( time, function, u, functionCoefficient, dofVectorCoefficient );
+      tnlTraverser< MeshType, MeshEntityType > meshTraverser;
+      meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                                      TraverserEntitiesProcessor >
+                                                    ( u.getMesh(),
+                                                      userData );
+      meshTraverser.template processInteriorEntities< TraverserUserData,
+                                                      TraverserEntitiesProcessor >
+                                                    ( u.getMesh(),
+                                                      userData );
+
+   }
+   if( std::is_same< DeviceType, tnlCuda >::value )
+   {
+      RealType* kernelTime = tnlCuda::passToDevice( time );
+      Function* kernelFunction = tnlCuda::passToDevice( function );
+      MeshFunction* kernelU = tnlCuda::passToDevice( u );
+      RealType* kernelFunctionCoefficient = tnlCuda::passToDevice( functionCoefficient );
+      RealType* kernelDofVectorCoefficient = tnlCuda::passToDevice( dofVectorCoefficient );
+      TraverserUserData userData( *kernelTime, *kernelFunction, *kernelU, *kernelFunctionCoefficient, *kernelDofVectorCoefficient );
+      checkCudaDevice;
+      tnlTraverser< MeshType, MeshEntityType > meshTraverser;
+      meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                                      TraverserEntitiesProcessor >
+                                                    ( u.getMesh(),
+                                                      userData );
+      meshTraverser.template processInteriorEntities< TraverserUserData,
+                                                      TraverserEntitiesProcessor >
+                                                    ( u.getMesh(),
+                                                      userData );
+
+      checkCudaDevice;
+      tnlCuda::freeFromDevice( kernelTime );
+      tnlCuda::freeFromDevice( kernelFunction );
+      tnlCuda::freeFromDevice( kernelU );
+      tnlCuda::freeFromDevice( kernelFunctionCoefficient );
+      tnlCuda::freeFromDevice( kernelDofVectorCoefficient );
+      checkCudaDevice;
+   }
+}
+
+#endif /* SRC_FUNCTIONS_TNLFUNCTIONEVALUATOR_IMPL_H_ */
diff --git a/src/functions/tnlMeshFunction.h b/src/functions/tnlMeshFunction.h
index 9f1f1435659924b5649c95c98dc21945555a03f6..add52cc1c939d2b202206e15a949f1879285d050 100644
--- a/src/functions/tnlMeshFunction.h
+++ b/src/functions/tnlMeshFunction.h
@@ -15,7 +15,10 @@
  *                                                                         *
  ***************************************************************************/
 
-#include <functions/tnlFunction.h>
+#include <core/tnlObject.h>
+#include <functions/tnlDomain.h>
+#include <functions/tnlMeshFunctionGnuplotWriter.h>
+#include <functions/tnlMeshFunctionVTKWriter.h>
 
 #ifndef TNLMESHFUNCTION_H
 #define TNLMESHFUNCTION_H
@@ -23,8 +26,9 @@
 template< typename Mesh,
           int MeshEntityDimensions = Mesh::meshDimensions,
           typename Real = typename Mesh::RealType >
-class tnlMeshFunction : public tnlFunction< Mesh::meshDimensions,
-                                            MeshFunction >
+class tnlMeshFunction : 
+   public tnlObject,
+   public tnlDomain< Mesh::meshDimensions, MeshDomain >
 {
    //static_assert( Mesh::DeviceType::DeviceType == Vector::DeviceType::DeviceType,
    //               "Both mesh and vector of a mesh function must reside on the same device.");
@@ -35,35 +39,49 @@ class tnlMeshFunction : public tnlFunction< Mesh::meshDimensions,
       typedef typename MeshType::IndexType IndexType;
       typedef Real RealType;
       typedef tnlVector< RealType, DeviceType, IndexType > VectorType;
+      typedef tnlMeshFunction< Mesh, MeshEntityDimensions, Real > ThisType;
       
-      static constexpr int getMeshEntityDimensions() { return  MeshEntityDimensions; };
+      static constexpr int getEntitiesDimensions() { return MeshEntityDimensions; };
       
       tnlMeshFunction();
       
+      tnlMeshFunction( const MeshType& mesh );
+      
       template< typename Vector >
       tnlMeshFunction( const MeshType& mesh,
                        Vector& data,
                        const IndexType& offset = 0 );
       
+      static tnlString getType();
+      
+      tnlString getTypeVirtual() const;
+      
+      static tnlString getSerializationType();
+
+      virtual tnlString getSerializationTypeVirtual() const;      
+      
       static void configSetup( tnlConfigDescription& config,
                                const tnlString& prefix = "" );
 
       bool setup( const tnlParameterContainer& parameters,
                   const tnlString& prefix = "" );      
       
-      // TODO: implement bind tnlVector ( using shared pointers )
-      /*template< typename Vector >
-      bool bind( const MeshType& mesh,
-                 Vector& data,
-                 const IndexType& offset = 0 );*/
+      template< typename Vector >
+      void bind( const MeshType& mesh,
+                 const Vector& data,
+                 const IndexType& offset = 0 );
       
-      void setMesh( const MeshType& mesh ) const;      
+      void setMesh( const MeshType& mesh );
       
-      const MeshType& getMesh() const;      
+      const MeshType& getMesh() const;
       
       const VectorType& getData() const;      
       
-      VectorType& getData();      
+      VectorType& getData();
+      
+      bool refresh( const RealType& time = 0.0 ) const;
+      
+      bool deepRefresh( const RealType& time = 0.0 ) const;
       
       template< typename EntityType >
       RealType getValue( const EntityType& meshEntity ) const;
@@ -74,20 +92,61 @@ class tnlMeshFunction : public tnlFunction< Mesh::meshDimensions,
       
       template< typename EntityType >
       __cuda_callable__
-      RealType& operator()( const EntityType& meshEntityIndex );
+      RealType& operator()( const EntityType& meshEntity,
+                            const RealType& time = 0.0 );
       
       template< typename EntityType >
       __cuda_callable__
-      const RealType& operator()( const EntityType& meshEntityIndex ) const;
+      const RealType& operator()( const EntityType& meshEntity,
+                                  const RealType& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType& operator[]( const IndexType& meshEntityIndex );
+      
+      __cuda_callable__
+      const RealType& operator[]( const IndexType& meshEntityIndex ) const;
+
+      template< typename Function >
+      ThisType& operator = ( const Function& f );
+      
+      template< typename Function >
+      ThisType& operator -= ( const Function& f );
+
+      template< typename Function >
+      ThisType& operator += ( const Function& f );
+      
+      RealType getLpNorm( const RealType& p ) const;
+      
+      RealType getMaxNorm() const;
+      
+      bool save( tnlFile& file ) const;
+
+      bool load( tnlFile& file );
+      
+      bool boundLoad( tnlFile& file );
+      
+      bool write( const tnlString& fileName,
+                  const tnlString& format = "vtk" ) const;
+      
+      using tnlObject::save;
+      
+      using tnlObject::load;
+            
+      using tnlObject::boundLoad;
             
    protected:
       
       const MeshType* mesh;
       
-      VectorType data;     
+      VectorType data;
+      
+      template< typename, typename > friend class tnlMeshFunctionEvaluator;
 };
 
 #include <functions/tnlMeshFunction_impl.h>
+#include <functions/tnlMeshFunctionGnuplotWriter_impl.h>
+#include <functions/tnlMeshFunctionVTKWriter_impl.h>
+
 
 #endif	/* TNLMESHFUNCTION_H */
 
diff --git a/src/functions/tnlMeshFunctionEvaluator.h b/src/functions/tnlMeshFunctionEvaluator.h
new file mode 100644
index 0000000000000000000000000000000000000000..882d2e5d0e171ee5b51dd7bcebe4a02b2e6aa617
--- /dev/null
+++ b/src/functions/tnlMeshFunctionEvaluator.h
@@ -0,0 +1,171 @@
+/***************************************************************************
+                          tnlMeshFunctionEvaluator.h  -  description
+                             -------------------
+    begin                : Jan 1, 2016
+    copyright            : (C) 2016 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 TNLMESHFUNCTIONEVALUATOR_H
+#define	TNLMESHFUNCTIONEVALUATOR_H
+
+#include <mesh/tnlGrid.h>
+#include <functions/tnlMeshFunction.h>
+#include <functions/tnlOperatorFunction.h>
+
+template< typename OutMeshFunction,
+          typename InFunction,
+          typename Real >
+class tnlMeshFunctionEvaluatorTraverserUserData;
+
+/***
+ * General mesh function evaluator. As an input function any type implementing
+ * getValue( meshEntity, time ) may be substituted.
+ * Methods:
+ *  evaluate() -  evaluate the input function on its domain
+ *  evaluateAllEntities() - evaluate the input function on ALL mesh entities
+ *  evaluateInteriorEntities() - evaluate the input function only on the INTERIOR mesh entities
+ *  evaluateBoundaryEntities() - evaluate the input function only on the BOUNDARY mesh entities
+ */
+template< typename OutMeshFunction,
+          typename InFunction >
+class tnlMeshFunctionEvaluator : public tnlDomain< OutMeshFunction::getEntitiesDimensions(), MeshDomain >
+{
+   public:
+      typedef typename OutMeshFunction::MeshType MeshType;
+      typedef typename MeshType::RealType MeshRealType;
+      typedef typename MeshType::DeviceType MeshDeviceType;
+      typedef typename MeshType::IndexType MeshIndexType;
+      typedef typename OutMeshFunction::RealType RealType;
+      typedef tnlMeshFunctionEvaluatorTraverserUserData< OutMeshFunction, InFunction, RealType > TraverserUserData;
+
+      
+      const static int meshEntityDimensions = OutMeshFunction::getEntitiesDimensions();
+      
+      static_assert( MeshType::meshDimensions == InFunction::getDimensions(), 
+         "Input function and the mesh of the mesh function have both different number of dimensions." );
+      
+      static void evaluate( OutMeshFunction& meshFunction,
+                            const InFunction& function,                          
+                            const RealType& time = 0.0,
+                            const RealType& outFunctionMultiplicator = 0.0,
+                            const RealType& inFunctionMultiplicator = 1.0 );
+
+      static void evaluateAllEntities( OutMeshFunction& meshFunction,
+                                       const InFunction& function,                          
+                                       const RealType& time = 0.0,
+                                       const RealType& outFunctionMultiplicator = 0.0,
+                                       const RealType& inFunctionMultiplicator = 1.0 );
+      
+      static void evaluateInteriorEntities( OutMeshFunction& meshFunction,
+                                            const InFunction& function,                          
+                                            const RealType& time = 0.0,
+                                            const RealType& outFunctionMultiplicator = 0.0,
+                                            const RealType& inFunctionMultiplicator = 1.0 );
+
+      static void evaluateBoundaryEntities( OutMeshFunction& meshFunction,
+                                            const InFunction& function,                          
+                                            const RealType& time = 0.0,
+                                            const RealType& outFunctionMultiplicator = 0.0,
+                                            const RealType& inFunctionMultiplicator = 1.0 );
+
+   protected:
+
+      enum EntitiesType { all, boundary, interior };
+      
+      static void evaluateEntities( OutMeshFunction& meshFunction,
+                                    const InFunction& function,                          
+                                    const RealType& time,
+                                    const RealType& outFunctionMultiplicator,
+                                    const RealType& inFunctionMultiplicator,
+                                    EntitiesType entitiesType );
+
+      
+}; 
+
+template< typename OutMeshFunction,
+          typename InFunction,
+          typename Real >
+class tnlMeshFunctionEvaluatorTraverserUserData
+{
+   public:
+
+      typedef InFunction InFunctionType;
+
+      tnlMeshFunctionEvaluatorTraverserUserData( const InFunction* function,
+                                                 const Real* time,
+                                                 OutMeshFunction* meshFunction,
+                                                 const Real* outFunctionMultiplicator,
+                                                 const Real* inFunctionMultiplicator )
+      : meshFunction( meshFunction ), function( function ), time( time ), 
+        outFunctionMultiplicator( outFunctionMultiplicator ),
+        inFunctionMultiplicator( inFunctionMultiplicator ){}
+
+      OutMeshFunction* meshFunction;            
+      const InFunction* function;
+      const Real *time, *outFunctionMultiplicator, *inFunctionMultiplicator;
+
+};
+
+
+template< typename MeshType,
+          typename UserData > 
+class tnlMeshFunctionEvaluatorAssignmentEntitiesProcessor
+{
+   public:
+
+      template< typename EntityType >
+      __cuda_callable__
+      static inline void processEntity( const MeshType& mesh,
+                                        UserData& userData,
+                                        const EntityType& entity )
+      {
+         typedef tnlFunctionAdapter< MeshType, typename UserData::InFunctionType > FunctionAdapter;
+         ( *userData.meshFunction )( entity ) = 
+            *userData.inFunctionMultiplicator *
+            FunctionAdapter::getValue( *userData.function, entity, *userData.time );
+         /*cerr << "Idx = " << entity.getIndex() 
+            << " Value = " << FunctionAdapter::getValue( *userData.function, entity, *userData.time ) 
+            << " stored value = " << ( *userData.meshFunction )( entity )
+            << " multiplicators = " << endl;*/
+      }
+};
+
+template< typename MeshType,
+          typename UserData > 
+class tnlMeshFunctionEvaluatorAdditionEntitiesProcessor
+{
+   public:
+
+      template< typename EntityType >
+      __cuda_callable__
+      static inline void processEntity( const MeshType& mesh,
+                                        UserData& userData,
+                                        const EntityType& entity )
+      {
+         typedef tnlFunctionAdapter< MeshType, typename UserData::InFunctionType > FunctionAdapter;
+         ( *userData.meshFunction )( entity ) = 
+            *userData.outFunctionMultiplicator * ( *userData.meshFunction )( entity ) +
+            *userData.inFunctionMultiplicator *
+            FunctionAdapter::getValue( *userData.function, entity, *userData.time );
+         /*cerr << "Idx = " << entity.getIndex() 
+            << " Value = " << FunctionAdapter::getValue( *userData.function, entity, *userData.time ) 
+            << " stored value = " << ( *userData.meshFunction )( entity )
+            << " multiplicators = " << endl;*/
+      }
+};
+
+
+#include <functions/tnlMeshFunctionEvaluator_impl.h>
+
+#endif	/* TNLMESHFUNCTIONEVALUATOR_H */
+
diff --git a/src/functions/tnlMeshFunctionEvaluator_impl.h b/src/functions/tnlMeshFunctionEvaluator_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..83d463e35c07e79fa13e267d2558b8ff896a3ef4
--- /dev/null
+++ b/src/functions/tnlMeshFunctionEvaluator_impl.h
@@ -0,0 +1,212 @@
+/***************************************************************************
+                          tnlMeshFunctionEvaluator.h  -  description
+                             -------------------
+    begin                : Jan 5, 2016
+    copyright            : (C) 2016 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 TNLMESHFUNCTIONEVALUATOR_IMPL_H
+#define	TNLMESHFUNCTIONEVALUATOR_IMPL_H
+
+#include <functions/tnlMeshFunctionEvaluator.h>
+#include <mesh/tnlTraverser.h>
+
+template< typename OutMeshFunction,
+          typename InFunction >
+void
+tnlMeshFunctionEvaluator< OutMeshFunction, InFunction >::
+evaluate( OutMeshFunction& meshFunction,
+          const InFunction& function,                          
+          const RealType& time,
+          const RealType& outFunctionMultiplicator,
+          const RealType& inFunctionMultiplicator )
+{
+   switch( InFunction::getDomainType() )
+   {
+      case SpaceDomain:
+      case MeshDomain:   
+         evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, all );
+         break;
+      case MeshInteriorDomain:
+         evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, interior );
+         break;
+      case MeshBoundaryDomain:
+         evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, boundary );
+         break;
+   }         
+}
+
+
+template< typename OutMeshFunction,
+          typename InFunction >
+void
+tnlMeshFunctionEvaluator< OutMeshFunction, InFunction >::
+evaluateAllEntities( OutMeshFunction& meshFunction,
+                     const InFunction& function,                          
+                     const RealType& time,
+                     const RealType& outFunctionMultiplicator,
+                     const RealType& inFunctionMultiplicator )
+{
+   return evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, all );
+}
+
+template< typename OutMeshFunction,
+          typename InFunction >
+void
+tnlMeshFunctionEvaluator< OutMeshFunction, InFunction >::
+evaluateInteriorEntities( OutMeshFunction& meshFunction,
+                          const InFunction& function,                          
+                          const RealType& time,
+                          const RealType& outFunctionMultiplicator,
+                          const RealType& inFunctionMultiplicator )
+{
+   return evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, interior );
+}
+
+template< typename OutMeshFunction,
+          typename InFunction >
+void 
+tnlMeshFunctionEvaluator< OutMeshFunction, InFunction >::
+evaluateBoundaryEntities( OutMeshFunction& meshFunction,
+                          const InFunction& function,                          
+                          const RealType& time,
+                          const RealType& outFunctionMultiplicator,
+                          const RealType& inFunctionMultiplicator )
+{
+   return evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, boundary );
+}
+
+
+
+template< typename OutMeshFunction,
+          typename InFunction >
+void
+tnlMeshFunctionEvaluator< OutMeshFunction, InFunction >::
+evaluateEntities( OutMeshFunction& meshFunction,
+                  const InFunction& function,
+                  const RealType& time,
+                  const RealType& outFunctionMultiplicator,
+                  const RealType& inFunctionMultiplicator,
+                  EntitiesType entitiesType )
+{
+   typedef typename MeshType::template MeshEntity< OutMeshFunction::getEntitiesDimensions() > MeshEntityType;
+   typedef tnlMeshFunctionEvaluatorAssignmentEntitiesProcessor< MeshType, TraverserUserData > AssignmentEntitiesProcessor;
+   typedef tnlMeshFunctionEvaluatorAdditionEntitiesProcessor< MeshType, TraverserUserData > AdditionEntitiesProcessor;
+  
+   if( std::is_same< MeshDeviceType, tnlHost >::value )
+   {
+      TraverserUserData userData( &function, &time, &meshFunction, &outFunctionMultiplicator, &inFunctionMultiplicator );
+      tnlTraverser< MeshType, MeshEntityType > meshTraverser;
+      switch( entitiesType )
+      {
+         case all:            
+            if( outFunctionMultiplicator )
+               meshTraverser.template processAllEntities< TraverserUserData,
+                                                          AdditionEntitiesProcessor >
+                                                        ( meshFunction.getMesh(),
+                                                          userData );
+            else
+               meshTraverser.template processAllEntities< TraverserUserData,
+                                                         AssignmentEntitiesProcessor >
+                                                       ( meshFunction.getMesh(),
+                                                         userData );
+            break;
+         case interior:
+            if( outFunctionMultiplicator )
+               meshTraverser.template processInteriorEntities< TraverserUserData,
+                                                               AdditionEntitiesProcessor >
+                                                             ( meshFunction.getMesh(),
+                                                               userData );
+            else
+               meshTraverser.template processInteriorEntities< TraverserUserData,
+                                                               AssignmentEntitiesProcessor >
+                                                             ( meshFunction.getMesh(),
+                                                               userData );            
+            break;
+         case boundary:
+            if( outFunctionMultiplicator )
+               meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                                               AdditionEntitiesProcessor >
+                                                             ( meshFunction.getMesh(),
+                                                               userData );
+            else
+               meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                                               AssignmentEntitiesProcessor >
+                                                             ( meshFunction.getMesh(),
+                                                               userData );
+            break;
+      }
+   }
+   if( std::is_same< MeshDeviceType, tnlCuda >::value )
+   {      
+      OutMeshFunction* kernelMeshFunction = tnlCuda::passToDevice( meshFunction );
+      InFunction* kernelFunction = tnlCuda::passToDevice( function );
+      RealType* kernelTime = tnlCuda::passToDevice( time );
+      RealType* kernelOutFunctionMultiplicator = tnlCuda::passToDevice( outFunctionMultiplicator );
+      RealType* kernelInFunctionMultiplicator = tnlCuda::passToDevice( inFunctionMultiplicator );
+      
+      TraverserUserData userData( kernelFunction, kernelTime, kernelMeshFunction, kernelOutFunctionMultiplicator, kernelInFunctionMultiplicator );
+      checkCudaDevice;
+      tnlTraverser< MeshType, MeshEntityType > meshTraverser;
+      switch( entitiesType )
+      {
+         case all:            
+            if( outFunctionMultiplicator )
+               meshTraverser.template processAllEntities< TraverserUserData,
+                                                          AdditionEntitiesProcessor >
+                                                        ( meshFunction.getMesh(),
+                                                          userData );
+            else
+               meshTraverser.template processAllEntities< TraverserUserData,
+                                                         AssignmentEntitiesProcessor >
+                                                       ( meshFunction.getMesh(),
+                                                         userData );
+            break;
+         case interior:
+            if( outFunctionMultiplicator )
+               meshTraverser.template processInteriorEntities< TraverserUserData,
+                                                               AdditionEntitiesProcessor >
+                                                             ( meshFunction.getMesh(),
+                                                               userData );
+            else
+               meshTraverser.template processInteriorEntities< TraverserUserData,
+                                                               AssignmentEntitiesProcessor >
+                                                             ( meshFunction.getMesh(),
+                                                               userData );            
+            break;
+         case boundary:
+            if( outFunctionMultiplicator )
+               meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                                               AdditionEntitiesProcessor >
+                                                             ( meshFunction.getMesh(),
+                                                               userData );
+            else
+               meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                                               AssignmentEntitiesProcessor >
+                                                             ( meshFunction.getMesh(),
+                                                               userData );
+            break;         
+      }      
+
+      checkCudaDevice;      
+      tnlCuda::freeFromDevice( kernelMeshFunction );
+      tnlCuda::freeFromDevice( kernelFunction );
+      tnlCuda::freeFromDevice( kernelTime );
+      tnlCuda::freeFromDevice( kernelOutFunctionMultiplicator );
+      tnlCuda::freeFromDevice( kernelInFunctionMultiplicator );            
+      checkCudaDevice;
+   }
+}
+
+#endif	/* TNLMESHFUNCTIONEVALUATOR_IMPL_H */
+
diff --git a/src/functions/tnlMeshFunctionGnuplotWriter.h b/src/functions/tnlMeshFunctionGnuplotWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..ec405927166626b1278652045a665bd11099ebfb
--- /dev/null
+++ b/src/functions/tnlMeshFunctionGnuplotWriter.h
@@ -0,0 +1,127 @@
+/***************************************************************************
+                          tnlMeshFunctionGnuplotWriter.h  -  description
+                             -------------------
+    begin                : Jan 28, 2016
+    copyright            : (C) 2016 by 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 TNLMESHFUNCTIONGNUPLOTWRITER_H
+#define	TNLMESHFUNCTIONGNUPLOTWRITER_H
+
+#include<mesh/tnlGrid.h>
+
+template< typename, int, typename > class tnlMeshFunction;
+
+template< typename MeshFunction >
+class tnlMeshFunctionGnuplotWriter
+{
+   public:
+
+      static bool write( const MeshFunction& function,
+                         ostream& str );
+};
+
+/***
+ * 1D grids cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 1, MeshReal, Device, MeshIndex >, 1, Real > >
+{
+   public:
+      typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef tnlMeshFunction< MeshType, 1, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 1D grids vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 1, MeshReal, Device, MeshIndex >, 0, Real > >
+{
+   public:
+      typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef tnlMeshFunction< MeshType, 0, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 2D grids cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 2, Real > >
+{
+   public:
+      typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef tnlMeshFunction< MeshType, 2, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 2D grids faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 1, Real > >
+{
+   public:
+      typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef tnlMeshFunction< MeshType, 1, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         ostream& str );
+};
+
+
+/***
+ * 2D grids vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 0, Real > >
+{
+   public:
+      typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef tnlMeshFunction< MeshType, 0, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         ostream& str );
+};
+
+
+#endif	/* TNLMESHFUNCTIONGNUPLOTWRITER_H */
+
diff --git a/src/functions/tnlMeshFunctionGnuplotWriter_impl.h b/src/functions/tnlMeshFunctionGnuplotWriter_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..1c9815cccc4388d2937238b48fadd0303ffd94c0
--- /dev/null
+++ b/src/functions/tnlMeshFunctionGnuplotWriter_impl.h
@@ -0,0 +1,205 @@
+/***************************************************************************
+                          tnlMeshFunctionGnuplotWriter.h  -  description
+                             -------------------
+    begin                : Jan 28, 2016
+    copyright            : (C) 2016 by 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 TNLMESHFUNCTIONGNUPLOTWRITER_IMPL_H
+#define	TNLMESHFUNCTIONGNUPLOTWRITER_IMPL_H
+
+template< typename MeshFunction >
+bool
+tnlMeshFunctionGnuplotWriter< MeshFunction >::
+write( const MeshFunction& function,
+       ostream& str )
+{
+   std::cerr << "Gnuplot writer for mesh functions defined on mesh type " << MeshFunction::MeshType::getType() << " is not (yet) implemented." << std::endl;
+   return false;   
+}
+
+/****
+ * 1D grid, cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 1, MeshReal, Device, MeshIndex >, 1, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{ 
+   const MeshType& mesh = function.getMesh();
+   typename MeshType::Cell entity( mesh );
+   for( entity.getCoordinates().x() = 0;
+        entity.getCoordinates().x() < mesh.getDimensions().x();
+        entity.getCoordinates().x() ++ )
+   {
+      entity.refresh();
+      typename MeshType::VertexType v = entity.getCenter();
+      str << v << " " 
+          << function.getData().getElement( entity.getIndex() ) << std::endl;
+   }
+   return true;
+}
+
+/****
+ * 1D grid, vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 1, MeshReal, Device, MeshIndex >, 0, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{ 
+   const MeshType& mesh = function.getMesh();
+   typename MeshType::Vertex entity( mesh );
+   for( entity.getCoordinates().x() = 0;
+        entity.getCoordinates().x() <= mesh.getDimensions().x();
+        entity.getCoordinates().x() ++ )
+   {
+      entity.refresh();
+      typename MeshType::VertexType v = entity.getCenter();
+      str << v << " " 
+          << function.getData().getElement( entity.getIndex() ) << std::endl;      
+   }
+   return true;
+}
+
+
+/****
+ * 2D grid, cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 2, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{
+   const MeshType& mesh = function.getMesh();
+   typename MeshType::Cell entity( mesh );
+   for( entity.getCoordinates().y() = 0;
+        entity.getCoordinates().y() < mesh.getDimensions().y();
+        entity.getCoordinates().y() ++ ) 
+   {
+      for( entity.getCoordinates().x() = 0;
+           entity.getCoordinates().x() < mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+      {
+         entity.refresh();
+         typename MeshType::VertexType v = entity.getCenter();
+         str << v.x() << " " << v.y() << " "
+             << function.getData().getElement( entity.getIndex() ) << std::endl;      
+      }
+      str << std::endl;
+   }
+   return true;
+}
+
+/****
+ * 2D grid, faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 1, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{
+   const MeshType& mesh = function.getMesh();
+   typedef typename MeshType::Face EntityType;
+   typedef typename EntityType::EntityOrientationType EntityOrientation;
+   EntityType entity( mesh );
+   
+   entity.setOrientation( EntityOrientation( 1.0, 0.0 ) );
+   for( entity.getCoordinates().y() = 0;
+        entity.getCoordinates().y() < mesh.getDimensions().y();
+        entity.getCoordinates().y() ++ )       
+   {
+      for( entity.getCoordinates().x() = 0;
+           entity.getCoordinates().x() <= mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+      {
+         entity.refresh();
+         typename MeshType::VertexType v = entity.getCenter();
+         str << v.x() << " " << v.y() << " "
+             << function.getData().getElement( entity.getIndex() ) << std::endl;      
+      }
+      str << std::endl;
+   }
+   
+   entity.setOrientation( EntityOrientation( 0.0, 1.0 ) );
+         for( entity.getCoordinates().x() = 0;
+           entity.getCoordinates().x() < mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+
+   {
+            for( entity.getCoordinates().y() = 0;
+        entity.getCoordinates().y() <= mesh.getDimensions().y();
+        entity.getCoordinates().y() ++ ) 
+
+      {
+         entity.refresh();
+         typename MeshType::VertexType v = entity.getCenter();
+         str << v.x() << " " << v.y() << " "
+             << function.getData().getElement( entity.getIndex() ) << std::endl;      
+      }
+      str << std::endl;
+   }   
+   return true;
+}
+
+
+/****
+ * 2D grid, vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionGnuplotWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 0, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{
+   const MeshType& mesh = function.getMesh();
+   typename MeshType::Vertex entity( mesh );
+   for( entity.getCoordinates().y() = 0;
+        entity.getCoordinates().y() <= mesh.getDimensions().y();
+        entity.getCoordinates().y() ++ )   
+   {
+      for( entity.getCoordinates().x() = 0;
+           entity.getCoordinates().x() <= mesh.getDimensions().x();
+           entity.getCoordinates().x() ++ )
+      {
+         entity.refresh();
+         typename MeshType::VertexType v = entity.getCenter();
+         str << v.x() << " " << v.y() << " "
+             << function.getData().getElement( entity.getIndex() ) << std::endl;      
+      }
+      str << std::endl;
+   }
+   return true;
+}
+
+#endif	/* TNLMESHFUNCTIONGNUPLOTWRITER_IMPL_H */
+
diff --git a/src/functions/tnlMeshFunctionNormGetter.h b/src/functions/tnlMeshFunctionNormGetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..93f65c1975db708087d6a4b750e4dfa0908bb49e
--- /dev/null
+++ b/src/functions/tnlMeshFunctionNormGetter.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+                          tnlMeshFunctionNormGetter.h  -  description
+                             -------------------
+    begin                : Jan 5, 2016
+    copyright            : (C) 2016 by 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 TNLMESHFUNCTIONNORMGETTER_H
+#define	TNLMESHFUNCTIONNORMGETTER_H
+
+template< typename MeshFunction,
+          typename Mesh = typename MeshFunction::MeshType >
+class tnlMeshFunctionNormGetter
+{
+};
+
+/***
+ * Specialization for grids
+ * TODO: implement this even for other devices
+ */
+template< int Dimensions,
+          typename MeshReal,
+          typename MeshIndex,
+          int EntityDimensions >
+class tnlMeshFunctionNormGetter< tnlMeshFunction< tnlGrid< Dimensions, MeshReal, tnlHost, MeshIndex >, EntityDimensions >,
+                                 tnlGrid< Dimensions, MeshReal, tnlHost, MeshIndex > >
+{
+   public:
+      
+      typedef tnlMeshFunction< tnlGrid< Dimensions, MeshReal, tnlHost, MeshIndex >, EntityDimensions > MeshFunctionType;
+      typedef tnlGrid< Dimensions, MeshReal, tnlHost, MeshIndex > GridType;
+      typedef MeshReal MeshRealType;
+      typedef tnlHost DeviceType;
+      typedef MeshIndex MeshIndexType;
+      typedef typename MeshFunctionType::RealType RealType;
+      typedef typename MeshFunctionType::MeshType MeshType;
+      typedef typename MeshType::Face EntityType;
+      
+      static RealType getNorm( const MeshFunctionType& function,
+                               const RealType& p )
+      {
+         if( EntityDimensions == Dimensions )
+         {
+            if( p == 1.0 )
+               return function.getMesh().getCellMeasure() * function.getData().lpNorm( 1.0 );
+            if( p == 2.0 )
+               return sqrt( function.getMesh().getCellMeasure() ) * function.getData().lpNorm( 2.0 );
+            return pow( function.getMesh().getCellMeasure(), 1.0 / p ) * function.getData().lpNorm( p );
+         }
+         if( EntityDimensions > 0 )
+         {
+            if( p == 1.0 )
+            {
+               RealType result( 0.0 );
+               for( MeshIndexType i = 0;
+                    i < function.getMesh().template getEntitiesCount< EntityType >();
+                    i++ )
+               {
+                  EntityType entity = function.getMesh().template getEntity< EntityType >( i );
+                  result += fabs( function[ i ] ) * entity.getMeasure();
+               }
+               return result;
+            }
+            if( p == 2.0 )
+            {
+               RealType result( 0.0 );
+               for( MeshIndexType i = 0;
+                    i < function.getMesh().template getEntitiesCount< EntityType >();
+                    i++ )
+               {
+                  EntityType entity = function.getMesh().template getEntity< EntityType >( i );
+                  result += function[ i ] * function[ i ] * entity.getMeasure();
+               }            
+               return sqrt( result );
+            }
+
+            RealType result( 0.0 );
+            for( MeshIndexType i = 0;
+                 i < function.getMesh().template getEntitiesCount< EntityType >();
+                 i++ )
+            {
+               EntityType entity = function.getMesh().template getEntity< EntityType >( i );
+               result += pow( fabs( function[ i ] ), p ) * entity.getMeasure();
+            }                     
+            return pow( result, 1.0 / p );
+         }
+         
+         if( p == 1.0 )
+            return function.getData().lpNorm( 1.0 );
+         if( p == 2.0 )
+            return function.getData().lpNorm( 2.0 );
+         return function.getData().lpNorm( p );
+      }
+};
+
+/****
+ * Specialization for CUDA devices
+ */
+template< int Dimensions,
+          typename MeshReal,
+          typename MeshIndex,
+          int EntityDimensions >
+class tnlMeshFunctionNormGetter< tnlMeshFunction< tnlGrid< Dimensions, MeshReal, tnlCuda, MeshIndex >, EntityDimensions >,
+                                 tnlGrid< Dimensions, MeshReal, tnlCuda, MeshIndex > >
+{
+   public:
+      
+      typedef tnlMeshFunction< tnlGrid< Dimensions, MeshReal, tnlCuda, MeshIndex >, EntityDimensions > MeshFunctionType;
+      typedef tnlGrid< Dimensions, MeshReal, tnlCuda, MeshIndex > GridType;
+      typedef MeshReal MeshRealType;
+      typedef tnlCuda DeviceType;
+      typedef MeshIndex MeshIndexType;
+      typedef typename MeshFunctionType::RealType RealType;
+      typedef typename MeshFunctionType::MeshType MeshType;
+      typedef typename MeshType::Face EntityType;
+      
+      static RealType getNorm( const MeshFunctionType& function,
+                               const RealType& p )
+      {
+         if( EntityDimensions == Dimensions )
+         {
+            if( p == 1.0 )
+               return function.getMesh().getCellMeasure() * function.getData().lpNorm( 1.0 );
+            if( p == 2.0 )
+               return sqrt( function.getMesh().getCellMeasure() ) * function.getData().lpNorm( 2.0 );
+            return pow( function.getMesh().getCellMeasure(), 1.0 / p ) * function.getData().lpNorm( p );
+         }
+         if( EntityDimensions > 0 )
+         {
+            tnlAssert( false, std::cerr << "Not implemented yet." << std::endl );
+         }
+         
+         if( p == 1.0 )
+            return function.getData().lpNorm( 1.0 );
+         if( p == 2.0 )
+            return function.getData().lpNorm( 2.0 );
+         return function.getData().lpNorm( p );
+      }
+};
+
+
+#endif	/* TNLMESHFUNCTIONNORMGETTER_H */
+
diff --git a/src/functions/tnlMeshFunctionVTKWriter.h b/src/functions/tnlMeshFunctionVTKWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..b06e4ea27ff18f38db6d00fbea097f26194ddd6b
--- /dev/null
+++ b/src/functions/tnlMeshFunctionVTKWriter.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+                          tnlMeshFunctionVTKWriter.h  -  description
+                             -------------------
+    begin                : Jan 28, 2016
+    copyright            : (C) 2016 by 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 TNLMESHFUNCTIONVTKWRITER_H
+#define	TNLMESHFUNCTIONVTKWRITER_H
+
+template< typename MeshFunction >
+class tnlMeshFunctionVTKWriter
+{
+   public:
+      
+      static bool write( const MeshFunction& function,
+                         ostream& str )
+      {
+         std::cerr << "VTK writer for mesh functions defined on mesh type " << MeshFunction::MeshType::getType() << " is not (yet) implmeneted." << std::endl;
+         return false;
+      }
+};
+
+
+#endif	/* TNLMESHFUNCTIONVTKWRITER_H */
+
diff --git a/src/functions/tnlMeshFunctionVTKWriter_impl.h b/src/functions/tnlMeshFunctionVTKWriter_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..4173fd0399e50145efd5c76e03715ac824c8284d
--- /dev/null
+++ b/src/functions/tnlMeshFunctionVTKWriter_impl.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+                          tnlMeshFunctionVTKWriter_impl.h  -  description
+                             -------------------
+    begin                : Jan 28, 2016
+    copyright            : (C) 2016 by 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 TNLMESHFUNCTIONVTKWRITER_IMPL_H
+#define	TNLMESHFUNCTIONVTKWRITER_IMPL_H
+
+
+
+#endif	/* TNLMESHFUNCTIONVTKWRITER_IMPL_H */
+
diff --git a/src/functions/tnlMeshFunction_impl.h b/src/functions/tnlMeshFunction_impl.h
index 28206862100a603905deebfeb61eb6c4dcc64e4b..2b08d2f2927c25def185d48b1084a40299379331 100644
--- a/src/functions/tnlMeshFunction_impl.h
+++ b/src/functions/tnlMeshFunction_impl.h
@@ -16,6 +16,12 @@
  ***************************************************************************/
 
 #include <core/tnlAssert.h>
+#include <functions/tnlMeshFunction.h>
+#include <functions/tnlFunctionEvaluator.h>
+#include <functions/tnlMeshFunctionEvaluator.h>
+#include <functions/tnlMeshFunctionNormGetter.h>
+#include <functions/tnlMeshFunctionGnuplotWriter.h>
+#include <functions/tnlMeshFunctionVTKWriter.h>
 
 #ifndef TNLMESHFUNCTION_IMPL_H
 #define	TNLMESHFUNCTION_IMPL_H
@@ -29,6 +35,16 @@ tnlMeshFunction()
 {
 }
 
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+tnlMeshFunction( const Mesh& mesh )
+: mesh( &mesh )
+{
+   this->data.setSize( mesh.template getEntitiesCount< typename Mesh::template MeshEntity< MeshEntityDimensions > >() );
+}
+
 template< typename Mesh,
           int MeshEntityDimensions,
           typename Real >
@@ -38,9 +54,57 @@ tnlMeshFunction( const MeshType& mesh,
                  Vector& data,
                  const IndexType& offset )
 {
-   //this->bind( mesh, data, offset );   
+   this->bind( mesh, data, offset );   
 }
 
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+tnlString 
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+getType()
+{
+   return tnlString( "tnlMeshFunction< " ) +
+                     Mesh::getType() + ", " +
+                     tnlString( MeshEntityDimensions ) + ", " +
+                     ::getType< Real >() +
+                     " >";
+};
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+tnlString 
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+getTypeVirtual() const
+{
+   return this->getType();
+};
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+tnlString 
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+getSerializationType()
+{
+   return tnlString( "tnlMeshFunction< " ) +
+                     Mesh::getSerializationType() + ", " +
+                     tnlString( MeshEntityDimensions ) + ", " +
+                     ::getType< Real >() +
+                     " >";
+};
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+tnlString 
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+getSerializationTypeVirtual() const
+{
+   return this->getSerializationType();
+};
+
 template< typename Mesh,
           int MeshEntityDimensions,
           typename Real >
@@ -69,26 +133,26 @@ setup( const tnlParameterContainer& parameters,
    return true;
 }
 
-/*template< typename Mesh,
+template< typename Mesh,
           int MeshEntityDimensions,
           typename Real >
    template< typename Vector >
-bool
+void
 tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
 bind( const MeshType& mesh,
-      Vector& data,
+      const Vector& data,
       const IndexType& offset )
 {
    this->mesh = &mesh;
-   return this->data.bind( data, offset, mesh.template getEntitiesCount< MeshEntity >() );      
-}*/
+   this->data.bind( data, offset, mesh.template getEntitiesCount< typename Mesh::template MeshEntity< MeshEntityDimensions > >() );
+}
 
 template< typename Mesh,
           int MeshEntityDimensions,
           typename Real >
 void
 tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
-setMesh( const MeshType& mesh ) const
+setMesh( const MeshType& mesh )
 {
    this->mesh = &mesh;
 }
@@ -100,7 +164,7 @@ const typename tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::MeshType&
 tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
 getMesh() const
 {
-   return this->mesh;
+   return *this->mesh;
 }
 
 template< typename Mesh,
@@ -123,6 +187,26 @@ getData()
    return this->data;
 }
 
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+bool
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+refresh( const RealType& time ) const
+{  
+   return true;
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+bool
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+deepRefresh( const RealType& time ) const
+{
+   return true;
+}
+
 template< typename Mesh,
           int MeshEntityDimensions,
           typename Real >
@@ -155,7 +239,8 @@ template< typename Mesh,
 __cuda_callable__
 typename tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::RealType& 
 tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
-operator()( const EntityType& meshEntity )
+operator()( const EntityType& meshEntity,
+            const RealType& time )
 {
    static_assert( EntityType::entityDimensions == MeshEntityDimensions, "Calling with wrong EntityType -- entity dimensions do not match." );
    return this->data[ meshEntity.getIndex() ];
@@ -168,11 +253,150 @@ template< typename Mesh,
 __cuda_callable__
 const typename tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::RealType& 
 tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
-operator()( const EntityType& meshEntity ) const
+operator()( const EntityType& meshEntity,
+            const RealType& time ) const
 {
    static_assert( EntityType::entityDimensions == MeshEntityDimensions, "Calling with wrong EntityType -- entity dimensions do not match." );
    return this->data[ meshEntity.getIndex() ];
 }
 
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+__cuda_callable__
+typename tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::RealType& 
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+operator[]( const IndexType& meshEntityIndex )
+{   
+   return this->data[ meshEntityIndex ];
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+__cuda_callable__
+const typename tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::RealType& 
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+operator[]( const IndexType& meshEntityIndex ) const
+{
+   return this->data[ meshEntityIndex ];
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+   template< typename Function >
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >&
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+operator = ( const Function& f )
+{
+   tnlMeshFunctionEvaluator< ThisType, Function >::evaluate( *this, f );
+   return *this;
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+   template< typename Function >
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >&
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+operator += ( const Function& f )
+{
+   tnlMeshFunctionEvaluator< ThisType, Function >::evaluate( *this, f, 1.0, 1.0 );
+   return *this;
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+   template< typename Function >
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >&
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+operator -= ( const Function& f )
+{
+   tnlMeshFunctionEvaluator< ThisType, Function >::evaluate( *this, f, 1.0, -1.0 );
+   return *this;
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+Real
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+getLpNorm( const RealType& p ) const
+{
+   return tnlMeshFunctionNormGetter< ThisType >::getNorm( *this, p );
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+Real
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+getMaxNorm() const
+{
+   return this->data.absMax();
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >      
+bool
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+save( tnlFile& file ) const
+{
+   if( ! tnlObject::save( file ) )
+      return false;
+   return this->data.save( file );
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+bool
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+load( tnlFile& file )
+{
+   if( ! tnlObject::load( file ) )
+      return false;
+   return this->data.load( file );   
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+bool
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+boundLoad( tnlFile& file )
+{
+   if( ! tnlObject::load( file ) )
+      return false;
+   return this->data.boundLoad( file );   
+}
+
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+bool
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+write( const tnlString& fileName,
+       const tnlString& format ) const
+{
+   std::fstream file;
+   file.open( fileName.getString(), std::ios::out );
+   if( ! file )
+   {
+      std::cerr << "Unbable to open a file " << fileName << "." << std::endl;
+      return false;
+   }
+   if( format == "vtk" )
+      return tnlMeshFunctionVTKWriter< ThisType >::write( *this, file );
+   if( format == "gnuplot" )
+      return tnlMeshFunctionGnuplotWriter< ThisType >::write( *this, file );
+   return true;
+}
+      
+
+
 #endif	/* TNLMESHFUNCTION_IMPL_H */
 
diff --git a/src/functions/tnlOperatorFunction.h b/src/functions/tnlOperatorFunction.h
new file mode 100644
index 0000000000000000000000000000000000000000..d31ff2448d33c87ac9b9f8f5c447d5874b6ead9d
--- /dev/null
+++ b/src/functions/tnlOperatorFunction.h
@@ -0,0 +1,350 @@
+/***************************************************************************
+                          tnlOperatorFunction.h  -  description
+                             -------------------
+    begin                : Dec 31, 2015
+    copyright            : (C) 2015 by 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 TNLOPERATORFUNCTION_H
+#define	TNLOPERATORFUNCTION_H
+
+#include <type_traits>
+#include <core/tnlCuda.h>
+#include <functions/tnlMeshFunction.h>
+#include <solvers/pde/tnlBoundaryConditionsSetter.h>
+
+/***
+ * This class evaluates given operator on given preimageFunction. If the flag 
+ * EvaluateOnFly is set on true, the values on particular mesh entities
+ * are computed just  when operator() is called. If the EvaluateOnFly flag
+ * is 'false', values on all mesh entities are evaluated by calling a method
+ * refresh() they are stores in internal mesh preimageFunction and the operator()
+ * just returns precomputed values. If BoundaryConditions are void then the
+ * values on the boundary mesh entities are undefined. In this case, the mesh
+ * preimageFunction evaluator evaluates this preimageFunction only on the INTERIOR mesh entities.
+ */
+
+template< typename Operator,
+          typename MeshFunction,
+          typename BoundaryConditions = void,
+          bool EvaluateOnFly = false >
+class tnlOperatorFunction{};
+
+/****
+ * Specialization for 'On the fly' evaluation with the boundary conditions does not make sense.
+ */
+template< typename Operator,
+          typename MeshFunction,
+          typename BoundaryConditions >
+class tnlOperatorFunction< Operator, MeshFunction, BoundaryConditions, true >
+ : public tnlDomain< Operator::getMeshDimensions(), MeshDomain >
+{   
+};
+
+/****
+ * Specialization for 'On the fly' evaluation and no boundary conditions.
+ */
+template< typename Operator,
+          typename MeshFunction >
+class tnlOperatorFunction< Operator, MeshFunction, void, true >
+ : public tnlDomain< Operator::getDimensions(), Operator::getDomainType() >
+{   
+   public:
+      
+      static_assert( MeshFunction::getDomainType() == MeshDomain ||
+                     MeshFunction::getDomainType() == MeshInteriorDomain ||
+                     MeshFunction::getDomainType() == MeshBoundaryDomain,
+         "Only mesh preimageFunctions may be used in the operator preimageFunction. Use tnlExactOperatorFunction instead of tnlOperatorFunction." );
+      static_assert( std::is_same< typename Operator::MeshType, typename MeshFunction::MeshType >::value,
+          "Both, operator and mesh preimageFunction must be defined on the same mesh." );
+      
+      typedef Operator OperatorType;
+      typedef MeshFunction FunctionType;
+      typedef typename OperatorType::MeshType MeshType;
+      typedef typename OperatorType::RealType RealType;
+      typedef typename OperatorType::DeviceType DeviceType;
+      typedef typename OperatorType::IndexType IndexType;
+      typedef typename OperatorType::ExactOperatorType ExactOperatorType;
+      typedef tnlMeshFunction< MeshType, OperatorType::getPreimageEntitiesDimensions() > PreimageFunctionType;
+      
+      static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); };     
+      
+      tnlOperatorFunction( const OperatorType& operator_ )
+      :  operator_( operator_ ), preimageFunction( 0 ){};
+      
+      tnlOperatorFunction( const OperatorType& operator_,
+                           const FunctionType& preimageFunction )
+      :  operator_( operator_ ), preimageFunction( &preimageFunction ){};
+      
+      const MeshType& getMesh() const
+      { 
+         tnlAssert( this->preimageFunction, std::cerr << "The preimage function was not set." << std::endl );
+         return this->preimageFunction->getMesh(); 
+      };
+      
+      void setPreimageFunction( const FunctionType& preimageFunction ) { this->preimageFunction = &preimageFunction; }
+      
+      Operator& getOperator() { return this->operator_; }
+      
+      const Operator& getOperator() const { return this->operator_; }
+      
+      bool refresh( const RealType& time = 0.0 ) { return true; };
+      
+      bool deepRefresh( const RealType& time = 0.0 ) { return true; };
+      
+      template< typename MeshEntity >
+      __cuda_callable__
+      RealType operator()(
+         const MeshEntity& meshEntity,
+         const RealType& time = 0.0 ) const
+      {
+         tnlAssert( this->preimageFunction, std::cerr << "The preimage function was not set." << std::endl );
+         return operator_( *preimageFunction, meshEntity, time );
+      }
+      
+   protected:
+      
+      const Operator& operator_;
+      
+      const FunctionType* preimageFunction;
+      
+      template< typename, typename > friend class tnlMeshFunctionEvaluator;
+};
+
+/****
+ * Specialization for precomputed evaluation and no boundary conditions.
+ */
+template< typename Operator,
+          typename PreimageFunction >
+class tnlOperatorFunction< Operator, PreimageFunction, void, false >
+ : public tnlDomain< Operator::getDimensions(), Operator::getDomainType() >
+{   
+   public:
+      
+      static_assert( PreimageFunction::getDomainType() == MeshDomain ||
+                     PreimageFunction::getDomainType() == MeshInteriorDomain ||
+                     PreimageFunction::getDomainType() == MeshBoundaryDomain,
+         "Only mesh preimageFunctions may be used in the operator preimageFunction. Use tnlExactOperatorFunction instead of tnlOperatorFunction." );
+      static_assert( std::is_same< typename Operator::MeshType, typename PreimageFunction::MeshType >::value,
+          "Both, operator and mesh preimageFunction must be defined on the same mesh." );
+      
+      typedef Operator OperatorType;
+      typedef typename OperatorType::MeshType MeshType;
+      typedef typename OperatorType::RealType RealType;
+      typedef typename OperatorType::DeviceType DeviceType;
+      typedef typename OperatorType::IndexType IndexType;
+      typedef PreimageFunction PreimageFunctionType;
+      typedef tnlMeshFunction< MeshType, Operator::getImageEntitiesDimensions() > ImageFunctionType;
+      typedef tnlOperatorFunction< Operator, PreimageFunction, void, true > OperatorFunction;
+      typedef typename OperatorType::ExactOperatorType ExactOperatorType;
+      
+      static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); };     
+      
+      tnlOperatorFunction( OperatorType& operator_,
+                           const MeshType& mesh )
+      :  operator_( operator_ ), imageFunction( mesh )
+      {};
+      
+      tnlOperatorFunction( OperatorType& operator_,
+                           PreimageFunctionType& preimageFunction )
+      :  operator_( operator_ ), imageFunction( preimageFunction.getMesh() ), preimageFunction( &preimageFunction )
+      {};
+      
+      const MeshType& getMesh() const { return this->imageFunction.getMesh(); };
+      
+      ImageFunctionType& getImageFunction() { return this->imageFunction; };
+      
+      const ImageFunctionType& getImageFunction() const { return this->imageFunction; };
+      
+      void setPreimageFunction( PreimageFunction& preimageFunction )
+      { 
+         this->preimageFunction = &preimageFunction;
+         this->imageFunction.setMesh( preimageFunction.getMesh() );
+      };
+      
+      const PreimageFunctionType& getPreimageFunction() const { return *this->preimageFunction; };
+      
+      Operator& getOperator() { return this->operator_; }
+      
+      const Operator& getOperator() const { return this->operator_; }
+
+      bool refresh( const RealType& time = 0.0 )
+      {
+         OperatorFunction operatorFunction( this->operator_, *preimageFunction );         
+         this->operator_.setPreimageFunction( *this->preimageFunction );
+         if( ! this->operator_.refresh( time ) ||
+             ! operatorFunction.refresh( time )  )
+             return false;
+         this->imageFunction = operatorFunction;
+         return true;
+      };
+      
+      bool deepRefresh( const RealType& time = 0.0 )
+      {
+         if( ! this->preimageFunction->deepRefresh( time ) )
+            return false;
+         return this->refresh( time );
+      };
+      
+      template< typename MeshEntity >
+      __cuda_callable__
+      RealType operator()(
+         const MeshEntity& meshEntity,
+         const RealType& time = 0 ) const
+      {
+         return imageFunction[ meshEntity.getIndex() ];
+      }
+      
+      __cuda_callable__
+      RealType operator[]( const IndexType& index ) const
+      {
+         return imageFunction[ index ];
+      }
+      
+   protected:
+      
+      Operator& operator_;
+      
+      PreimageFunctionType* preimageFunction;
+      
+      ImageFunctionType imageFunction;
+      
+      template< typename, typename > friend class tnlMeshFunctionEvaluator;
+};
+
+/****
+ * Specialization for precomputed evaluation and with boundary conditions.
+ */
+template< typename Operator,
+          typename PreimageFunction,
+          typename BoundaryConditions >
+class tnlOperatorFunction< Operator, PreimageFunction, BoundaryConditions, false >
+  : public tnlDomain< Operator::getMeshDimensions(), MeshDomain >
+{   
+   public:
+      
+      static_assert( PreimageFunction::getDomainType() == MeshDomain ||
+                     PreimageFunction::getDomainType() == MeshInteriorDomain ||
+                     PreimageFunction::getDomainType() == MeshBoundaryDomain,
+         "Only mesh preimageFunctions may be used in the operator preimageFunction. Use tnlExactOperatorFunction instead of tnlOperatorFunction." );
+      static_assert( std::is_same< typename Operator::MeshType, typename PreimageFunction::MeshType >::value,
+          "Both, operator and mesh preimageFunction must be defined on the same mesh." );
+      static_assert( std::is_same< typename BoundaryConditions::MeshType, typename Operator::MeshType >::value,
+         "The operator and the boundary conditions are defined on different mesh types." );      
+      
+      typedef Operator OperatorType;
+      typedef typename OperatorType::MeshType MeshType;
+      typedef typename OperatorType::RealType RealType;
+      typedef typename OperatorType::DeviceType DeviceType;
+      typedef typename OperatorType::IndexType IndexType;
+      typedef PreimageFunction PreimageFunctionType;
+      typedef tnlMeshFunction< MeshType, Operator::getImageEntitiesDimensions() > ImageFunctionType;
+      typedef BoundaryConditions BoundaryConditionsType;
+      typedef tnlOperatorFunction< Operator, PreimageFunction, void, true > OperatorFunction;
+      typedef typename OperatorType::ExactOperatorType ExactOperatorType;
+      
+      static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); };     
+      
+      tnlOperatorFunction( OperatorType& operator_,
+                           const BoundaryConditionsType& boundaryConditions,
+                           const MeshType& mesh )
+      :  operator_( operator_ ),
+         boundaryConditions( boundaryConditions ),
+         imageFunction( mesh ),
+         preimageFunction( 0 )
+      {};
+      
+      tnlOperatorFunction( OperatorType& operator_,
+                           const BoundaryConditionsType& boundaryConditions,
+                           const PreimageFunctionType& preimageFunction )
+      :  operator_( operator_ ),
+         boundaryConditions( boundaryConditions ),
+         imageFunction( preimageFunction.getMesh() ),
+         preimageFunction( &preimageFunction )
+      {};
+      
+      const MeshType& getMesh() const { return imageFunction.getMesh(); };
+      
+      void setPreimageFunction( const PreimageFunction& preimageFunction )
+      { 
+         this->preimageFunction = &preimageFunction;
+      }
+      
+      const PreimageFunctionType& getPreimageFunction() const
+      { 
+         tnlAssert( this->preimageFunction, );
+         return *this->preimageFunction;
+      };
+      
+      PreimageFunctionType& getPreimageFunction()
+      { 
+         tnlAssert( this->preimageFunction, );
+         return *this->preimageFunction; 
+      };      
+      
+      const ImageFunctionType& getImageFunction() const { return this->imageFunction; };
+      
+      ImageFunctionType& getImageFunction() { return this->imageFunction; };
+      
+      Operator& getOperator() { return this->operator_; }
+      
+      const Operator& getOperator() const { return this->operator_; }
+
+      bool refresh( const RealType& time = 0.0 )
+      {
+         OperatorFunction operatorFunction( this->operator_, *this->preimageFunction );
+         this->operator_.setPreimageFunction( *this->preimageFunction );
+         if( ! this->operator_.refresh( time ) ||
+             ! operatorFunction.refresh( time )  )
+             return false;
+         this->imageFunction = operatorFunction;
+         tnlBoundaryConditionsSetter< ImageFunctionType, BoundaryConditionsType >::apply( this->boundaryConditions, time, this->imageFunction );
+         return true;
+      };
+      
+      bool deepRefresh( const RealType& time = 0.0 )
+      {
+         return preimageFunction->deepRefresh( time ) && 
+                this->refresh( time );
+      };
+      
+      template< typename MeshEntity >
+      __cuda_callable__
+      const RealType& operator()(
+         const MeshEntity& meshEntity,
+         const RealType& time = 0 ) const
+      {
+         return imageFunction[ meshEntity.getIndex() ];
+      }
+      
+      __cuda_callable__
+      const RealType& operator[]( const IndexType& index ) const
+      {
+         return imageFunction[ index ];
+      }
+      
+   protected:
+      
+      Operator& operator_;
+      
+      const PreimageFunctionType* preimageFunction;
+      
+      ImageFunctionType imageFunction;
+      
+      const BoundaryConditionsType& boundaryConditions;
+      
+      template< typename, typename > friend class tnlMeshFunctionEvaluator;
+};
+
+#endif	/* TNLOPERATORFUNCTION_H */
+
diff --git a/src/functions/tnlSinBumpsFunction.h b/src/functions/tnlSinBumpsFunction.h
index 4af21e0792ca40def1d3fe89009939364ba320f1..68878e10cd8d83eeeb4e1e9a1723595f1a971d56 100644
--- a/src/functions/tnlSinBumpsFunction.h
+++ b/src/functions/tnlSinBumpsFunction.h
@@ -20,10 +20,10 @@
 
 #include <config/tnlParameterContainer.h>
 #include <core/vectors/tnlStaticVector.h>
-#include <functions/tnlFunction.h>
+#include <functions/tnlDomain.h>
 
 template< typename Vertex >
-class tnlSinBumpsFunctionBase : public tnlFunction< Vertex::size, AnalyticFunction >
+class tnlSinBumpsFunctionBase : public tnlDomain< Vertex::size, SpaceDomain >
 {
    public:
       
@@ -79,8 +79,13 @@ class tnlSinBumpsFunction< 1, Real  > : public tnlSinBumpsFunctionBase< tnlStati
                 int ZDiffOrder = 0 >
 #endif
       __cuda_callable__
-      RealType getValue( const VertexType& v,
-                         const Real& time = 0.0 ) const;
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+      
+   __cuda_callable__
+   RealType operator()( const VertexType& v,
+                        const Real& time = 0.0 ) const;
+      
 };
 
 template< typename Real >
@@ -107,8 +112,13 @@ class tnlSinBumpsFunction< 2, Real > : public tnlSinBumpsFunctionBase< tnlStatic
                 int ZDiffOrder = 0 >
 #endif
       __cuda_callable__
-      RealType getValue( const VertexType& v,
-                         const Real& time = 0.0 ) const;
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+      
+   __cuda_callable__
+   RealType operator()( const VertexType& v,
+                        const Real& time = 0.0 ) const;
+      
 };
 
 template< typename Real >
@@ -134,8 +144,13 @@ class tnlSinBumpsFunction< 3, Real > : public tnlSinBumpsFunctionBase< tnlStatic
                 int ZDiffOrder = 0 >
 #endif
       __cuda_callable__
-      RealType getValue( const VertexType& v,
+      RealType getPartialDerivative( const VertexType& v,
                          const Real& time = 0.0 ) const;
+      
+   __cuda_callable__
+   RealType operator()( const VertexType& v,
+                        const Real& time = 0.0 ) const;
+      
 };
 
 template< int Dimensions,
diff --git a/src/functions/tnlSinBumpsFunction_impl.h b/src/functions/tnlSinBumpsFunction_impl.h
index 308ff76f9754238dc55a6ba0f3b8276e329e5fae..34497733472727517d5a6a2aea8900727d3253d8 100644
--- a/src/functions/tnlSinBumpsFunction_impl.h
+++ b/src/functions/tnlSinBumpsFunction_impl.h
@@ -83,8 +83,8 @@ template< typename Real >
 __cuda_callable__
 Real
 tnlSinBumpsFunction< 1, Real >::
-getValue( const VertexType& v,
-          const Real& time ) const
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    const RealType& x = v.x();
    if( YDiffOrder != 0 || ZDiffOrder != 0 )
@@ -98,6 +98,17 @@ getValue( const VertexType& v,
    return 0.0;
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+tnlSinBumpsFunction< 1, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
 /****
  * 2D
  */
@@ -109,7 +120,7 @@ tnlSinBumpsFunction< 2, Real >::tnlSinBumpsFunction()
 
 template< typename Real >
 bool tnlSinBumpsFunction< 2, Real >::setup( const tnlParameterContainer& parameters,
-                                           const tnlString& prefix )
+                                            const tnlString& prefix )
 {
    this->amplitude = parameters.getParameter< double >( prefix + "amplitude" );
    this->waveLength.x() = parameters.getParameter< double >( prefix + "wave-length-x" );
@@ -127,8 +138,8 @@ template< typename Real >
 __cuda_callable__
 Real
 tnlSinBumpsFunction< 2, Real>::
-getValue( const VertexType& v,
-          const Real& time ) const
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    const RealType& x = v.x();
    const RealType& y = v.y();
@@ -146,9 +157,21 @@ getValue( const VertexType& v,
       return 2.0 * M_PI / this->waveLength.y() * this->amplitude * cos( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) * sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() );
    if( XDiffOrder == 0 && YDiffOrder == 2 )
       return -4.0 * M_PI * M_PI / ( this->waveLength.y() * this->waveLength.y() ) * this->amplitude * sin( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) * sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() );
+   if( XDiffOrder == 1 && YDiffOrder == 1 )
+      return 4.0 * M_PI * M_PI / ( this->waveLength.x() * this->waveLength.y() ) * this->amplitude * cos( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) * cos( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() );
    return 0.0;
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+tnlSinBumpsFunction< 2, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
 /****
  * 3D
  */
@@ -180,8 +203,8 @@ template< typename Real >
 __cuda_callable__
 Real
 tnlSinBumpsFunction< 3, Real >::
-getValue( const VertexType& v,
-          const Real& time ) const
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    const RealType& x = v.x();
    const RealType& y = v.y();
@@ -203,7 +226,24 @@ getValue( const VertexType& v,
       return 2.0 * M_PI / this->waveLength.z() * this->amplitude * cos( this->phase.z() + 2.0 * M_PI * z / this->waveLength.z() ) * sin( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) * sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() );
    if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 2)
       return -4.0 * M_PI * M_PI / ( this->waveLength.z() * this->waveLength.z() ) * this->amplitude * sin( this->phase.z() + 2.0 * M_PI * z / this->waveLength.z() ) * sin( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) * sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() );
+   if( XDiffOrder == 1 && YDiffOrder == 1 && ZDiffOrder == 0)
+      return 4.0 * M_PI * M_PI / ( this->waveLength.x() * this->waveLength.y() ) * this->amplitude * cos( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ) * cos( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) * sin( this->phase.z() + 2.0 * M_PI * z / this->waveLength.z() );
+   if( XDiffOrder == 1 && YDiffOrder == 0 && ZDiffOrder == 1)
+      return 4.0 * M_PI * M_PI / ( this->waveLength.x() * this->waveLength.z() ) * this->amplitude * cos( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ) * sin( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) * cos( this->phase.z() + 2.0 * M_PI * z / this->waveLength.z() );
+   if( XDiffOrder == 0 && YDiffOrder == 1 && ZDiffOrder == 1)
+      return 4.0 * M_PI * M_PI / ( this->waveLength.y() * this->waveLength.z() ) * this->amplitude * sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ) * cos( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) * cos( this->phase.z() + 2.0 * M_PI * z / this->waveLength.z() );
    return 0.0;
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+tnlSinBumpsFunction< 3, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
 #endif /* TNLSINBUMPSFUNCTION_IMPL_H_ */
diff --git a/src/functions/tnlSinWaveFunction.h b/src/functions/tnlSinWaveFunction.h
index adb5bc47a94aefdb3a76fcaeb4892b2cd84fb0ea..a1ea37ea3b557dee3c91e10eccf032160e6021bc 100644
--- a/src/functions/tnlSinWaveFunction.h
+++ b/src/functions/tnlSinWaveFunction.h
@@ -20,11 +20,11 @@
 
 #include <config/tnlParameterContainer.h>
 #include <core/vectors/tnlStaticVector.h>
-#include <functions/tnlFunction.h>
+#include <functions/tnlDomain.h>
 
 template< int dimensions,
           typename Real = double >
-class tnlSinWaveFunctionBase : public tnlFunction< dimensions, AnalyticFunction >
+class tnlSinWaveFunctionBase : public tnlDomain< dimensions, SpaceDomain >
 {
    public:
       
@@ -73,8 +73,12 @@ class tnlSinWaveFunction< 1, Real > : public tnlSinWaveFunctionBase< 1, Real >
                 int ZDiffOrder = 0 >
 #endif
       __cuda_callable__
-      RealType getValue( const VertexType& v,
-                         const Real& time = 0.0 ) const;
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;      
 
 };
 
@@ -96,8 +100,13 @@ class tnlSinWaveFunction< 2, Real > : public tnlSinWaveFunctionBase< 2, Real >
                 int ZDiffOrder = 0 >
 #endif
       __cuda_callable__
-      RealType getValue( const VertexType& v,
-                         const Real& time = 0.0 ) const;
+      RealType getPartialDerivative( const VertexType& v,
+                                     const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
 };
 
 template< typename Real >
@@ -120,8 +129,13 @@ class tnlSinWaveFunction< 3, Real > : public tnlSinWaveFunctionBase< 3, Real >
                 int ZDiffOrder = 0 >
 #endif
       __cuda_callable__
-      RealType getValue( const VertexType& v,
+      RealType getPartialDerivative( const VertexType& v,
                          const Real& time = 0.0 ) const;
+      
+      __cuda_callable__
+      RealType operator()( const VertexType& v,
+                           const Real& time = 0.0 ) const;
+      
 };
 
 template< int Dimensions,
diff --git a/src/functions/tnlSinWaveFunction_impl.h b/src/functions/tnlSinWaveFunction_impl.h
index 14e7976f2bfc8864529e176c64eb9497a2ca51f0..e03d31e95ffe90d9afd8b7029743151ad5d9e918 100644
--- a/src/functions/tnlSinWaveFunction_impl.h
+++ b/src/functions/tnlSinWaveFunction_impl.h
@@ -85,8 +85,8 @@ template< typename Real >
 __cuda_callable__
 Real
 tnlSinWaveFunction< 1, Real >::
-getValue( const VertexType& v,
-          const Real& time ) const
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    const RealType& x = v.x();
    if( YDiffOrder != 0 || ZDiffOrder != 0 )
@@ -109,6 +109,17 @@ getValue( const VertexType& v,
    return 0.0;
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+tnlSinWaveFunction< 1, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
 
 template< typename Real >
    template< int XDiffOrder,
@@ -117,8 +128,8 @@ template< typename Real >
 __cuda_callable__
 Real
 tnlSinWaveFunction< 2, Real >::
-getValue( const VertexType& v,
-          const Real& time ) const
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    const RealType& x = v.x();
    const RealType& y = v.y();
@@ -136,9 +147,23 @@ getValue( const VertexType& v,
       return 2.0 * M_PI * y / ( this->waveLength * sqrt( x * x + y * y ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength );
    if( XDiffOrder == 0 && YDiffOrder == 2 )
       return 2.0 * M_PI * y * y / ( this->waveLength * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ) - 4.0 * M_PI * M_PI * y * y / ( this->waveLength * this->waveLength * ( x * x + y * y ) ) * this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength );
+   if( XDiffOrder == 1 && YDiffOrder == 1 )
+      return -4.0 * M_PI * M_PI * x * y / ( this->waveLength * this->waveLength * (x * x + y * y ) )* this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ) 
+             - 2.0 * M_PI * this->amplitude * x * y * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ) / ( this->waveLength  * sqrt( (x * x + y * y )  * (x * x + y * y ) * (x * x + y * y ) ) );
    return 0.0;
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+tnlSinWaveFunction< 2, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
 template< typename Real >
    template< int XDiffOrder,
              int YDiffOrder,
@@ -146,8 +171,8 @@ template< typename Real >
 __cuda_callable__
 Real
 tnlSinWaveFunction< 3, Real >::
-getValue( const VertexType& v,
-          const Real& time ) const
+getPartialDerivative( const VertexType& v,
+                      const Real& time ) const
 {
    const RealType& x = v.x();
    const RealType& y = v.y();
@@ -168,7 +193,27 @@ getValue( const VertexType& v,
       return 2.0 * M_PI * z / ( this->waveLength * sqrt( x * x + y * y + z * z ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y + z * z ) / this->waveLength );
    if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 2 )
       return 2.0 * M_PI * ( x * x + y * y ) / ( this->waveLength * sqrt( x * x + y * y + z * z ) * sqrt( x * x + y * y + z * z ) * sqrt( x * x + y * y + z * z ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y + z * z ) / this->waveLength ) - 4.0 * M_PI * M_PI * z * z / ( this->waveLength * this->waveLength * ( x * x + y * y + z * z ) ) * this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y + z * z ) / this->waveLength ); 
+   if( XDiffOrder == 1 && YDiffOrder == 1 && ZDiffOrder == 0 )
+      return -4.0 * M_PI * M_PI * x * y / ( this->waveLength * this->waveLength * (x * x + y * y + z * z ) )* this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y + z * z ) / this->waveLength ) 
+             - 2.0 * M_PI * this->amplitude * x * y * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y + z * z ) / this->waveLength ) / ( this->waveLength  * sqrt( (x * x + y * y + z * z )  * (x * x + y * y + z * z ) * (x * x + y * y + z * z ) ) );
+   if( XDiffOrder == 1 && YDiffOrder == 0 && ZDiffOrder == 1 )
+      return -4.0 * M_PI * M_PI * x * z / ( this->waveLength * this->waveLength * (x * x + y * y + z * z ) )* this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y + z * z ) / this->waveLength ) 
+             - 2.0 * M_PI * this->amplitude * x * z * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y + z * z ) / this->waveLength ) / ( this->waveLength  * sqrt( (x * x + y * y + z * z )  * (x * x + y * y + z * z ) * (x * x + y * y + z * z ) ) );
+   if( XDiffOrder == 0 && YDiffOrder == 1 && ZDiffOrder == 1 )
+      return -4.0 * M_PI * M_PI * z * y / ( this->waveLength * this->waveLength * (x * x + y * y + z * z ) )* this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y + z * z ) / this->waveLength ) 
+             - 2.0 * M_PI * this->amplitude * z * y * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y + z * z ) / this->waveLength ) / ( this->waveLength  * sqrt( (x * x + y * y + z * z )  * (x * x + y * y + z * z ) * (x * x + y * y + z * z ) ) );
    return 0.0;
 }
 
+template< typename Real >
+__cuda_callable__
+Real
+tnlSinWaveFunction< 3, Real >::
+operator()( const VertexType& v,
+            const Real& time ) const
+{
+   return this->template getPartialDerivative< 0, 0, 0 >( v, time );
+}
+
+
 #endif /* TNLSINWAVEFUNCTION_IMPL_H_ */
diff --git a/src/functions/tnlTestFunction.h b/src/functions/tnlTestFunction.h
index 6684bd23a5abdb0406f77baebf91ea6d09a01a9f..71ed8828c57761c8071b6115d09ba2d078f62245 100644
--- a/src/functions/tnlTestFunction.h
+++ b/src/functions/tnlTestFunction.h
@@ -22,19 +22,24 @@
 #include <core/vectors/tnlStaticVector.h>
 #include <config/tnlConfigDescription.h>
 #include <config/tnlParameterContainer.h>
-#include <functions/tnlFunction.h>
+#include <functions/tnlDomain.h>
 
 template< int FunctionDimensions,
           typename Real = double,
           typename Device = tnlHost >
-class tnlTestFunction : public tnlFunction< FunctionDimensions, AnalyticFunction >
+class tnlTestFunction : public tnlDomain< FunctionDimensions, SpaceDomain >
 {
    protected:
 
    enum TestFunctions{ constant,
                        expBump,
                        sinBumps,
-                       sinWave };
+                       sinWave,
+		       cylinder,
+		       flowerpot,
+		       twins,
+           pseudoSquare,
+           blob };
 
    enum TimeDependence { none,
                          linear,
@@ -67,17 +72,16 @@ class tnlTestFunction : public tnlFunction< FunctionDimensions, AnalyticFunction
              int ZDiffOrder = 0 >
 #endif
    __cuda_callable__
-   Real getValue( const VertexType& vertex,
-                  const Real& time = 0 ) const;
+   Real getPartialDerivative( const VertexType& vertex,
+                              const Real& time = 0 ) const;
 
-#ifdef HAVE_NOT_CXX11
    __cuda_callable__
-   Real getValue( const VertexType& vertex,
+   Real operator()( const VertexType& vertex,
                   const Real& time = 0 ) const
    {
-      return this->getValue< 0, 0, 0 >( vertex, time );
+      return this->getPartialDerivative< 0, 0, 0 >( vertex, time );
    }
-#endif                  
+
 
 #ifdef HAVE_NOT_CXX11
    template< int XDiffOrder,
@@ -94,6 +98,7 @@ class tnlTestFunction : public tnlFunction< FunctionDimensions, AnalyticFunction
 
 #ifdef HAVE_NOT_CXX11
    template< typename Vertex >
+   __cuda_callable__
    Real getTimeDerivative( const Vertex& vertex,
                            const Real& time = 0 ) const
    {
diff --git a/src/functions/tnlTestFunction_impl.cpp b/src/functions/tnlTestFunction_impl.cpp
index c8baf09f22da5f5871f785e763fdf4c254110c62..dbac900553eda49dd3a8ef9b1f21bf38a46aa640 100644
--- a/src/functions/tnlTestFunction_impl.cpp
+++ b/src/functions/tnlTestFunction_impl.cpp
@@ -20,17 +20,21 @@
 
 #include <functions/tnlTestFunction.h>
 
+#ifdef INSTANTIATE_FLOAT
 template class tnlTestFunction< 1, float, tnlHost >;
 template class tnlTestFunction< 2, float, tnlHost >;
 template class tnlTestFunction< 3, float, tnlHost >;
+#endif
 
 template class tnlTestFunction< 1, double, tnlHost >;
 template class tnlTestFunction< 2, double, tnlHost >;
 template class tnlTestFunction< 3, double, tnlHost >;
 
+#ifdef INSTANTIATE_LONG_DOUBLE
 template class tnlTestFunction< 1, long double, tnlHost >;
 template class tnlTestFunction< 2, long double, tnlHost >;
 template class tnlTestFunction< 3, long double, tnlHost >;
+#endif
 
 #endif
 
diff --git a/src/functions/tnlTestFunction_impl.cu b/src/functions/tnlTestFunction_impl.cu
index 69354815a11103d8134d35d27e97e323bc3f314b..de2cdc1e3c20f9ec222abc878695d42bceca1f3b 100644
--- a/src/functions/tnlTestFunction_impl.cu
+++ b/src/functions/tnlTestFunction_impl.cu
@@ -20,17 +20,21 @@
 
 #include <functions/tnlTestFunction.h>
 
+#ifdef INSTANTIATE_FLOAT
 template class tnlTestFunction< 1, float, tnlCuda >;
 template class tnlTestFunction< 2, float, tnlCuda >;
 template class tnlTestFunction< 3, float, tnlCuda >;
+#endif
 
 template class tnlTestFunction< 1, double, tnlCuda >;
 template class tnlTestFunction< 2, double, tnlCuda >;
 template class tnlTestFunction< 3, double, tnlCuda >;
 
-/*template class tnlTestFunction< 1, long double, tnlCuda >;
+#ifdef INSTANTIATE_LONG_DOUBLE
+template class tnlTestFunction< 1, long double, tnlCuda >;
 template class tnlTestFunction< 2, long double, tnlCuda >;
-template class tnlTestFunction< 3, long double, tnlCuda >;*/
+template class tnlTestFunction< 3, long double, tnlCuda >;
+#endif
 
 #endif
 #endif
diff --git a/src/functions/tnlTestFunction_impl.h b/src/functions/tnlTestFunction_impl.h
index 5609a46a1f8a2ab04a57530b1554dba843a7ad71..46f70b3e4fa6bf5b4717702c176b201dc7c49e8b 100644
--- a/src/functions/tnlTestFunction_impl.h
+++ b/src/functions/tnlTestFunction_impl.h
@@ -24,6 +24,17 @@
 #include <functions/tnlSinBumpsFunction.h>
 #include <functions/tnlSinWaveFunction.h>
 
+// This is from origin/mean-curvature
+#include <functions/tnlConstantFunction.h>
+#include <functions/tnlExpBumpFunction.h>
+#include <functions/tnlSinBumpsFunction.h>
+#include <functions/tnlSinWaveFunction.h>
+#include <functions/initial_conditions/tnlCylinderFunction.h>
+#include <functions/initial_conditions/tnlFlowerpotFunction.h>
+#include <functions/initial_conditions/tnlTwinsFunction.h>
+#include <functions/initial_conditions/level_set_functions/tnlBlobFunction.h>
+#include <functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h>
+
 template< int FunctionDimensions,
           typename Real,
           typename Device >
@@ -48,6 +59,11 @@ configSetup( tnlConfigDescription& config,
       config.addEntryEnum( "exp-bump" );
       config.addEntryEnum( "sin-wave" );
       config.addEntryEnum( "sin-bumps" );
+      config.addEntryEnum( "cylinder" );
+      config.addEntryEnum( "flowerpot" );
+      config.addEntryEnum( "twins" );
+      config.addEntryEnum( "pseudoSquare" );
+      config.addEntryEnum( "blob" );
    config.addEntry     < double >( prefix + "constant", "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 );
@@ -63,6 +79,8 @@ configSetup( tnlConfigDescription& config,
    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     < double >( prefix + "diameter", "Diameter for the cylinder, flowerpot test functions.", 1.0 );
+  config.addEntry     < double >( prefix + "height", "Height of zero-level-set function for the blob, pseudosquare test functions.", 1.0 );
    config.addEntry     < tnlString >( prefix + "time-dependence", "Time dependence of the test function.", "none" );
       config.addEntryEnum( "none" );
       config.addEntryEnum( "linear" );
@@ -153,6 +171,36 @@ setup( const tnlParameterContainer& parameters,
       functionType = sinWave;
       return setupFunction< FunctionType >( parameters );
    }
+   if( testFunction == "cylinder" )
+   {
+      typedef tnlCylinderFunction< Dimensions, Real > FunctionType;
+      functionType = cylinder;
+      return setupFunction< FunctionType >( parameters );
+   }
+   if( testFunction == "flowerpot" )
+   {
+      typedef tnlFlowerpotFunction< Dimensions, Real > FunctionType;
+      functionType = flowerpot;
+      return setupFunction< FunctionType >( parameters );
+   }
+   if( testFunction == "twins" )
+   {
+      typedef tnlTwinsFunction< Dimensions, Real > FunctionType;
+      functionType = twins;
+      return setupFunction< FunctionType >( parameters );
+   }
+   if( testFunction == "pseudoSquare" )
+   {
+      typedef tnlPseudoSquareFunction< Dimensions, Real > FunctionType;
+      functionType = pseudoSquare;
+      return setupFunction< FunctionType >( parameters );
+   }
+   if( testFunction == "blob" )
+   {
+      typedef tnlBlobFunction< Dimensions, Real > FunctionType;
+      functionType = blob;
+      return setupFunction< FunctionType >( parameters );
+   }
    cerr << "Unknown function " << testFunction << endl;
    return false;
 }
@@ -188,6 +236,21 @@ operator = ( const tnlTestFunction& function )
       case sinWave:
          this->copyFunction< tnlSinWaveFunction< FunctionDimensions, Real > >( function.function );
          break;
+      case cylinder:
+         this->copyFunction< tnlCylinderFunction< FunctionDimensions, Real > >( function.function );
+         break;
+      case flowerpot:
+         this->copyFunction< tnlFlowerpotFunction< FunctionDimensions, Real > >( function.function );
+         break;
+      case twins:
+         this->copyFunction< tnlTwinsFunction< FunctionDimensions, Real > >( function.function );
+         break;
+      case pseudoSquare:
+         this->copyFunction< tnlPseudoSquareFunction< FunctionDimensions, Real > >( function.function );
+         break;
+      case blob:
+         this->copyFunction< tnlBlobFunction< FunctionDimensions, Real > >( function.function );
+         break;
       default:
          tnlAssert( false, );
          break;
@@ -204,7 +267,7 @@ template< int FunctionDimensions,
 __cuda_callable__
 Real
 tnlTestFunction< FunctionDimensions, Real, Device >::
-getValue( const VertexType& vertex,
+getPartialDerivative( const VertexType& vertex,
           const Real& time ) const
 {
    Real scale( 1.0 );
@@ -228,16 +291,31 @@ getValue( const VertexType& vertex,
    {
       case constant:
          return scale * ( ( tnlConstantFunction< Dimensions, Real >* ) function )->
-                   getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case expBump:
          return scale * ( ( tnlExpBumpFunction< Dimensions, Real >* ) function )->
-                  getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case sinBumps:
          return scale * ( ( tnlSinBumpsFunction< Dimensions, Real >* ) function )->
-                  getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case sinWave:
          return scale * ( ( tnlSinWaveFunction< Dimensions, Real >* ) function )->
-                  getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      case cylinder:
+         return scale * ( ( tnlCylinderFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      case flowerpot:
+         return scale * ( ( tnlFlowerpotFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      case twins:
+         return scale * ( ( tnlTwinsFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      case pseudoSquare:
+         return scale * ( ( tnlPseudoSquareFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+      case blob:
+         return scale * ( ( tnlBlobFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       default:
          return 0.0;
    }
@@ -274,16 +352,37 @@ getTimeDerivative( const VertexType& vertex,
    {
       case constant:
          return scale * ( ( tnlConstantFunction< Dimensions, Real >* ) function )->
-                  getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case expBump:
          return scale * ( ( tnlExpBumpFunction< Dimensions, Real >* ) function )->
-                  getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case sinBumps:
          return scale * ( ( tnlSinBumpsFunction< Dimensions, Real >* ) function )->
-                  getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case sinWave:
          return scale * ( ( tnlSinWaveFunction< Dimensions, Real >* ) function )->
-                  getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+         break;
+      case cylinder:
+         return scale * ( ( tnlCylinderFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+         break;
+      case flowerpot:
+         return scale * ( ( tnlFlowerpotFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+         break;
+      case twins:
+         return scale * ( ( tnlTwinsFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+         break;
+      case pseudoSquare:
+         return scale * ( ( tnlPseudoSquareFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+         break;
+      case blob:
+         return scale * ( ( tnlBlobFunction< Dimensions, Real >* ) function )->
+                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+         break;
       default:
          return 0.0;
    }
@@ -330,6 +429,21 @@ deleteFunctions()
       case sinWave:
          deleteFunction< tnlSinWaveFunction< Dimensions, Real> >();
          break;
+      case cylinder:
+         deleteFunction< tnlCylinderFunction< Dimensions, Real> >();
+         break;
+      case flowerpot:
+         deleteFunction< tnlFlowerpotFunction< Dimensions, Real> >();
+         break;
+      case twins:
+         deleteFunction< tnlTwinsFunction< Dimensions, Real> >();
+         break;
+      case pseudoSquare:
+         deleteFunction< tnlPseudoSquareFunction< Dimensions, Real> >();
+         break;
+      case blob:
+         deleteFunction< tnlBlobFunction< Dimensions, Real> >();
+         break;
    }
 }
 
@@ -395,6 +509,16 @@ print( ostream& str ) const
          return printFunction< tnlSinBumpsFunction< Dimensions, Real> >( str );
       case sinWave:
          return printFunction< tnlSinWaveFunction< Dimensions, Real> >( str );
+      case cylinder:
+         return printFunction< tnlCylinderFunction< Dimensions, Real> >( str );
+      case flowerpot:
+         return printFunction< tnlFlowerpotFunction< Dimensions, Real> >( str );
+      case twins:
+         return printFunction< tnlTwinsFunction< Dimensions, Real> >( str );
+      case pseudoSquare:
+         return printFunction< tnlPseudoSquareFunction< Dimensions, Real> >( str );
+      case blob:
+         return printFunction< tnlBlobFunction< Dimensions, Real> >( str );
    }
    return str;
 }
@@ -411,30 +535,38 @@ tnlTestFunction< FunctionDimensions, Real, Device >::
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 
+#ifdef INSTANTIATE_FLOAT
 extern template class tnlTestFunction< 1, float, tnlHost >;
 extern template class tnlTestFunction< 2, float, tnlHost >;
 extern template class tnlTestFunction< 3, float, tnlHost >;
+#endif
 
 extern template class tnlTestFunction< 1, double, tnlHost >;
 extern template class tnlTestFunction< 2, double, tnlHost >;
 extern template class tnlTestFunction< 3, double, tnlHost >;
 
+#ifdef INSTANTIATE_LONG_DOUBLE
 extern template class tnlTestFunction< 1, long double, tnlHost >;
 extern template class tnlTestFunction< 2, long double, tnlHost >;
 extern template class tnlTestFunction< 3, long double, tnlHost >;
+#endif
 
 #ifdef HAVE_CUDA
+#ifdef INSTANTIATE_FLOAT
 extern template class tnlTestFunction< 1, float, tnlCuda>;
 extern template class tnlTestFunction< 2, float, tnlCuda >;
 extern template class tnlTestFunction< 3, float, tnlCuda >;
+#endif
 
 extern template class tnlTestFunction< 1, double, tnlCuda >;
 extern template class tnlTestFunction< 2, double, tnlCuda >;
 extern template class tnlTestFunction< 3, double, tnlCuda >;
 
-/*extern template class tnlTestFunction< 1, long double, tnlCuda >;
+#ifdef INSTANTIATE_LONG_DOUBLE
+extern template class tnlTestFunction< 1, long double, tnlCuda >;
 extern template class tnlTestFunction< 2, long double, tnlCuda >;
-extern template class tnlTestFunction< 3, long double, tnlCuda >;*/
+extern template class tnlTestFunction< 3, long double, tnlCuda >;
+#endif
 #endif
 
 #endif
diff --git a/src/matrices/tnlMatrixSetter.h b/src/matrices/tnlMatrixSetter.h
index 516c86a54e491c87ff1646aa604e768ef8575485..0a9989bb04d3c34d696ab6fe21f88f5ddd698ea0 100644
--- a/src/matrices/tnlMatrixSetter.h
+++ b/src/matrices/tnlMatrixSetter.h
@@ -137,30 +137,6 @@ class tnlMatrixSetter< tnlGrid< Dimensions, Real, Device, Index >,
                      userData.boundaryConditions->getLinearSystemRowLength( mesh, entity.getIndex(), entity );
          }
 
-         
-         /*
-         __cuda_callable__
-         static void processCell( const MeshType& mesh,
-                                  TraversalUserData& userData,
-                                  const IndexType index,
-                                  const CoordinatesType& coordinates )
-         {
-            ( *userData.rowLengths )[ index ] =
-                     userData.boundaryConditions->getLinearSystemRowLength( mesh, index, coordinates );
-         }
-
-         __cuda_callable__
-         static void processFace( const MeshType& mesh,
-                                  TraversalUserData& userData,
-                                  const IndexType index,
-                                  const CoordinatesType& coordinates )
-         {
-             //printf("Matrix setter: Index = %d \n", index );
-            ( *userData.rowLengths )[ index ] =
-                     userData.boundaryConditions->getLinearSystemRowLength( mesh, index, coordinates );
-         }*/
-         
-
    };
 
    class TraversalInteriorEntitiesProcessor
@@ -176,30 +152,6 @@ class tnlMatrixSetter< tnlGrid< Dimensions, Real, Device, Index >,
             ( *userData.rowLengths )[ entity.getIndex() ] =
                      userData.differentialOperator->getLinearSystemRowLength( mesh, entity.getIndex(), entity );
          }
-
-
-         /*__cuda_callable__
-         static void processCell( const MeshType& mesh,
-                                  TraversalUserData& userData,
-                                  const IndexType index,
-                                  const CoordinatesType& coordinates )
-         {
-            ( *userData.rowLengths )[ index ] =
-                     userData.differentialOperator->getLinearSystemRowLength( mesh, index, coordinates );
-         }
-         
-         __cuda_callable__
-         static void processFace( const MeshType& mesh,
-                                  TraversalUserData& userData,
-                                  const IndexType index,
-                                  const CoordinatesType& coordinates )
-         {
-            // printf("Matrix setter: Index = %d \n", index );
-            ( *userData.rowLengths )[ index ] =
-                     userData.differentialOperator->getLinearSystemRowLength( mesh, index, coordinates );
-         }*/
-         
-
    };
 
 };
diff --git a/src/matrices/tnlSlicedEllpackMatrix_impl.h b/src/matrices/tnlSlicedEllpackMatrix_impl.h
index 628e5e39a7321465a2a248e7dd7b61b8e04e2818..a185b5ea056148d71451bb961329843e4ab92463 100644
--- a/src/matrices/tnlSlicedEllpackMatrix_impl.h
+++ b/src/matrices/tnlSlicedEllpackMatrix_impl.h
@@ -92,7 +92,7 @@ template< typename Real,
           int SliceSize >
 Index tnlSlicedEllpackMatrix< Real, Device, Index, SliceSize >::getRowLength( const IndexType row ) const
 {
-   const IndexType slice = roundUpDivision( row, SliceSize );
+   const IndexType slice = row / SliceSize;
    return this->sliceCompressedRowsLengths.getElement( slice );
 }
 
@@ -447,7 +447,7 @@ getRow( const IndexType rowIndex )
 {
    Index rowBegin, rowEnd, step;
    DeviceDependentCode::initRowTraverseFast( *this, rowIndex, rowBegin, rowEnd, step );
-   const IndexType slice = roundUpDivision( rowIndex, SliceSize );
+   const IndexType slice = rowIndex / SliceSize;
    return MatrixRow( &this->columnIndexes[ rowBegin ],
                      &this->values[ rowBegin ],
                      this->sliceCompressedRowsLengths[ slice ],
@@ -465,7 +465,7 @@ getRow( const IndexType rowIndex ) const
 {
    Index rowBegin, rowEnd, step;
    DeviceDependentCode::initRowTraverseFast( *this, rowIndex, rowBegin, rowEnd, step );
-   const IndexType slice = roundUpDivision( rowIndex, SliceSize );
+   const IndexType slice = rowIndex / SliceSize;
    return MatrixRow( &this->columnIndexes[ rowBegin ],
                      &this->values[ rowBegin ],
                      this->sliceCompressedRowsLengths[ slice ],
diff --git a/src/matrices/tnlSparseMatrixRow.h b/src/matrices/tnlSparseMatrixRow.h
index 7290ffb41ee56299094a6acac25f1651339b8c3a..b2c7372033563aba1103fe8dd304e62d4c64efeb 100644
--- a/src/matrices/tnlSparseMatrixRow.h
+++ b/src/matrices/tnlSparseMatrixRow.h
@@ -43,6 +43,8 @@ class tnlSparseMatrixRow
       void setElement( const Index& elementIndex,
                        const Index& column,
                        const Real& value );
+      
+      void print( ostream& str ) const;
 
    protected:
 
@@ -53,6 +55,13 @@ class tnlSparseMatrixRow
       Index length, step;
 };
 
+template< typename Real, typename Index >
+ostream& operator << ( ostream& str, const tnlSparseMatrixRow< Real, Index >& row )
+{
+   row.print( str );
+   return str;
+}
+
 #include <matrices/tnlSparseMatrixRow_impl.h>
 
 #endif /* TNLSPARSEMATRIXROW_H_ */
diff --git a/src/matrices/tnlSparseMatrixRow_impl.h b/src/matrices/tnlSparseMatrixRow_impl.h
index 79f171f158dd1e2362ef42ad163bf77fe5805bb4..3728cdcf32d675f4b1b98b307911ca2661ef7c3f 100644
--- a/src/matrices/tnlSparseMatrixRow_impl.h
+++ b/src/matrices/tnlSparseMatrixRow_impl.h
@@ -77,4 +77,17 @@ setElement( const Index& elementIndex,
    this->values[ elementIndex * step ] = value;
 }
 
+template< typename Real, typename Index >
+void
+tnlSparseMatrixRow< Real, Index >::
+print( ostream& str ) const
+{
+   Index pos( 0 );
+   for( Index i = 0; i < length; i++ )
+   {
+      str << " [ " << columns[ pos ] << " ] = " << values[ pos ] << ", ";
+      pos += step;   
+   }
+}
+
 #endif /* TNLSPARSEMATRIXROW_IMPL_H_ */
diff --git a/src/mesh/grids/CMakeLists.txt b/src/mesh/grids/CMakeLists.txt
index ffe9c564b6cb23f77b04d6857e47440cfaced10d..1e8370d051f9a85558b0ea044a7e6f577118dc2f 100644
--- a/src/mesh/grids/CMakeLists.txt
+++ b/src/mesh/grids/CMakeLists.txt
@@ -12,6 +12,7 @@ SET( headers tnlBoundaryGridEntityChecker.h
              tnlGridEntityCenterGetter.h
              tnlGridEntityGetter.h
              tnlGridEntityGetter_impl.h
+             tnlGridEntityMeasureGetter.h
              tnlNeighbourGridEntityGetter.h
              tnlNeighbourGridEntityGetter1D_impl.h
              tnlNeighbourGridEntityGetter2D_impl.h
diff --git a/src/mesh/grids/tnlGrid1D.h b/src/mesh/grids/tnlGrid1D.h
index f621a43f67f33d98e35cf3ba554d7c87a7c85992..9d9962ce61b4849b8b6c68ca376c0f51381d915b 100644
--- a/src/mesh/grids/tnlGrid1D.h
+++ b/src/mesh/grids/tnlGrid1D.h
@@ -46,12 +46,13 @@ class tnlGrid< 1, Real, Device, Index > : public tnlObject
    
    template< int EntityDimensions, 
              typename Config = tnlGridEntityCrossStencilStorage< 1 > >
-   using GridEntity = tnlGridEntity< ThisType, EntityDimensions, Config >;
+   using MeshEntity = tnlGridEntity< ThisType, EntityDimensions, Config >;
      
-   typedef GridEntity< meshDimensions, tnlGridEntityCrossStencilStorage< 1 > > Cell;
-   typedef GridEntity< 0 > Vertex;
+   typedef MeshEntity< meshDimensions, tnlGridEntityCrossStencilStorage< 1 > > Cell;
+   typedef MeshEntity< 0 > Face;
+   typedef MeshEntity< 0 > Vertex;
 
-   static constexpr int getDimensionsCount() { return meshDimensions; };
+   static constexpr int getMeshDimensions() { return meshDimensions; };
    
    tnlGrid();
 
@@ -91,6 +92,13 @@ class tnlGrid< 1, Real, Device, Index > : public tnlObject
    __cuda_callable__
    inline Index getEntityIndex( const EntityType& entity ) const;
    
+   template< typename EntityType >
+   __cuda_callable__
+   RealType getEntityMeasure( const EntityType& entity ) const;
+   
+   __cuda_callable__
+   RealType getCellMeasure() const;
+   
    __cuda_callable__
    inline VertexType getSpaceSteps() const;
 
diff --git a/src/mesh/grids/tnlGrid1D_impl.h b/src/mesh/grids/tnlGrid1D_impl.h
index 36dd4f9bf0d9e9308dea22f463fa421c5efb5b91..bd9f30ac8a3d52f1fd2a00156f32763d60fb04bb 100644
--- a/src/mesh/grids/tnlGrid1D_impl.h
+++ b/src/mesh/grids/tnlGrid1D_impl.h
@@ -26,13 +26,14 @@
 #include <mesh/grids/tnlGridEntityGetter_impl.h>
 #include <mesh/grids/tnlNeighbourGridEntityGetter1D_impl.h>
 #include <mesh/grids/tnlGrid1D.h>
+#include <mesh/grids/tnlGridEntityMeasureGetter.h>
 
 using namespace std;
 
 template< typename Real,
           typename Device,
           typename Index >
-tnlGrid< 1, Real, Device, Index > :: tnlGrid()
+tnlGrid< 1, Real, Device, Index >::tnlGrid()
 : numberOfCells( 0 ),
   numberOfVertices( 0 )
 {
@@ -41,19 +42,19 @@ tnlGrid< 1, Real, Device, Index > :: tnlGrid()
 template< typename Real,
           typename Device,
           typename Index  >
-tnlString tnlGrid< 1, Real, Device, Index > :: getType()
+tnlString tnlGrid< 1, Real, Device, Index >::getType()
 {
    return tnlString( "tnlGrid< " ) +
-          tnlString( getDimensionsCount() ) + ", " +
+          tnlString( getMeshDimensions() ) + ", " +
           tnlString( ::getType< RealType >() ) + ", " +
-          tnlString( Device :: getDeviceType() ) + ", " +
+          tnlString( Device::getDeviceType() ) + ", " +
           tnlString( ::getType< IndexType >() ) + " >";
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-tnlString tnlGrid< 1, Real, Device, Index > :: getTypeVirtual() const
+tnlString tnlGrid< 1, Real, Device, Index >::getTypeVirtual() const
 {
    return this -> getType();
 }
@@ -61,7 +62,7 @@ tnlString tnlGrid< 1, Real, Device, Index > :: getTypeVirtual() const
 template< typename Real,
           typename Device,
           typename Index >
-tnlString tnlGrid< 1, Real, Device, Index > :: getSerializationType()
+tnlString tnlGrid< 1, Real, Device, Index >::getSerializationType()
 {
    return HostType::getType();
 };
@@ -69,7 +70,7 @@ tnlString tnlGrid< 1, Real, Device, Index > :: getSerializationType()
 template< typename Real,
           typename Device,
           typename Index >
-tnlString tnlGrid< 1, Real, Device, Index > :: getSerializationTypeVirtual() const
+tnlString tnlGrid< 1, Real, Device, Index >::getSerializationTypeVirtual() const
 {
    return this->getSerializationType();
 };
@@ -77,7 +78,7 @@ tnlString tnlGrid< 1, Real, Device, Index > :: getSerializationTypeVirtual() con
 template< typename Real,
           typename Device,
           typename Index >
-void tnlGrid< 1, Real, Device, Index > :: computeSpaceSteps()
+void tnlGrid< 1, Real, Device, Index >::computeSpaceSteps()
 {
    if( this->getDimensions().x() != 0 )
    {
@@ -106,7 +107,7 @@ void tnlGrid< 1, Real, Device, Index >::setDimensions( const Index xSize )
 template< typename Real,
           typename Device,
           typename Index  >
-void tnlGrid< 1, Real, Device, Index > :: setDimensions( const CoordinatesType& dimensions )
+void tnlGrid< 1, Real, Device, Index >::setDimensions( const CoordinatesType& dimensions )
 {
    this -> setDimensions( dimensions. x() );
 }
@@ -116,7 +117,7 @@ template< typename Real,
           typename Index  >
 __cuda_callable__ inline
 const typename tnlGrid< 1, Real, Device, Index >::CoordinatesType&
-   tnlGrid< 1, Real, Device, Index > :: getDimensions() const
+   tnlGrid< 1, Real, Device, Index >::getDimensions() const
 {
    return this->dimensions;
 }
@@ -124,7 +125,7 @@ const typename tnlGrid< 1, Real, Device, Index >::CoordinatesType&
 template< typename Real,
           typename Device,
           typename Index >
-void tnlGrid< 1, Real, Device, Index > :: setDomain( const VertexType& origin,
+void tnlGrid< 1, Real, Device, Index >::setDomain( const VertexType& origin,
                                                      const VertexType& proportions )
 {
    this->origin = origin;
@@ -136,8 +137,8 @@ template< typename Real,
           typename Device,
           typename Index  >
 __cuda_callable__ inline
-const typename tnlGrid< 1, Real, Device, Index > :: VertexType& 
-  tnlGrid< 1, Real, Device, Index > :: getOrigin() const
+const typename tnlGrid< 1, Real, Device, Index >::VertexType& 
+  tnlGrid< 1, Real, Device, Index >::getOrigin() const
 {
    return this->origin;
 }
@@ -146,8 +147,8 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-const typename tnlGrid< 1, Real, Device, Index > :: VertexType& 
-   tnlGrid< 1, Real, Device, Index > :: getProportions() const
+const typename tnlGrid< 1, Real, Device, Index >::VertexType& 
+   tnlGrid< 1, Real, Device, Index >::getProportions() const
 {
    return this->proportions;
 }
@@ -204,6 +205,29 @@ getEntityIndex( const EntityType& entity ) const
    return tnlGridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity );
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename EntityType >
+__cuda_callable__
+Real
+tnlGrid< 1, Real, Device, Index >::
+getEntityMeasure( const EntityType& entity ) const
+{
+   return tnlGridEntityMeasureGetter< ThisType, EntityType::getDimensions() >::getMeasure( *this, entity );
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Real
+tnlGrid< 1, Real, Device, Index >::
+getCellMeasure() const
+{
+   return this->template getSpaceStepsProducts< 1 >();
+}
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -233,7 +257,8 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__ inline
-Real tnlGrid< 1, Real, Device, Index > :: getSmallestSpaceStep() const
+Real tnlGrid< 1, Real, Device, Index >::
+getSmallestSpaceStep() const
 {
    return this->spaceSteps.x();
 }
@@ -303,7 +328,7 @@ bool tnlGrid< 1, Real, Device, Index >::save( tnlFile& file ) const
 template< typename Real,
           typename Device,
           typename Index >
-bool tnlGrid< 1, Real, Device, Index > :: load( tnlFile& file )
+bool tnlGrid< 1, Real, Device, Index >::load( tnlFile& file )
 {
    if( ! tnlObject::load( file ) )
       return false;
@@ -322,7 +347,7 @@ bool tnlGrid< 1, Real, Device, Index > :: load( tnlFile& file )
 template< typename Real,
           typename Device,
           typename Index >
-bool tnlGrid< 1, Real, Device, Index > :: save( const tnlString& fileName ) const
+bool tnlGrid< 1, Real, Device, Index >::save( const tnlString& fileName ) const
 {
    return tnlObject::save( fileName );
 }
@@ -330,7 +355,7 @@ bool tnlGrid< 1, Real, Device, Index > :: save( const tnlString& fileName ) cons
 template< typename Real,
           typename Device,
           typename Index >
-bool tnlGrid< 1, Real, Device, Index > :: load( const tnlString& fileName )
+bool tnlGrid< 1, Real, Device, Index >::load( const tnlString& fileName )
 {
    return tnlObject::load( fileName );
 }
@@ -351,7 +376,7 @@ template< typename Real,
            typename Device,
            typename Index >
    template< typename MeshFunction >
-bool tnlGrid< 1, Real, Device, Index > :: write( const MeshFunction& function,
+bool tnlGrid< 1, Real, Device, Index >::write( const MeshFunction& function,
                                                  const tnlString& fileName,
                                                  const tnlString& format ) const
 {
@@ -363,7 +388,7 @@ bool tnlGrid< 1, Real, Device, Index > :: write( const MeshFunction& function,
       return false;
    }
    fstream file;
-   file. open( fileName. getString(), ios :: out );
+   file. open( fileName. getString(), ios::out );
    if( ! file )
    {
       cerr << "I am not able to open the file " << fileName << "." << endl;
@@ -373,7 +398,7 @@ bool tnlGrid< 1, Real, Device, Index > :: write( const MeshFunction& function,
    const RealType hx = getSpaceSteps(). x();
    if( format == "gnuplot" )
    {
-      typename ThisType::template GridEntity< getDimensionsCount() > entity( *this );
+      typename ThisType::template MeshEntity< getMeshDimensions() > entity( *this );
       for( entity.getCoordinates().x() = 0;
            entity.getCoordinates().x() < getDimensions(). x();
            entity.getCoordinates().x() ++ )
@@ -395,7 +420,7 @@ void
 tnlGrid< 1, Real, Device, Index >::
 writeProlog( tnlLogger& logger )
 {
-   logger.writeParameter( "Dimensions:", getDimensionsCount() );
+   logger.writeParameter( "Dimensions:", getMeshDimensions() );
    logger.writeParameter( "Domain origin:", this->origin );
    logger.writeParameter( "Domain proportions:", this->proportions );
    logger.writeParameter( "Domain dimensions:", this->dimensions );
diff --git a/src/mesh/grids/tnlGrid2D.h b/src/mesh/grids/tnlGrid2D.h
index c9fc66388b2060bec6e442aa0cf6d09f0cc31c8b..06b6111b3aae0b42ccfcab91aec297124f62992c 100644
--- a/src/mesh/grids/tnlGrid2D.h
+++ b/src/mesh/grids/tnlGrid2D.h
@@ -42,14 +42,14 @@ class tnlGrid< 2, Real, Device, Index > : public tnlObject
    static const int meshDimensions = 2;
 
    template< int EntityDimensions, 
-             typename Config = tnlGridEntityCrossStencilStorage< 1 > >
-   using GridEntity = tnlGridEntity< ThisType, EntityDimensions, Config >;
+             typename Config = tnlGridEntityNoStencilStorage >//CrossStencilStorage< 1 > >
+   using MeshEntity = tnlGridEntity< ThisType, EntityDimensions, Config >;
    
-   typedef GridEntity< meshDimensions, tnlGridEntityCrossStencilStorage< 1 > > Cell;
-   typedef GridEntity< meshDimensions - 1 > Face;
-   typedef GridEntity< 0 > Vertex;
+   typedef MeshEntity< meshDimensions, tnlGridEntityCrossStencilStorage< 1 > > Cell;
+   typedef MeshEntity< meshDimensions - 1, tnlGridEntityNoStencilStorage > Face;
+   typedef MeshEntity< 0 > Vertex;
    
-   static constexpr int getDimensionsCount() { return meshDimensions; };
+   static constexpr int getMeshDimensions() { return meshDimensions; };
 
    tnlGrid();
 
@@ -87,6 +87,13 @@ class tnlGrid< 2, Real, Device, Index > : public tnlObject
    template< typename EntityType >
    __cuda_callable__
    inline Index getEntityIndex( const EntityType& entity ) const;
+
+   template< typename EntityType >
+   __cuda_callable__
+   RealType getEntityMeasure( const EntityType& entity ) const;
+      
+   __cuda_callable__
+   RealType getCellMeasure() const;
    
    __cuda_callable__
    inline VertexType getSpaceSteps() const;
@@ -99,7 +106,6 @@ class tnlGrid< 2, Real, Device, Index > : public tnlObject
    inline RealType getSmallestSpaceStep() const;
 
    
-   
    template< typename GridFunction >
    typename GridFunction::RealType getAbsMax( const GridFunction& f ) const;
 
diff --git a/src/mesh/grids/tnlGrid2D_impl.h b/src/mesh/grids/tnlGrid2D_impl.h
index bbb00e2e24b61e7819a309f1ba9ebc7acf1658c2..c0b03f3c07e466ffdc60d8aae6fe206ca1b3ce3b 100644
--- a/src/mesh/grids/tnlGrid2D_impl.h
+++ b/src/mesh/grids/tnlGrid2D_impl.h
@@ -24,6 +24,7 @@
 #include <mesh/tnlGnuplotWriter.h>
 #include <mesh/grids/tnlGridEntityGetter_impl.h>
 #include <mesh/grids/tnlNeighbourGridEntityGetter2D_impl.h>
+#include <mesh/grids/tnlGridEntityMeasureGetter.h>
 
 using namespace std;
 
@@ -45,7 +46,7 @@ template< typename Real,
 tnlString tnlGrid< 2, Real, Device, Index > :: getType()
 {
    return tnlString( "tnlGrid< " ) +
-          tnlString( getDimensionsCount() ) + ", " +
+          tnlString( getMeshDimensions() ) + ", " +
           tnlString( ::getType< RealType >() ) + ", " +
           tnlString( Device :: getDeviceType() ) + ", " +
           tnlString( ::getType< IndexType >() ) + " >";
@@ -256,6 +257,30 @@ getEntityIndex( const EntityType& entity ) const
    return tnlGridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity );
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename EntityType >
+__cuda_callable__
+Real
+tnlGrid< 2, Real, Device, Index >::
+getEntityMeasure( const EntityType& entity ) const
+{
+   return tnlGridEntityMeasureGetter< ThisType, EntityType::getDimensions() >::getMeasure( *this, entity );
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Real
+tnlGrid< 2, Real, Device, Index >::
+getCellMeasure() const
+{
+   return this->template getSpaceStepsProducts< 1, 1 >();
+}
+
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -292,7 +317,7 @@ Real tnlGrid< 2, Real, Device, Index > :: getSmallestSpaceStep() const
 {
    return Min( this->spaceSteps.x(), this->spaceSteps.y() );
 }
- 
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -434,7 +459,7 @@ bool tnlGrid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
            << this -> getProportions(). x() << "cm , "
            << this -> getProportions(). y() << "cm );"
            << endl << endl;
-      GridEntity< 0 > vertex( *this );
+      MeshEntity< 0 > vertex( *this );
       CoordinatesType& vertexCoordinates = vertex.getCoordinates();
       VertexType v;
       for( Index j = 0; j < this -> dimensions. y(); j ++ )
@@ -472,7 +497,7 @@ bool tnlGrid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
       }
       file << endl;
 
-      GridEntity< 2 > cell( *this );
+      MeshEntity< 2 > cell( *this );
       CoordinatesType& cellCoordinates = cell.getCoordinates();
       const RealType cellMeasure = this->getSpaceSteps().x() * this->getSpaceSteps().y();
       for( Index i = 0; i < this -> dimensions. x(); i ++ )
@@ -590,7 +615,7 @@ void
 tnlGrid< 2, Real, Device, Index >::
 writeProlog( tnlLogger& logger )
 {
-   logger.writeParameter( "Dimensions:", getDimensionsCount() );
+   logger.writeParameter( "Dimensions:", getMeshDimensions() );
    logger.writeParameter( "Domain origin:", this->origin );
    logger.writeParameter( "Domain proportions:", this->proportions );
    logger.writeParameter( "Domain dimensions:", this->dimensions );
diff --git a/src/mesh/grids/tnlGrid3D.h b/src/mesh/grids/tnlGrid3D.h
index b25e8b3212b999a61ed9394b651a87efd6a72f32..e05258eba4c621b6028a09c574ae8d699030812c 100644
--- a/src/mesh/grids/tnlGrid3D.h
+++ b/src/mesh/grids/tnlGrid3D.h
@@ -43,14 +43,14 @@ class tnlGrid< 3, Real, Device, Index > : public tnlObject
 
    template< int EntityDimensions, 
              typename Config = tnlGridEntityCrossStencilStorage< 1 > >
-   using GridEntity = tnlGridEntity< ThisType, EntityDimensions, Config >;
+   using MeshEntity = tnlGridEntity< ThisType, EntityDimensions, Config >;
 
-   typedef GridEntity< meshDimensions, tnlGridEntityCrossStencilStorage< 1 > > Cell;
-   typedef GridEntity< meshDimensions - 1 > Face;
-   typedef GridEntity< 1 > Edge;
-   typedef GridEntity< 0 > Vertex;
+   typedef MeshEntity< meshDimensions, tnlGridEntityCrossStencilStorage< 1 > > Cell;
+   typedef MeshEntity< meshDimensions - 1 > Face;
+   typedef MeshEntity< 1 > Edge;
+   typedef MeshEntity< 0 > Vertex;
 
-   static constexpr int getDimensionsCount() { return meshDimensions; };
+   static constexpr int getMeshDimensions() { return meshDimensions; };
 
    tnlGrid();
 
@@ -88,6 +88,13 @@ class tnlGrid< 3, Real, Device, Index > : public tnlObject
    template< typename EntityType >
    __cuda_callable__
    inline Index getEntityIndex( const EntityType& entity ) const;
+   
+   template< typename EntityType >
+   __cuda_callable__
+   RealType getEntityMeasure( const EntityType& entity ) const;
+      
+   __cuda_callable__
+   RealType getCellMeasure() const;
 
    __cuda_callable__
    inline VertexType getSpaceSteps() const;
@@ -99,8 +106,7 @@ class tnlGrid< 3, Real, Device, Index > : public tnlObject
    
    __cuda_callable__
    inline RealType getSmallestSpaceStep() const;
- 
-
+      
    template< typename GridFunction >
    typename GridFunction::RealType getAbsMax( const GridFunction& f ) const;
 
diff --git a/src/mesh/grids/tnlGrid3D_impl.h b/src/mesh/grids/tnlGrid3D_impl.h
index d8084e83dc5557fa49e314d1baa5f0033d901772..55974cfd2c0c10338497295da4a8a33ef157f6e4 100644
--- a/src/mesh/grids/tnlGrid3D_impl.h
+++ b/src/mesh/grids/tnlGrid3D_impl.h
@@ -23,6 +23,7 @@
 #include <mesh/grids/tnlGridEntityGetter_impl.h>
 #include <mesh/grids/tnlNeighbourGridEntityGetter3D_impl.h>
 #include <mesh/grids/tnlGrid3D.h>
+#include <mesh/grids/tnlGridEntityMeasureGetter.h>
 
 template< typename Real,
           typename Device,
@@ -302,6 +303,29 @@ getEntityIndex( const EntityType& entity ) const
    return tnlGridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity );
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+   template< typename EntityType >
+__cuda_callable__
+Real
+tnlGrid< 3, Real, Device, Index >::
+getEntityMeasure( const EntityType& entity ) const
+{
+   return tnlGridEntityMeasureGetter< ThisType, EntityType::getDimensions() >::getMeasure( *this, entity );
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Real
+tnlGrid< 3, Real, Device, Index >::
+getCellMeasure() const
+{
+   return this->template getSpaceStepsProducts< 1, 1, 1 >();
+}
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -360,7 +384,7 @@ typename GridFunction::RealType
                                                  const typename GridFunction::RealType& p ) const
 {
    typename GridFunction::RealType lpNorm( 0.0 );
-   GridEntity< getDimensionsCount() > cell;
+   MeshEntity< getMeshDimensions() > cell;
    for( cell.getCoordinates().z() = 0;
         cell.getCoordinates().z() < getDimensions().z();
         cell.getCoordinates().z()++ )
@@ -388,7 +412,7 @@ template< typename Real,
                                                                            const GridFunction& f2 ) const
 {
    typename GridFunction::RealType maxDiff( -1.0 );
-   GridEntity< getDimensionsCount() > cell( *this );
+   MeshEntity< getMeshDimensions() > cell( *this );
    for( cell.getCoordinates().z() = 0;
         cell.getCoordinates().z() < getDimensions().z();
         cell.getCoordinates().z()++ )
@@ -415,7 +439,7 @@ template< typename Real,
                                                                  const typename GridFunction::RealType& p ) const
 {
    typename GridFunction::RealType lpNorm( 0.0 );
-   GridEntity< getDimensionsCount() > cell( *this );
+   MeshEntity< getMeshDimensions() > cell( *this );
 
    for( cell.getCoordinates().z() = 0;
         cell.getCoordinates().z() < getDimensions().z();
@@ -554,7 +578,7 @@ void
 tnlGrid< 3, Real, Device, Index >::
 writeProlog( tnlLogger& logger )
 {
-   logger.writeParameter( "Dimensions:", getDimensionsCount() );
+   logger.writeParameter( "Dimensions:", getMeshDimensions() );
    logger.writeParameter( "Domain origin:", this->origin );
    logger.writeParameter( "Domain proportions:", this->proportions );
    logger.writeParameter( "Domain dimensions:", this->dimensions );
diff --git a/src/mesh/grids/tnlGridEntity.h b/src/mesh/grids/tnlGridEntity.h
index 6954fb3a90c299a496e7a22429aa071364e5cc3a..8e0666bcf66bcc2857f4347959d63de584a70de5 100644
--- a/src/mesh/grids/tnlGridEntity.h
+++ b/src/mesh/grids/tnlGridEntity.h
@@ -51,6 +51,8 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, EntityDimension
    public:
       
       typedef tnlGrid< Dimensions, Real, Device, Index > GridType;
+      typedef GridType MeshType;
+      typedef typename GridType::RealType RealType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
       typedef Config ConfigType;
@@ -58,6 +60,10 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, EntityDimension
       static const int meshDimensions = GridType::meshDimensions;
       
       static const int entityDimensions = EntityDimensions;
+            
+      constexpr static int getDimensions() { return EntityDimensions; };
+      
+      constexpr static int getMeshDimensions() { return meshDimensions; };
       
       typedef tnlStaticVector< meshDimensions, IndexType > EntityOrientationType;
       typedef tnlStaticVector< meshDimensions, IndexType > EntityBasisType;
@@ -131,7 +137,10 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, EntityDimension
       VertexType getCenter() const;
       
       __cuda_callable__ inline
-      const GridType& getGrid() const;
+      const RealType& getMeasure() const;
+      
+      __cuda_callable__ inline
+      const GridType& getMesh() const;
       
    protected:
       
@@ -168,6 +177,8 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, Dimensions, Con
    public:
       
       typedef tnlGrid< Dimensions, Real, Device, Index > GridType;
+      typedef GridType MeshType;
+      typedef typename GridType::RealType RealType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
       typedef typename GridType::VertexType VertexType;
@@ -176,6 +187,11 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, Dimensions, Con
       static const int meshDimensions = GridType::meshDimensions;
       
       static const int entityDimensions = meshDimensions;
+
+      constexpr static int getDimensions() { return entityDimensions; };
+      
+      constexpr static int getMeshDimensions() { return meshDimensions; };
+      
       
       typedef tnlStaticVector< meshDimensions, IndexType > EntityOrientationType;
       typedef tnlStaticVector< meshDimensions, IndexType > EntityBasisType;
@@ -222,11 +238,17 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, Dimensions, Con
       Index getIndex() const;
             
       __cuda_callable__ inline
-      const EntityOrientationType getOrientation() const;     
+      const EntityOrientationType getOrientation() const;
+      
+      __cuda_callable__ inline
+      void setOrientation( const EntityOrientationType& orientation ){};
       
       __cuda_callable__ inline
       const EntityBasisType getBasis() const;
       
+      __cuda_callable__ inline
+      void setBasis( const EntityBasisType& basis ){};
+      
       template< int NeighbourEntityDimensions = Dimensions >
       __cuda_callable__ inline
       const NeighbourEntities< NeighbourEntityDimensions >&
@@ -238,11 +260,14 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, Dimensions, Con
       __cuda_callable__ inline
       VertexType getCenter() const;
       
+      __cuda_callable__ inline
+      const RealType& getMeasure() const;      
+      
       __cuda_callable__ inline
       const VertexType& getEntityProportions() const;      
       
       __cuda_callable__ inline
-      const GridType& getGrid() const;
+      const GridType& getMesh() const;
 
    protected:
       
@@ -278,7 +303,9 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >
 {
    public:
       
-      typedef tnlGrid< Dimensions, Real, Device, Index > GridType;      
+      typedef tnlGrid< Dimensions, Real, Device, Index > GridType;
+      typedef GridType MeshType;
+      typedef typename GridType::RealType RealType;
       typedef typename GridType::IndexType IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
       typedef typename GridType::VertexType VertexType;
@@ -288,6 +315,10 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >
       
       static const int entityDimensions = 0;
       
+      constexpr static int getDimensions() { return entityDimensions; };
+      
+      constexpr static int getMeshDimensions() { return meshDimensions; };      
+      
       typedef tnlStaticVector< meshDimensions, IndexType > EntityOrientationType;
       typedef tnlStaticVector< meshDimensions, IndexType > EntityBasisType;
       typedef tnlGridEntity< GridType, entityDimensions, Config > ThisType;
@@ -335,9 +366,16 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >
       __cuda_callable__ inline
       const EntityOrientationType getOrientation() const;     
       
+      __cuda_callable__ inline
+      void setOrientation( const EntityOrientationType& orientation ){};
+      
       __cuda_callable__ inline
       const EntityBasisType getBasis() const;
       
+      __cuda_callable__ inline
+      void setBasis( const EntityBasisType& basis ){};
+
+      
       template< int NeighbourEntityDimensions = entityDimensions >
       __cuda_callable__ inline
       const NeighbourEntities< NeighbourEntityDimensions >&
@@ -348,12 +386,15 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >
       
       __cuda_callable__ inline
       VertexType getCenter() const;
+
+      __cuda_callable__ inline
+      const RealType getMeasure() const;      
       
       __cuda_callable__ inline
       VertexType getEntityProportions() const;
       
       __cuda_callable__ inline
-      const GridType& getGrid() const;
+      const GridType& getMesh() const;
       
    protected:
       
@@ -368,10 +409,7 @@ class tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >
       EntityBasisType basis;
       
       NeighbourGridEntitiesStorageType neighbourEntitiesStorage;
-      
-      //__cuda_callable__ inline
-      //tnlGridEntity();
-      
+            
       friend class tnlBoundaryGridEntityChecker< ThisType >;
       
       friend class tnlGridEntityCenterGetter< ThisType >;
diff --git a/src/mesh/grids/tnlGridEntityMeasureGetter.h b/src/mesh/grids/tnlGridEntityMeasureGetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c8ec01eaa3e63aa7d63dde1a89cbe1c4fa0681b
--- /dev/null
+++ b/src/mesh/grids/tnlGridEntityMeasureGetter.h
@@ -0,0 +1,174 @@
+/***************************************************************************
+                          tnlGridEntityMeasureGetter.h  -  description
+                             -------------------
+    begin                : Jan 25, 2016
+    copyright            : (C) 2016 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 TNLGRIDENTITYMEASUREGETTER_H
+#define	TNLGRIDENTITYMEASUREGETTER_H
+
+template< typename Grid,
+          int EntityDimensions >
+class tnlGridEntityMeasureGetter
+{   
+};
+
+/***
+ * Common implementation for vertices
+ */
+template< int Dimensions,
+          typename Real,
+          typename Device,
+          typename Index >
+class tnlGridEntityMeasureGetter< tnlGrid< Dimensions, Real, Device, Index >, 0 >
+{
+   public:
+      
+      typedef tnlGrid< Dimensions, Real, Device, Index > GridType;
+            
+      template< typename EntityType >
+      static const Real& getMeasure( const GridType& grid,
+                                     const EntityType& entity )
+      {
+         return 0.0;
+      }
+};
+
+/****
+ * 1D grid
+ */
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlGridEntityMeasureGetter< tnlGrid< 1, Real, Device, Index >, 1 >
+{
+   public:
+      
+      typedef tnlGrid< 1, Real, Device, Index > GridType;
+      
+      template< typename EntityType >
+      static const Real& getMeasure( const GridType& grid,
+                                     const EntityType& entity )
+      {
+         return grid.template getSpaceStepsProducts< 1 >();
+      }
+};
+
+/****
+ * 2D grid
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlGridEntityMeasureGetter< tnlGrid< 2, Real, Device, Index >, 2 >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > GridType;
+      
+      template< typename EntityType >
+      static const Real& getMeasure( const GridType& grid,
+                                     const EntityType& entity )
+      {
+         return grid.template getSpaceStepsProducts< 1, 1 >();
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlGridEntityMeasureGetter< tnlGrid< 2, Real, Device, Index >, 1 >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > GridType;
+      
+      template< typename EntityType >
+      static const Real& getMeasure( const GridType& grid,
+                                     const EntityType& entity )
+      {
+         if( entity.getOrientation().x() )
+            return grid.template getSpaceStepsProducts< 0, 1 >();
+         else
+            return grid.template getSpaceStepsProducts< 1, 0 >();
+      }
+};
+
+/****
+ * 3D grid
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlGridEntityMeasureGetter< tnlGrid< 3, Real, Device, Index >, 3 >
+{
+   public:
+      
+      typedef tnlGrid< 3, Real, Device, Index > GridType;
+      
+      template< typename EntityType >
+      static const Real& getMeasure( const GridType& grid,
+                                     const EntityType& entity )
+      {
+         return grid.template getSpaceStepsProducts< 1, 1, 1 >();
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlGridEntityMeasureGetter< tnlGrid< 3, Real, Device, Index >, 2 >
+{
+   public:
+      
+      typedef tnlGrid< 3, Real, Device, Index > GridType;
+      
+      template< typename EntityType >
+      static const Real& getMeasure( const GridType& grid,
+                                     const EntityType& entity )
+      {
+         if( entity.getOrientation().x() )
+            return grid.template getSpaceStepsProducts< 0, 1, 1 >();
+         if( entity.getOrientation().y() )
+            return grid.template getSpaceStepsProducts< 1, 0, 1 >();
+         else
+            return grid.template getSpaceStepsProducts< 1, 1, 0 >();
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlGridEntityMeasureGetter< tnlGrid< 3, Real, Device, Index >, 1 >
+{
+   public:
+      
+      typedef tnlGrid< 3, Real, Device, Index > GridType;
+      
+      template< typename EntityType >
+      static const Real& getMeasure( const GridType& grid,
+                                     const EntityType& entity )
+      {
+         if( entity.getBasis().x() )
+            return grid.template getSpaceStepsProducts< 1, 0, 0 >();
+         if( entity.getBasis().y() )
+            return grid.template getSpaceStepsProducts< 0, 1, 0 >();
+         else
+            return grid.template getSpaceStepsProducts< 0, 0, 1 >();
+      }
+};
+
+#endif	/* TNLGRIDENTITYMEASUREGETTER_H */
+
diff --git a/src/mesh/grids/tnlGridEntity_impl.h b/src/mesh/grids/tnlGridEntity_impl.h
index 1f550d6c696cb30997e5c8c33e176b7b4da9c54c..2a4660778c4082e644c0767a0348013024504f7f 100644
--- a/src/mesh/grids/tnlGridEntity_impl.h
+++ b/src/mesh/grids/tnlGridEntity_impl.h
@@ -21,6 +21,7 @@
 
 #include <mesh/grids/tnlBoundaryGridEntityChecker.h>
 #include <mesh/grids/tnlGridEntityCenterGetter.h>
+#include <mesh/grids/tnlGridEntityMeasureGetter.h>
 #include <mesh/grids/tnlGridEntity.h>
 
 
@@ -142,10 +143,12 @@ Index
 tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
 getIndex() const
 {
+   typedef tnlGrid< Dimensions, Real, Device, Index > GridType;
+   typedef typename GridType::template MeshEntity< EntityDimensions > EntityType;
    tnlAssert( this->entityIndex >= 0 &&
-              this-> entityIndex < grid.template getEntitiesCount< EntityDimensions >(),
+              this-> entityIndex < grid.template getEntitiesCount< EntityType >(),
               cerr << "this->entityIndex = " << this->entityIndex
-                   << " grid.template getEntitiesCount< EntityDimensions >() = " << grid.template getEntitiesCount< EntityDimensions >() );
+                   << " grid.template getEntitiesCount< EntityDimensions >() = " << grid.template getEntitiesCount< EntityType >() );
    tnlAssert( this->entityIndex == grid.getEntityIndex( *this ),
               cerr << "this->entityIndex = " << this->entityIndex
                    << " grid.getEntityIndex( *this ) = " << grid.getEntityIndex( *this ) );
@@ -253,6 +256,20 @@ getCenter() const
    return tnlGridEntityCenterGetter< ThisType >::getEntityCenter( *this );
 }
 
+template< int Dimensions,
+          typename Real,
+          typename Device,
+          typename Index,
+          int EntityDimensions,
+          typename Config >
+__cuda_callable__ inline
+const typename tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::RealType&
+tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
+getMeasure() const
+{
+   return tnlGridEntityMeasureGetter< GridType, EntityDimensions >::getMeasure( this->getMesh(), *this );
+}
+
 template< int Dimensions,
           typename Real,
           typename Device,
@@ -262,7 +279,7 @@ template< int Dimensions,
 __cuda_callable__ inline
 const typename tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::GridType&
 tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, EntityDimensions, Config >::
-getGrid() const
+getMesh() const
 {
    return this->grid;
 }
@@ -456,6 +473,20 @@ getCenter() const
    return tnlGridEntityCenterGetter< ThisType >::getEntityCenter( *this );
 }
 
+template< int Dimensions,
+          typename Real,
+          typename Device,
+          typename Index,
+          typename Config >
+__cuda_callable__ inline
+const typename tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, Dimensions, Config >::RealType&
+tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, Dimensions, Config >::
+getMeasure() const
+{
+   return this->getMesh().getCellMeasure();
+}
+
+
 template< int Dimensions,
           typename Real,
           typename Device,
@@ -477,7 +508,7 @@ template< int Dimensions,
 __cuda_callable__ inline
 const typename tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, Dimensions, Config >::GridType&
 tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, Dimensions, Config >::
-getGrid() const
+getMesh() const
 {
    return this->grid;
 }
@@ -486,16 +517,6 @@ getGrid() const
 /****
  * Specialization for vertices
  */
-/*template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index >
-__cuda_callable__ inline
-tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0 >::
-tnlGridEntity()
-{
-}*/
-
 template< int Dimensions,
           typename Real,
           typename Device,
@@ -594,10 +615,12 @@ Index
 tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >::
 getIndex() const
 {
+   typedef tnlGrid< Dimensions, Real, Device, Index > GridType;
+   typedef typename GridType::Vertex Vertex;
    tnlAssert( this->entityIndex >= 0 &&
-              this-> entityIndex < grid.template getEntitiesCount< 0 >(),
+              this-> entityIndex < grid.template getEntitiesCount< Vertex >(),
               cerr << "this->entityIndex = " << this->entityIndex
-                   << " grid.template getEntitiesCount< 0 >() = " << grid.template getEntitiesCount< 0 >() );
+                   << " grid.template getEntitiesCount< 0 >() = " << grid.template getEntitiesCount< Vertex >() );
    tnlAssert( this->entityIndex == grid.getEntityIndex( *this ),
               cerr << "this->entityIndex = " << this->entityIndex
                    << " grid.getEntityIndex( *this ) = " << grid.getEntityIndex( *this ) );
@@ -670,6 +693,20 @@ getCenter() const
    return tnlGridEntityCenterGetter< ThisType >::getEntityCenter( *this );
 }
 
+template< int Dimensions,
+          typename Real,
+          typename Device,
+          typename Index,
+          typename Config >
+__cuda_callable__ inline
+const typename tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >::RealType
+tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >::
+getMeasure() const
+{
+   return 0.0;
+}
+
+
 template< int Dimensions,
           typename Real,
           typename Device,
@@ -691,9 +728,9 @@ template< int Dimensions,
 __cuda_callable__ inline
 const typename tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >::GridType&
 tnlGridEntity< tnlGrid< Dimensions, Real, Device, Index >, 0, Config >::
-getGrid() const
+getMesh() const
 {
-   return this->gridType;
+   return this->grid;
 }
 
 #endif	/* TNLGRIDENTITY_IMPL_H */
diff --git a/src/mesh/grids/tnlGridTraverser.h b/src/mesh/grids/tnlGridTraverser.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b05a88e4eeec5212c3b8a67f33c92f4372a0ca4
--- /dev/null
+++ b/src/mesh/grids/tnlGridTraverser.h
@@ -0,0 +1,223 @@
+/***************************************************************************
+                          tnlGridTraverser.h  -  description
+                             -------------------
+    begin                : Jan 2, 2016
+    copyright            : (C) 2016 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 TNLGRIDTRAVERSER_H
+#define	TNLGRIDTRAVERSER_H
+
+
+/****
+ * This is only a helper class for tnlTraverser specializations for tnlGrid.
+ */
+template< typename Grid >
+class tnlGridTraverser
+{   
+};
+
+/****
+ * 1D grid, tnlHost
+ */
+template< typename Real,           
+          typename Index >
+class tnlGridTraverser< tnlGrid< 1, Real, tnlHost, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 1, Real, tnlHost, Index > GridType;
+      typedef Real RealType;
+      typedef tnlHost DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+      
+      template<
+         typename GridEntity,
+         typename EntitiesProcessor,
+         typename UserData,
+         bool processOnlyBoundaryEntities >
+      static void
+      processEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         const CoordinatesType& entityOrientation,
+         const CoordinatesType& entityBasis,
+         UserData& userData );
+};
+
+/****
+ * 1D grid, tnlCuda
+ */
+template< typename Real,           
+          typename Index >
+class tnlGridTraverser< tnlGrid< 1, Real, tnlCuda, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 1, Real, tnlCuda, Index > GridType;
+      typedef Real RealType;
+      typedef tnlHost DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+      
+      template<
+         typename GridEntity,
+         typename EntitiesProcessor,
+         typename UserData,
+         bool processOnlyBoundaryEntities  >
+      static void
+      processEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         const CoordinatesType& entityOrientation,
+         const CoordinatesType& entityBasis,         
+         UserData& userData );
+};
+
+/****
+ * 2D grid, tnlHost
+ */
+template< typename Real,           
+          typename Index >
+class tnlGridTraverser< tnlGrid< 2, Real, tnlHost, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, tnlHost, Index > GridType;
+      typedef Real RealType;
+      typedef tnlHost DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+      
+      template<
+         typename GridEntity,
+         typename EntitiesProcessor,
+         typename UserData,
+         bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary = 1,
+         int YOrthogonalBoundary = 1 >
+      static void
+      processEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         const CoordinatesType& entityOrientation,
+         const CoordinatesType& entityBasis,         
+         UserData& userData );
+};
+
+/****
+ * 2D grid, tnlCuda
+ */
+template< typename Real,           
+          typename Index >
+class tnlGridTraverser< tnlGrid< 2, Real, tnlCuda, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, tnlCuda, Index > GridType;
+      typedef Real RealType;
+      typedef tnlHost DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+      
+      template<
+         typename GridEntity,
+         typename EntitiesProcessor,
+         typename UserData,
+         bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary = 1,
+         int YOrthogonalBoundary = 1  >
+      static void
+      processEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         const CoordinatesType& entityOrientation,
+         const CoordinatesType& entityBasis,         
+         UserData& userData );
+};
+
+/****
+ * 3D grid, tnlHost
+ */
+template< typename Real,           
+          typename Index >
+class tnlGridTraverser< tnlGrid< 3, Real, tnlHost, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 3, Real, tnlHost, Index > GridType;
+      typedef Real RealType;
+      typedef tnlHost DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+      
+      template<
+         typename GridEntity,
+         typename EntitiesProcessor,
+         typename UserData,
+         bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary = 1,
+         int YOrthogonalBoundary = 1,
+         int ZOrthogonalBoundary = 1 >
+      static void
+      processEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         const CoordinatesType& entityOrientation,
+         const CoordinatesType& entityBasis,         
+         UserData& userData );
+};
+
+/****
+ * 3D grid, tnlCuda
+ */
+template< typename Real,           
+          typename Index >
+class tnlGridTraverser< tnlGrid< 3, Real, tnlCuda, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 3, Real, tnlCuda, Index > GridType;
+      typedef Real RealType;
+      typedef tnlHost DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+      
+      template<
+         typename GridEntity,
+         typename EntitiesProcessor,
+         typename UserData,
+         bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary = 1,
+         int YOrthogonalBoundary = 1,
+         int ZOrthogonalBoundary = 1 >
+      static void
+      processEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         const CoordinatesType& entityOrientation,
+         const CoordinatesType& entityBasis,         
+         UserData& userData );
+};
+
+#include <mesh/grids/tnlGridTraverser_impl.h>
+
+#endif	/* TNLGRIDTRAVERSER_H */
+
diff --git a/src/mesh/grids/tnlGridTraverser_impl.h b/src/mesh/grids/tnlGridTraverser_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..93a6fdac22bae92f285b42c94dd559ead740eb25
--- /dev/null
+++ b/src/mesh/grids/tnlGridTraverser_impl.h
@@ -0,0 +1,534 @@
+/***************************************************************************
+                          tnlGridTraverser_impl.h  -  description
+                             -------------------
+    begin                : Jan 2, 2016
+    copyright            : (C) 2016 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 TNLGRIDTRAVERSER_IMPL_H
+#define	TNLGRIDTRAVERSER_IMPL_H
+
+/****
+ * 1D traverser, host
+ */
+template< typename Real,           
+          typename Index >      
+   template<
+      typename GridEntity,
+      typename EntitiesProcessor,
+      typename UserData,
+      bool processOnlyBoundaryEntities >
+void
+tnlGridTraverser< tnlGrid< 1, Real, tnlHost, Index > >::
+processEntities(
+   const GridType& grid,
+   const CoordinatesType& begin,
+   const CoordinatesType& end,
+   const CoordinatesType& entityOrientation,
+   const CoordinatesType& entityBasis,   
+   UserData& userData )
+{
+   GridEntity entity( grid );
+   entity.setOrientation( entityOrientation );
+   entity.setBasis( entityBasis );
+   
+   if( processOnlyBoundaryEntities )
+   {
+      entity.getCoordinates() = begin;
+      entity.refresh();
+      EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+      entity.getCoordinates() = end;
+      entity.refresh();
+      EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+   }
+   else
+   {
+      for( entity.getCoordinates().x() = begin.x();
+           entity.getCoordinates().x() <= end.x();
+           entity.getCoordinates().x() ++ )
+      {
+         entity.refresh();
+         EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+      }
+   }
+}
+
+/****
+ * 1D traverser, CUDA
+ */
+#ifdef HAVE_CUDA
+template< typename Real,
+          typename Index,
+          typename GridEntity,
+          typename UserData,
+          typename EntitiesProcessor,
+          bool processOnlyBoundaryEntities >
+__global__ void 
+tnlGridTraverser1D(
+   const tnlGrid< 1, Real, tnlCuda, Index >* grid,
+   UserData* userData,
+   const typename GridEntity::CoordinatesType* begin,
+   const typename GridEntity::CoordinatesType* end,
+   const typename GridEntity::CoordinatesType* entityOrientation,
+   const typename GridEntity::CoordinatesType* entityBasis,   
+   const Index gridIdx )
+{
+   typedef Real RealType;
+   typedef Index IndexType;
+   typedef tnlGrid< 1, Real, tnlCuda, Index > GridType;
+   typename GridType::CoordinatesType coordinates;
+   
+   coordinates.x() = begin->x() + ( gridIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
+   
+   GridEntity entity( *grid, coordinates, *entityOrientation, *entityBasis );
+   
+   if( coordinates.x() <= end->x() )
+   {
+      if( ! processOnlyBoundaryEntities || entity.isBoundaryEntity() )
+      {
+         entity.refresh();
+         EntitiesProcessor::processEntity( entity.getMesh(), *userData, entity );
+      }
+   }
+}
+#endif
+
+template< typename Real,           
+          typename Index >      
+   template<
+      typename GridEntity,
+      typename EntitiesProcessor,
+      typename UserData,
+      bool processOnlyBoundaryEntities >
+void
+tnlGridTraverser< tnlGrid< 1, Real, tnlCuda, Index > >::
+processEntities(
+   const GridType& grid,
+   const CoordinatesType& begin,
+   const CoordinatesType& end,
+   const CoordinatesType& entityOrientation,
+   const CoordinatesType& entityBasis,   
+   UserData& userData )
+{
+#ifdef HAVE_CUDA   
+   CoordinatesType* kernelBegin = tnlCuda::passToDevice( begin );
+   CoordinatesType* kernelEnd = tnlCuda::passToDevice( end );
+   CoordinatesType* kernelEntityOrientation = tnlCuda::passToDevice( entityOrientation );
+   CoordinatesType* kernelEntityBasis = tnlCuda::passToDevice( entityBasis );
+   typename GridEntity::MeshType* kernelGrid = tnlCuda::passToDevice( grid );
+   UserData* kernelUserData = tnlCuda::passToDevice( userData );
+      
+   dim3 cudaBlockSize( 256 );
+   dim3 cudaBlocks;
+   cudaBlocks.x = tnlCuda::getNumberOfBlocks( end.x() - begin.x() + 1, cudaBlockSize.x );
+   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
+
+   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
+      tnlGridTraverser1D< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities >
+         <<< cudaBlocks, cudaBlockSize >>>
+         ( kernelGrid,
+           kernelUserData,
+           kernelBegin,
+           kernelEnd,
+           kernelEntityOrientation,
+           kernelEntityBasis,
+           gridXIdx );
+   cudaThreadSynchronize();
+   checkCudaDevice;
+   tnlCuda::freeFromDevice( kernelGrid );
+   tnlCuda::freeFromDevice( kernelBegin );
+   tnlCuda::freeFromDevice( kernelEnd );
+   tnlCuda::freeFromDevice( kernelEntityOrientation );
+   tnlCuda::freeFromDevice( kernelEntityBasis );
+   tnlCuda::freeFromDevice( kernelUserData );
+   checkCudaDevice;
+#endif
+}
+
+
+/****
+ * 2D traverser, host
+ */
+template< typename Real,           
+          typename Index >      
+   template<
+      typename GridEntity,
+      typename EntitiesProcessor,
+      typename UserData,
+      bool processOnlyBoundaryEntities,
+      int XOrthogonalBoundary,
+      int YOrthogonalBoundary >
+void
+tnlGridTraverser< tnlGrid< 2, Real, tnlHost, Index > >::
+processEntities(
+   const GridType& grid,
+   const CoordinatesType& begin,
+   const CoordinatesType& end,
+   const CoordinatesType& entityOrientation,
+   const CoordinatesType& entityBasis,      
+   UserData& userData )
+{
+   GridEntity entity( grid );
+   entity.setOrientation( entityOrientation );
+   entity.setBasis( entityBasis );
+
+   if( processOnlyBoundaryEntities )
+   {
+      if( YOrthogonalBoundary )
+         for( entity.getCoordinates().x() = begin.x();
+              entity.getCoordinates().x() <= end.x();
+              entity.getCoordinates().x() ++ )
+         {
+            entity.getCoordinates().y() = begin.y();
+            entity.refresh();
+            EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+            entity.getCoordinates().y() = end.y();
+            entity.refresh();
+            EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+         }
+      if( XOrthogonalBoundary )
+         for( entity.getCoordinates().y() = begin.y();
+              entity.getCoordinates().y() <= end.y();
+              entity.getCoordinates().y() ++ )
+         {
+            entity.getCoordinates().x() = begin.x();
+            entity.refresh();
+            EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+            entity.getCoordinates().x() = end.x();
+            entity.refresh();
+            EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+         }
+   }
+   else
+   {
+      for( entity.getCoordinates().y() = begin.y();
+           entity.getCoordinates().y() <= end.y();
+           entity.getCoordinates().y() ++ )
+         for( entity.getCoordinates().x() = begin.x();
+              entity.getCoordinates().x() <= end.x();
+              entity.getCoordinates().x() ++ )
+         {
+            entity.refresh();
+            EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+         }
+   }
+}
+
+/****
+ * 2D traverser, CUDA
+ */
+#ifdef HAVE_CUDA
+template< typename Real,
+          typename Index,
+          typename GridEntity,
+          typename UserData,
+          typename EntitiesProcessor,
+          bool processOnlyBoundaryEntities >
+__global__ void 
+tnlGridTraverser2D(
+   const tnlGrid< 2, Real, tnlCuda, Index >* grid,
+   UserData* userData,
+   const typename GridEntity::CoordinatesType* begin,
+   const typename GridEntity::CoordinatesType* end,
+   const typename GridEntity::CoordinatesType* entityOrientation,
+   const typename GridEntity::CoordinatesType* entityBasis,   
+   const Index gridXIdx,
+   const Index gridYIdx )
+{
+   typedef tnlGrid< 2, Real, tnlCuda, Index > GridType;
+   typename GridType::CoordinatesType coordinates;
+
+   coordinates.x() = begin->x() + ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
+   coordinates.y() = begin->y() + ( gridYIdx * tnlCuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;  
+   
+   GridEntity entity( *grid, coordinates, *entityOrientation, *entityBasis );
+
+   if( entity.getCoordinates().x() <= end->x() &&
+       entity.getCoordinates().y() <= end->y() )
+   {
+      entity.refresh();
+      if( ! processOnlyBoundaryEntities || entity.isBoundaryEntity() )
+      {         
+         EntitiesProcessor::processEntity
+         ( *grid,
+           *userData,
+           entity );
+      }
+   }
+}
+#endif
+
+template< typename Real,           
+          typename Index >      
+   template<
+      typename GridEntity,
+      typename EntitiesProcessor,
+      typename UserData,
+      bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary,
+         int YOrthogonalBoundary >
+void
+tnlGridTraverser< tnlGrid< 2, Real, tnlCuda, Index > >::
+processEntities(
+   const GridType& grid,
+   const CoordinatesType& begin,
+   const CoordinatesType& end,
+   const CoordinatesType& entityOrientation,
+   const CoordinatesType& entityBasis,
+   UserData& userData )
+{
+#ifdef HAVE_CUDA   
+   CoordinatesType* kernelBegin = tnlCuda::passToDevice( begin );
+   CoordinatesType* kernelEnd = tnlCuda::passToDevice( end );
+   CoordinatesType* kernelEntityOrientation = tnlCuda::passToDevice( entityOrientation );
+   CoordinatesType* kernelEntityBasis = tnlCuda::passToDevice( entityBasis );
+   typename GridEntity::MeshType* kernelGrid = tnlCuda::passToDevice( grid );
+   UserData* kernelUserData = tnlCuda::passToDevice( userData );
+      
+   dim3 cudaBlockSize( 16, 16 );
+   dim3 cudaBlocks;
+   cudaBlocks.x = tnlCuda::getNumberOfBlocks( end.x() - begin.x() + 1, cudaBlockSize.x );
+   cudaBlocks.y = tnlCuda::getNumberOfBlocks( end.y() - begin.y() + 1, cudaBlockSize.y );
+   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
+   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
+
+   for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
+      for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
+         tnlGridTraverser2D< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities >
+            <<< cudaBlocks, cudaBlockSize >>>
+            ( kernelGrid,
+              kernelUserData,
+              kernelBegin,
+              kernelEnd,
+              kernelEntityOrientation,
+              kernelEntityBasis,
+              gridXIdx,
+              gridYIdx );
+   cudaThreadSynchronize();
+   checkCudaDevice;   
+   tnlCuda::freeFromDevice( kernelGrid );
+   tnlCuda::freeFromDevice( kernelBegin );
+   tnlCuda::freeFromDevice( kernelEnd );
+   tnlCuda::freeFromDevice( kernelEntityOrientation );
+   tnlCuda::freeFromDevice( kernelEntityBasis );
+   tnlCuda::freeFromDevice( kernelUserData );
+   checkCudaDevice;
+#endif
+}
+
+/****
+ * 3D traverser, host
+ */
+template< typename Real,           
+          typename Index >      
+   template<
+      typename GridEntity,
+      typename EntitiesProcessor,
+      typename UserData,
+      bool processOnlyBoundaryEntities,
+      int XOrthogonalBoundary,
+      int YOrthogonalBoundary,
+      int ZOrthogonalBoundary >
+void
+tnlGridTraverser< tnlGrid< 3, Real, tnlHost, Index > >::
+processEntities(
+   const GridType& grid,
+   const CoordinatesType& begin,
+   const CoordinatesType& end,
+   const CoordinatesType& entityOrientation,
+   const CoordinatesType& entityBasis,      
+   UserData& userData )
+{
+   GridEntity entity( grid );
+   entity.setOrientation( entityOrientation );
+   entity.setBasis( entityBasis );
+
+   if( processOnlyBoundaryEntities )
+   {
+      if( ZOrthogonalBoundary )
+         for( entity.getCoordinates().y() = begin.y();
+              entity.getCoordinates().y() <= end.y();
+              entity.getCoordinates().y() ++ )
+            for( entity.getCoordinates().x() = begin.x();
+                 entity.getCoordinates().x() <= end.x();
+                 entity.getCoordinates().x() ++ )
+            {
+               entity.getCoordinates().z() = begin.z();
+               entity.refresh();
+               EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+               entity.getCoordinates().z() = end.z();
+               entity.refresh();
+               EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+            }
+      if( YOrthogonalBoundary )
+         for( entity.getCoordinates().z() = begin.z();
+                 entity.getCoordinates().z() <= end.z();
+                 entity.getCoordinates().z() ++ )
+            for( entity.getCoordinates().x() = begin.x();
+                 entity.getCoordinates().x() <= end.x();
+                 entity.getCoordinates().x() ++ )
+            {
+               entity.getCoordinates().y() = begin.y();
+               entity.refresh();
+               EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+               entity.getCoordinates().y() = end.y();
+               entity.refresh();
+               EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+            }
+      if( XOrthogonalBoundary )
+         for( entity.getCoordinates().z() = begin.z();
+              entity.getCoordinates().z() <= end.z();
+              entity.getCoordinates().z() ++ )
+            for( entity.getCoordinates().y() = begin.y();
+                 entity.getCoordinates().y() <= end.y();
+                 entity.getCoordinates().y() ++ )
+            {
+               entity.getCoordinates().x() = begin.x();
+               entity.refresh();
+               EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+               entity.getCoordinates().x() = end.x();
+               entity.refresh();
+               EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+            }
+   }
+   else
+   {
+      for( entity.getCoordinates().z() = begin.z();
+           entity.getCoordinates().z() <= end.z();
+           entity.getCoordinates().z() ++ )
+         for( entity.getCoordinates().y() = begin.y();
+              entity.getCoordinates().y() <= end.y();
+              entity.getCoordinates().y() ++ )
+            for( entity.getCoordinates().x() = begin.x();
+                 entity.getCoordinates().x() <= end.x();
+                 entity.getCoordinates().x() ++ )
+            {
+               entity.refresh();
+               EntitiesProcessor::processEntity( entity.getMesh(), userData, entity );
+            }
+   }
+}
+
+/****
+ * 3D traverser, CUDA
+ */
+#ifdef HAVE_CUDA
+template< typename Real,
+          typename Index,
+          typename GridEntity,
+          typename UserData,
+          typename EntitiesProcessor,
+          bool processOnlyBoundaryEntities >
+__global__ void 
+tnlGridTraverser3D(
+   const tnlGrid< 3, Real, tnlCuda, Index >* grid,
+   UserData* userData,
+   const typename GridEntity::CoordinatesType* begin,
+   const typename GridEntity::CoordinatesType* end,
+   const typename GridEntity::CoordinatesType* entityOrientation,
+   const typename GridEntity::CoordinatesType* entityBasis,   
+   const Index gridXIdx,
+   const Index gridYIdx,
+   const Index gridZIdx )
+{
+   typedef tnlGrid< 3, Real, tnlCuda, Index > GridType;
+   typename GridType::CoordinatesType coordinates;
+
+   coordinates.x() = begin->x() + ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
+   coordinates.y() = begin->y() + ( gridYIdx * tnlCuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;  
+   coordinates.z() = begin->z() + ( gridZIdx * tnlCuda::getMaxGridSize() + blockIdx.z ) * blockDim.z + threadIdx.z;  
+   
+   GridEntity entity( *grid, coordinates, *entityOrientation, *entityBasis );
+
+   if( entity.getCoordinates().x() <= end->x() &&
+       entity.getCoordinates().y() <= end->y() && 
+       entity.getCoordinates().z() <= end->z() )
+   {
+      entity.refresh();
+      if( ! processOnlyBoundaryEntities || entity.isBoundaryEntity() )
+      {         
+         EntitiesProcessor::processEntity
+         ( *grid,
+           *userData,
+           entity );
+      }
+   }
+}
+#endif
+
+template< typename Real,           
+          typename Index >      
+   template<
+      typename GridEntity,
+      typename EntitiesProcessor,
+      typename UserData,
+      bool processOnlyBoundaryEntities,
+         int XOrthogonalBoundary,
+         int YOrthogonalBoundary,
+         int ZOrthogonalBoundary >
+void
+tnlGridTraverser< tnlGrid< 3, Real, tnlCuda, Index > >::
+processEntities(
+   const GridType& grid,
+   const CoordinatesType& begin,
+   const CoordinatesType& end,
+   const CoordinatesType& entityOrientation,
+   const CoordinatesType& entityBasis,
+   UserData& userData )
+{
+#ifdef HAVE_CUDA   
+   CoordinatesType* kernelBegin = tnlCuda::passToDevice( begin );
+   CoordinatesType* kernelEnd = tnlCuda::passToDevice( end );
+   CoordinatesType* kernelEntityOrientation = tnlCuda::passToDevice( entityOrientation );
+   CoordinatesType* kernelEntityBasis = tnlCuda::passToDevice( entityBasis );
+   typename GridEntity::MeshType* kernelGrid = tnlCuda::passToDevice( grid );
+   UserData* kernelUserData = tnlCuda::passToDevice( userData );
+      
+   dim3 cudaBlockSize( 8, 8, 8 );
+   dim3 cudaBlocks;
+   cudaBlocks.x = tnlCuda::getNumberOfBlocks( end.x() - begin.x() + 1, cudaBlockSize.x );
+   cudaBlocks.y = tnlCuda::getNumberOfBlocks( end.y() - begin.y() + 1, cudaBlockSize.y );
+   cudaBlocks.z = tnlCuda::getNumberOfBlocks( end.z() - begin.z() + 1, cudaBlockSize.z );
+   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
+   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
+   const IndexType cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z );
+
+   for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
+      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
+         for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
+            tnlGridTraverser3D< Real, Index, GridEntity, UserData, EntitiesProcessor, processOnlyBoundaryEntities >
+               <<< cudaBlocks, cudaBlockSize >>>
+               ( kernelGrid,
+                 kernelUserData,
+                 kernelBegin,
+                 kernelEnd,
+                 kernelEntityOrientation,
+                 kernelEntityBasis,
+                 gridXIdx,
+                 gridYIdx,
+                 gridZIdx );
+   cudaThreadSynchronize();
+   checkCudaDevice;   
+   tnlCuda::freeFromDevice( kernelGrid );
+   tnlCuda::freeFromDevice( kernelBegin );
+   tnlCuda::freeFromDevice( kernelEnd );
+   tnlCuda::freeFromDevice( kernelEntityOrientation );
+   tnlCuda::freeFromDevice( kernelEntityBasis );
+   tnlCuda::freeFromDevice( kernelUserData );
+   checkCudaDevice;
+#endif
+}
+
+
+#endif	/* TNLGRIDTRAVERSER_IMPL_H */
+
diff --git a/src/mesh/grids/tnlNeighbourGridEntityGetter.h b/src/mesh/grids/tnlNeighbourGridEntityGetter.h
index 8a73e3d9dd0a90b9e402f80a4f4139c085155f68..95dc471d0605edf34cfb01cccf55f47b116c5c2c 100644
--- a/src/mesh/grids/tnlNeighbourGridEntityGetter.h
+++ b/src/mesh/grids/tnlNeighbourGridEntityGetter.h
@@ -48,14 +48,14 @@ class tnlNeighbourGridEntityGetter
       __cuda_callable__
       tnlNeighbourGridEntityGetter( const GridEntity& entity )
       {
-         tnlAssert( false, );
+         //tnlAssert( false, );
       };
       
       __cuda_callable__
       void refresh( const typename GridEntity::GridType& grid,
                     const typename GridEntity::IndexType& entityIndex )
       {
-         tnlAssert( false, );
+         //tnlAssert( false, );
       };
 
 };
diff --git a/src/mesh/grids/tnlNeighbourGridEntityGetter1D_impl.h b/src/mesh/grids/tnlNeighbourGridEntityGetter1D_impl.h
index 7c62d1598680d2f11a45a47d465df9bc902f11ca..858ca7d91a1ee88af78928d11c2f02665852e4a3 100644
--- a/src/mesh/grids/tnlNeighbourGridEntityGetter1D_impl.h
+++ b/src/mesh/grids/tnlNeighbourGridEntityGetter1D_impl.h
@@ -62,14 +62,14 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( this->entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    this->entity.getCoordinates() < this->entity.getGrid().getDimensions(),
+                    this->entity.getCoordinates() < this->entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << this->entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( step ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step ) );
       }
@@ -79,14 +79,14 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( step ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return this->entity.getIndex() + step;
       }
@@ -142,16 +142,16 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( this->entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    this->entity.getCoordinates() < this->entity.getGrid().getDimensions(),
+                    this->entity.getCoordinates() < this->entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << this->entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( step ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step ) );
+         return NeighbourGridEntityType( this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + step ) );
       }
       
       template< int step >
@@ -159,14 +159,14 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( step ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
 #ifndef HAVE_CUDA  // TODO: fix it -- does not work with nvcc
          if( step < -stencilSize || step > stencilSize )
@@ -243,14 +243,14 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates().x() + step <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates().x() + step <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step + ( step < 0 ) ) );
       }
@@ -260,14 +260,14 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         tnlAssert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates().x() + step <= entity.getGrid().getDimensions(),
+         tnlAssert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ).x() &&
+                    entity.getCoordinates().x() + step <= entity.getMesh().getDimensions().x(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return this->entity.getIndex() + step + ( step < 0 );
       }
@@ -290,6 +290,84 @@ class tnlNeighbourGridEntityGetter<
  * |       0         |              1            |       None        |
  * +-----------------+---------------------------+-------------------+
  */
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Config,
+          typename StencilStorage >
+class tnlNeighbourGridEntityGetter< 
+   tnlGridEntity< tnlGrid< 1, Real, Device, Index >, 0, Config >,
+   1,
+   StencilStorage > //tnlGridEntityStencilStorageTag< tnlGridEntityNoStencil > > 
+{
+   public:
+      
+      static const int EntityDimensions = 0;
+      static const int NeighbourEntityDimensions = 1;
+      typedef tnlGrid< 1, Real, Device, Index > GridType;
+      typedef tnlGridEntity< GridType, EntityDimensions, Config > GridEntityType;
+      typedef tnlGridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+      typedef tnlGridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetter;
+      
+      __cuda_callable__ inline
+      tnlNeighbourGridEntityGetter( const GridEntityType& entity )
+      : entity( entity )
+      {}
+      
+      void test() const { cerr << "***" << endl; };
+      
+      template< int step >
+      __cuda_callable__ inline
+      NeighbourGridEntityType getEntity() const
+      {
+         tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
+              cerr << "entity.getCoordinates() = " << entity.getCoordinates()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
+                   << " EntityDimensions = " << EntityDimensions );
+         tnlAssert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
+                    entity.getCoordinates().x() + step < entity.getMesh().getDimensions(),
+              cerr << "entity.getCoordinates() = " << entity.getCoordinates()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
+                   << " EntityDimensions = " << EntityDimensions );
+         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step - ( step > 0 ) ) );
+      }
+      
+      template< int step >
+      __cuda_callable__ inline
+      IndexType getEntityIndex() const
+      {
+         tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
+              cerr << "entity.getCoordinates() = " << entity.getCoordinates()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
+                   << " EntityDimensions = " << EntityDimensions );
+         tnlAssert( entity.getCoordinates().x() + step - ( step > 0 ) >= 0 &&
+                    entity.getCoordinates().x() + step - ( step > 0 ) < entity.getMesh().getDimensions().x(),
+              cerr << "entity.getCoordinates() = " << entity.getCoordinates()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
+                   << " EntityDimensions = " << EntityDimensions );
+         return this->entity.getIndex() + step - ( step > 0 );
+      }
+      
+      __cuda_callable__
+      void refresh( const GridType& grid, const IndexType& entityIndex ){};
+
+   protected:
+
+      const GridEntityType& entity;
+};
+
+/****   TODO: Implement this, now it is only a copy of specialization for none stencil storage
+ * +-----------------+---------------------------+-------------------+
+ * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |       
+ * +-----------------+---------------------------+-------------------+
+ * |       0         |              1            |       Cross       |
+ * +-----------------+---------------------------+-------------------+
+ */
 template< typename Real,
           typename Device,
           typename Index,
@@ -297,7 +375,7 @@ template< typename Real,
 class tnlNeighbourGridEntityGetter< 
    tnlGridEntity< tnlGrid< 1, Real, Device, Index >, 0, Config >,
    1,
-   tnlGridEntityStencilStorageTag< tnlGridEntityNoStencil > > 
+   tnlGridEntityStencilStorageTag< tnlGridEntityCrossStencil > > 
 {
    public:
       
@@ -322,14 +400,14 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates().x() + step < entity.getGrid().getDimensions(),
+                    entity.getCoordinates().x() + step < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step - ( step > 0 ) ) );
       }
@@ -339,14 +417,14 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates().x() + step < entity.getGrid().getDimensions(),
+                    entity.getCoordinates().x() + step < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return this->entity.getIndex() + step - ( step > 0 );
       }
@@ -357,11 +435,9 @@ class tnlNeighbourGridEntityGetter<
    protected:
 
       const GridEntityType& entity;
-      
-      //tnlNeighbourGridEntityGetter(){};
-      
 };
 
+
 /****
  * +-----------------+---------------------------+-------------------+
  * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |       
@@ -400,14 +476,14 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates().x() + step <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates().x() + step <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + step ) );
       }
@@ -417,14 +493,14 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates() <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) &&
-                    entity.getCoordinates().x() + step <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates().x() + step <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
 
          return this->entity.getIndex() + step;
@@ -437,8 +513,6 @@ class tnlNeighbourGridEntityGetter<
    protected:
 
       const GridEntityType& entity;
-      
-      //tnlNeighbourGridEntityGetter(){};      
 };
 
 
diff --git a/src/mesh/grids/tnlNeighbourGridEntityGetter2D_impl.h b/src/mesh/grids/tnlNeighbourGridEntityGetter2D_impl.h
index 1f1d327a7b4a771348c36b856749835a9a0ce4de..338c207b3b8bccc394e3f7ca2efa6eebbce1158f 100644
--- a/src/mesh/grids/tnlNeighbourGridEntityGetter2D_impl.h
+++ b/src/mesh/grids/tnlNeighbourGridEntityGetter2D_impl.h
@@ -62,14 +62,14 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntityType( this->grid,
                                          CoordinatesType( entity.getCoordinates().x() + stepX,
@@ -81,16 +81,16 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return this->entity.getIndex() + stepY * entity.getGrid().getDimensions().x() + stepX;
+         return this->entity.getIndex() + stepY * entity.getMesh().getDimensions().x() + stepX;
       }
       
       __cuda_callable__
@@ -146,16 +146,16 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-            return NeighbourGridEntityType( this->grid,
+            return NeighbourGridEntityType( this->entity.getMesh(),
                                             CoordinatesType( entity.getCoordinates().x() + stepX,
                                                              entity.getCoordinates().y() + stepY ) );
       }
@@ -165,25 +165,25 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
 #ifndef HAVE_CUDA // TODO: fix this to work with CUDA         
          if( ( stepX != 0 && stepY != 0 ) ||
              ( stepX < -stencilSize || stepX > stencilSize ||
                stepY < -stencilSize || stepY > stencilSize ) )         
-            return this->entity.getIndex() + stepY * entity.getGrid().getDimensions().x() + stepX;
+            return this->entity.getIndex() + stepY * entity.getMesh().getDimensions().x() + stepX;
          if( stepY == 0 )
             return stencilX[ stepX + stencilSize ];
          return stencilY[ stepY + stencilSize ];
 #else
-         return this->entity.getIndex() + stepY * entity.getGrid().getDimensions().x() + stepX;
+         return this->entity.getIndex() + stepY * entity.getMesh().getDimensions().x() + stepX;
 #endif         
          
       }
@@ -209,7 +209,7 @@ class tnlNeighbourGridEntityGetter<
             static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
             {
                neighbourEntityGetter.stencilY[ index + stencilSize ] = 
-                  entityIndex + index * neighbourEntityGetter.entity.getGrid().getDimensions().x();
+                  entityIndex + index * neighbourEntityGetter.entity.getMesh().getDimensions().x();
             }
       };
 
@@ -277,9 +277,9 @@ class tnlNeighbourGridEntityGetter<
          tnlAssert( ! stepX + ! stepY == 1,
                     cerr << "Only one of the steps can be non-zero: stepX = " << stepX << " stepY = " << stepY );
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + 
                        CoordinatesType( stepX + ( stepX < 0 ),
@@ -287,12 +287,12 @@ class tnlNeighbourGridEntityGetter<
                     entity.getCoordinates() + 
                        CoordinatesType( stepX + ( stepX < 0 ), 
                                         stepY + ( stepY < 0 ) ) 
-                       < entity.getGrid().getDimensions() + CoordinatesType( Sign( stepX ), Sign( stepY ) ),
+                       < entity.getMesh().getDimensions() + CoordinatesType( Sign( stepX ), Sign( stepY ) ),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->entity.getGrid(),
+         return NeighbourGridEntityType( this->entity.getMesh(),
                                          CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                           entity.getCoordinates().y() + stepY + ( stepY < 0 ) ),
                                          EntityOrientationType( stepX > 0 ? 1 : -1,
@@ -304,7 +304,7 @@ class tnlNeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         return GridEntityGetter::getEntityIndex( this->entity.getGrid(), this->template getEntity< stepX, stepY >() );
+         return GridEntityGetter::getEntityIndex( this->entity.getMesh(), this->template getEntity< stepX, stepY >() );
       }
       
       __cuda_callable__
@@ -313,8 +313,6 @@ class tnlNeighbourGridEntityGetter<
    protected:
 
       const GridEntityType& entity;
-      
-      //tnlNeighbourGridEntityGetter(){};      
 };
 
 /****
@@ -359,19 +357,19 @@ class tnlNeighbourGridEntityGetter<
          tnlAssert( stepX != 0 && stepY != 0,
                     cerr << " stepX = " << stepX << " stepY = " << stepY );
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + 
                        CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() + 
                        CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) 
-                       < entity.getGrid().getDimensions() + CoordinatesType( Sign( stepX ), Sign( stepY ) ),
+                       < entity.getMesh().getDimensions() + CoordinatesType( Sign( stepX ), Sign( stepY ) ),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) )
-                   << " entity.getGrid().getDimensions() + CoordinatesType( Sign( stepX ), Sign( stepY ) ) = " 
-                   << entity.getGrid().getDimensions()  + CoordinatesType( Sign( stepX ), Sign( stepY ) )
+                   << " entity.getMesh().getDimensions() + CoordinatesType( Sign( stepX ), Sign( stepY ) ) = " 
+                   << entity.getMesh().getDimensions()  + CoordinatesType( Sign( stepX ), Sign( stepY ) )
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntityType( this->grid,
                                          CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
@@ -382,7 +380,7 @@ class tnlNeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         return GridEntityGetter::getEntityIndex( this->entity.getGrid(), this->template getEntity< stepX, stepY >() );
+         return GridEntityGetter::getEntityIndex( this->entity.getMesh(), this->template getEntity< stepX, stepY >() );
       }
       
       __cuda_callable__
@@ -434,33 +432,35 @@ class tnlNeighbourGridEntityGetter<
       __cuda_callable__ inline
       NeighbourGridEntityType getEntity() const
       {
-         tnlAssert( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) &&
+         /*tnlAssert( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) &&
                     ( ( !! stepY ) == ( !! entity.getOrientation().y() ) ),
                     cerr << "( stepX, stepY ) cannot be perpendicular to entity coordinates: stepX = " << stepX << " stepY = " << stepY
-                         << " entity.getOrientation() = " << entity.getOrientation() );
+                         << " entity.getOrientation() = " << entity.getOrientation() );*/
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions() + entity.getOrientation(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions() + entity.getOrientation(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() + entity.getOrientation() = " << entity.getGrid().getDimensions() + entity.getOrientation()
+                   << " entity.getMesh().getDimensions() + entity.getOrientation() = " << entity.getMesh().getDimensions() + entity.getOrientation()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + 
-                       CoordinatesType( stepX - ( stepX > 0 ), stepY - ( stepY > 0 ) ) >= CoordinatesType( 0, 0 ) &&
+                       CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ), 
+                                        stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ) ) >= CoordinatesType( 0, 0 ) &&
                     entity.getCoordinates() + 
-                       CoordinatesType( stepX - ( stepX > 0 ), stepY - ( stepY > 0 ) ) < entity.getGrid().getDimensions(),
-              cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) = "
+                       CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ), 
+                                        stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ) ) < entity.getMesh().getDimensions(),
+              cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 )  * ( entity.getOrientation().x() != 0.0 ), stepY + ( stepY < 0 ) * ( entity.getOrientation().y() != 0.0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->entity.getGrid(),
-                                         CoordinatesType( entity.getCoordinates().x() + stepX - ( stepX > 0 ),
-                                                          entity.getCoordinates().y() + stepY - ( stepY > 0 ) ) );
+         return NeighbourGridEntityType( this->entity.getMesh(),
+                     CoordinatesType( entity.getCoordinates().x() + stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ),
+                                      entity.getCoordinates().y() + stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ) ) );
       }
       
       template< int stepX, int stepY >
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         return GridEntityGetter::getEntityIndex( this->entity.getGrid(), this->template getEntity< stepX, stepY >() );
+         return GridEntityGetter::getEntityIndex( this->entity.getMesh(), this->template getEntity< stepX, stepY >() );
       }
       
       __cuda_callable__
@@ -469,8 +469,6 @@ class tnlNeighbourGridEntityGetter<
    protected:
 
       const GridEntityType& entity;
-      
-      //tnlNeighbourGridEntityGetter(){};      
 };
 
 /****
@@ -512,14 +510,14 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntityType( this->grid,
                                          CoordinatesType( entity.getCoordinates().x() + stepX,
@@ -531,16 +529,16 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return this->entity.getIndex() + stepY * ( entity.getGrid().getDimensions().x() + 1 ) + stepX;
+         return this->entity.getIndex() + stepY * ( entity.getMesh().getDimensions().x() + 1 ) + stepX;
       }
       
       __cuda_callable__
diff --git a/src/mesh/grids/tnlNeighbourGridEntityGetter3D_impl.h b/src/mesh/grids/tnlNeighbourGridEntityGetter3D_impl.h
index fbf8ad91c284eed5aff18ca6eac8834164894155..a30fe9ee895838986533084b39bbd0ab79cca532 100644
--- a/src/mesh/grids/tnlNeighbourGridEntityGetter3D_impl.h
+++ b/src/mesh/grids/tnlNeighbourGridEntityGetter3D_impl.h
@@ -63,14 +63,14 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX,
                                                       entity.getCoordinates().y() + stepY,
@@ -82,17 +82,17 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ ) = " 
                    << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return this->entity.getIndex() + ( stepZ * entity.getGrid().getDimensions().y() + stepY ) * entity.getGrid().getDimensions().x() + stepX;
+         return this->entity.getIndex() + ( stepZ * entity.getMesh().getDimensions().y() + stepY ) * entity.getMesh().getDimensions().x() + stepX;
       }
       
       __cuda_callable__
@@ -149,16 +149,16 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getGrid().getDimensions(),
-              cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+         tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getMesh().getDimensions(),
+              cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY ) = " << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX,
+         return NeighbourGridEntityType( this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + stepX,
                                                       entity.getCoordinates().y() + stepY,
                                                       entity.getCoordinates().z() + stepZ ) );
       }
@@ -168,29 +168,29 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ ) = " 
                    << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
 #ifndef HAVE_CUDA // TODO: fix this to work with CUDA         
          if( ( stepX != 0 && stepY != 0 && stepZ != 0 ) ||
              ( stepX < -stencilSize || stepX > stencilSize ||
                stepY < -stencilSize || stepY > stencilSize ||
                stepZ < -stencilSize || stepZ > stencilSize ) )                  
-            return this->entity.getIndex() + ( stepZ * entity.getGrid().getDimensions().y() + stepY ) * entity.getGrid().getDimensions().x() + stepX;
+            return this->entity.getIndex() + ( stepZ * entity.getMesh().getDimensions().y() + stepY ) * entity.getMesh().getDimensions().x() + stepX;
          if( stepY == 0 && stepZ == 0 )
             return stencilX[ stepX + stencilSize ];
          if( stepZ == 0 )
             return stencilY[ stepY + stencilSize ];
          return stencilZ[ stepZ + stencilSize ];
 #else
-         return this->entity.getIndex() + ( stepZ * entity.getGrid().getDimensions().y() + stepY ) * entity.getGrid().getDimensions().x() + stepX;
+         return this->entity.getIndex() + ( stepZ * entity.getMesh().getDimensions().y() + stepY ) * entity.getMesh().getDimensions().x() + stepX;
 #endif         
 
       }
@@ -216,7 +216,7 @@ class tnlNeighbourGridEntityGetter<
             static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
             {
                neighbourEntityGetter.stencilY[ index + stencilSize ] = 
-                  entityIndex + index * neighbourEntityGetter.entity.getGrid().getDimensions().x();
+                  entityIndex + index * neighbourEntityGetter.entity.getMesh().getDimensions().x();
             }
       };
       
@@ -229,7 +229,7 @@ class tnlNeighbourGridEntityGetter<
             static void exec( ThisType& neighbourEntityGetter, const IndexType& entityIndex )
             {
                neighbourEntityGetter.stencilZ[ index + stencilSize ] = 
-                  entityIndex + index * neighbourEntityGetter.entity.getGrid().cellZNeighboursStep;
+                  entityIndex + index * neighbourEntityGetter.entity.getMesh().cellZNeighboursStep;
             }
       };
 
@@ -301,9 +301,98 @@ class tnlNeighbourGridEntityGetter<
                          << " stepY = " << stepY
                          << " stepZ = " << stepZ );
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
+              cerr << "entity.getCoordinates() = " << entity.getCoordinates()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
+                   << " EntityDimensions = " << EntityDimensions );
+         tnlAssert( entity.getCoordinates() + 
+                       CoordinatesType( stepX + ( stepX < 0 ), 
+                                        stepY + ( stepY < 0 ),
+                                        stepZ + ( stepZ < 0 ) ) >= CoordinatesType( 0, 0, 0 ) &&
+                    entity.getCoordinates() + 
+                       CoordinatesType( stepX + ( stepX < 0 ),
+                                        stepY + ( stepY < 0 ),
+                                        stepZ + ( stepZ < 0 ) ) 
+                       < entity.getMesh().getDimensions() + 
+                        CoordinatesType( Sign( stepX ), Sign( stepY ), Sign(  stepZ ) ),
+              cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) = "
+                   << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) )
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
+                   << " EntityDimensions = " << EntityDimensions );
+         return NeighbourGridEntityType( this->entity.getMesh(),
+                                         CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
+                                                          entity.getCoordinates().y() + stepY + ( stepY < 0 ),
+                                                          entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ),
+                                         EntityOrientationType( stepX > 0 ? 1 : -1,
+                                                                stepY > 0 ? 1 : -1,
+                                                                stepZ > 0 ? 1 : -1 ),
+                                         EntityBasisType( ! stepX, !stepY, !stepZ ) );
+      }
+      
+      template< int stepX, int stepY, int stepZ >
+      __cuda_callable__ inline
+      IndexType getEntityIndex() const
+      {
+         return GridEntityGetter::getEntityIndex( this->entity.getMesh(), getEntity< stepX, stepY, stepZ >() );
+      }
+      
+      __cuda_callable__
+      void refresh( const GridType& grid, const IndexType& entityIndex ){};
+      
+   protected:
+
+      const GridEntityType& entity;
+      
+      //tnlNeighbourGridEntityGetter(){};            
+};
+
+/****      TODO: Finish it, knonw it is only a copy of specialization for none stored stencil
+ * +-----------------+---------------------------+-------------------+
+ * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |       
+ * +-----------------+---------------------------+-------------------+
+ * |       3         |              2            |       Cross       |
+ * +-----------------+---------------------------+-------------------+
+ */
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename Config >
+class tnlNeighbourGridEntityGetter< 
+   tnlGridEntity< tnlGrid< 3, Real, Device, Index >, 3, Config >,
+   2,
+   tnlGridEntityStencilStorageTag< tnlGridEntityCrossStencil > >
+{
+   public:
+      
+      static const int EntityDimensions = 3;
+      static const int NeighbourEntityDimensions = 2;
+      typedef tnlGrid< 3, Real, Device, Index > GridType;
+      typedef tnlGridEntity< GridType, EntityDimensions, Config > GridEntityType;
+      typedef tnlGridEntity< GridType, NeighbourEntityDimensions, Config > NeighbourGridEntityType;
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+      typedef tnlGridEntityGetter< GridType, NeighbourGridEntityType > GridEntityGetter;
+      typedef typename GridEntityType::EntityOrientationType EntityOrientationType;
+      typedef typename GridEntityType::EntityBasisType EntityBasisType;
+
+      __cuda_callable__ inline
+      tnlNeighbourGridEntityGetter( const GridEntityType& entity )
+      : entity( entity )
+      {}
+      
+      template< int stepX, int stepY, int stepZ >
+      __cuda_callable__ inline
+      NeighbourGridEntityType getEntity() const
+      {
+         tnlAssert( ! stepX + ! stepY + ! stepZ == 2,
+                    cerr << "Only one of the steps can be non-zero: stepX = " << stepX 
+                         << " stepY = " << stepY
+                         << " stepZ = " << stepZ );
+         tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + 
                        CoordinatesType( stepX + ( stepX < 0 ), 
@@ -313,13 +402,13 @@ class tnlNeighbourGridEntityGetter<
                        CoordinatesType( stepX + ( stepX < 0 ),
                                         stepY + ( stepY < 0 ),
                                         stepZ + ( stepZ < 0 ) ) 
-                       < entity.getGrid().getDimensions() + 
+                       < entity.getMesh().getDimensions() + 
                         CoordinatesType( Sign( stepX ), Sign( stepY ), Sign(  stepZ ) ),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( this->entity.getGrid(),
+         return NeighbourGridEntityType( this->entity.getMesh(),
                                          CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                           entity.getCoordinates().y() + stepY + ( stepY < 0 ),
                                                           entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ),
@@ -333,7 +422,7 @@ class tnlNeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         return GridEntityGetter::getEntityIndex( this->entity.getGrid(), getEntity< stepX, stepY, stepZ >() );
+         return GridEntityGetter::getEntityIndex( this->entity.getMesh(), getEntity< stepX, stepY, stepZ >() );
       }
       
       __cuda_callable__
@@ -346,6 +435,7 @@ class tnlNeighbourGridEntityGetter<
       //tnlNeighbourGridEntityGetter(){};            
 };
 
+
 /****
  * +-----------------+---------------------------+-------------------+
  * | EntityDimenions | NeighbourEntityDimensions |  Stored Stencil   |       
@@ -390,9 +480,9 @@ class tnlNeighbourGridEntityGetter<
                          << " stepY = " << stepY
                          << " stepZ = " << stepZ );
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + 
                        CoordinatesType( stepX + ( stepX < 0 ), 
@@ -402,11 +492,11 @@ class tnlNeighbourGridEntityGetter<
                        CoordinatesType( stepX + ( stepX < 0 ),
                                         stepY + ( stepY < 0 ),
                                         stepZ + ( stepZ < 0 ) ) 
-                       < entity.getGrid().getDimensions() + 
+                       < entity.getMesh().getDimensions() + 
                         CoordinatesType( Sign( stepX ), Sign( stepY ), Sign(  stepZ ) ),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                       entity.getCoordinates().y() + stepY + ( stepY < 0 ),
@@ -419,7 +509,7 @@ class tnlNeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         return GridEntityGetter::getEntityIndex( this->entity.getGrid(), getEntity< stepX, stepY, stepZ >( entity ) );
+         return GridEntityGetter::getEntityIndex( this->entity.getMesh(), getEntity< stepX, stepY, stepZ >( entity ) );
       }
       
       __cuda_callable__
@@ -476,9 +566,9 @@ class tnlNeighbourGridEntityGetter<
                          << " stepY = " << stepY
                          << " stepZ = " << stepZ );
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + 
                        CoordinatesType( stepX + ( stepX < 0 ),
@@ -488,12 +578,12 @@ class tnlNeighbourGridEntityGetter<
                        CoordinatesType( stepX + ( stepX < 0 ),
                                         stepY + ( stepY < 0 ),
                                         stepZ + ( stepZ < 0 ) ) 
-                       < entity.getGrid().getDimensions() + 
+                       < entity.getMesh().getDimensions() + 
                             CoordinatesType( Sign( stepX ), Sign( stepY ), Sign( stepZ ) ),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 )  ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) )
-                   << " entity.getGrid().getDimensions() + CoordinatesType( Sign( stepX ), Sign( stepY ), Sign( stepZ ) ) = " 
-                   << entity.getGrid().getDimensions()  + CoordinatesType( Sign( stepX ), Sign( stepY ), Sign( stepZ ) )
+                   << " entity.getMesh().getDimensions() + CoordinatesType( Sign( stepX ), Sign( stepY ), Sign( stepZ ) ) = " 
+                   << entity.getMesh().getDimensions()  + CoordinatesType( Sign( stepX ), Sign( stepY ), Sign( stepZ ) )
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ),
                                                       entity.getCoordinates().y() + stepY + ( stepY < 0 ),
@@ -504,7 +594,7 @@ class tnlNeighbourGridEntityGetter<
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         return GridEntityGetter::getEntityIndex( entity.getGrid(), getEntity< stepX, stepY, stepZ >( entity ) );
+         return GridEntityGetter::getEntityIndex( entity.getMesh(), getEntity< stepX, stepY, stepZ >( entity ) );
       }
       
       __cuda_callable__
@@ -555,40 +645,43 @@ class tnlNeighbourGridEntityGetter<
       __cuda_callable__ inline
       NeighbourGridEntityType getEntity() const
       {
-         tnlAssert( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) &&
+         /*tnlAssert( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) &&
                     ( ( !! stepY ) == ( !! entity.getOrientation().y() ) ) &&
                     ( ( !! stepZ ) == ( !! entity.getOrientation().z() ) ),
                     cerr << "( stepX, stepY, stepZ ) cannot be perpendicular to entity coordinates: stepX = " << stepX
                          << " stepY = " << stepY << " stepZ = " << stepZ
-                         << " entity.getOrientation() = " << entity.getOrientation() );
+                         << " entity.getOrientation() = " << entity.getOrientation() );*/
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() < entity.getGrid().getDimensions() + entity.getOrientation(),
+                    entity.getCoordinates() < entity.getMesh().getDimensions() + entity.getOrientation(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() + entity.getOrientation() = " << entity.getGrid().getDimensions() + entity.getOrientation()
+                   << " entity.getMesh().getDimensions() + entity.getOrientation() = " << entity.getMesh().getDimensions() + entity.getOrientation()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + 
-                       CoordinatesType( stepX - ( stepX > 0 ),
-                                        stepY - ( stepY > 0 ),
-                                        stepZ - ( stepZ > 0 ) ) >= CoordinatesType( 0, 0, 0 ) &&
+                       CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ),
+                                        stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ),
+                                        stepZ - ( stepZ > 0 ) * ( entity.getOrientation().z() != 0.0 ) ) >= CoordinatesType( 0, 0, 0 ) &&
                     entity.getCoordinates() + 
-                       CoordinatesType( stepX - ( stepX > 0 ),
-                                        stepY - ( stepY > 0 ),
-                                        stepZ - ( stepZ > 0 ) ) < entity.getGrid().getDimensions(),
-              cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) = "
-                   << entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                       CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ),
+                                        stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ),
+                                        stepZ - ( stepZ > 0 ) * ( entity.getOrientation().z() != 0.0 ) ) < entity.getMesh().getDimensions(),
+              cerr << "entity.getCoordinates()  + CoordinatesType( stepX + ( stepX < 0 ) * ( entity.getOrientation().x() != 0.0 ), stepY + ( stepY < 0 ) * ( entity.getOrientation().y() != 0.0 ), stepZ + ( stepZ < 0 ) * ( entity.getOrientation().z() != 0.0 ) ) = "
+                   << entity.getCoordinates()  + CoordinatesType( 
+                        stepX + ( stepX < 0 ) * ( entity.getOrientation().x() != 0.0 ),
+                        stepY + ( stepY < 0 ) * ( entity.getOrientation().y() != 0.0 ),
+                        stepZ + ( stepZ < 0 ) * ( entity.getOrientation().z() != 0.0 ) )
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return NeighbourGridEntityType( entity.getGrid(),
-                                         CoordinatesType( entity.getCoordinates().x() + stepX - ( stepX > 0 ),
-                                                          entity.getCoordinates().y() + stepY - ( stepY > 0 ),
-                                                          entity.getCoordinates().z() + stepZ - ( stepZ > 0 ) ) );
+         return NeighbourGridEntityType( entity.getMesh(),
+                                         CoordinatesType( entity.getCoordinates().x() + stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ),
+                                                          entity.getCoordinates().y() + stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ),
+                                                          entity.getCoordinates().z() + stepZ - ( stepZ > 0 ) * ( entity.getOrientation().z() != 0.0 ) ) );
       }
       
       template< int stepX, int stepY, int stepZ >
       __cuda_callable__ inline
       IndexType getEntityIndex() const
       {
-         return GridEntityGetter::getEntityIndex( entity.getGrid(), getEntity< stepX, stepY, stepZ >() );
+         return GridEntityGetter::getEntityIndex( entity.getMesh(), getEntity< stepX, stepY, stepZ >() );
       }
       
       __cuda_callable__
@@ -639,15 +732,15 @@ class tnlNeighbourGridEntityGetter<
       NeighbourGridEntityType getEntity() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ ) = " 
                    << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          return NeighbourGridEntity( CoordinatesType( entity.getCoordinates().x() + stepX,
                                                       entity.getCoordinates().y() + stepY,
@@ -659,17 +752,17 @@ class tnlNeighbourGridEntityGetter<
       IndexType getEntityIndex() const
       {
          tnlAssert( entity.getCoordinates() >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates() = " << entity.getCoordinates()
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
          tnlAssert( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) &&
-                    entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) <= entity.getGrid().getDimensions(),
+                    entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) <= entity.getMesh().getDimensions(),
               cerr << "entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ ) = "
                    << entity.getCoordinates()  + CoordinatesType( stepX, stepY, stepZ )
-                   << " entity.getGrid().getDimensions() = " << entity.getGrid().getDimensions()
+                   << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions()
                    << " EntityDimensions = " << EntityDimensions );
-         return this->entity.getIndex() + stepZ * ( entity.getGrid().getDimensions().y() + 1 + stepY ) * ( entity.getGrid().getDimensions().x() + 1 ) + stepX;
+         return this->entity.getIndex() + stepZ * ( entity.getMesh().getDimensions().y() + 1 + stepY ) * ( entity.getMesh().getDimensions().x() + 1 ) + stepX;
       }
       
       __cuda_callable__
diff --git a/src/mesh/grids/tnlTraverser_Grid1D.h b/src/mesh/grids/tnlTraverser_Grid1D.h
index 83b0dcec3eec6a14af435776ff3747b4d96fb331..f4036af9985ff155f39bf57121886bc4bcfcb363 100644
--- a/src/mesh/grids/tnlTraverser_Grid1D.h
+++ b/src/mesh/grids/tnlTraverser_Grid1D.h
@@ -21,14 +21,15 @@
 #include <mesh/tnlTraverser.h>
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
-class tnlTraverser< tnlGrid< 1, Real, tnlHost, Index >, GridEntity, 1 >
+class tnlTraverser< tnlGrid< 1, Real, Device, Index >, GridEntity, 1 >
 {
    public:
-      typedef tnlGrid< 1, Real, tnlHost, Index > GridType;
+      typedef tnlGrid< 1, Real, Device, Index > GridType;
       typedef Real RealType;
-      typedef tnlHost DeviceType;
+      typedef Device DeviceType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
@@ -41,19 +42,25 @@ class tnlTraverser< tnlGrid< 1, Real, tnlHost, Index >, GridEntity, 1 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
-
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
 };
 
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
-class tnlTraverser< tnlGrid< 1, Real, tnlHost, Index >, GridEntity, 0 >
+class tnlTraverser< tnlGrid< 1, Real, Device, Index >, GridEntity, 0 >
 {
    public:
-      typedef tnlGrid< 1, Real, tnlHost, Index > GridType;
+      typedef tnlGrid< 1, Real, Device, Index > GridType;
       typedef Real RealType;
-      typedef tnlHost DeviceType;
+      typedef Device DeviceType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
@@ -66,8 +73,15 @@ class tnlTraverser< tnlGrid< 1, Real, tnlHost, Index >, GridEntity, 0 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
 };
 
+#ifdef UNDEF
+
 /****
  * CUDA traversals
  */
@@ -93,6 +107,24 @@ class tnlTraverser< tnlGrid< 1, Real, tnlCuda, Index >, GridEntity, 1 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;
+      
+
 
 };
 
@@ -118,9 +150,26 @@ class tnlTraverser< tnlGrid< 1, Real, tnlCuda, Index >, GridEntity, 0 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
 
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;      
 };
 
+#endif
+
 #include <mesh/grids/tnlTraverser_Grid1D_impl.h>
 
 #endif /* TNLTRAVERSER_GRID1D_H_ */
diff --git a/src/mesh/grids/tnlTraverser_Grid1D_impl.h b/src/mesh/grids/tnlTraverser_Grid1D_impl.h
index 44c0c32a4ca5957b3bfd3d252ab86e31a935ba74..3dc0a5168cafe4a1c3fbda90adf7c8690db37c80 100644
--- a/src/mesh/grids/tnlTraverser_Grid1D_impl.h
+++ b/src/mesh/grids/tnlTraverser_Grid1D_impl.h
@@ -18,334 +18,165 @@
 #ifndef TNLTRAVERSER_GRID1D_IMPL_H_
 #define TNLTRAVERSER_GRID1D_IMPL_H_
 
+#include <mesh/grids/tnlGridTraverser.h>
+
+
+/****
+ * Grid 1D, cells
+ */
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 1, Real, tnlHost, Index >, GridEntity, 1 >::
+tnlTraverser< tnlGrid< 1, Real, Device, Index >, GridEntity, 1 >::
 processBoundaryEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
     * Boundary cells
     */
-   const int CellDimensions = GridType::meshDimensions;
-   typename GridType::template GridEntity< CellDimensions > entity( grid );
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-   const IndexType& xSize = grid.getDimensions().x();   
-   coordinates.x() = 0;
-   entity.refresh();
-   EntitiesProcessor::processEntity( grid, userData, entity );
-   coordinates.x() = xSize - 1;
-   entity.refresh();
-   EntitiesProcessor::processEntity( grid, userData, entity );
+   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true >(
+      grid,
+      CoordinatesType( 0 ),
+      grid.getDimensions() - CoordinatesType( 1 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 1, Real, tnlHost, Index >, GridEntity, 1 >::
+tnlTraverser< tnlGrid< 1, Real, Device, Index >, GridEntity, 1 >::
 processInteriorEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
     * Interior cells
     */
-   const int CellDimensions = GridType::meshDimensions;
-   typename GridType::template GridEntity< CellDimensions > cell( grid );
-
-   const IndexType& xSize = grid.getDimensions().x();
-   for( cell.getCoordinates().x() = 1;
-        cell.getCoordinates().x() < xSize - 1;
-        cell.getCoordinates().x()++ )
-   {
-      cell.refresh();
-      EntitiesProcessor::processEntity( grid, userData, cell );
-   }
+   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1 ),
+      grid.getDimensions() - CoordinatesType( 2 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 1, Real, tnlHost, Index >, GridEntity, 0 >::
-processBoundaryEntities( const GridType& grid,
-                         UserData& userData ) const
+tnlTraverser< tnlGrid< 1, Real, Device, Index >, GridEntity, 1 >::
+processAllEntities(
+   const GridType& grid,
+   UserData& userData ) const
 {
    /****
-    * Boundary vertices
+    * All cells
     */
-   const int VerticesDimensions = 0;
-   typename GridType::template GridEntity< VerticesDimensions > entity( grid );
-   
-   CoordinatesType& coordinates = entity.getCoordinates();
-   const IndexType& xSize = grid.getDimensions().x();
-   coordinates.x() = 0;
-   entity.refresh();
-   EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-   coordinates.x() = xSize;
-   entity.refresh();
-   EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
+   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0 ),
+      grid.getDimensions() - CoordinatesType( 1 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
-template< typename Real,
-          typename Index,
-          typename GridEntity >
-   template< typename UserData,
-             typename EntitiesProcessor >
-void
-tnlTraverser< tnlGrid< 1, Real, tnlHost, Index >, GridEntity, 0 >::
-processInteriorEntities( const GridType& grid,
-                         UserData& userData ) const
-{
-   /****
-    * Interior vertices
-    */
-   const int VerticesDimensions = 0;
-   typename GridType::template GridEntity< VerticesDimensions > entity( grid );
-   
-   CoordinatesType& coordinates = entity.getCoordinates();
-   const IndexType& xSize = grid.getDimensions().x();
-   for( coordinates.x() = 1; coordinates.x() < xSize; coordinates.x() ++ )
-   {
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-   }
-}
-
-/*****
- *
- *  CUDA specialization
- *
+/****
+ * Grid 1D, vertices
  */
-
-#ifdef HAVE_CUDA
-template< typename Real,
-          typename Index,
-          typename UserData,
-          typename EntitiesProcessor,
-          bool processAllEntities,
-          bool processBoundaryEntities >
-__global__ void tnlTraverserGrid1DCells( const tnlGrid< 1, Real, tnlCuda, Index >* grid,
-                                         UserData* userData,
-                                         Index gridXIdx )
-{
-   typedef tnlGrid< 1, Real, tnlCuda, Index > GridType;
-   const int CellDimensions = GridType::meshDimensions;
-   typename GridType::template GridEntity< CellDimensions > entity( *grid );
-   typedef typename GridType::CoordinatesType CoordinatesType;
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const Index index = ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   coordinates.x() = index;   
-
-   if( coordinates.x() < grid->getDimensions().x() )
-   {
-      entity.refresh();
-      if( processAllEntities || entity.isBoundaryEntity() == processBoundaryEntities )
-      {
-         EntitiesProcessor::processEntity( *grid, *userData, entity );
-      }
-   }
-}
-#endif
-
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 1, Real, tnlCuda, Index >, GridEntity, 1 >::
+tnlTraverser< tnlGrid< 1, Real, Device, Index >, GridEntity, 0 >::
 processBoundaryEntities( const GridType& grid,
                          UserData& userData ) const
 {
-#ifdef HAVE_CUDA
-
-   /****
-    * Boundary conditions
-    */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 256 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      tnlTraverserGrid1DCells< Real, Index, UserData, EntitiesProcessor, false, true >
-                             <<< cudaBlocks, cudaBlockSize >>>
-                             ( kernelGrid,
-                               kernelUserData,
-                               gridXIdx );
-   cudaThreadSynchronize();
-   checkCudaDevice;
-   tnlCuda::freeFromDevice( kernelGrid );
-   tnlCuda::freeFromDevice( kernelUserData );
-   checkCudaDevice;
-#endif
-}
-template< typename Real,
-          typename Index,
-          typename GridEntity >
-   template< typename UserData,
-             typename EntitiesProcessor >
-void
-tnlTraverser< tnlGrid< 1, Real, tnlCuda, Index >, GridEntity, 1 >::
-processInteriorEntities( const GridType& grid,
-                         UserData& userData ) const
-{
-#ifdef HAVE_CUDA
    /****
-    * Interior cells
+    * Boundary vertices
     */
-   checkCudaDevice;
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 256 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-
-   dim3 cudaGridSize;
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx++ )
-   {
-      if( gridXIdx == cudaXGrids - 1 )
-         cudaGridSize.x = cudaBlocks.x % tnlCuda::getMaxGridSize();
-      tnlTraverserGrid1DCells< Real, Index, UserData, EntitiesProcessor, false, false >
-         <<< cudaGridSize, cudaBlockSize >>>
-         ( kernelGrid,
-           kernelUserData,
-           gridXIdx );
-   }
-   checkCudaDevice;
-   tnlCuda::freeFromDevice( kernelGrid );
-   tnlCuda::freeFromDevice( kernelUserData );
-   checkCudaDevice;
-#endif
+   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true >(
+      grid,
+      CoordinatesType( 0 ),
+      grid.getDimensions(),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
-#ifdef HAVE_CUDA
-template< typename Real,
-          typename Index,
-          typename UserData,
-          typename EntitiesProcessor,
-          bool processAllEntities,
-          bool processBoundaryEntities >
-__global__ void tnlTraverserGrid1DVertices( const tnlGrid< 1, Real, tnlCuda, Index >* grid,
-                                            UserData* userData,
-                                            Index gridXIdx )
-{
-   typedef tnlGrid< 1, Real, tnlCuda, Index > GridType;
-   typename GridType::template GridEntity< GridType::Vertices > vertex;
-
-   const Index& xSize = grid->getDimensions().x();
-
-   const Index index = ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   vertex.getCoordinates().x() = index;   
-
-   if( vertex.getCoordinates().x() <= grid->getDimensions().x() )
-   {
-      vertex.setIndex( index );
-      if( processAllEntities || vertex.isBoundaryEntity() == processBoundaryEntities )
-      {
-         EntitiesProcessor::processEntity
-            ( *grid,
-              *userData,
-              vertex.getIndex(),
-              vertex );
-      }
-   }
-}
-#endif
-
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 1, Real, tnlCuda, Index >, GridEntity, 0 >::
-processBoundaryEntities( const GridType& grid,
+tnlTraverser< tnlGrid< 1, Real, Device, Index >, GridEntity, 0 >::
+processInteriorEntities( const GridType& grid,
                          UserData& userData ) const
 {
-   #ifdef HAVE_CUDA
-
    /****
-    * Boundary vertices
+    * Interior vertices
     */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 256 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      tnlTraverserGrid1DVertices< Real, Index, UserData, EntitiesProcessor, false, true >
-         <<< cudaBlocks, cudaBlockSize >>>
-         ( kernelGrid,
-           kernelUserData,
-           gridXIdx );
-   cudaThreadSynchronize();
-   checkCudaDevice;
-   tnlCuda::freeFromDevice( kernelGrid );
-   tnlCuda::freeFromDevice( kernelUserData );
-   checkCudaDevice;
-#endif
-
+   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1 ),
+      grid.getDimensions() - CoordinatesType( 1 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 1, Real, tnlCuda, Index >, GridEntity, 0 >::
-processInteriorEntities( const GridType& grid,
-                         UserData& userData ) const
+tnlTraverser< tnlGrid< 1, Real, Device, Index >, GridEntity, 0 >::
+processAllEntities(
+   const GridType& grid,
+   UserData& userData ) const
 {
-#ifdef HAVE_CUDA
    /****
-    * Interior vertices
+    * All vertices
     */
-   checkCudaDevice;
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 256 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-
-   dim3 cudaGridSize;
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx++ )
-   {
-      if( gridXIdx == cudaXGrids - 1 )
-         cudaGridSize.x = cudaBlocks.x % tnlCuda::getMaxGridSize();
-      tnlTraverserGrid1DVertices< Real, Index, UserData, EntitiesProcessor, false, false >
-         <<< cudaGridSize, cudaBlockSize >>>
-         ( kernelGrid,
-           kernelUserData,
-           gridXIdx );
-   }
-   checkCudaDevice;
-   tnlCuda::freeFromDevice( kernelGrid );
-   tnlCuda::freeFromDevice( kernelUserData );
-   checkCudaDevice;
-#endif
+   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0 ),
+      grid.getDimensions(),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 #endif /* TNLTRAVERSER_GRID1D_IMPL_H_ */
diff --git a/src/mesh/grids/tnlTraverser_Grid2D.h b/src/mesh/grids/tnlTraverser_Grid2D.h
index 4dd2fd8f3764c9d2bfbb8b79192180df8424334f..18baa41ae8abc280ef55112d22ac3507924c7c21 100644
--- a/src/mesh/grids/tnlTraverser_Grid2D.h
+++ b/src/mesh/grids/tnlTraverser_Grid2D.h
@@ -21,14 +21,15 @@
 
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
-class tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 2 >
+class tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 2 >
 {
    public:
-      typedef tnlGrid< 2, Real, tnlHost, Index > GridType;
+      typedef tnlGrid< 2, Real, Device, Index > GridType;
       typedef Real RealType;
-      typedef tnlHost DeviceType;
+      typedef Device DeviceType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
@@ -41,17 +42,23 @@ class tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 2 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
 };
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
-class tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 1 >
+class tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 1 >
 {
    public:
-      typedef tnlGrid< 2, Real, tnlHost, Index > GridType;
+      typedef tnlGrid< 2, Real, Device, Index > GridType;
       typedef Real RealType;
-      typedef tnlHost DeviceType;
+      typedef Device DeviceType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
@@ -64,17 +71,24 @@ class tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 1 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
 };
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
-class tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 0 >
+class tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 0 >
 {
    public:
-      typedef tnlGrid< 2, Real, tnlHost, Index > GridType;
+      typedef tnlGrid< 2, Real, Device, Index > GridType;
       typedef Real RealType;
-      typedef tnlHost DeviceType;
+      typedef Device DeviceType;
       typedef Index IndexType;
       typedef typename GridType::CoordinatesType CoordinatesType;
 
@@ -87,9 +101,15 @@ class tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 0 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
 };
 
 
+#ifdef UNDEF
 template< typename Real,
           typename Index,
           typename GridEntity >
@@ -112,6 +132,22 @@ class tnlTraverser< tnlGrid< 2, Real, tnlCuda, Index >, GridEntity, 2 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;      
 };
 
 template< typename Real,
@@ -135,6 +171,21 @@ class tnlTraverser< tnlGrid< 2, Real, tnlCuda, Index >, GridEntity, 1 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;            
 };
 
 template< typename Real,
@@ -158,8 +209,25 @@ class tnlTraverser< tnlGrid< 2, Real, tnlCuda, Index >, GridEntity, 0 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;            
 };
 
+#endif // UNDEF
 
 #include <mesh/grids/tnlTraverser_Grid2D_impl.h>
 
diff --git a/src/mesh/grids/tnlTraverser_Grid2D_impl.h b/src/mesh/grids/tnlTraverser_Grid2D_impl.h
index a91fb1e892a3c0cc4ed93e2edf322e47c3f92b3a..c59b2773fe8589547dbca9b0717a2fbaee3711cd 100644
--- a/src/mesh/grids/tnlTraverser_Grid2D_impl.h
+++ b/src/mesh/grids/tnlTraverser_Grid2D_impl.h
@@ -19,658 +19,260 @@
 #ifndef TNLTRAVERSER_GRID2D_IMPL_H_
 #define TNLTRAVERSER_GRID2D_IMPL_H_
 
+#include <mesh/grids/tnlGridTraverser.h>
+
+/****
+ * Grid 2D, cells
+ */
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 2 >::
+tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 2 >::
 processBoundaryEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
-    * Traversing boundary cells
+    * Boundary cells
     */
-   const int CellDimensions = GridType::meshDimensions;
-   typename GridType::template GridEntity< CellDimensions > entity( grid );
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-
-   for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-   {
-      coordinates.y() = 0;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity );
-      coordinates.y() = ySize - 1;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity );
-   }
-   for( coordinates.y() = 1; coordinates.y() < ySize - 1; coordinates.y() ++ )
-   {
-      coordinates.x() = 0;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity );
-      coordinates.x() = xSize - 1;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity );
-   }
+   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1 >(
+      grid,
+      CoordinatesType( 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 2 >::
+tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 2 >::
 processInteriorEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
-    * Traversing interior cells
+    * Interior cells
     */
-   const int CellDimensions = GridType::meshDimensions;
-   
-   typename GridType::template GridEntity< CellDimensions > entity( grid );
-   CoordinatesType& coordinates = entity.getCoordinates();
-   
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-
-#ifdef HAVE_OPENMP
-//#pragma omp parallel for
-#endif
-   for( coordinates.y() = 1; coordinates.y() < ySize - 1; coordinates.y() ++ )
-      for( coordinates.x() = 1; coordinates.x() < xSize - 1; coordinates.x() ++ )
-      {
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
+   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+      
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1, 1 ),
+      grid.getDimensions() - CoordinatesType( 2, 2 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 1 >::
-processBoundaryEntities( const GridType& grid,
-                         UserData& userData ) const
+tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 2 >::
+processAllEntities( const GridType& grid,
+                    UserData& userData ) const
 {
    /****
-    * Traversing boundary faces
-    */   
-   const int FaceDimensions = GridType::meshDimensions - 1;
-   typedef typename GridType::template GridEntity< FaceDimensions > EntityType;
-   typedef typename EntityType::EntityOrientationType EntityOrientationType;
-   EntityType entity( grid );
-
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-   entity.setOrientation( EntityOrientationType( 1, 0 ) );
-   for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-   {
-      coordinates.x() = 0;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-      coordinates.x() = xSize;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-   }
-
-   entity.setOrientation( EntityOrientationType( 0, 1 ) );
-   for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-   {      
-      coordinates.y() = 0;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-      coordinates.y() = ySize;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-   }
-}
-
-template< typename Real,
-          typename Index,
-          typename GridEntity >
-   template< typename UserData,
-             typename EntitiesProcessor >
-void
-tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 1 >::
-processInteriorEntities( const GridType& grid,
-                         UserData& userData ) const
-{
-   /****
-    * Traversing interior faces
+    * All cells
     */
-   const int FaceDimensions = GridType::meshDimensions - 1;
-   typedef typename GridType::template GridEntity< FaceDimensions > EntityType;
-   typedef typename EntityType::EntityOrientationType EntityOrientationType;
-   EntityType entity( grid );
-
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-
-#ifdef HAVE_OPENMP
-//#pragma omp parallel for
-#endif
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-   entity.setOrientation( EntityOrientationType( 1, 0 ) );
-   for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-      for( coordinates.x() = 1; coordinates.x() < xSize; coordinates.x() ++ )
-      {
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-      }
-
-   entity.setOrientation( EntityOrientationType( 0, 1 ) );
-   for( coordinates.y() = 1; coordinates.y() < ySize; coordinates.y() ++ )
-      for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-      {
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-      }
+   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+      
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
-
+/****
+ * Grid 2D, faces
+ */
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 0 >::
+tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 1 >::
 processBoundaryEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
-    * Traversing boundary vertices
-    */
-   const int VertexDimensions = 0;
-   typedef typename GridType::template GridEntity< VertexDimensions > EntityType;
-   typedef typename EntityType::EntityOrientationType EntityOrientation;
-   EntityType entity( grid );
-
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
+    * Boundary faces
+    */ 
+   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
    
-   CoordinatesType& coordinates = entity.getCoordinates();
-   for( coordinates.x() = 0; coordinates.x() <= xSize; coordinates.x() ++ )
-   {
-      coordinates.y() = 0;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-      coordinates.y() = ySize;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-   }
-   for( coordinates.y() = 1; coordinates.y() <= ySize; coordinates.y() ++ )
-   {
-      coordinates.x() = 0;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-      coordinates.x() = xSize;
-      entity.refresh();
-      EntitiesProcessor::processEntity( grid, userData, entity.getIndex(), entity );
-   }
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 0 >(
+      grid,
+      CoordinatesType( 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 0, 1 ),
+      CoordinatesType( 1, 0 ),
+      CoordinatesType( 0, 1 ),
+      userData );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 0, 1 >(
+      grid,
+      CoordinatesType( 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 0 ),
+      CoordinatesType( 0, 1 ),
+      CoordinatesType( 1, 0 ),
+      userData );   
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 2, Real, tnlHost, Index >, GridEntity, 0 >::
+tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 1 >::
 processInteriorEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
-    * Traversing interior vertices
+    * Interior faces
     */
-   const int VertexDimensions = 0;
-   typedef typename GridType::template GridEntity< VertexDimensions > EntityType;
-   typedef typename EntityType::EntityOrientationType EntityOrientation;
-   EntityType entity( grid );
+   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
    
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-
-#ifdef HAVE_OPENMP
-  //#pragma omp parallel for
-#endif
-   CoordinatesType& coordinates = entity.getCoordinates();
-   for( coordinates.y() = 1; coordinates.y() < ySize; coordinates.y() ++ )
-      for( coordinates.x() = 1; coordinates.x() < xSize; coordinates.x() ++ )
-      {
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, grid.getVertexIndex( entity ), entity );
-      }  
-}
-
-/***
- *
- *    CUDA Specializations
- *
- */
-
-#ifdef HAVE_CUDA
-template< typename Real,
-          typename Index,
-          typename UserData,
-          typename EntitiesProcessor,
-          bool processAllEntities,
-          bool processBoundaryEntities >
-__global__ void tnlTraverserGrid2DCells( const tnlGrid< 2, Real, tnlCuda, Index >* grid,
-                                         UserData* userData,
-                                         const Index gridXIdx,
-                                         const Index gridYIdx )
-{
-   typedef tnlGrid< 2, Real, tnlCuda, Index > GridType;
-   const int CellDimensions = GridType::meshDimensions;
-   typename GridType::template GridEntity< CellDimensions > entity( *grid );
-   typedef typename GridType::CoordinatesType CoordinatesType;
-   //CoordinatesType& coordinates = entity.getCoordinates();
-
-   /*const Index& xSize = grid->getDimensions().x();
-   const Index& ySize = grid->getDimensions().y();*/
-
-   entity.getCoordinates().x() = ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   entity.getCoordinates().y() = ( gridYIdx * tnlCuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;  
-
-   if( entity.getCoordinates().x() < grid->getDimensions().x() &&
-       entity.getCoordinates().y() < grid->getDimensions().y() )
-   {
-      entity.refresh();
-      if( processAllEntities || entity.isBoundaryEntity() == processBoundaryEntities )
-      {         
-         EntitiesProcessor::processEntity
-         ( *grid,
-           *userData,
-           entity );
-      }
-   }
-}
-
-template< typename Real,
-          typename Index,
-          typename UserData,
-          typename EntitiesProcessor,
-          bool processAllEntities,
-          bool processBoundaryEntities >
-__global__ void tnlTraverserGrid2DFaces( const tnlGrid< 2, Real, tnlCuda, Index >* grid,
-                                         UserData* userData,
-                                         const Index gridXIdx,
-                                         const Index gridYIdx,
-                                         int nx,
-                                         int ny )
-{
-   typedef tnlGrid< 2, Real, tnlCuda, Index > GridType;
-   const int FaceDimensions = GridType::meshDimensions - 1;
-   typedef typename GridType::template GridEntity< GridType::Cells > EntityType;
-   EntityType entity( *grid );
-   typedef typename GridType::CoordinatesType CoordinatesType;
-   CoordinatesType& coordinates = entity.getCoordinates();
-   entity.setOrientation( typename EntityType::EntityOrientationType( nx, ny ) );
-
-   const Index& xSize = grid->getDimensions().x();
-   const Index& ySize = grid->getDimensions().y();
-
-   coordinates.x() = ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   coordinates.y() = ( gridYIdx * tnlCuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;
-
-   if( coordinates.x() < grid->getDimensions().x() + nx &&
-       coordinates.y() < grid->getDimensions().y() + ny )
-   {
-      entity.setIndex( grid->getEntityIndex( entity ) );
-      if( processAllEntities || entity.isBoundaryEntity() == processBoundaryEntities )
-      {         
-         EntitiesProcessor::processEntity
-            ( *grid,
-              *userData,
-              entity );
-      }
-   }
-}
-
-template< typename Real,
-          typename Index,
-          typename UserData,
-          typename EntitiesProcessor,
-          bool processAllEntities,
-          bool processBoundaryEntities >
-__global__ void tnlTraverserGrid2DVertices( const tnlGrid< 2, Real, tnlCuda, Index >* grid,
-                                            UserData* userData,
-                                            const Index gridXIdx,
-                                            const Index gridYIdx )
-{
-   typedef tnlGrid< 2, Real, tnlCuda, Index > GridType;
-   const int VertexDimensions = 0;
-   typedef typename GridType::template GridEntity< VertexDimensions > EntityType;
-   typedef typename GridType::CoordinatesType CoordinatesType;
-   EntityType entity( *grid );
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const Index& xSize = grid->getDimensions().x();
-   const Index& ySize = grid->getDimensions().y();
-
-   coordinates.x() = ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   coordinates.y() = ( gridYIdx * tnlCuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;
-
-   if( coordinates.x() <= grid->getDimensions().x() &&
-       coordinates.y() <= grid->getDimensions().y() )
-   {
-      entity.setIndex( grid->getEntityIndex( entity ) );
-      if( processAllEntities || entity.isBoundaryEntity() == processBoundaryEntities )
-      {
-         EntitiesProcessor::processEntity
-         ( *grid,
-           *userData,
-           entity );
-      }
-   }
-}
-#endif
-
-template< typename Real,
-          typename Index,
-          typename GridEntity >
-   template< typename UserData,
-             typename EntitiesProcessor >
-void
-tnlTraverser< tnlGrid< 2, Real, tnlCuda, Index >, GridEntity, 2 >::
-processBoundaryEntities( const GridType& grid,
-                         UserData& userData ) const
-{
-#ifdef HAVE_CUDA
-
-   /****
-    * Boundary conditions
-    */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 16, 16 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-      {
-         tnlTraverserGrid2DCells< Real, Index, UserData, EntitiesProcessor, false, true >
-                                        <<< cudaBlocks, cudaBlockSize >>>
-                                       ( kernelGrid,
-                                         kernelUserData,
-                                         gridXIdx,
-                                         gridYIdx );
-         checkCudaDevice;
-      }
-   cudaThreadSynchronize();   
-#endif
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1 ),
+      CoordinatesType( 1, 0 ),
+      CoordinatesType( 0, 1 ),
+      userData );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 1 ),
+      grid.getDimensions() - CoordinatesType( 1, 1 ),
+      CoordinatesType( 0, 1 ),
+      CoordinatesType( 1, 0 ),
+      userData );   
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 2, Real, tnlCuda, Index >, GridEntity, 2 >::
-processInteriorEntities( const GridType& grid,
+tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 1 >::
+processAllEntities( const GridType& grid,
                          UserData& userData ) const
 {
-#ifdef HAVE_CUDA
    /****
-    * Interior cells
-    */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 16, 16 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-      {
-         tnlTraverserGrid2DCells< Real, Index, UserData, EntitiesProcessor, false, false >
-                                        <<< cudaBlocks, cudaBlockSize >>>
-                                       ( kernelGrid,
-                                         kernelUserData,
-                                         gridXIdx,
-                                         gridYIdx );
-         checkCudaDevice;
-      }
-   tnlCuda::freeFromDevice( kernelGrid );
-   tnlCuda::freeFromDevice( kernelUserData );
-#endif
+    * All faces
+    */ 
+   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 0, 1 ),
+      CoordinatesType( 1, 0 ),
+      CoordinatesType( 0, 1 ),
+      userData );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 0 ),
+      CoordinatesType( 0, 1 ),
+      CoordinatesType( 1, 0 ),
+      userData );   
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 2, Real, tnlCuda, Index >, GridEntity, 1 >::
+tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 0 >::
 processBoundaryEntities( const GridType& grid,
                          UserData& userData ) const
 {
-#ifdef HAVE_CUDA
    /****
-    * Boundary faces
+    * Boundary vertices
     */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 16, 16 );
-   dim3 cudaBlocks;
-   IndexType cudaXGrids, cudaYGrids;
-
-   /****
-    * < 1, 0 > faces
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-      {
-         tnlTraverserGrid2DFaces< Real, Index, UserData, EntitiesProcessor, false, true >
-            <<< cudaBlocks, cudaBlockSize >>>
-            ( kernelGrid,
-              kernelUserData,
-              gridXIdx,
-              gridYIdx,
-              1, 0  );
-         checkCudaDevice;
-      }
-   cudaThreadSynchronize();
+   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
    
-
-   /****
-    * < 0, 1 > faces
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-      {
-         tnlTraverserGrid2DFaces< Real, Index, UserData, EntitiesProcessor, false, true >
-            <<< cudaBlocks, cudaBlockSize >>>
-            ( kernelGrid,
-              kernelUserData,
-              gridXIdx,
-              gridYIdx,
-              0, 1 );
-         checkCudaDevice;
-      }
-   cudaThreadSynchronize();
-   
-#endif
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1 >(
+      grid,
+      CoordinatesType( 0, 0 ),
+      grid.getDimensions(),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 2, Real, tnlCuda, Index >, GridEntity, 1 >::
+tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 0 >::
 processInteriorEntities( const GridType& grid,
                          UserData& userData ) const
 {
-#ifdef HAVE_CUDA
-   /****
-    * Traversing interior faces
-    */
-   
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 16, 16 );
-   dim3 cudaBlocks;
-   IndexType cudaXGrids, cudaYGrids;
-
    /****
-    * < 1, 0 > faces
+    * Interior vertices
     */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-      {
-         tnlTraverserGrid2DFaces< Real, Index, UserData, EntitiesProcessor, false, false >
-            <<< cudaBlocks, cudaBlockSize >>>
-            ( kernelGrid,
-              kernelUserData,
-              gridXIdx,
-              gridYIdx,
-              1, 0 );
-         checkCudaDevice;
-      }
-   cudaThreadSynchronize();
+   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
    
-
-   /****
-    * < 0, 1 > faces
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-      {
-         tnlTraverserGrid2DFaces< Real, Index, UserData, EntitiesProcessor, false, false >
-            <<< cudaBlocks, cudaBlockSize >>>
-            ( kernelGrid,
-              kernelUserData,
-              gridXIdx,
-              gridYIdx,
-              0, 1 );
-         checkCudaDevice;
-      }
-   cudaThreadSynchronize();
-#endif
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1, 1 ),
+      grid.getDimensions() - CoordinatesType( 1, 1 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
-
-template< typename Real,
-          typename Index,
-          typename GridEntity >
-   template< typename UserData,
-             typename EntitiesProcessor >
-void
-tnlTraverser< tnlGrid< 2, Real, tnlCuda, Index >, GridEntity, 0 >::
-processBoundaryEntities( const GridType& grid,
-                         UserData& userData ) const
-{
-#ifdef HAVE_CUDA
-   /****
-    * Traversing boundary vertices    
-    */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 16, 16 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-      {
-         tnlTraverserGrid2DVertices< Real, Index, UserData, EntitiesProcessor, false, true >
-            <<< cudaBlocks, cudaBlockSize >>>
-            ( kernelGrid,
-              kernelUserData,
-              gridXIdx,
-              gridYIdx );
-         checkCudaDevice;
-      }
-   cudaThreadSynchronize();   
-#endif
-}
-
-
+   
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 2, Real, tnlCuda, Index >, GridEntity, 0 >::
-processInteriorEntities( const GridType& grid,
+tnlTraverser< tnlGrid< 2, Real, Device, Index >, GridEntity, 0 >::
+processAllEntities( const GridType& grid,
                          UserData& userData ) const
 {
-#ifdef HAVE_CUDA
    /****
-    * Traversing interior vertices    
+    * All vertices
     */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 16, 16 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-      {
-         tnlTraverserGrid2DVertices< Real, Index, UserData, EntitiesProcessor, false, false >
-            <<< cudaBlocks, cudaBlockSize >>>
-            ( kernelGrid,
-              kernelUserData,
-              gridXIdx,
-              gridYIdx );
-         checkCudaDevice;
-      }
-   cudaThreadSynchronize();   
-#endif
+   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0 ),
+      grid.getDimensions(),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
-
-
 #endif /* TNLTRAVERSER_GRID2D_IMPL_H_ */
diff --git a/src/mesh/grids/tnlTraverser_Grid3D.h b/src/mesh/grids/tnlTraverser_Grid3D.h
index 4279c7413e66dbc4a520bd053dd0ba57a7fa0169..c00b1c4c50365ce97eba8ffd2860734d7c096527 100644
--- a/src/mesh/grids/tnlTraverser_Grid3D.h
+++ b/src/mesh/grids/tnlTraverser_Grid3D.h
@@ -18,6 +18,127 @@
 #ifndef TNLTRAVERSER_GRID3D_H_
 #define TNLTRAVERSER_GRID3D_H_
 
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename GridEntity >
+class tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 3 >
+{
+   public:
+      typedef tnlGrid< 3, Real, Device, Index > GridType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processBoundaryEntities( const GridType& grid,
+                                    UserData& userData ) const;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processInteriorEntities( const GridType& grid,
+                                    UserData& userData ) const;
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename GridEntity >
+class tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 2 >
+{
+   public:
+      typedef tnlGrid< 3, Real, Device, Index > GridType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processBoundaryEntities( const GridType& grid,
+                                    UserData& userData ) const;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processInteriorEntities( const GridType& grid,
+                                    UserData& userData ) const;
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename GridEntity >
+class tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 1 >
+{
+   public:
+      typedef tnlGrid< 3, Real, Device, Index > GridType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processBoundaryEntities( const GridType& grid,
+                                    UserData& userData ) const;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processInteriorEntities( const GridType& grid,
+                                    UserData& userData ) const;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename GridEntity >
+class tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 0 >
+{
+   public:
+      typedef tnlGrid< 3, Real, Device, Index > GridType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef typename GridType::CoordinatesType CoordinatesType;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processBoundaryEntities( const GridType& grid,
+                                    UserData& userData ) const;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processInteriorEntities( const GridType& grid,
+                                    UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+};
+
+
+
+#ifdef UNDEF
+
 
 template< typename Real,
           typename Index,
@@ -40,6 +161,23 @@ class tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 3 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;      
+      
 };
 
 template< typename Real,
@@ -63,6 +201,23 @@ class tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 2 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;      
+      
 };
 
 template< typename Real,
@@ -86,6 +241,22 @@ class tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 1 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;            
 };
 
 template< typename Real,
@@ -109,6 +280,22 @@ class tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 0 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;            
 };
 
 /****
@@ -136,6 +323,22 @@ class tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 3 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;            
 };
 
 template< typename Real,
@@ -159,6 +362,22 @@ class tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 2 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;            
 };
 
 template< typename Real,
@@ -182,6 +401,23 @@ class tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 1 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
+
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;      
+      
 };
 
 template< typename Real,
@@ -205,8 +441,25 @@ class tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 0 >
                 typename EntitiesProcessor >
       void processInteriorEntities( const GridType& grid,
                                     UserData& userData ) const;
-};
+      
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processAllEntities( const GridType& grid,
+                               UserData& userData ) const;
+      
+   protected:
 
+      template< typename UserData,
+                typename EntitiesProcessor >
+      void processSubgridEntities(
+         const GridType& grid,
+         const CoordinatesType& begin,
+         const CoordinatesType& end,
+         GridEntity& entity,
+         UserData& userData ) const;      
+      
+};
+#endif // UNDEF
 
 #include <mesh/grids/tnlTraverser_Grid3D_impl.h>
 
diff --git a/src/mesh/grids/tnlTraverser_Grid3D_impl.h b/src/mesh/grids/tnlTraverser_Grid3D_impl.h
index 8bc9f1c7f3e1228f81439bc07e9d022b90488ab9..0e4ba1e39a067963d83772b9b026d3afa222d13c 100644
--- a/src/mesh/grids/tnlTraverser_Grid3D_impl.h
+++ b/src/mesh/grids/tnlTraverser_Grid3D_impl.h
@@ -18,1205 +18,412 @@
 #ifndef TNLTRAVERSER_GRID3D_IMPL_H_
 #define TNLTRAVERSER_GRID3D_IMPL_H_
 
+#include <mesh/grids/tnlGridTraverser.h>
+
+/****
+ * Grid 3D, cells
+ */
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 3 >::
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 3 >::
 processBoundaryEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
-    * Boundary conditions
+    * Boundary cells
     */
-   const int CellDimensions = GridType::meshDimensions;
-   typename GridType::template GridEntity< CellDimensions > entity( grid );
-   
-   CoordinatesType& coordinates = entity.getCoordinates();
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-   const IndexType& zSize = grid.getDimensions().z();
-
-   for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-      for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-      {
-         coordinates.z() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.z() = zSize - 1;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
-
-   for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-      {
-         coordinates.y() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.y() = ySize - 1;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
-
-   for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-      {
-         coordinates.x() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.x() = xSize - 1;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
+   static_assert( GridEntity::entityDimensions == 3, "The entity has wrong dimensions." );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1, 1 >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1, 1 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
+
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 3 >::
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 3 >::
 processInteriorEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
     * Interior cells
     */
-   const int CellDimensions = GridType::meshDimensions;
-   typename GridType::template GridEntity< CellDimensions > entity( grid );
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-   const IndexType& zSize = grid.getDimensions().z();
-
-#ifdef HAVE_OPENMP
-//#pragma omp parallel for
-#endif
-   for( coordinates.z() = 1; coordinates.z() < zSize - 1; coordinates.z() ++ )
-      for( coordinates.y() = 1; coordinates.y() < ySize - 1; coordinates.y() ++ )
-         for( coordinates.x() = 1; coordinates.x() < xSize - 1; coordinates.x() ++ )
-         {
-            entity.refresh();
-            EntitiesProcessor::processEntity( grid, userData, entity );
-         }
-}
-
-template< typename Real,
-          typename Index,
-          typename GridEntity >
-   template< typename UserData,
-             typename EntitiesProcessor >
-void
-tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 2 >::
-processBoundaryEntities( const GridType& grid,
-                         UserData& userData ) const
-{
-   /****
-    * Traversing boundary faces
-    */
-   const int FaceDimensions = GridType::meshDimensions - 1;
-   typedef typename GridType::template GridEntity< FaceDimensions > EntityType;
-   EntityType entity;
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-   const IndexType& zSize = grid.getDimensions().z();
-
-   entity.setOrientation( typename EntityType::EntityOrientationType( 1, 0, 0 ) );
-   for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-      {
-         coordinates.x() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.x() = xSize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
-
-   entity.setOrientation( typename EntityType::EntityOrientationType( 0, 1, 0 ) );
-   for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-      {
-         coordinates.y() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.y() = ySize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
-  
-   entity.setOrientation( typename EntityType::EntityOrientationType( 0, 0, 1 ) );
-   for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-      for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )      
-      {         
-         coordinates.z() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.z() = zSize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }     
+   static_assert( GridEntity::entityDimensions == 3, "The entity has wrong dimensions." );
+      
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1, 1, 1 ),
+      grid.getDimensions() - CoordinatesType( 2, 2, 2 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 2 >::
-processInteriorEntities( const GridType& grid,
-                         UserData& userData ) const
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 3 >::
+processAllEntities( const GridType& grid,
+                    UserData& userData ) const
 {
    /****
-    * Traversing interior faces
+    * All cells
     */
-   const int FaceDimensions = GridType::meshDimensions - 1;
-   typedef typename GridType::template GridEntity< FaceDimensions > EntityType;
-   EntityType entity;
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-   const IndexType& zSize = grid.getDimensions().z();
-
-#ifdef HAVE_OPENMP
-//#pragma omp parallel for
-#endif
-
-   entity.setOrientation( typename EntityType::EntityOrientationType( 1, 0, 0 ) );
-   for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-         for( coordinates.x() = 1; coordinates.x() < xSize; coordinates.x() ++ )
-         {
-            entity.refresh();         
-            EntitiesProcessor::processEntity( grid, userData, entity );
-         }
-
-   entity.setOrientation( typename EntityType::EntityOrientationType( 0, 1, 0 ) );
-   for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 1; coordinates.y() < ySize; coordinates.y() ++ )
-         for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-         {
-            entity.refresh();
-            EntitiesProcessor::processEntity( grid, userData, entity );
-         }
-            
-   
-   entity.setOrientation( typename EntityType::EntityOrientationType( 0, 0, 1 ) );
-   for( coordinates.z() = 1; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-         for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-         {
-            entity.refresh();
-            EntitiesProcessor::processEntity( grid, userData, entity );
-         }
+   static_assert( GridEntity::entityDimensions == 3, "The entity has wrong dimensions." );
+      
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1, 1 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
-
+/****
+ * Grid 3D, faces
+ */
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 1 >::
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 2 >::
 processBoundaryEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
-    * Traversing boundary edges
-    */
-   const int EdgeDimensions = 1;
-   typedef typename GridType::template GridEntity< EdgeDimensions > EntityType;
-   EntityType entity;
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-   const IndexType& zSize = grid.getDimensions().z();
-   
-   entity.setBasis( typename EntityType::EntityBasisType( 1, 0, 0 ) );
-   for( coordinates.y() = 0; coordinates.y() <= ySize; coordinates.y() ++ )
-      for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )      
-      {
-         coordinates.z() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );        
-         coordinates.z() = zSize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
-   
-   entity.setBasis( typename EntityType::EntityBasisType( 0, 1, 0 ) );
-   for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-      for( coordinates.x() = 0; coordinates.x() <= xSize; coordinates.x() ++ )      
-      {
-         coordinates.z() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.z() = zSize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
-   
-   entity.setBasis( typename EntityType::EntityBasisType( 1, 0, 0 ) );
-   for( coordinates.z() = 0; coordinates.z() <= zSize; coordinates.z() ++ )
-      for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-      {
-         coordinates.y() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.y() = ySize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
+    * Boundary faces
+    */ 
+   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
    
-   entity.setBasis( typename EntityType::EntityBasisType( 0, 0, 1 ) );
-   for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.x() = 0; coordinates.x() <= xSize; coordinates.x() ++ )
-      {
-         coordinates.y() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.y() = ySize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
-
-   entity.setBasis( typename EntityType::EntityBasisType( 0, 1, 0 ) );
-   for( coordinates.z() = 0; coordinates.z() <= zSize; coordinates.z() ++ )
-      for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-      {
-         coordinates.x() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.x() = xSize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 0, 0 >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 0, 1, 1 ),
+      CoordinatesType( 1, 0, 0 ),
+      CoordinatesType( 0, 1, 1 ),
+      userData );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 0, 1, 0 >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 0, 1 ),
+      CoordinatesType( 0, 1, 0 ),
+      CoordinatesType( 1, 0, 1 ),
+      userData );   
    
-   entity.setBasis( typename EntityType::EntityBasisType( 0, 0, 1 ) );
-   for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 0; coordinates.y() <= ySize; coordinates.y() ++ )
-      {
-         coordinates.x() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.x() = xSize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 0, 0, 1 >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1, 0 ),
+      CoordinatesType( 0, 1, 0 ),
+      CoordinatesType( 1, 1, 0 ),
+      userData );   
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 1 >::
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 2 >::
 processInteriorEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
-    * Traversing interior edges
-    */
-   const int EdgeDimensions = 1;
-   typedef typename GridType::template GridEntity< EdgeDimensions > EntityType;
-   EntityType entity;
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-   const IndexType& zSize = grid.getDimensions().z();
-
-#ifdef HAVE_OPENMP
-//#pragma omp parallel for
-#endif
-
-   entity.setBasis( typename EntityType::EntityBasisType( 0, 0, 1 ) );
-   for( coordinates.z() = 1; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 1; coordinates.y() < ySize; coordinates.y() ++ )
-         for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ )
-         {
-            entity.refresh();
-            EntitiesProcessor::processEntity( grid, userData, entity );
-         }
-
-   entity.setBasis( typename EntityType::EntityBasisType( 0, 1, 0 ) );
-   for( coordinates.z() = 1; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ )
-         for( coordinates.x() = 1; coordinates.x() < xSize; coordinates.x() ++ )
-         {
-            entity.refresh();
-            EntitiesProcessor::processEntity( grid, userData, entity );
-         }
-   
-   entity.setBasis( typename EntityType::EntityBasisType( 1, 0, 0 ) );
-   for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 1; coordinates.y() < ySize; coordinates.y() ++ )
-         for( coordinates.x() = 1; coordinates.x() < xSize; coordinates.x() ++ )
-         {
-            entity.refresh();
-            EntitiesProcessor::processEntity( grid, userData, entity );
-         }
-}
-
-
-template< typename Real,
-          typename Index,
-          typename GridEntity >
-   template< typename UserData,
-             typename EntitiesProcessor >
-void
-tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 0 >::
-processBoundaryEntities( const GridType& grid,
-                         UserData& userData ) const
-{
-   /****
-    * Traversing boundary vertices
-    */
-   const int VertexDimensions = 0;
-   typedef typename GridType::template GridEntity< VertexDimensions > EntityType;
-   EntityType entity;
-
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-   const IndexType& zSize = grid.getDimensions().z();
-   typedef typename GridType::Vertex VertexTopology;
+    * Interior faces
+    */ 
+   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
    
-   for( coordinates.y() = 0; coordinates.y() <= ySize; coordinates.y() ++ )
-      for( coordinates.x() = 0; coordinates.x() <= xSize; coordinates.x() ++ )
-      {
-         coordinates.z() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.z() = zSize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
-
-   for( coordinates.z() = 0; coordinates.z() <= zSize; coordinates.z() ++ )
-      for( coordinates.x() = 0; coordinates.x() <= xSize; coordinates.x() ++ )
-      {
-         coordinates.y() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.y() = ySize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
-
-   for( coordinates.z() = 0; coordinates.z() <= zSize; coordinates.z() ++ )
-      for( coordinates.y() = 0; coordinates.y() <= ySize; coordinates.y() ++ )
-      {
-         coordinates.x() = 0;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-         coordinates.x() = xSize;
-         entity.refresh();
-         EntitiesProcessor::processEntity( grid, userData, entity );
-      }
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1, 1 ),
+      CoordinatesType( 1, 0, 0 ),
+      CoordinatesType( 0, 1, 1 ),
+      userData );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 1, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1, 1 ),
+      CoordinatesType( 0, 1, 0 ),
+      CoordinatesType( 1, 0, 1 ),
+      userData );   
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0, 1 ),
+      grid.getDimensions() - CoordinatesType( 1, 1, 1 ),
+      CoordinatesType( 0, 0, 1 ),
+      CoordinatesType( 1, 1, 0 ),
+      userData );   
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlHost, Index >, GridEntity, 0 >::
-processInteriorEntities( const GridType& grid,
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 2 >::
+processAllEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
-    * Traversing interior vertices
-    */
-   const int VertexDimensions = 0;
-   typedef typename GridType::template GridEntity< VertexDimensions > EntityType;
-   EntityType entity;
-   
-   CoordinatesType& coordinates = entity.getCoordinates();
+    * All faces
+    */ 
+   static_assert( GridEntity::entityDimensions == 2, "The entity has wrong dimensions." );
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 0, 1, 1 ),
+      CoordinatesType( 1, 0, 0 ),
+      CoordinatesType( 0, 1, 1 ),
+      userData );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 0, 1 ),
+      CoordinatesType( 0, 1, 0 ),
+      CoordinatesType( 1, 0, 1 ),
+      userData );   
    
-   const IndexType& xSize = grid.getDimensions().x();
-   const IndexType& ySize = grid.getDimensions().y();
-   const IndexType& zSize = grid.getDimensions().z();
-
-#ifdef HAVE_OPENMP
-//#pragma omp parallel for
-#endif
-   for( coordinates.z() = 1; coordinates.z() < zSize; coordinates.z() ++ )
-      for( coordinates.y() = 1; coordinates.y() < ySize; coordinates.y() ++ )
-         for( coordinates.x() = 1; coordinates.x() < xSize; coordinates.x() ++ )
-         {
-            entity.refresh();
-            EntitiesProcessor::processEntity( grid, userData, entity );
-         }
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1, 0 ),
+      CoordinatesType( 0, 0, 1 ),
+      CoordinatesType( 1, 1, 0 ),
+      userData );      
 }
 
-
-/***
- *
- *    CUDA Specializations
- *
+/****
+ * Grid 3D, edges
  */
-#ifdef HAVE_CUDA
-template< typename Real,
-          typename Index,
-          typename UserData,
-          typename EntitiesProcessor,
-          bool processAllEntities,
-          bool processBoundaryEntities >
-__global__ void tnlTraverserGrid3DCells( const tnlGrid< 3, Real, tnlCuda, Index >* grid,
-                                         UserData* userData,
-                                         const Index gridXIdx,
-                                         const Index gridYIdx,
-                                         const Index gridZIdx )
-{
-   typedef tnlGrid< 3, Real, tnlCuda, Index > GridType;
-   const int CellDimensions = GridType::meshDimensions;
-   typename GridType::template GridEntity< CellDimensions > entity( *grid );
-   typedef typename GridType::CoordinatesType CoordinatesType;
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const Index& xSize = grid->getDimensions().x();
-   const Index& ySize = grid->getDimensions().y();
-   const Index& zSize = grid->getDimensions().z();
-
-   coordinates.x() = ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   coordinates.y() = ( gridYIdx * tnlCuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;
-   coordinates.z() = ( gridZIdx * tnlCuda::getMaxGridSize() + blockIdx.z ) * blockDim.z + threadIdx.z;
-
-   if( coordinates.x() < grid->getDimensions().x() &&
-       coordinates.y() < grid->getDimensions().y() &&
-       coordinates.z() < grid->getDimensions().z() )
-   {
-      entity.refresh();
-      if( processAllEntities || entity.isBoundaryEntity() == processBoundaryEntities )
-      {         
-         EntitiesProcessor::template processEntity
-            ( *grid,
-              *userData,
-              entity );
-      }
-   }
-}
-
-template< typename Real,
-          typename Index,
-          typename UserData,
-          typename EntitiesProcessor,
-          bool processAllEntities,
-          bool processBoundaryEntities >
-__global__ void tnlTraverserGrid3DFaces( const tnlGrid< 3, Real, tnlCuda, Index >* grid,
-                                         UserData* userData,
-                                         const Index gridXIdx,
-                                         const Index gridYIdx,
-                                         const Index gridZIdx,
-                                         int nx,
-                                         int ny,
-                                         int nz )
-{
-   typedef tnlGrid< 3, Real, tnlCuda, Index > GridType;
-   const int FaceDimensions = GridType::meshDimensions - 1;
-   typename GridType::template GridEntity< FaceDimensions > entity( *grid );
-   entity.setOrientation( nx, ny, nz );
-   typedef typename GridType::CoordinatesType CoordinatesType;
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const Index& xSize = grid->getDimensions().x();
-   const Index& ySize = grid->getDimensions().y();
-   const Index& zSize = grid->getDimensions().z();
-
-   coordinates.x() = ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   coordinates.y() = ( gridYIdx * tnlCuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;
-   coordinates.z() = ( gridZIdx * tnlCuda::getMaxGridSize() + blockIdx.z ) * blockDim.z + threadIdx.z;
-
-   if( coordinates.x() < grid->getDimensions().x() + nx &&
-       coordinates.y() < grid->getDimensions().y() + ny &&
-       coordinates.z() < grid->getDimensions().z() + nz )
-   {
-      entity.refresh();
-      if( processAllEntities || entity.isBoundaryEntity() == processBoundaryEntities )
-      {         
-         EntitiesProcessor::processEntity
-            ( *grid,
-              *userData,
-              entity );
-      }
-   }
-}
-
-template< typename Real,
-          typename Index,
-          typename UserData,
-          typename EntitiesProcessor,
-          bool processAllEntities,
-          bool processBoundaryEntities >
-__global__ void tnlTraverserGrid3DEdges( const tnlGrid< 3, Real, tnlCuda, Index >* grid,
-                                         UserData* userData,
-                                         const Index gridXIdx,
-                                         const Index gridYIdx,
-                                         const Index gridZIdx,
-                                         int dx,
-                                         int dy,
-                                         int dz )
-{
-   typedef tnlGrid< 3, Real, tnlCuda, Index > GridType;
-   const int EdgeDimensions = 1;
-   typename GridType::template GridEntity< EdgeDimensions > entity( *grid );
-   entity.setBasis( dx, dy, dz );
-   typedef typename GridType::CoordinatesType CoordinatesType;
-   CoordinatesType& coordinates = entity.getCoordinates();
-
-   const Index& xSize = grid->getDimensions().x();
-   const Index& ySize = grid->getDimensions().y();
-   const Index& zSize = grid->getDimensions().z();
-
-   coordinates.x() = ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   coordinates.y() = ( gridYIdx * tnlCuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;
-   coordinates.z() = ( gridZIdx * tnlCuda::getMaxGridSize() + blockIdx.z ) * blockDim.z + threadIdx.z;
-
-   if( coordinates.x() < grid->getDimensions().x() + !dx &&
-       coordinates.y() < grid->getDimensions().y() + !dy &&
-       coordinates.z() < grid->getDimensions().z() + !dz )
-   {
-      entity.refresh();
-      if( processAllEntities || entity.isBoundaryEntity() == processBoundaryEntities )
-      {         
-         EntitiesProcessor::processEntity
-            ( *grid,
-              *userData,
-              entity );
-      }
-   }
-}
-
-template< typename Real,
-          typename Index,
-          typename UserData,
-          typename EntitiesProcessor,
-          bool processAllEntities,
-          bool processBoundaryEntities >
-__global__ void tnlTraverserGrid3DVertices( const tnlGrid< 3, Real, tnlCuda, Index >* grid,
-                                            UserData* userData,
-                                            const Index gridXIdx,
-                                            const Index gridYIdx,
-                                            const Index gridZIdx )
-{
-   typedef tnlGrid< 3, Real, tnlCuda, Index > GridType;
-   const int VertexDimensions = 0;
-   typename GridType::template GridEntity< VertexDimensions > entity( *grid );
-   typedef typename GridType::CoordinatesType CoordinatesType;
-   CoordinatesType& coordinates = entity.getCoordinates();
-   
-   const Index& xSize = grid->getDimensions().x();
-   const Index& ySize = grid->getDimensions().y();
-   const Index& zSize = grid->getDimensions().z();
-
-   coordinates.x() = ( gridXIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   coordinates.y() = ( gridYIdx * tnlCuda::getMaxGridSize() + blockIdx.y ) * blockDim.y + threadIdx.y;
-   coordinates.z() = ( gridZIdx * tnlCuda::getMaxGridSize() + blockIdx.z ) * blockDim.z + threadIdx.z;
-
-   if( coordinates.x() < grid->getDimensions().x() &&
-       coordinates.y() < grid->getDimensions().y() &&
-       coordinates.z() < grid->getDimensions().z() )
-   {
-      entity.refresh();
-      if( processAllEntities || entity.isBoundaryEntity() == processBoundaryEntities )
-      {         
-         EntitiesProcessor::template processEntity
-         ( *grid,
-           *userData,
-           entity );
-      }
-   }
-}
-
-#endif
-
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 3 >::
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 1 >::
 processBoundaryEntities( const GridType& grid,
                          UserData& userData ) const
 {
-#ifdef HAVE_CUDA
    /****
-    * Boundary cells
-    */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 8, 8, 4 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z(), cudaBlockSize.z );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   const IndexType cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DCells< Real, Index, UserData, EntitiesProcessor, false, true >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx );
-         }
-   cudaThreadSynchronize();
-   checkCudaDevice;
-#endif
+    * Boundary edges
+    */ 
+   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 0, 1, 1 >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 0, 0 ),
+      CoordinatesType( 0, 1, 1 ),
+      CoordinatesType( 1, 0, 0 ),
+      userData );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 0, 1 >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 0, 1, 0 ),
+      CoordinatesType( 1, 0, 1 ),
+      CoordinatesType( 0, 1, 0 ),
+      userData );   
+   
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1, 0 >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 0, 0, 1 ),
+      CoordinatesType( 1, 1, 0 ),
+      CoordinatesType( 0, 0, 1 ),
+      userData );   
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 3 >::
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 1 >::
 processInteriorEntities( const GridType& grid,
                          UserData& userData ) const
 {
-   #ifdef HAVE_CUDA
-
-   /****
-    * Interior cells
-    */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 8, 8, 4 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z(), cudaBlockSize.z );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   const IndexType cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DCells< Real, Index, UserData, EntitiesProcessor, false, false >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx );
-         }
-   checkCudaDevice;
-   tnlCuda::freeFromDevice( kernelGrid );
-   tnlCuda::freeFromDevice( kernelUserData );
-#endif
-}
-
-
-template< typename Real,
-          typename Index,
-          typename GridEntity >
-   template< typename UserData,
-             typename EntitiesProcessor >
-void
-tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 2 >::
-processBoundaryEntities( const GridType& grid,
-                         UserData& userData ) const
-{
-#ifdef HAVE_CUDA
    /****
-    * Boundary faces
-    */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 8, 8, 4 );
-   dim3 cudaBlocks;
-   IndexType cudaXGrids, cudaYGrids, cudaZGrids;
-
-   /****
-    * < 1, 0, 0 > faces
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z(), cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z );
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DFaces< Real, Index, UserData, EntitiesProcessor, false, true >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 1, 0, 0 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
-   
-   /****
-    * < 0, 1, 0 > faces
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z(), cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z);
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DFaces< Real, Index, UserData, EntitiesProcessor, false, true >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 0, 1, 0 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
+    * Interior edges
+    */ 
+   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
    
-   /****
-    * < 0, 0, 1 > faces
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z() + 1, cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z);
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DFaces< Real, Index, UserData, EntitiesProcessor, false, true >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 0, 0, 1 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
-#endif
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 1, 1 ),
+      grid.getDimensions() - CoordinatesType( 0, 1, 1 ),
+      CoordinatesType( 0, 1, 1 ),
+      CoordinatesType( 1, 0, 0 ),
+      userData );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1, 0, 1 ),
+      grid.getDimensions() - CoordinatesType( 1, 0, 1 ),
+      CoordinatesType( 1, 0, 1 ),
+      CoordinatesType( 0, 1, 0 ),
+      userData );   
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1, 1, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 1, 0 ),
+      CoordinatesType( 1, 1, 0 ),
+      CoordinatesType( 0, 0, 1 ),
+      userData );   
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 2 >::
-processInteriorEntities( const GridType& grid,
-                         UserData& userData ) const
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 1 >::
+processAllEntities( const GridType& grid,
+                    UserData& userData ) const
 {
-#ifdef HAVE_CUDA
-   /****
-    * Traversing interior faces
-    */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 8, 8, 4 );
-   dim3 cudaBlocks;
-   IndexType cudaXGrids, cudaYGrids, cudaZGrids;
-
    /****
-    * < 1, 0, 0 > faces
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z(), cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z );
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DFaces< Real, Index, UserData, EntitiesProcessor, false, false >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 1, 0, 0 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
+    * All edges
+    */ 
+   static_assert( GridEntity::entityDimensions == 1, "The entity has wrong dimensions." );
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 1, 0, 0 ),
+      CoordinatesType( 0, 1, 1 ),      
+      CoordinatesType( 1, 0, 0 ),
+      userData );
+
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 0, 1, 0 ),
+      CoordinatesType( 1, 0, 1 ),      
+      CoordinatesType( 0, 1, 0 ),
+      userData );   
    
-   /****
-    * < 0, 1, 0 > faces
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z(), cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z);
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DFaces< Real, Index, UserData, EntitiesProcessor, false, false >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 0, 1, 0 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
-   
-   /****
-    * < 0, 0, 1 > faces
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z() + 1, cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z);
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DFaces< Real, Index, UserData, EntitiesProcessor, false, false >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 0, 0, 1 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
-#endif
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions() - CoordinatesType( 0, 0, 1 ),
+      CoordinatesType( 1, 1, 0 ),      
+      CoordinatesType( 0, 0, 1 ),
+      userData );      
 }
 
-
+/****
+ * Grid 3D, vertices
+ */
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 1 >::
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 0 >::
 processBoundaryEntities( const GridType& grid,
                          UserData& userData ) const
 {
-#ifdef HAVE_CUDA
    /****
-    * Boundary edges
+    * Boundary vertices
     */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 8, 8, 4 );
-   dim3 cudaBlocks;
-   IndexType cudaXGrids, cudaYGrids, cudaZGrids;
-
-   /****
-    * < 1, 0, 0 > edges
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z() + 1, cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z );
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DEdges< Real, Index, UserData, EntitiesProcessor, false, true >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 1, 0, 0 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
-   
-   /****
-    * < 0, 1, 0 > edges
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z() + 1, cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z);
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DEdges< Real, Index, UserData, EntitiesProcessor, false, true >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 0, 1, 0 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
+   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
    
-   /****
-    * < 0, 0, 1 > edges
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z(), cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z);
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DEdges< Real, Index, UserData, EntitiesProcessor, false, true >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 0, 0, 1 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
-#endif
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1, 1 >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions(),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 1 >::
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 0 >::
 processInteriorEntities( const GridType& grid,
                          UserData& userData ) const
 {
-#ifdef HAVE_CUDA
-   /****
-    * Boundary edges
-    */
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 8, 8, 4 );
-   dim3 cudaBlocks;
-   IndexType cudaXGrids, cudaYGrids, cudaZGrids;
-
-   /****
-    * < 1, 0, 0 > edges
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x(), cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z() + 1, cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z );
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DEdges< Real, Index, UserData, EntitiesProcessor, false, true >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 1, 0, 0 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
-   
    /****
-    * < 0, 1, 0 > edges
+    * Interior vertices
     */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y(), cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z() + 1, cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z);
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DEdges< Real, Index, UserData, EntitiesProcessor, false, false >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 0, 1, 0 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
+   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
    
-   /****
-    * < 0, 0, 1 > edges
-    */
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z(), cudaBlockSize.z );
-   cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z);
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DEdges< Real, Index, UserData, EntitiesProcessor, false, false >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx,
-                 0, 0, 1 );
-            checkCudaDevice;
-         }
-   cudaThreadSynchronize();
-#endif   
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 1, 1, 1 ),
+      grid.getDimensions() - CoordinatesType( 1, 1, 1 ),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
-
-
-template< typename Real,
-          typename Index,
-          typename GridEntity >
-   template< typename UserData,
-             typename EntitiesProcessor >
-void
-tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 0 >::
-processBoundaryEntities( const GridType& grid,
-                         UserData& userData ) const
-{
-   /****
-    * Traversing boundary vertices
-    */
-#ifdef HAVE_CUDA
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 8, 8, 4 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z() + 1, cudaBlockSize.z );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   const IndexType cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DVertices< Real, Index, UserData, EntitiesProcessor, false, true >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx );
-         }
-   cudaThreadSynchronize();
-   checkCudaDevice;
-#endif
    
-}
-
 template< typename Real,
+          typename Device,
           typename Index,
           typename GridEntity >
    template< typename UserData,
              typename EntitiesProcessor >
 void
-tnlTraverser< tnlGrid< 3, Real, tnlCuda, Index >, GridEntity, 0 >::
-processInteriorEntities( const GridType& grid,
+tnlTraverser< tnlGrid< 3, Real, Device, Index >, GridEntity, 0 >::
+processAllEntities( const GridType& grid,
                          UserData& userData ) const
 {
    /****
-    * Traversing interior vertices
+    * All vertices
     */
-#ifdef HAVE_CUDA
-   GridType* kernelGrid = tnlCuda::passToDevice( grid );
-   UserData* kernelUserData = tnlCuda::passToDevice( userData );
-
-   dim3 cudaBlockSize( 8, 8, 4 );
-   dim3 cudaBlocks;
-   cudaBlocks.x = tnlCuda::getNumberOfBlocks( grid.getDimensions().x() + 1, cudaBlockSize.x );
-   cudaBlocks.y = tnlCuda::getNumberOfBlocks( grid.getDimensions().y() + 1, cudaBlockSize.y );
-   cudaBlocks.z = tnlCuda::getNumberOfBlocks( grid.getDimensions().z() + 1, cudaBlockSize.z );
-   const IndexType cudaXGrids = tnlCuda::getNumberOfGrids( cudaBlocks.x );
-   const IndexType cudaYGrids = tnlCuda::getNumberOfGrids( cudaBlocks.y );
-   const IndexType cudaZGrids = tnlCuda::getNumberOfGrids( cudaBlocks.z );
-
-   for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
-      for( IndexType gridYIdx = 0; gridYIdx < cudaYGrids; gridYIdx ++ )
-         for( IndexType gridZIdx = 0; gridZIdx < cudaZGrids; gridZIdx ++ )
-         {
-            tnlTraverserGrid3DVertices< Real, Index, UserData, EntitiesProcessor, false, false >
-               <<< cudaBlocks, cudaBlockSize >>>
-               ( kernelGrid,
-                 kernelUserData,
-                 gridXIdx,
-                 gridYIdx,
-                 gridZIdx );
-         }
-   cudaThreadSynchronize();
-   checkCudaDevice;
-#endif
+   static_assert( GridEntity::entityDimensions == 0, "The entity has wrong dimensions." );
+   
+   tnlGridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >(
+      grid,
+      CoordinatesType( 0, 0, 0 ),
+      grid.getDimensions(),
+      CoordinatesType(),
+      CoordinatesType(),
+      userData );
 }
 
 #endif /* TNLTRAVERSER_GRID3D_IMPL_H_ */
diff --git a/src/mesh/tnlDummyMesh.h b/src/mesh/tnlDummyMesh.h
index 4c2d3b2dddc2dae7f41e932e91f00565746d16c1..6c3c5274b7002ee7ce8c053f8c292ad3ded23100 100644
--- a/src/mesh/tnlDummyMesh.h
+++ b/src/mesh/tnlDummyMesh.h
@@ -32,6 +32,8 @@ class tnlDummyMesh
    static const int meshDimensions = 1;
 
    const Real& getParametricStep(){ return 0.0; }
+   
+   tnlString getSerializationType() const { return tnlString( "tnlDummyMesh" ); }
 
    template< typename GridFunction >
    typename GridFunction::RealType getDifferenceAbsMax( const GridFunction& f1,
diff --git a/src/operators/CMakeLists.txt b/src/operators/CMakeLists.txt
index f03203db39ba607c03ab96d63838a48af4928a17..49150421003fc0a9061b2b2f0aa73fe10a44ba64 100755
--- a/src/operators/CMakeLists.txt
+++ b/src/operators/CMakeLists.txt
@@ -1,16 +1,15 @@
-ADD_SUBDIRECTORY( gradient )
 ADD_SUBDIRECTORY( diffusion )
 ADD_SUBDIRECTORY( euler )
+ADD_SUBDIRECTORY( interpolants )
+ADD_SUBDIRECTORY( operator-Q )
+ADD_SUBDIRECTORY( operator-curvature )
 
 SET( headers tnlFiniteDifferences.h
              tnlFiniteDifferences_impl.h
              tnlDirichletBoundaryConditions.h
              tnlDirichletBoundaryConditions_impl.h
              tnlNeumannBoundaryConditions.h
-             tnlNeumannBoundaryConditions_impl.h
-             tnlExactOperatorEvaluator.h
-             tnlOperatorEnumerator.h
-             tnlOperatorEnumerator_impl.h )
+             tnlNeumannBoundaryConditions_impl.h )
              
 SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/operators )
 
@@ -30,4 +29,4 @@ set( tnl_operators_SOURCES
      ${common_SOURCES}
      PARENT_SCOPE )
    
-INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/operators )
\ No newline at end of file
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/operators )
diff --git a/src/operators/diffusion/CMakeLists.txt b/src/operators/diffusion/CMakeLists.txt
index cd9601b16a9b4459368b76351a5bef6c931b9ff4..789bc1f72c8908195c754d4eb330f6c3da04751d 100755
--- a/src/operators/diffusion/CMakeLists.txt
+++ b/src/operators/diffusion/CMakeLists.txt
@@ -1,7 +1,12 @@
+ADD_SUBDIRECTORY( nonlinear-diffusion-operators )
+
 SET( headers tnlLinearDiffusion.h
              tnlLinearDiffusion_impl.h
              tnlExactLinearDiffusion.h             
-             tnlExactLinearDiffusion_impl.h )
+             tnlExactLinearDiffusion_impl.h
+	     tnlOneSidedNonlinearDiffusion.h             
+             tnlExactNonlinearDiffusion.h
+             tnlOneSidedMeanCurvature.h )
 
 SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/operators/diffusion )
 
diff --git a/src/operators/diffusion/nonlinear-diffusion-operators/CMakeLists.txt b/src/operators/diffusion/nonlinear-diffusion-operators/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..f7487b5d9837550e62b509f1bbdcf3eec6e9859c
--- /dev/null
+++ b/src/operators/diffusion/nonlinear-diffusion-operators/CMakeLists.txt
@@ -0,0 +1,4 @@
+SET( headers tnlFiniteVolumeNonlinearOperator.h
+             tnlFiniteVolumeNonlinearOperator_impl.h )
+
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/operators/diffusion/nonlinear-diffusion-operators )
diff --git a/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator.h b/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator.h
new file mode 100644
index 0000000000000000000000000000000000000000..af39c588118eb976eec6425cd2c9d068d530c5e5
--- /dev/null
+++ b/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator.h
@@ -0,0 +1,179 @@
+#ifndef TNLFINITEVOLUMENONLINEAROPERATOR_H
+#define	TNLFINITEVOLUMENONLINEAROPERATOR_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename NonlinearDiffusionOperator,
+	  typename OperatorQ,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class tnlFiniteVolumeNonlinearOperator
+{
+ 
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+class tnlFiniteVolumeNonlinearOperator< tnlGrid< 1,MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef OperatorQ OperatorQType;
+
+   static tnlString getType();
+   
+   template< typename MeshEntity,
+             typename Vector >
+   __cuda_callable__
+   Real operator()( const MeshEntity& entity,
+                    const Vector& u,
+                    const RealType& time) const;
+   
+   template< typename MeshEntity >
+   __cuda_callable__
+   Index getLinearSystemRowLength( const MeshType& mesh,
+                                   const IndexType& index,
+                                   const MeshEntity& entity ) const;
+
+   template< typename MeshEntity,
+             typename MeshFunction,
+             typename Vector,
+             typename Matrix >
+   __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunction& u,
+                               Vector& b,
+                               Matrix& matrix ) const;
+   
+   public:
+   
+   OperatorQ operatorQ;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+class tnlFiniteVolumeNonlinearOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef OperatorQ OperatorQType;
+   
+
+   static tnlString getType();
+   
+   template< typename MeshEntity,
+             typename Vector >
+   __cuda_callable__
+   Real operator()( const MeshEntity& entity,
+                    const Vector& u,
+                    const RealType& time) const;
+   
+   
+   template< typename MeshEntity >
+   __cuda_callable__
+   Index getLinearSystemRowLength( const MeshType& mesh,
+                                   const IndexType& index,
+                                   const MeshEntity& entity ) const;
+
+   template< typename MeshEntity,
+             typename MeshFunction,
+             typename Vector,
+             typename Matrix >
+   __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunction& u,
+                               Vector& b,
+                               Matrix& matrix ) const;
+   
+   public:
+   
+   OperatorQ operatorQ;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+class tnlFiniteVolumeNonlinearOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef OperatorQ OperatorQType;
+
+   static tnlString getType();
+   
+   template< typename MeshEntity, 
+             typename Vector >
+   __cuda_callable__
+   Real operator()( const MeshEntity& entity,
+                    const Vector& u,
+                    const RealType& time) const;
+   
+   template< typename MeshEntity >
+   __cuda_callable__
+   Index getLinearSystemRowLength( const MeshType& mesh,
+                                   const IndexType& index,
+                                   const MeshEntity& entity ) const;
+
+   template< typename MeshEntity,
+             typename MeshFunction,
+             typename Vector,
+             typename Matrix >
+   __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunction& u,
+                               Vector& b,
+                               Matrix& matrix ) const;
+   
+   public:
+   
+   OperatorQ operatorQ;
+};
+
+
+#include "tnlFiniteVolumeNonlinearOperator_impl.h"
+
+
+#endif	/* TNLFINITEVOLUMENONLINEAROPERATOR_H */
diff --git a/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator_impl.h b/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..9bd82a6965d7253712ac51446a31577a95f3df22
--- /dev/null
+++ b/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator_impl.h
@@ -0,0 +1,309 @@
+
+#ifndef TNLFINITEVOLUMENONLINEAROPERATOR__IMPL_H
+#define	TNLFINITEVOLUMENONLINEAROPERATOR__IMPL_H
+
+#include "tnlFiniteVolumeNonlinearOperator.h"
+
+#include <mesh/tnlGrid.h>
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+tnlString
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getType()
+{
+   return tnlString( "tnlFiniteVolumeNonlinearOperator< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", " +
+	  OperatorQ::getType() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+template< typename MeshEntity,
+          typename Vector >
+__cuda_callable__
+Real
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+operator()( const MeshEntity& entity,
+          const Vector& u,
+          const Real& time ) const
+{
+   return 0.0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+   template< typename MeshEntity >
+__cuda_callable__
+Index
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   return 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+template< typename MeshEntity,
+          typename MeshFunction,
+          typename Vector,
+          typename Matrix >
+__cuda_callable__
+void
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunction& u,
+                    Vector& b,
+                    Matrix& matrix ) const
+{
+   typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+	  typename OperatorQ >
+tnlString
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getType()
+{
+   return tnlString( "tnlFiniteVolumeNonlinearOperator< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", " +
+	  OperatorQ::getType() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+template< typename MeshEntity,
+          typename Vector >
+__cuda_callable__
+Real
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+operator()( const MeshEntity& entity,
+            const Vector& u,
+            const Real& time ) const
+{
+   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const IndexType& cellIndex = entity.getIndex();
+   return operatorQ( entity, u, time ) * 
+      ( (  u[ neighbourEntities.template getEntityIndex<  1, 0 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -2, 0 >() / operatorQ.operator()( entity, u, time, 1 )
+      + (  u[ neighbourEntities.template getEntityIndex<  0, 1 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< 0, -2 >() / operatorQ.operator()( entity, u, time, 0, 1 ) 
+      - ( -u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] + u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -2, 0 >() / operatorQ.operator()( entity, u, time, -1)
+      - ( -u[ neighbourEntities.template getEntityIndex<  0,-1 >() ] + u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< 0, -2 >() / operatorQ.operator()( entity, u, time, 0, -1) );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+   template< typename MeshEntity >
+__cuda_callable__
+Index
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   return 5;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+template< typename MeshEntity, 
+          typename MeshFunction,
+          typename Vector,
+          typename Matrix >
+__cuda_callable__
+void
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunction& u,
+                    Vector& b,
+                    Matrix& matrix ) const
+{
+   typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+   const RealType aCoef = - tau * operatorQ.operator()( entity, u, time ) * mesh.template getSpaceStepsProducts< 0, -2 >() / 
+                       operatorQ.operator()( entity, u, time, 0, -1 );
+   const RealType bCoef = - tau * operatorQ.operator()( entity, u, time ) * mesh.template getSpaceStepsProducts< -2, 0 >() / 
+                       operatorQ.operator()( entity, u, time, -1 );
+   const RealType cCoef = tau * operatorQ.operator()( entity, u, time ) * ( mesh.template getSpaceStepsProducts< -2, 0 >() / 
+                       operatorQ.operator()( entity, u, time, 1 ) + mesh.template getSpaceStepsProducts< 0, -2 >() / 
+                       operatorQ.operator()( entity, u, time, 0, 1 )
+                       + mesh.template getSpaceStepsProducts< -2, 0 >() / operatorQ.operator()( entity, u, time, -1 ) + 
+                       mesh.template getSpaceStepsProducts< 0, -2 >() / operatorQ.operator()( entity, u, time, 0, -1 ) );
+   const RealType dCoef = - tau * operatorQ.operator()( entity, u, time ) * mesh.template getSpaceStepsProducts< -2, 0 >() / 
+                       operatorQ.operator()( entity, u, time, 1 );
+   const RealType eCoef = - tau * operatorQ.operator()( entity, u, time ) * mesh.template getSpaceStepsProducts< 0, -2 >() / 
+                       operatorQ.operator()(  entity, u, time, 0, 1 );
+   matrixRow.setElement( 0, neighbourEntities.template getEntityIndex<  0, -1 >(), aCoef );
+   matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< -1,  0 >(), bCoef );
+   matrixRow.setElement( 2, entity.getIndex(),                                     cCoef );
+   matrixRow.setElement( 3, neighbourEntities.template getEntityIndex<  1,  0 >(), dCoef );
+   matrixRow.setElement( 4, neighbourEntities.template getEntityIndex<  0,  1 >(), eCoef );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+ 	  typename OperatorQ >
+tnlString
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getType()
+{
+   return tnlString( "tnlFiniteVolumeNonlinearOperator< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", " +
+	  OperatorQ::getType() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+template< typename MeshEntity,
+          typename Vector >
+__cuda_callable__
+Real
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+operator()( const MeshEntity& entity,
+            const Vector& u,
+            const Real& time ) const
+{
+   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const IndexType& cellIndex = entity.getIndex();
+   return operatorQ( entity, u, time ) * 
+      ( (u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ]) 
+          * mesh.template getSpaceStepsProducts< -2, 0, 0 >() / operatorQ( entity, u, time, 1 )
+          + ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, -2, 0 >()/
+          operatorQ( entity, u, time, 0, 1 ) 
+          + ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, 0, -2 >()/
+          operatorQ( entity, u, time, 0, 0, 1 ) 
+          - ( - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ]  + u[ cellIndex ]) 
+          * mesh.template getSpaceStepsProducts< -2, 0, 0 >() / operatorQ( entity, u, time, -1)
+          -( - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] + u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, -2, 0 >()
+          /operatorQ( entity, u, time, 0, -1) 
+          -( - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] + u[ cellIndex ]) * mesh.template getSpaceStepsProducts< 0, 0, -2 >()
+          /operatorQ( entity, u, time, 0, 0, -1) );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+   template< typename MeshEntity >
+__cuda_callable__
+Index
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   return 7;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+template< typename MeshEntity,
+          typename MeshFunction,
+          typename Vector,
+          typename Matrix >
+#ifdef HAVE_CUDA
+__cuda_callable__
+#endif
+void
+tnlFiniteVolumeNonlinearOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunction& u,
+                    Vector& b,
+                    Matrix& matrix ) const
+{
+   typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+   const RealType aCoef = - tau * operatorQ( entity, u, time ) *
+                       mesh.template getSpaceStepsProducts< 0, 0, -2 >() / operatorQ.operator()( entity, u, time, 0, 0, -1 );
+   const RealType bCoef = - tau * operatorQ( entity, u, time ) * 
+                       mesh.template getSpaceStepsProducts< 0, -2, 0 >() / operatorQ.operator()( entity, u, time, 0, -1, 0 );
+   const RealType cCoef = - tau * operatorQ( entity, u, time ) * 
+                       mesh.template getSpaceStepsProducts< -2, 0, 0 >() / operatorQ.operator()( entity, u, time, -1, 0, 0 );
+   const RealType dCoef = tau * operatorQ( entity, u, time ) * ( 
+                       mesh.template getSpaceStepsProducts< -2, 0, 0 >() / operatorQ.operator()( entity, u, time, 1, 0, 0 ) + 
+                       mesh.template getSpaceStepsProducts< 0, -2, 0 >() / operatorQ.operator()( entity, u, time, 0, 1, 0 ) +
+                       mesh.template getSpaceStepsProducts< 0, 0, -2 >() / operatorQ.operator()( entity, u, time, 0, 0, 1 ) + 
+                       mesh.template getSpaceStepsProducts< -2, 0, 0 >() / operatorQ.operator()( entity, u, time, -1, 0, 0 ) +
+                       mesh.template getSpaceStepsProducts< 0, -2, 0 >() / operatorQ.operator()( entity, u, time, 0, -1, 0 ) + 
+                       mesh.template getSpaceStepsProducts< 0, 0, -2 >() / operatorQ.operator()( entity, u, time, 0, 0, -1 ) );
+   const RealType eCoef = - tau * operatorQ.operator()( entity, u, time ) *
+                       mesh.template getSpaceStepsProducts< -2, 0, 0 >() / operatorQ.operator()( entity, u, time, 1, 0, 0 );
+   const RealType fCoef = - tau * operatorQ.operator()( entity, u, time ) *
+                       mesh.template getSpaceStepsProducts< 0, -2, 0 >() / operatorQ.operator()( entity, u, time, 0, 1, 0 );
+   const RealType gCoef = - tau * operatorQ.operator()( entity, u, time ) * 
+                       mesh.template getSpaceStepsProducts< 0, 0, -2 >() / operatorQ.operator()( entity, u, time, 0, 0, 1 );
+   matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< 0,0,-1 >(), aCoef );
+   matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0,-1,0 >(), bCoef );
+   matrixRow.setElement( 2, neighbourEntities.template getEntityIndex< -1,0,0 >(), cCoef );
+   matrixRow.setElement( 3, entity.getIndex(),                                     dCoef );
+   matrixRow.setElement( 4, neighbourEntities.template getEntityIndex< 1,0,0 >(),  eCoef );
+   matrixRow.setElement( 5, neighbourEntities.template getEntityIndex< 0,1,0 >(),  fCoef );
+   matrixRow.setElement( 6, neighbourEntities.template getEntityIndex< 0,0,1 >(),  gCoef );
+}
+#endif	/* TNLFINITEVOLUMENONLINEAROPERATOR__IMPL_H */
diff --git a/src/operators/diffusion/nonlinear-diffusion-operators/tnlOneSideDiffNonlinearOperator.h~ b/src/operators/diffusion/nonlinear-diffusion-operators/tnlOneSideDiffNonlinearOperator.h~
new file mode 100644
index 0000000000000000000000000000000000000000..041307fa9a7e284a398ef402020bc02efb0a5e9e
--- /dev/null
+++ b/src/operators/diffusion/nonlinear-diffusion-operators/tnlOneSideDiffNonlinearOperator.h~
@@ -0,0 +1,194 @@
+#ifndef TNLONESIDEDIFFNONLINEAROPERATOR_H
+#define	TNLONESIDEDIFFNONLINEAROPERATOR_H
+
+#include <core/vectors/tnlVector.h>
+#include "tnlForwardFiniteDifference.h"
+#include "tnlBackwardFiniteDifference.h"
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename NonlinearDiffusionOperator,
+	  typename OperatorQ,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class tnlOneSideDiffNonlinearOperator
+{
+ 
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+class tnlOneSideDiffNonlinearOperator< tnlGrid< 1,MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef OperatorQ OperatorQType;
+
+   static tnlString getType();
+   
+   template< typename Vector >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+   Real getValue( const MeshType& mesh,
+                  const IndexType cellIndex,
+                  const CoordinatesType& coordinates,
+                  const Vector& u,
+                  const RealType& time) const;
+   
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+   Index getLinearSystemRowLength( const MeshType& mesh,
+                                   const IndexType& index,
+                                   const CoordinatesType& coordinates ) const
+   {}
+
+   template< typename Vector, typename MatrixRow >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const CoordinatesType& coordinates,
+                               Vector& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const
+   {}
+
+
+   private:
+
+   OperatorQ operatorQ;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+class tnlOneSideDiffNonlinearOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedej OperatorQ OperatorQType:
+   
+
+   static tnlString getType();
+   
+   template< typename Vector >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+   Real getValue( const MeshType& mesh,
+                  const IndexType cellIndex,
+                  const CoordinatesType& coordinates,
+                  const Vector& u,
+                  const RealType& time) const;
+   
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+   Index getLinearSystemRowLength( const MeshType& mesh,
+                                   const IndexType& index,
+                                   const CoordinatesType& coordinates ) const
+   {}
+
+   template< typename Vector, typename MatrixRow >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const CoordinatesType& coordinates,
+                               Vector& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const
+   {}
+
+   private:
+
+   OperatorQ operatorQ;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+class tnlOneSideDiffNonlinearOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedej OperatorQ OperatorQType;
+
+   static tnlString getType();
+   
+   template< typename Vector >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+   Real getValue( const MeshType& mesh,
+                  const IndexType cellIndex,
+                  const CoordinatesType& coordinates,
+                  const Vector& u,
+                  const RealType& time) const
+   {}
+   
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+   Index getLinearSystemRowLength( const MeshType& mesh,
+                                   const IndexType& index,
+                                   const CoordinatesType& coordinates ) const 
+   {}
+
+   template< typename Vector, typename MatrixRow >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const CoordinatesType& coordinates,
+                               Vector& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const 
+   {}
+
+};
+
+
+#include "tnlOneSideDiffNonlinearOperator_impl.h"
+
+
+#endif	/* TNLONESIDEDIFFNONLINEAROPERATOR_H */
diff --git a/src/operators/diffusion/nonlinear-diffusion-operators/tnlOneSideDiffNonlinearOperator_impl.h~ b/src/operators/diffusion/nonlinear-diffusion-operators/tnlOneSideDiffNonlinearOperator_impl.h~
new file mode 100644
index 0000000000000000000000000000000000000000..1bbd523ee06371fe7537b096d8c93217a2deae55
--- /dev/null
+++ b/src/operators/diffusion/nonlinear-diffusion-operators/tnlOneSideDiffNonlinearOperator_impl.h~
@@ -0,0 +1,84 @@
+
+#ifndef TNLONESIDEDIFFNONLINEAROPERATOR_IMPL_H
+#define	TNLONESIDEDIFFNONLINEAROPERATOR_IMPL_H
+
+#include "tnlOneSideDiffNonlinearOperator.h"
+
+#include <mesh/tnlGrid.h>
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+tnlString
+tnlOneSideDiffNonlinearOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getType()
+{
+   return tnlString( "tnlOneSideDiffNonlinearOperator< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", " +
+	  OperatorQ::getType() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+	  typename OperatorQ >
+tnlString
+tnlNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getType()
+{
+   return tnlString( "tnlOneSideDiffNonlinearOperator< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", " +
+	  OperatorQ::getType() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename OperatorQ >
+template< typename Vector >
+#ifdef HAVE_CUDA
+__device__ __host__
+#endif
+Real
+tnlNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getValue( const MeshType& mesh,
+          const IndexType cellIndex,
+          const CoordinatesType& coordinates,
+          const Vector& u,
+          const Real& time ) const
+{
+   return operatorQ.getValueStriped(mesh,cellIndex,u)*((fDifference.getValueX(mesh,cellIndex,u)/operatorQ.getValue(mesh,cellIndex,u)
+          -bDifference.getValueX(mesh,cellIndex,u)/operatorQ.getValue(mesh,mesh.template getCellNextToCell<-1,0>(cellIndex),u))
+          *mesh.getHxInverse()+(fDifference.getValueY(mesh,cellIndex,u)/operatorQ.getValue(mesh,cellIndex,u)
+          -bDifference.getValueY(mesh,cellIndex,u)/operatorQ.getValue(mesh,mesh.template getCellNextToCell<0,-1>(cellIndex),u))*mesh.getHyInverse());
+}
+       
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+ 	  typename OperatorQ >
+tnlString
+tnlNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
+getType()
+{
+   return tnlString( "tnlOneSideDiffNonlinearOperator< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", " +
+	  OperatorQ::getType() + " >";
+}
+
+#endif	/* TNLONESIDEDIFFNONLINEAROPERATOR_IMPL_H */
diff --git a/src/operators/diffusion/tnlExactLinearDiffusion.h b/src/operators/diffusion/tnlExactLinearDiffusion.h
index 2f8665e243501dd5c159e05c904bb98ceac6a0b8..af6dbf4c922a05b6f83812466ceb5fcb1f93ab22 100644
--- a/src/operators/diffusion/tnlExactLinearDiffusion.h
+++ b/src/operators/diffusion/tnlExactLinearDiffusion.h
@@ -18,52 +18,58 @@
 #ifndef TNLEXACTLINEARDIFFUSION_H_
 #define TNLEXACTLINEARDIFFUSION_H_
 
-#include <functions/tnlFunction.h>
+#include <functions/tnlDomain.h>
 
 template< int Dimensions >
 class tnlExactLinearDiffusion
 {};
 
 template<>
-class tnlExactLinearDiffusion< 1 > : public tnlFunction< 1, AnalyticFunction >
+class tnlExactLinearDiffusion< 1 > : public tnlDomain< 1, SpaceDomain >
 {
    public:
 
-      static tnlString getType();
+      static const int Dimensions = 1;
+      
+      static tnlString getType();      
    
       template< typename Function >
       __cuda_callable__ inline
-      typename Function::RealType getValue( const Function& function,
-                                            const typename Function::VertexType& v,
-                                            const typename Function::RealType& time = 0.0 ) const;
+      typename Function::RealType operator()( const Function& function,
+                                              const typename Function::VertexType& v,
+                                              const typename Function::RealType& time = 0.0 ) const;
 };
 
 template<>
-class tnlExactLinearDiffusion< 2 > : public tnlFunction< 2, AnalyticFunction >
+class tnlExactLinearDiffusion< 2 > : public tnlDomain< 2, SpaceDomain >
 {
    public:
       
-      static tnlString getType();
+      static const int Dimensions = 2;
+      
+      static tnlString getType();      
 
       template< typename Function >
       __cuda_callable__ inline
-      typename Function::RealType getValue( const Function& function,
-                                            const typename Function::VertexType& v,
-                                            const typename Function::RealType& time = 0.0 ) const;
+      typename Function::RealType operator()( const Function& function,
+                                              const typename Function::VertexType& v,
+                                              const typename Function::RealType& time = 0.0 ) const;
 };
 
 template<>
-class tnlExactLinearDiffusion< 3 > : public tnlFunction< 3 >
+class tnlExactLinearDiffusion< 3 > : public tnlDomain< 3 >
 {
    public:
       
+      static const int Dimensions = 3;
+      
       static tnlString getType();
 
       template< typename Function >
       __cuda_callable__ inline
-      typename Function::RealType getValue( const Function& function,
-                                            const typename Function::VertexType& v,
-                                            const typename Function::RealType& time = 0.0 ) const;
+      typename Function::RealType operator()( const Function& function,
+                                              const typename Function::VertexType& v,
+                                              const typename Function::RealType& time = 0.0 ) const;
 };
 
 #include <operators/diffusion/tnlExactLinearDiffusion_impl.h>
diff --git a/src/operators/diffusion/tnlExactLinearDiffusion_impl.h b/src/operators/diffusion/tnlExactLinearDiffusion_impl.h
index 580ccd10b9d2d1dbd43d667579fdc03224a32e6f..1903e6029887b2900bddab1587ffce2e6e791ca8 100644
--- a/src/operators/diffusion/tnlExactLinearDiffusion_impl.h
+++ b/src/operators/diffusion/tnlExactLinearDiffusion_impl.h
@@ -29,11 +29,11 @@ template< typename Function >
 __cuda_callable__ inline
 typename Function::RealType
 tnlExactLinearDiffusion< 1 >::
-getValue( const Function& function,
-          const typename Function::VertexType& v,
-          const typename Function::RealType& time ) const
+operator()( const Function& function,
+            const typename Function::VertexType& v,
+            const typename Function::RealType& time ) const
 {
-   return function.template getValue< 2, 0, 0 >( v, time );
+   return function.template getPartialDerivative< 2, 0, 0 >( v, time );
 }
 
 tnlString
@@ -47,12 +47,12 @@ template< typename Function >
 __cuda_callable__ inline
 typename Function::RealType
 tnlExactLinearDiffusion< 2 >::
-getValue( const Function& function,
-          const typename Function::VertexType& v,
+operator()( const Function& function,
+            const typename Function::VertexType& v,
           const typename Function::RealType& time ) const
 {
-   return function.template getValue< 2, 0, 0 >( v, time ) +
-          function.template getValue< 0, 2, 0 >( v, time );
+   return function.template getPartialDerivative< 2, 0, 0 >( v, time ) +
+          function.template getPartialDerivative< 0, 2, 0 >( v, time );
 }
 
 tnlString
@@ -66,13 +66,13 @@ template< typename Function >
 __cuda_callable__ inline
 typename Function::RealType
 tnlExactLinearDiffusion< 3 >::
-getValue( const Function& function,
-          const typename Function::VertexType& v,
-          const typename Function::RealType& time ) const
+operator()( const Function& function,
+            const typename Function::VertexType& v,
+            const typename Function::RealType& time ) const
 {
-   return function.template getValue< 2, 0, 0 >( v, time ) +
-          function.template getValue< 0, 2, 0 >( v, time ) +
-          function.template getValue< 0, 0, 2 >( v, time );
+   return function.template getPartialDerivative< 2, 0, 0 >( v, time ) +
+          function.template getPartialDerivative< 0, 2, 0 >( v, time ) +
+          function.template getPartialDerivative< 0, 0, 2 >( v, time );
 
 }
 
diff --git a/src/operators/diffusion/tnlExactMeanCurvature.h b/src/operators/diffusion/tnlExactMeanCurvature.h
new file mode 100644
index 0000000000000000000000000000000000000000..bb4b3d67fb798ad1c8d2a5605cea77c532528d12
--- /dev/null
+++ b/src/operators/diffusion/tnlExactMeanCurvature.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+                          tnlExactMeanCurvature.h  -  description
+                             -------------------
+    begin                : Feb 18, 2016
+    copyright            : (C) 2016 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 TNLEXACTMEANCURVATURE_H
+#define	TNLEXACTMEANCURVATURE_H
+
+#include<operators/diffusion/tnlExactNonlinearDiffusion.h>
+#include<operators/tnlExactFunctionInverseOperator.h>
+#include<operators/geometric/tnlExactGradientNorm.h>
+
+template< int Dimensions,
+          typename InnerOperator = tnlExactIdentityOperator< Dimensions > >
+class tnlExactMeanCurvature
+: public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+     
+      typedef tnlExactGradientNorm< Dimensions > ExactGradientNorm;
+      typedef tnlExactFunctionInverseOperator< Dimensions, ExactGradientNorm > FunctionInverse;
+      typedef tnlExactNonlinearDiffusion< Dimensions, FunctionInverse > NonlinearDiffusion;
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlExactMeanCurvature< " ) + 
+                tnlString( Dimensions) + ", " +
+                InnerOperator::getType() + " >";         
+      }
+      
+      template< typename Real >
+      void setRegularizationEpsilon( const Real& eps)
+      {
+         nonlinearDiffusion.getNonlinearity().getInnerOperator().setRegularizationEpislon( eps );
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+         operator()( const Function& function,
+                     const typename Function::VertexType& v, 
+                     const typename Function::RealType& time = 0.0 ) const
+      {
+         return this->nonlinearDiffusion( function, v, time );
+      }
+      
+      template< typename Function, 
+                int XDerivative = 0,
+                int YDerivative = 0,
+                int ZDerivative = 0 >
+      __cuda_callable__
+      typename Function::RealType
+         getPartialDerivative( const Function& function,
+                               const typename Function::VertexType& v,
+                               const typename Function::RealType& time = 0.0 ) const
+      {
+         static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
+            "Partial derivative must be non-negative integer." );
+         static_assert( XDerivative + YDerivative + ZDerivative < 1, "Partial derivative of higher order then 1 are not implemented yet." );
+         typedef typename Function::RealType RealType;
+         
+         if( XDerivative == 1 )
+         {
+         }
+         if( YDerivative == 1 )
+         {
+         }
+         if( ZDerivative == 1 )
+         {
+         }         
+      }
+      
+      
+   protected:
+      
+      ExactGradientNorm gradientNorm;
+      
+      FunctionInverse functionInverse;
+      
+      NonlinearDiffusion nonlinearDiffusion;
+      
+};
+
+
+#endif	/* TNLEXACTMEANCURVATURE_H */
+
diff --git a/src/operators/diffusion/tnlExactNonlinearDiffusion.h b/src/operators/diffusion/tnlExactNonlinearDiffusion.h
new file mode 100644
index 0000000000000000000000000000000000000000..3dd005bc237d56b8539c8acb9fcba8ebd8179848
--- /dev/null
+++ b/src/operators/diffusion/tnlExactNonlinearDiffusion.h
@@ -0,0 +1,207 @@
+/***************************************************************************
+                          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 TNLEXACTNONLINEARDIFFUSION_H_
+#define TNLEXACTNONLINEARDIFFUSION_H_
+
+#include <functions/tnlDomain.h>
+#include <operators/tnlExactIdentityOperator.h>
+
+
+template<  int Dimensions, 
+           typename Nonlinearity,
+           typename InnerOperator = tnlExactIdentityOperator< Dimensions > >
+class tnlExactNonlinearDiffusion
+{};
+
+
+template< typename Nonlinearity,
+          typename InnerOperator >
+class tnlExactNonlinearDiffusion< 1, Nonlinearity, InnerOperator > 
+   : public tnlDomain< 1, SpaceDomain >
+{
+   public:
+
+      static tnlString getType()
+      {
+         return "tnlExactNonlinearDiffusion< 1, " + Nonlinearity::getType() + " >";
+      };
+      
+      Nonlinearity& getNonlinearity()
+      {
+         return this->nonlinearity;
+      }
+      
+      const Nonlinearity& getNonlinearity() const
+      {
+         return this->nonlinearity;
+      }
+      
+      InnerOperator& getInnerOperator()
+      {
+         return this->innerOperator;
+      }
+      
+      const InnerOperator& getInnerOperator() const
+      {
+         return this->innerOperator;
+      }      
+   
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType
+      operator()( const Function& function,
+                  const typename Function::VertexType& v,
+                  const typename Function::RealType& time = 0.0 ) const
+      {
+         typedef typename Function::RealType RealType;         
+         const RealType u_x = innerOperator.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );
+         const RealType u_xx = innerOperator.template getPartialDerivative< Function, 2, 0, 0 >( function, v, time );
+         const RealType g = nonlinearity( function, v, time ); 
+         const RealType g_x = nonlinearity.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );
+         return u_xx - u_x * g_x / g;          
+      }
+   
+      protected:
+         
+         Nonlinearity nonlinearity;
+
+         InnerOperator innerOperator;
+};
+
+template< typename Nonlinearity,
+          typename InnerOperator >
+class tnlExactNonlinearDiffusion< 2, Nonlinearity, InnerOperator >
+   : public tnlDomain< 2, SpaceDomain >
+{
+   public:
+      
+      static tnlString getType()
+      {
+         return "tnlExactNonlinearDiffusion< " + Nonlinearity::getType() + ", 2 >";
+      };
+      
+      Nonlinearity& getNonlinearity()
+      {
+         return this->nonlinearity;
+      }
+      
+      const Nonlinearity& getNonlinearity() const
+      {
+         return this->nonlinearity;
+      }
+      
+      InnerOperator& getInnerOperator()
+      {
+         return this->innerOperator;
+      }
+      
+      const InnerOperator& getInnerOperator() const
+      {
+         return this->innerOperator;
+      }      
+
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType
+      operator()( const Function& function,
+                  const typename Function::VertexType& v,
+                  const typename Function::RealType& time = 0.0 ) const
+      {
+         typedef typename Function::RealType RealType;         
+         const RealType u_x  = innerOperator.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );
+         const RealType u_y  = innerOperator.template getPartialDerivative< Function, 0, 1, 0 >( function, v, time );
+         const RealType u_xx = innerOperator.template getPartialDerivative< Function, 2, 0, 0 >( function, v, time );
+         const RealType u_yy = innerOperator.template getPartialDerivative< Function, 0, 2, 0 >( function, v, time );
+         const RealType g   = nonlinearity( function, v, time ); 
+         const RealType g_x = nonlinearity.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );
+         const RealType g_y = nonlinearity.template getPartialDerivative< Function, 0, 1, 0 >( function, v, time );
+
+         return  u_xx + u_yy - ( g_x * u_x + g_y * u_y ) / g; 
+      }
+
+      protected:
+         
+         Nonlinearity nonlinearity;
+         
+         InnerOperator innerOperator;
+      
+};
+
+template< typename Nonlinearity,
+          typename InnerOperator  >
+class tnlExactNonlinearDiffusion< 3, Nonlinearity, InnerOperator >
+   : public tnlDomain< 3, SpaceDomain >
+{
+   public:
+      
+      static tnlString getType()
+      {
+         return "tnlExactNonlinearDiffusion< " + Nonlinearity::getType() + ", 3 >";
+      }
+      
+      Nonlinearity& getNonlinearity()
+      {
+         return this->nonlinearity;
+      }
+      
+      const Nonlinearity& getNonlinearity() const
+      {
+         return this->nonlinearity;
+      }
+      
+      InnerOperator& getInnerOperator()
+      {
+         return this->innerOperator;
+      }
+      
+      const InnerOperator& getInnerOperator() const
+      {
+         return this->innerOperator;
+      }      
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+      operator()( const Function& function,
+                  const typename Function::VertexType& v,
+                  const typename Function::RealType& time = 0.0 ) const
+      {
+         typedef typename Function::RealType RealType;         
+         const RealType u_x  = innerOperator.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );
+         const RealType u_y  = innerOperator.template getPartialDerivative< Function, 0, 1, 0 >( function, v, time );
+         const RealType u_z  = innerOperator.template getPartialDerivative< Function, 0, 0, 1 >( function, v, time );
+         const RealType u_xx = innerOperator.template getPartialDerivative< Function, 2, 0, 0 >( function, v, time );
+         const RealType u_yy = innerOperator.template getPartialDerivative< Function, 0, 2, 0 >( function, v, time );
+         const RealType u_zz = innerOperator.template getPartialDerivative< Function, 0, 0, 2 >( function, v, time );
+         const RealType g   = nonlinearity( function, v, time ) ;
+         const RealType g_x = nonlinearity.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );
+         const RealType g_y = nonlinearity.template getPartialDerivative< Function, 0, 1, 0 >( function, v, time );
+         const RealType g_z = nonlinearity.template getPartialDerivative< Function, 0, 0, 1 >( function, v, time );
+
+         return  u_xx + u_yy + u_zz - ( g_x * u_x + g_y * u_y + g_z * u_z ) / g; 
+      }
+      
+      protected:
+         
+         Nonlinearity nonlinearity;
+         
+         InnerOperator innerOperator;
+};
+
+
+#endif /* TNLEXACTNONLINEARDIFFUSION_H_ */
diff --git a/src/operators/diffusion/tnlLinearDiffusion.h b/src/operators/diffusion/tnlLinearDiffusion.h
index c416c922435c363863031722785a781f64231e88..b4683676e673a985b0a233f5a3f016b9f8bf7f4e 100644
--- a/src/operators/diffusion/tnlLinearDiffusion.h
+++ b/src/operators/diffusion/tnlLinearDiffusion.h
@@ -19,7 +19,10 @@
 #define	TNLLINEARDIFFUSION_H
 
 #include <core/vectors/tnlVector.h>
+#include <functions/tnlMeshFunction.h>
 #include <mesh/tnlGrid.h>
+#include <operators/tnlOperator.h>
+#include <operators/diffusion/tnlExactLinearDiffusion.h>
 
 template< typename Mesh,
           typename Real = typename Mesh::RealType,
@@ -36,6 +39,8 @@ template< typename MeshReal,
           typename Real,
           typename Index >
 class tnlLinearDiffusion< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >
+: public tnlOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >,
+                      MeshInteriorDomain, 1, 1, Real, Index >
 {
    public:    
    
@@ -43,32 +48,40 @@ class tnlLinearDiffusion< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef Real RealType;
       typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef typename MeshType::template GridEntity< MeshType::meshDimensions > CellType;
-      enum { Dimensions = MeshType::meshDimensions };
+      typedef Index IndexType;      
+      typedef tnlExactLinearDiffusion< 1 > ExactOperatorType;
+      
+      static const int Dimensions = MeshType::meshDimensions;
+      
+      static constexpr int getMeshDimensions() { return Dimensions; }
+      
+      template< int EntityDimensions = Dimensions >
+      using MeshFunction = tnlMeshFunction< MeshType, EntityDimensions >;
 
       static tnlString getType();
 
-      template< typename Vector >
+      template< typename PreimageFunction, typename MeshEntity >
       __cuda_callable__
-      inline Real getValue( const MeshType& mesh,
-                            const CellType& cell,
-                            const Vector& u,
-                            const RealType& time ) const;
+      inline Real operator()( const PreimageFunction& u,
+                              const MeshEntity& entity,
+                              const RealType& time = 0.0 ) const;
 
+      template< typename MeshEntity >
       __cuda_callable__
       inline Index getLinearSystemRowLength( const MeshType& mesh,
                                              const IndexType& index,
-                                             const CellType& cell ) const;
+                                             const MeshEntity& entity ) const;
 
-      template< typename Vector, typename MatrixRow >
+      template< typename MeshEntity,
+                typename Vector,
+                typename MatrixRow >
       __cuda_callable__
       inline void updateLinearSystem( const RealType& time,
                                       const RealType& tau,
                                       const MeshType& mesh,
                                       const IndexType& index,
-                                      const CellType& cell,
-                                      Vector& u,
+                                      const MeshEntity& entity,
+                                      const MeshFunction< 1 >& u,
                                       Vector& b,
                                       MatrixRow& matrixRow ) const;
 
@@ -81,6 +94,8 @@ template< typename MeshReal,
           typename Real,
           typename Index >
 class tnlLinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >
+: public tnlOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >,
+                      MeshInteriorDomain, 2, 2, Real, Index >
 {
    public: 
    
@@ -88,18 +103,24 @@ class tnlLinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index
       typedef typename MeshType::CoordinatesType CoordinatesType;
       typedef Real RealType;
       typedef Device DeviceType;
-      typedef Index IndexType;
-      enum { Dimensions = MeshType::meshDimensions };
+      typedef Index IndexType;      
+      typedef tnlExactLinearDiffusion< 2 > ExactOperatorType;
+      
+      static const int Dimensions = MeshType::meshDimensions;
+      
+      static constexpr int getMeshDimensions() { return Dimensions; }
+
+      
+      template< int EntityDimensions = Dimensions >
+      using MeshFunction = tnlMeshFunction< MeshType, EntityDimensions >;      
 
       static tnlString getType();
 
-      template< typename Vector,
-                typename EntityType >
+      template< typename PreimageFunction, typename EntityType >
       __cuda_callable__
-      inline Real getValue( const MeshType& mesh,
-                            const EntityType& entity,
-                            const Vector& u,
-                            const Real& time ) const;
+      inline Real operator()( const PreimageFunction& u,
+                              const EntityType& entity,
+                              const Real& time = 0.0 ) const;
 
       template< typename EntityType >
       __cuda_callable__
@@ -116,7 +137,7 @@ class tnlLinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index
                                       const MeshType& mesh,
                                       const IndexType& index,
                                       const EntityType& entity,
-                                      Vector& u,
+                                      const MeshFunction< 2 >& u,
                                       Vector& b,
                                       MatrixRow& matrixRow ) const;
 };
@@ -128,6 +149,8 @@ template< typename MeshReal,
           typename Real,
           typename Index >
 class tnlLinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+: public tnlOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >,
+                      MeshInteriorDomain, 3, 3, Real, Index >
 {
    public: 
    
@@ -136,17 +159,24 @@ class tnlLinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index
       typedef Real RealType;
       typedef Device DeviceType;
       typedef Index IndexType;
-      enum { Dimensions = MeshType::meshDimensions };
+      typedef tnlExactLinearDiffusion< 3 > ExactOperatorType;
+
+      static const int Dimensions = MeshType::meshDimensions;
+      
+      static constexpr int getMeshDimensions() { return Dimensions; }      
 
+      template< int EntityDimensions = Dimensions >
+      using MeshFunction = tnlMeshFunction< MeshType, EntityDimensions >;
+
+      
       static tnlString getType();
 
-      template< typename Vector,
+      template< typename PreimageFunction, 
                 typename EntityType >
       __cuda_callable__
-      inline Real getValue( const MeshType& mesh,
-                            const EntityType& entity,
-                            const Vector& u,
-                            const Real& time ) const;
+      inline Real operator()( const PreimageFunction& u,
+                              const EntityType& entity,
+                              const Real& time = 0.0 ) const;
 
       template< typename EntityType >
       __cuda_callable__
@@ -163,7 +193,7 @@ class tnlLinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index
                                       const MeshType& mesh,
                                       const IndexType& index,
                                       const EntityType& entity,
-                                      Vector& u,
+                                      const MeshFunction< 3 >& u,
                                       Vector& b,
                                       MatrixRow& matrixRow ) const;
 
diff --git a/src/operators/diffusion/tnlLinearDiffusion_impl.h b/src/operators/diffusion/tnlLinearDiffusion_impl.h
index 32bf945ff68fddcb3c80fe47949822f1d573ada5..ef38d2e8b0f65119b6769fb778b9475df777ec4d 100644
--- a/src/operators/diffusion/tnlLinearDiffusion_impl.h
+++ b/src/operators/diffusion/tnlLinearDiffusion_impl.h
@@ -41,20 +41,22 @@ template< typename MeshReal,
           typename MeshIndex,
           typename Real,
           typename Index >
-template< typename Vector >
+template< typename PreimageFunction,
+          typename MeshEntity >
 __cuda_callable__
 inline
 Real
 tnlLinearDiffusion< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-getValue( const MeshType& mesh,
-          const CellType& cell,
-          const Vector& u,
-          const Real& time ) const
+operator()( const PreimageFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
 {
-   const typename CellType::template NeighbourEntities< 1 >& neighbourEntities = cell.getNeighbourEntities();
-   const RealType& hxSquareInverse = mesh.template getSpaceStepsProducts< - 2 >();
+   static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimensions() == 1, "Wrong preimage function" );
+   const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< - 2 >();
    return ( u[ neighbourEntities.template getEntityIndex< -1 >() ]
-            - 2.0 * u[ cell.getIndex() ]
+            - 2.0 * u[ entity.getIndex() ]
             + u[ neighbourEntities.template getEntityIndex< 1 >() ] ) * hxSquareInverse;
 }
 
@@ -63,13 +65,14 @@ template< typename MeshReal,
           typename MeshIndex,
           typename Real,
           typename Index >
+   template< typename MeshEntity >          
 __cuda_callable__
 inline
 Index
 tnlLinearDiffusion< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
 getLinearSystemRowLength( const MeshType& mesh,
                           const IndexType& index,
-                          const CellType& cell ) const
+                          const MeshEntity& entity ) const
 {
    return 3;
 }
@@ -79,7 +82,9 @@ template< typename MeshReal,
           typename MeshIndex,
           typename Real,
           typename Index >
-   template< typename Vector, typename Matrix >
+   template< typename MeshEntity,
+             typename Vector, 
+             typename Matrix >
 __cuda_callable__
 inline
 void
@@ -88,12 +93,12 @@ updateLinearSystem( const RealType& time,
                     const RealType& tau,
                     const MeshType& mesh,
                     const IndexType& index,
-                    const CellType& cell,
-                    Vector& u,
+                    const MeshEntity& entity,
+                    const MeshFunction< 1 >& u,
                     Vector& b,
                     Matrix& matrix ) const
 {
-   const typename CellType::template NeighbourEntities< 1 >& neighbourEntities = cell.getNeighbourEntities();
+   const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
    const RealType lambdaX = tau * mesh.template getSpaceStepsProducts< -2 >();
    matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< -1 >(),      - lambdaX );
@@ -139,20 +144,21 @@ template< typename MeshReal,
           typename MeshIndex,
           typename Real,
           typename Index >
-template< typename Vector,
+template< typename PreimageFunction,
           typename EntityType >
 __cuda_callable__
 inline
 Real
 tnlLinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-getValue( const MeshType& mesh,
-          const EntityType& entity,
-          const Vector& u,
-          const Real& time ) const
+operator()( const PreimageFunction& u,
+            const EntityType& entity,
+            const Real& time ) const
 {
+   static_assert( EntityType::entityDimensions == 2, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimensions() == 2, "Wrong preimage function" );
    const typename EntityType::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
-   const RealType& hxSquareInverse = mesh.template getSpaceStepsProducts< -2, 0 >();
-   const RealType& hySquareInverse = mesh.template getSpaceStepsProducts< 0, -2 >();
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >();
+   const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2 >();
    return ( u[ neighbourEntities.template getEntityIndex< -1,  0 >() ]
           + u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] ) * hxSquareInverse +
           ( u[ neighbourEntities.template getEntityIndex<  0, -1 >() ]
@@ -177,7 +183,7 @@ updateLinearSystem( const RealType& time,
                     const MeshType& mesh,
                     const IndexType& index,
                     const EntityType& entity,
-                    Vector& u,
+                    const MeshFunction< 2 >& u,
                     Vector& b,
                     Matrix& matrix ) const
 {
@@ -213,21 +219,22 @@ template< typename MeshReal,
           typename MeshIndex,
           typename Real,
           typename Index >
-template< typename Vector,
+template< typename PreimageFunction,
           typename EntityType >
 __cuda_callable__
 inline
 Real
 tnlLinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-getValue( const MeshType& mesh,
-          const EntityType& entity,
-          const Vector& u,
-          const Real& time ) const
+operator()( const PreimageFunction& u,
+            const EntityType& entity,
+            const Real& time ) const
 {
+   static_assert( EntityType::entityDimensions == 3, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimensions() == 3, "Wrong preimage function" );
    const typename EntityType::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
-   const RealType& hxSquareInverse = mesh.template getSpaceStepsProducts< -2,  0,  0 >();
-   const RealType& hySquareInverse = mesh.template getSpaceStepsProducts<  0, -2,  0 >();
-   const RealType& hzSquareInverse = mesh.template getSpaceStepsProducts<  0,  0, -2 >();
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >();
+   const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >();
+   const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts<  0,  0, -2 >();
    return (   u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ]
             + u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] ) * hxSquareInverse +
           (   u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ]
@@ -271,7 +278,7 @@ updateLinearSystem( const RealType& time,
                     const MeshType& mesh,
                     const IndexType& index,
                     const EntityType& entity,
-                    Vector& u,
+                    const MeshFunction< 3 >& u,
                     Vector& b,
                     Matrix& matrix ) const
 {
@@ -279,7 +286,7 @@ updateLinearSystem( const RealType& time,
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
    const RealType lambdaX = tau * mesh.template getSpaceStepsProducts< -2, 0, 0 >();
    const RealType lambdaY = tau * mesh.template getSpaceStepsProducts< 0, -2, 0 >();
-   const RealType lambdaZ = tau * mesh.template getSpaceStepsProducts< 0, 0, -2 >();
+   const RealType  lambdaZ = tau * mesh.template getSpaceStepsProducts< 0, 0, -2 >();
    matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< 0, 0, -1 >(), -lambdaZ );
    matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, -1, 0 >(), -lambdaY );
    matrixRow.setElement( 2, neighbourEntities.template getEntityIndex< -1, 0, 0 >(), -lambdaX );
diff --git a/src/operators/diffusion/tnlNonlinearDiffusion_impl.h b/src/operators/diffusion/tnlNonlinearDiffusion_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..88f0bae7ea1b840b24c3f37e73f5a2ba4874a69d
--- /dev/null
+++ b/src/operators/diffusion/tnlNonlinearDiffusion_impl.h
@@ -0,0 +1,240 @@
+
+#ifndef TNLNONLINEARDIFFUSION_IMPL_H
+#define	TNLNONLINEARDIFFUSION_IMPL_H
+
+#include "tnlNonlinearDiffusion.h"
+
+#include <mesh/tnlGrid.h>
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+tnlString
+tnlNonlinearDiffusion< tnlGrid< 1, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+getType()
+{
+   return tnlString( "tnlNonlinearDiffusion< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + "," +
+          NonlinearDiffusionOperator::getType() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+template< typename MeshEntity,
+          typename Vector >
+__cuda_callable__
+Real
+tnlNonlinearDiffusion< tnlGrid< 1, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+operator()( const MeshEntity& entity,
+            const Vector& u,
+            const Real& time ) const
+{
+    return nonlinearDiffusionOperator( u, entity, time );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+   template< typename MeshEntity >          
+__cuda_callable__
+Index
+tnlNonlinearDiffusion< tnlGrid< 1, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   return nonlinearDiffusionOperator.getLinearSystemRowLength( mesh, index, entity );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+template< typename MeshEntity,
+          typename MeshFunction,
+          typename Vector,           
+          typename Matrix >
+__cuda_callable__
+void
+tnlNonlinearDiffusion< tnlGrid< 1, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunction& u,
+                    Vector& b,
+                    Matrix& matrix ) const
+{
+    nonlinearDiffusionOperator.updateLinearSystem( time, tau, mesh, index, entity, u, b, matrix );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+tnlString
+tnlNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+getType()
+{
+   return tnlString( "tnlNonlinearDiffusion< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + "," +
+          NonlinearDiffusionOperator::getType() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+template< typename MeshEntity,
+          typename Vector >
+__cuda_callable__
+Real
+tnlNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+operator()( const MeshEntity& entity,
+            const Vector& u,
+            const Real& time ) const
+{
+    return nonlinearDiffusionOperator( u, entity, time );
+}
+       
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+   template< typename MeshEntity >
+__cuda_callable__
+Index
+tnlNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   return nonlinearDiffusionOperator.getLinearSystemRowLength( mesh, index, entity );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+template< typename MeshEntity,
+          typename MeshFunction,
+          typename Vector,           
+          typename Matrix >
+__cuda_callable__
+void
+tnlNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunction& u,
+                    Vector& b,
+                    Matrix& matrix ) const
+{
+    nonlinearDiffusionOperator.updateLinearSystem( time, tau, mesh, index, entity, u, b, matrix );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+tnlString
+tnlNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+getType()
+{
+   return tnlString( "tnlNonlinearDiffusion< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + "," +
+          NonlinearDiffusionOperator::getType() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+template< typename MeshEntity,
+          typename Vector >
+__cuda_callable__
+Real
+tnlNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+operator()( const MeshEntity& entity,
+            const Vector& u,
+            const Real& time ) const
+{
+    return nonlinearDiffusionOperator( u, entity, time );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+   template< typename MeshEntity >
+__cuda_callable__
+Index
+tnlNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   return nonlinearDiffusionOperator.getLinearSystemRowLength( mesh, index, entity );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          typename NonlinearDiffusionOperator >
+template< typename MeshEntity,
+          typename MeshFunction,
+          typename Vector,          
+          typename Matrix >
+__cuda_callable__
+void
+tnlNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunction& u,
+                    Vector& b,
+                    Matrix& matrix ) const
+{
+    nonlinearDiffusionOperator.updateLinearSystem( time, tau, mesh, index, entity, u, b, matrix );
+}
+
+#endif	/* TNLNONLINEARDIFFUSION_IMPL_H */
diff --git a/src/operators/diffusion/tnlOneSidedMeanCurvature.h b/src/operators/diffusion/tnlOneSidedMeanCurvature.h
new file mode 100644
index 0000000000000000000000000000000000000000..87386d89d8fe0145235e6b6c9f09b9226f536bbb
--- /dev/null
+++ b/src/operators/diffusion/tnlOneSidedMeanCurvature.h
@@ -0,0 +1,135 @@
+/***************************************************************************
+                          tnlOneSidedMeanCurvature.h  -  description
+                             -------------------
+    begin                : Feb 17, 2016
+    copyright            : (C) 2016 by 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 TNLONESIDEDTOTALVARIATIONMINIMIZATION_H
+#define	TNLONESIDEDTOTALVARIATIONMINIMIZATION_H
+
+#include <operators/tnlOperator.h>
+#include <operators/tnlFunctionInverseOperator.h>
+#include <operators/geometric/tnlFDMGradientNorm.h>
+#include <operators/tnlNeumannBoundaryConditions.h>
+#include <operators/diffusion/tnlOneSidedNonlinearDiffusion.h>
+#include <functions/tnlOperatorFunction.h>
+#include <functions/tnlConstantFunction.h>
+#include <operators/diffusion/tnlExactMeanCurvature.h>
+
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType,
+          bool EvaluateNonlinearityOnFly = false >
+class tnlOneSidedMeanCurvature
+   : public tnlOperator< Mesh, MeshInteriorDomain, Mesh::getMeshDimensions(), Mesh::getMeshDimensions(), Real, Index >
+{
+   public:
+            
+      typedef Mesh MeshType;
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef tnlFDMGradientNorm< MeshType, tnlForwardFiniteDifference, RealType, IndexType > GradientNorm;
+      typedef tnlFunctionInverseOperator< GradientNorm > NonlinearityOperator;
+      typedef tnlMeshFunction< MeshType, MeshType::getMeshDimensions(), RealType > NonlinearityMeshFunction;
+      typedef tnlConstantFunction< MeshType::getMeshDimensions(), RealType > NonlinearityBoundaryConditionsFunction;
+      typedef tnlNeumannBoundaryConditions< MeshType, NonlinearityBoundaryConditionsFunction > NonlinearityBoundaryConditions;
+      typedef tnlOperatorFunction< NonlinearityOperator, NonlinearityMeshFunction, NonlinearityBoundaryConditions, EvaluateNonlinearityOnFly > Nonlinearity;
+      typedef tnlOneSidedNonlinearDiffusion< Mesh, Nonlinearity, RealType, IndexType > NonlinearDiffusion;
+      typedef tnlExactMeanCurvature< Mesh::getMeshDimensions(), RealType > ExactOperatorType;
+      
+      tnlOneSidedMeanCurvature( const MeshType& mesh )
+      : nonlinearityOperator( gradientNorm ),
+        nonlinearity( nonlinearityOperator, nonlinearityBoundaryConditions, mesh ),
+        nonlinearDiffusion( nonlinearity ){}
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlOneSidedMeanCurvature< " ) +
+            MeshType::getType() + ", " +
+            ::getType< Real >() + ", " +
+            ::getType< Index >() + " >";         
+      }
+      
+      void setRegularizationEpsilon( const RealType& eps )
+      {
+         this->gradientNorm.setEps( eps );
+      }
+      
+      void setPreimageFunction( typename Nonlinearity::PreimageFunctionType& preimageFunction )
+      {
+         this->nonlinearity.setPreimageFunction( preimageFunction );
+      }
+      
+      bool refresh( const RealType& time = 0.0 )
+      {
+         return this->nonlinearity.refresh( time );
+      }
+      
+      bool deepRefresh( const RealType& time = 0.0 )
+      {
+         return this->nonlinearity.deepRefresh( time );
+      }      
+      
+      template< typename MeshFunction,
+                typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         return this->nonlinearDiffusion( u, entity, time );
+      }
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const
+      {
+         return this->nonlinearDiffusion.getLinearSystemRowLength( mesh, index, entity );
+      }
+
+      template< typename MeshEntity,
+                typename MeshFunction,
+                typename Vector,
+                typename Matrix >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunction& u,
+                               Vector& b,
+                               Matrix& matrix ) const
+      {
+         this->nonlinearDiffusion.updateLinearSystem( time, tau, mesh, index, entity, u, b, matrix );
+      }            
+      
+   protected:      
+      
+      NonlinearityBoundaryConditions nonlinearityBoundaryConditions;
+      
+      GradientNorm gradientNorm;
+
+      NonlinearityOperator nonlinearityOperator;
+      
+      Nonlinearity nonlinearity;
+      
+      NonlinearDiffusion nonlinearDiffusion;            
+};
+
+#endif	/* TNLONESIDEDTOTALVARIATIONMINIMIZATION_H */
+
diff --git a/src/operators/diffusion/tnlOneSidedNonlinearDiffusion.h b/src/operators/diffusion/tnlOneSidedNonlinearDiffusion.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a1e95bfe43b6fb5bf9a6d2a55cf087db8bcb442
--- /dev/null
+++ b/src/operators/diffusion/tnlOneSidedNonlinearDiffusion.h
@@ -0,0 +1,371 @@
+/***************************************************************************
+                          tnlOneSidedNonlinearDiffusion.h  -  description
+                             -------------------
+    begin                : Feb 16, 2016
+    copyright            : (C) 2016 by 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 TNLONESIDEDNONLINEARDIFFUSION_H
+#define	TNLONESIDEDNONLINEARDIFFUSION_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+#include <operators/diffusion/tnlExactNonlinearDiffusion.h>
+
+template< typename Mesh,
+          typename Nonlinearity,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class tnlOneSidedNonlinearDiffusion
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Nonlinearity,
+          typename Real,
+          typename Index >
+class tnlOneSidedNonlinearDiffusion< tnlGrid< 1,MeshReal, Device, MeshIndex >, Nonlinearity, Real, Index >
+{
+   public: 
+   
+      typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef Nonlinearity NonlinearityType;
+      typedef typename MeshType::template MeshEntity< MeshType::getMeshDimensions() > CellType;
+      typedef tnlExactNonlinearDiffusion< MeshType::getMeshDimensions(), typename Nonlinearity::ExactOperatorType, Real > ExactOperatorType;
+
+      tnlOneSidedNonlinearDiffusion( const Nonlinearity& nonlinearity )
+      : nonlinearity( nonlinearity ){}
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlOneSidedNonlinearDiffusion< " ) +
+            MeshType::getType() + ", " +
+            Nonlinearity::getType() + "," +
+            ::getType< Real >() + ", " +
+            ::getType< Index >() + " >";         
+      }     
+
+      template< typename MeshFunction,
+                typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::MeshType& mesh = entity.getMesh();
+         const RealType& hx_div = mesh.template getSpaceStepsProducts< -2 >();
+         const IndexType& center = entity.getIndex();
+         const IndexType& east = neighbourEntities.template getEntityIndex<  1 >();
+         const IndexType& west = neighbourEntities.template getEntityIndex< -1 >();
+         const RealType& u_c = u[ center ];
+         const RealType u_x_f = ( u[ east ] - u_c );
+         const RealType u_x_b = ( u_c - u[ west ] );
+         return ( u_x_f * this->nonlinearity[ center ] -
+                  u_x_b * this->nonlinearity[ west ] ) * hx_div;
+         
+      }
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const
+      {
+         return 3;
+      }
+
+      template< typename MeshEntity,
+                typename MeshFunction,
+                typename Vector,
+                typename Matrix >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunction& u,
+                               Vector& b,
+                               Matrix& matrix ) const
+      {
+         typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const IndexType& center = entity.getIndex();
+         const IndexType& east = neighbourEntities.template getEntityIndex<  1 >();
+         const IndexType& west = neighbourEntities.template getEntityIndex< -1 >();
+         const RealType lambda_x = tau * mesh.template getSpaceStepsProducts< -2 >();
+         const RealType& nonlinearity_center = this->nonlinearity[ center ];
+         const RealType& nonlinearity_west = this->nonlinearity[ west ];
+         const RealType aCoef = -lambda_x * nonlinearity_west;
+         const RealType bCoef = lambda_x * ( nonlinearity_center + nonlinearity_west );              
+         const RealType cCoef = -lambda_x * nonlinearity_center;
+         matrixRow.setElement( 0, west,   aCoef );
+         matrixRow.setElement( 1, center, bCoef );
+         matrixRow.setElement( 2, east,   cCoef );
+      }
+
+   public:
+       
+      const Nonlinearity& nonlinearity;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Nonlinearity,
+          typename Real,
+          typename Index >
+class tnlOneSidedNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, Nonlinearity, Real, Index >
+{
+   public: 
+   
+      typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef Nonlinearity NonlinearityType;
+      typedef tnlExactNonlinearDiffusion< MeshType::getMeshDimensions(), typename Nonlinearity::ExactOperatorType, Real > ExactOperatorType;      
+
+      tnlOneSidedNonlinearDiffusion( const Nonlinearity& nonlinearity )
+      : nonlinearity( nonlinearity ){}      
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlOneSidedNonlinearDiffusion< " ) +
+            MeshType::getType() + ", " +
+            Nonlinearity::getType() + "," +
+            ::getType< Real >() + ", " +
+            ::getType< Index >() + " >";         
+      }      
+
+      template< typename MeshFunction,
+                typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::MeshType& mesh = entity.getMesh();
+         const RealType& hx_div = mesh.template getSpaceStepsProducts< -2,  0 >();
+         const RealType& hy_div = mesh.template getSpaceStepsProducts<  0, -2 >();
+         const IndexType& center = entity.getIndex();
+         const IndexType& east = neighbourEntities.template getEntityIndex<  1, 0 >();
+         const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >();
+         const IndexType& north = neighbourEntities.template getEntityIndex< 0,  1 >();
+         const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >();         
+         const RealType& u_c = u[ center ];
+         const RealType u_x_f = ( u[ east ] - u_c );
+         const RealType u_x_b = ( u_c - u[ west ] );
+         const RealType u_y_f = ( u[ north ] - u_c );
+         const RealType u_y_b = ( u_c - u[ south ] );
+         
+         const RealType& nonlinearity_center = this->nonlinearity[ center ];
+         return ( u_x_f * nonlinearity_center - u_x_b * this->nonlinearity[ west ] ) * hx_div +
+                ( u_y_f * nonlinearity_center - u_y_b * this->nonlinearity[ south ] ) * hx_div;
+      }
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const
+      {
+         return 5;
+      }
+
+      template< typename MeshEntity,
+                typename MeshFunction,
+                typename Vector,
+                typename Matrix >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunction& u,
+                               Vector& b,
+                               Matrix& matrix ) const
+      {
+         typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const IndexType& center = entity.getIndex();
+         const IndexType& east  = neighbourEntities.template getEntityIndex<  1,  0 >();
+         const IndexType& west  = neighbourEntities.template getEntityIndex< -1,  0 >();
+         const IndexType& north = neighbourEntities.template getEntityIndex<  0,  1 >();
+         const IndexType& south = neighbourEntities.template getEntityIndex<  0, -1 >();                  
+         const RealType lambda_x = tau * mesh.template getSpaceStepsProducts< -2,  0 >();
+         const RealType lambda_y = tau * mesh.template getSpaceStepsProducts<  0, -2 >();
+         const RealType& nonlinearity_center = this->nonlinearity[ center ];
+         const RealType& nonlinearity_west = this->nonlinearity[ west ];
+         const RealType& nonlinearity_south = this->nonlinearity[ south ];
+         const RealType aCoef = -lambda_y * nonlinearity_south;
+         const RealType bCoef = -lambda_x * nonlinearity_west;
+         const RealType cCoef = lambda_x * ( nonlinearity_center + nonlinearity_west ) +
+                                lambda_y * ( nonlinearity_center + nonlinearity_south );
+         const RealType dCoef = -lambda_x * nonlinearity_center;
+         const RealType eCoef = -lambda_y * nonlinearity_center;
+         matrixRow.setElement( 0, south,  aCoef );
+         matrixRow.setElement( 1, west,   bCoef );
+         matrixRow.setElement( 2, center, cCoef );
+         matrixRow.setElement( 3, east,   dCoef );
+         matrixRow.setElement( 4, north,  eCoef );         
+      }
+   
+   public:
+       
+      const Nonlinearity& nonlinearity;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Nonlinearity,
+          typename Real,
+          typename Index >
+class tnlOneSidedNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, Nonlinearity, Real, Index >
+{
+   public: 
+   
+      typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef Nonlinearity NonlinearityType;
+      typedef tnlExactNonlinearDiffusion< MeshType::getMeshDimensions(), typename Nonlinearity::ExactOperatorType, Real > ExactOperatorType;
+
+      tnlOneSidedNonlinearDiffusion( const Nonlinearity& nonlinearity )
+      : nonlinearity( nonlinearity ){}
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlOneSidedNonlinearDiffusion< " ) +
+            MeshType::getType() + ", " +
+            Nonlinearity::getType() + "," +
+            ::getType< Real >() + ", " +
+            ::getType< Index >() + " >";         
+      }
+
+      template< typename MeshFunction,
+                typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const typename MeshEntity::MeshType& mesh = entity.getMesh();
+         const RealType& hx_div = mesh.template getSpaceStepsProducts< -2,  0,  0 >();
+         const RealType& hy_div = mesh.template getSpaceStepsProducts<  0, -2,  0 >();
+         const RealType& hz_div = mesh.template getSpaceStepsProducts<  0,  0, -2 >();
+         const IndexType& center = entity.getIndex();
+         const IndexType& east  = neighbourEntities.template getEntityIndex<  1,  0,  0 >();
+         const IndexType& west  = neighbourEntities.template getEntityIndex< -1,  0,  0 >();
+         const IndexType& north = neighbourEntities.template getEntityIndex<  0,  1,  0 >();
+         const IndexType& south = neighbourEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighbourEntities.template getEntityIndex<  0,  0,  1 >();
+         const IndexType& down  = neighbourEntities.template getEntityIndex<  0,  0, -1 >();         
+         
+         const RealType& u_c = u[ center ];
+         const RealType u_x_f = ( u[ east ] - u_c );
+         const RealType u_x_b = ( u_c - u[ west ] );
+         const RealType u_y_f = ( u[ north ] - u_c );
+         const RealType u_y_b = ( u_c - u[ south ] );
+         const RealType u_z_f = ( u[ up ] - u_c );
+         const RealType u_z_b = ( u_c - u[ down ] );         
+         
+         const RealType& nonlinearity_center = this->nonlinearity[ center ];
+         return ( u_x_f * nonlinearity_center - u_x_b * this->nonlinearity[ west ] ) * hx_div +
+                ( u_y_f * nonlinearity_center - u_y_b * this->nonlinearity[ south ] ) * hx_div +
+                ( u_z_f * nonlinearity_center - u_z_b * this->nonlinearity[ down ] ) * hz_div;
+         
+      }
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const
+      {
+         return 7;
+      }
+
+      template< typename MeshEntity,
+                typename MeshFunction,
+                typename Vector,                
+                typename Matrix >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunction& u,
+                               Vector& b,
+                               Matrix& matrix ) const
+      {
+         typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const IndexType& center = entity.getIndex();
+         const IndexType& east  = neighbourEntities.template getEntityIndex<  1,  0,  0 >();
+         const IndexType& west  = neighbourEntities.template getEntityIndex< -1,  0,  0 >();
+         const IndexType& north = neighbourEntities.template getEntityIndex<  0,  1,  0 >();
+         const IndexType& south = neighbourEntities.template getEntityIndex<  0, -1,  0 >();
+         const IndexType& up    = neighbourEntities.template getEntityIndex<  0,  0,  1 >();
+         const IndexType& down  = neighbourEntities.template getEntityIndex<  0,  0, -1 >();                  
+         
+         
+         const RealType lambda_x = tau * mesh.template getSpaceStepsProducts< -2,  0,  0 >();
+         const RealType lambda_y = tau * mesh.template getSpaceStepsProducts<  0, -2,  0 >();
+         const RealType lambda_z = tau * mesh.template getSpaceStepsProducts<  0,  0, -2 >();
+         const RealType& nonlinearity_center = this->nonlinearity[ center ];
+         const RealType& nonlinearity_west   = this->nonlinearity[ west ];
+         const RealType& nonlinearity_south  = this->nonlinearity[ south ];
+         const RealType& nonlinearity_down   = this->nonlinearity[ down ];
+         const RealType aCoef = -lambda_z * nonlinearity_down;
+         const RealType bCoef = -lambda_y * nonlinearity_south;
+         const RealType cCoef = -lambda_x * nonlinearity_west;
+         const RealType dCoef = lambda_x * ( nonlinearity_center + nonlinearity_west ) +
+                                lambda_y * ( nonlinearity_center + nonlinearity_south ) +
+                                lambda_z * ( nonlinearity_center + nonlinearity_down );
+         const RealType eCoef = -lambda_x * nonlinearity_center;
+         const RealType fCoef = -lambda_y * nonlinearity_center;
+         const RealType gCoef = -lambda_z * nonlinearity_center;
+         matrixRow.setElement( 0, down,   aCoef );
+         matrixRow.setElement( 1, south,  bCoef );
+         matrixRow.setElement( 2, west,   cCoef );
+         matrixRow.setElement( 3, center, dCoef );
+         matrixRow.setElement( 4, east,   eCoef );
+         matrixRow.setElement( 5, north,  fCoef );
+         matrixRow.setElement( 5, up,     gCoef );
+      }
+     
+   public:
+       
+      const Nonlinearity& nonlinearity;
+};
+
+#endif	/* TNLONESIDEDNONLINEARDIFFUSION_H */
diff --git a/src/operators/fdm/CMakeLists.txt b/src/operators/fdm/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d485cf80d6d2b5a87d6d3e13a2bfa4827eec0eb9
--- /dev/null
+++ b/src/operators/fdm/CMakeLists.txt
@@ -0,0 +1,22 @@
+SET( headers tnlBackwardFiniteDifference.h
+             tnlCentralFiniteDifference.h
+             tnlExactDifference.h
+             tnlFiniteDifference.h
+             tnlFiniteDifference_1D.h
+             tnlFiniteDifference_2D.h
+             tnlFiniteDifference_3D.h
+             tnlForwardFinteDifference.h )
+
+SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/operators/fdm )
+
+if( BUILD_CUDA)
+      set( tnl_operators_fdm_CUDA__SOURCES
+        ${common_SOURCES}
+        PARENT_SCOPE )
+endif()
+
+set( tnl_operators_fdm_SOURCES
+     ${common_SOURCES}
+     PARENT_SCOPE )   
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/operators/fdm )
diff --git a/src/operators/fdm/tnlBackwardFiniteDifference.h b/src/operators/fdm/tnlBackwardFiniteDifference.h
new file mode 100644
index 0000000000000000000000000000000000000000..f936b19b9d32f5cacfdc88aabb72042ee1f8c797
--- /dev/null
+++ b/src/operators/fdm/tnlBackwardFiniteDifference.h
@@ -0,0 +1,94 @@
+/***************************************************************************
+                          tnlBackwardFiniteDifference.h  -  description
+                             -------------------
+    begin                : Jan 9, 2016
+    copyright            : (C) 2016 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 TNLBACKWARDFINITEDIFFERENCE_H
+#define	TNLBACKWARDFINITEDIFFERENCE_H
+
+#include <operators/fdm/tnlFiniteDifferences.h>
+#include <operators/fdm/tnlExactDifference.h>
+#include <operators/tnlOperator.h>
+
+template< typename Mesh,
+          int Xdifference = 0,
+          int YDifference = 0,
+          int ZDifference = 0,
+          typename RealType = typename Mesh::RealType,
+          typename IndexType = typename Mesh::IndexType >
+class tnlBackwardFiniteDifference
+{    
+};
+
+template< int Dimensions,
+          typename MeshReal,
+          typename MeshDevice,
+          typename MeshIndex,
+          int XDifference,
+          int YDifference,
+          int ZDifference,
+          typename Real,
+          typename Index >
+class tnlBackwardFiniteDifference< tnlGrid< Dimensions, MeshReal, MeshDevice, MeshIndex >, XDifference, YDifference, ZDifference, Real, Index >
+: public tnlOperator< tnlGrid< Dimensions, MeshReal, MeshDevice, MeshIndex >,
+                      MeshInteriorDomain, Dimensions, Dimensions, Real, Index >
+{
+   public:
+      
+      typedef tnlGrid< Dimensions, MeshReal, MeshDevice, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef MeshDevice DeviceType;
+      typedef Index IndexType;
+      typedef tnlExactDifference< Dimensions, XDifference, YDifference, ZDifference > ExactOperatorType;
+      
+      static constexpr int getMeshDimensions() { return Dimensions; }
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlBackwardFiniteDifference< " ) +
+            MeshType::getType() + ", " +
+            tnlString( XDifference ) + ", " +
+            tnlString( YDifference ) + ", " +
+            tnlString( ZDifference ) + ", " +
+            ::getType< RealType >() + ", " +
+            ::getType< IndexType >() + " >";
+      }
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      inline Real operator()( const MeshFunction& u,
+                              const MeshEntity& entity,
+                              const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntitiesDimensions() == Dimensions,
+            "Finite differences can be evaluate only on mesh cells, i.e. the dimensions count of the mesh entities of mesh function must be the same as mesh dimensions count." );
+         const int XDirection = -1 * ( XDifference != 0 );
+         const int YDirection = -1 * ( YDifference != 0 );
+         const int ZDirection = -1 * ( ZDifference != 0 );
+         return tnlFiniteDifferences<
+            MeshType,
+            Real,
+            Index,
+            XDifference,
+            YDifference,
+            ZDifference,
+            XDirection,
+            YDirection,
+            ZDirection >::getValue( u, entity );
+      };
+};
+
+#endif	/* TNLBACKWARDFINITEDIFFERENCE_H */
+
diff --git a/src/operators/fdm/tnlCentralFiniteDifference.h b/src/operators/fdm/tnlCentralFiniteDifference.h
new file mode 100644
index 0000000000000000000000000000000000000000..f68f6a5d1a80a36afed4d129a9a6eab6658982cb
--- /dev/null
+++ b/src/operators/fdm/tnlCentralFiniteDifference.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+                          tnlCentralFiniteDifference.h  -  description
+                             -------------------
+    begin                : Jan 9, 2016
+    copyright            : (C) 2016 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 TNLCENTRALFINITEDIFFERENCE_H
+#define	TNLCENTRALFINITEDIFFERENCE_H
+
+#include <operators/fdm/tnlFiniteDifferences.h>
+#include <operators/fdm/tnlExactDifference.h>
+#include <operators/tnlOperator.h>
+
+template< typename Mesh,
+          int Xdifference = 0,
+          int YDifference = 0,
+          int ZDifference = 0,
+          typename RealType = typename Mesh::RealType,
+          typename IndexType = typename Mesh::IndexType >
+class tnlCentralFiniteDifference
+{    
+};
+
+template< int Dimensions,
+          typename MeshReal,
+          typename MeshDevice,
+          typename MeshIndex,
+          int XDifference,
+          int YDifference,
+          int ZDifference,
+          typename Real,
+          typename Index >
+class tnlCentralFiniteDifference< tnlGrid< Dimensions, MeshReal, MeshDevice, MeshIndex >, XDifference, YDifference, ZDifference, Real, Index >
+: public tnlOperator< tnlGrid< Dimensions, MeshReal, MeshDevice, MeshIndex >,
+                      MeshInteriorDomain, Dimensions, Dimensions, Real, Index >
+{
+   public:
+      
+      typedef tnlGrid< Dimensions, MeshReal, MeshDevice, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef MeshDevice DeviceType;
+      typedef Index IndexType;
+      typedef tnlExactDifference< Dimensions, XDifference, YDifference, ZDifference > ExactOperatorType;
+            
+      //static constexpr int getMeshDimensions() { return Dimensions; }
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlCentralFiniteDifference< " ) +
+            MeshType::getType() + ", " +
+            tnlString( XDifference ) + ", " +
+            tnlString( YDifference ) + ", " +
+            tnlString( ZDifference ) + ", " +
+            ::getType< RealType >() + ", " +
+            ::getType< IndexType >() + " >";
+      }
+
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      inline Real operator()( const MeshFunction& u,
+                              const MeshEntity& entity,
+                              const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntitiesDimensions() == Dimensions,
+            "Finite differences can be evaluate only on mesh cells, i.e. the dimensions count of the mesh entities of mesh function must be the same as mesh dimensions count." );
+         return tnlFiniteDifferences< MeshType, Real, Index, XDifference, YDifference, ZDifference, 0, 0, 0 >::getValue( u, entity );
+      };
+};
+
+
+#endif	/* TNLCENTRALFINITEDIFFERENCE_H */
+
diff --git a/src/operators/fdm/tnlExactDifference.h b/src/operators/fdm/tnlExactDifference.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf1b7f766f5c98116479b6ff0b4da1fa5c8c8c68
--- /dev/null
+++ b/src/operators/fdm/tnlExactDifference.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+                          tnlExactDifference.h  -  description
+                             -------------------
+    begin                : Jan 10, 2016
+    copyright            : (C) 2016 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 TNLEXACTDIFFERENCE_H
+#define	TNLEXACTDIFFERENCE_H
+
+template< int Dimensions,
+          int XDerivative,
+          int YDerivative,
+          int ZDerivative >
+class tnlExactDifference
+   : public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlExactDifference< " ) +
+            tnlString( Dimensions ) + ", " +
+            tnlString( XDerivative ) + ", " +
+            tnlString( YDerivative ) + ", " +
+            tnlString( ZDerivative ) + " >";
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType operator()( 
+         const Function& function,
+         const typename Function::VertexType& vertex,
+         const typename Function::RealType& time = 0 ) const
+      {
+         return function.template getPartialDerivative<
+            XDerivative,
+            YDerivative,
+            ZDerivative >(
+            vertex, 
+            time );
+      }
+};
+
+
+#endif	/* TNLEXACTDIFFERENCE_H */
+
diff --git a/src/operators/fdm/tnlFiniteDifferences.h b/src/operators/fdm/tnlFiniteDifferences.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed8b1a02395a0b8e1fd624e3ab27dd860dba6cb8
--- /dev/null
+++ b/src/operators/fdm/tnlFiniteDifferences.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+                          tnlFiniteDifferences.h  -  description
+                             -------------------
+    begin                : Jan 10, 2016
+    copyright            : (C) 2016 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 TNLFINITEDIFFERENCES_H
+#define	TNLFINITEDIFFERENCES_H
+
+template< typename Mesh,
+          typename Real,
+          typename Index,
+          int XDifference,
+          int YDifference,
+          int ZDifference,
+          int XDirection,
+          int YDirection,
+          int ZDirection >
+class tnlFiniteDifferences
+{   
+};
+
+#include <operators/fdm/tnlFiniteDifferences_1D.h>
+#include <operators/fdm/tnlFiniteDifferences_2D.h>
+#include <operators/fdm/tnlFiniteDifferences_3D.h>
+
+#endif	/* TNLFINITEDIFFERENCES_H */
+
diff --git a/src/operators/fdm/tnlFiniteDifferences_1D.h b/src/operators/fdm/tnlFiniteDifferences_1D.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f62e08b6c8f486fc0f0c72068d16c694b034e19
--- /dev/null
+++ b/src/operators/fdm/tnlFiniteDifferences_1D.h
@@ -0,0 +1,218 @@
+/***************************************************************************
+                          tnlFiniteDifferences_1D.h  -  description
+                             -------------------
+    begin                : Jan 10, 2016
+    copyright            : (C) 2016 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 TNLFINITEDIFFERENCES_1D_H
+#define	TNLFINITEDIFFERENCES_1D_H
+
+/***
+ * Default implementation for case when one differentiate with respect
+ * to some other variable than x. In this case the result is zero.
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          int XDifference,
+          int YDifference,
+          int ZDifference,
+          int XDirection,
+          int YDirection,
+          int ZDirection >
+class tnlFiniteDifferences< 
+   tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index,
+   XDifference, YDifference, ZDifference,
+   XDirection, YDirection, ZDirection >
+{   
+   static_assert( YDifference != 0 || ZDifference != 0,
+      "You try to use default finite difference with 'wrong' template parameters. It means that required finite difference was not implmented yet." );
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {
+         return 0.0;
+      }            
+};
+
+/****
+ * 1st order forward difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index,
+   1, 0, 0,
+   1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 1 >()] - u_c ) * hxDiv;
+      }            
+};
+
+/****
+ * 1st order backward difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index,
+   1, 0, 0,
+   -1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u_c - u[ neighbourEntities.template getEntityIndex< -1 >()] ) * hxDiv;
+      }            
+};
+
+/****
+ * 1st order central difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index,
+   1, 0, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1 >();
+         return ( u[ neighbourEntities.template getEntityIndex< 1 >() ] -
+                  u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * ( 0.5 * hxDiv );
+      }            
+};
+
+/****
+ * 2nd order central difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index,
+   2, 0, 0,
+   1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 2 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 1 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index,
+   2, 0, 0,
+   -1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< -2 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index,
+   2, 0, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 1 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * hxSquareDiv;
+      }            
+};
+
+
+#endif	/* TNLFINITEDIFFERENCES_1D_H */
+
diff --git a/src/operators/fdm/tnlFiniteDifferences_2D.h b/src/operators/fdm/tnlFiniteDifferences_2D.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4151b3b7aa7785a2aa741d5b6b6d60bbc800237
--- /dev/null
+++ b/src/operators/fdm/tnlFiniteDifferences_2D.h
@@ -0,0 +1,369 @@
+/***************************************************************************
+                          tnlFiniteDifferences_2D.h  -  description
+                             -------------------
+    begin                : Jan 10, 2016
+    copyright            : (C) 2016 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 TNLFINITEDIFFERENCES_2D_H
+#define	TNLFINITEDIFFERENCES_2D_H
+
+/***
+ * Default implementation for case when one differentiate with respect
+ * to z. In this case the result is zero.
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index,
+          int XDifference,
+          int YDifference,
+          int ZDifference,
+          int XDirection,
+          int YDirection,
+          int ZDirection >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   XDifference, YDifference, ZDifference,
+   XDirection, YDirection, ZDirection >
+{   
+   static_assert( ZDifference != 0,
+      "You try to use default finite difference with 'wrong' template parameters. It means that required finite difference was not implmented yet." );
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {
+         return 0.0;
+      }            
+};
+
+/****
+ * 1st order forward difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   1, 0, 0,
+   1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 1, 0 >()] - u_c ) * hxDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 1, 0,
+   0, 1, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 1 >()] - u_c ) * hyDiv;
+      }            
+};
+
+/****
+ * 1st order backward difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   1, 0, 0,
+   -1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1,  0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u_c - u[ neighbourEntities.template getEntityIndex< -1, 0 >()] ) * hxDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   0,  1, 0,
+   0, -1, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u_c - u[ neighbourEntities.template getEntityIndex< 0, -1 >()] ) * hyDiv;
+      }            
+};
+
+/****
+ * 1st order central difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   1, 0, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0 >();
+         return ( u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] -
+                  u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] ) * ( 0.5 * hxDiv );
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 1, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1 >();
+         return ( u[ neighbourEntities.template getEntityIndex< 0,  1 >() ] -
+                  u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] ) * ( 0.5 * hyDiv );
+      }            
+};
+
+
+/****
+ * 2nd order central difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   2, 0, 0,
+   1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2,0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 2, 0 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   2, 0, 0,
+   -1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< -2, 0 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   2, 0, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex<  1, 0 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 2, 0,
+   0 ,1, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 2 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   0,  2, 0,
+   0, -1, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, -2 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] ) * hxSquareDiv;
+      }            
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 2, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hySquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0,  1 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] ) * hySquareDiv;
+      }            
+};
+
+#endif	/* TNLFINITEDIFFERENCES_2D_H */
+
diff --git a/src/operators/fdm/tnlFiniteDifferences_3D.h b/src/operators/fdm/tnlFiniteDifferences_3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e7a0c6b57401b4783124299846f328c3c652b73
--- /dev/null
+++ b/src/operators/fdm/tnlFiniteDifferences_3D.h
@@ -0,0 +1,485 @@
+/***************************************************************************
+                          tnlFiniteDifferences_3D.h  -  description
+                             -------------------
+    begin                : Jan 10, 2016
+    copyright            : (C) 2016 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 TNLFINITEDIFFERENCES_3D_H
+#define	TNLFINITEDIFFERENCES_3D_H
+
+/****
+ * 1st order forward difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   1, 0, 0,
+   1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >()] - u_c ) * hxDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 1, 0,
+   0, 1, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >()] - u_c ) * hyDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 0, 1,
+   0, 0, 1 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hzDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >()] - u_c ) * hzDiv;
+      }            
+};
+
+/****
+ * 1st order backward difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   1, 0, 0,
+   -1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u_c - u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >()] ) * hxDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0,  1, 0,
+   0, -1, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__      
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u_c - u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >()] ) * hyDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 0,  1,
+   0, 0, -1 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hzDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u_c - u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >()] ) * hzDiv;
+      }            
+};
+
+/****
+ * 1st order central difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   1, 0, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >();
+         return ( u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] -
+                  u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] ) * ( 0.5 * hxDiv );
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 1, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hyDiv = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >();
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] -
+                  u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] ) * ( 0.5 * hyDiv );
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 0, 1,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hzDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >();
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] -
+                  u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] ) * ( 0.5 * hzDiv );
+      }            
+};
+
+/****
+ * 2nd order central difference
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   2, 0, 0,
+   1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 2, 0, 0 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   2, 0, 0,
+   -1, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< -2, 0, 0 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   2, 0, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex<  1, 0, 0 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 2, 0,
+   0, 1, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 2, 0 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0,  2, 0,
+   0, -1, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, -2, 0 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 2, 0,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hySquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0,  1, 0 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] ) * hySquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 0, 2,
+   0, 0 ,1 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 0, 2 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 0,  2,
+   0, 0, -1 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hxSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 0, -2 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] ) * hxSquareDiv;
+      }            
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteDifferences< 
+   tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index,
+   0, 0, 2,
+   0, 0, 0 >
+{   
+   public:
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      static Real getValue( const MeshFunction& u,
+                            const MeshEntity& entity )
+      {         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+         const Real& hzSquareDiv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >();
+         const Real& u_c = u[ entity.getIndex() ];
+         return ( u[ neighbourEntities.template getEntityIndex< 0, 0,  1 >() ] -
+                  2.0 * u_c +
+                  u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] ) * hzSquareDiv;
+      }            
+};
+
+
+#endif	/* TNLFINITEDIFFERENCES_3D_H */
+
diff --git a/src/operators/fdm/tnlForwardFiniteDifference.h b/src/operators/fdm/tnlForwardFiniteDifference.h
new file mode 100644
index 0000000000000000000000000000000000000000..27990f1f53a21e91e9c854e134028cbe0ff8e61d
--- /dev/null
+++ b/src/operators/fdm/tnlForwardFiniteDifference.h
@@ -0,0 +1,98 @@
+/***************************************************************************
+                          tnlForwardFiniteDifference.h  -  description
+                             -------------------
+    begin                : Jan 9, 2016
+    copyright            : (C) 2016 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 TNLFORWARDFINITEDIFFERENCE_H
+#define	TNLFORWARDFINITEDIFFERENCE_H
+
+#include <mesh/tnlGrid.h>
+#include <operators/fdm/tnlFiniteDifferences.h>
+#include <operators/fdm/tnlExactDifference.h>
+#include <operators/tnlOperator.h>
+
+template< typename Mesh,
+          int Xdifference = 0,
+          int YDifference = 0,
+          int ZDifference = 0,
+          typename RealType = typename Mesh::RealType,
+          typename IndexType = typename Mesh::IndexType >
+class tnlForwardFiniteDifference
+{    
+};
+
+template< int Dimensions,
+          typename MeshReal,
+          typename MeshDevice,
+          typename MeshIndex,
+          int XDifference,
+          int YDifference,
+          int ZDifference,
+          typename Real,
+          typename Index >
+class tnlForwardFiniteDifference< tnlGrid< Dimensions, MeshReal, MeshDevice, MeshIndex >, XDifference, YDifference, ZDifference, Real, Index >
+: public tnlOperator< tnlGrid< Dimensions, MeshReal, MeshDevice, MeshIndex >,
+                      MeshInteriorDomain, Dimensions, Dimensions, Real, Index >
+{
+   public:
+      
+      typedef tnlGrid< Dimensions, MeshReal, MeshDevice, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef MeshDevice DeviceType;
+      typedef Index IndexType;
+      typedef tnlExactDifference< Dimensions, XDifference, YDifference, ZDifference > ExactOperatorType;
+      
+      static constexpr int getMeshDimensions() { return Dimensions; }
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlForwardFiniteDifference< " ) +
+            MeshType::getType() + ", " +
+            tnlString( XDifference ) + ", " +
+            tnlString( YDifference ) + ", " +
+            tnlString( ZDifference ) + ", " +
+            ::getType< RealType >() + ", " +
+            ::getType< IndexType >() + " >";
+      }
+
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      inline Real operator()( const MeshFunction& u,
+                              const MeshEntity& entity,
+                              const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntitiesDimensions() == Dimensions,
+            "Finite differences can be evaluate only on mesh cells, i.e. the dimensions count of the mesh entities of mesh function must be the same as mesh dimensions count." );
+         const int XDirection = 1 * ( XDifference != 0 );
+         const int YDirection = 1 * ( YDifference != 0 );
+         const int ZDirection = 1 * ( ZDifference != 0 );
+
+         return tnlFiniteDifferences<
+            MeshType,
+            Real,
+            Index,
+            XDifference,
+            YDifference,
+            ZDifference,
+            XDirection,
+            YDirection,
+            ZDirection >::getValue( u, entity );
+
+      }
+};
+
+#endif	/* TNLFORWARDFINITEDIFFERENCE_H */
+
diff --git a/src/operators/geometric/CMakeLists.txt b/src/operators/geometric/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8ec90e37056837f8c3b65230320d207d84afc6a4
--- /dev/null
+++ b/src/operators/geometric/CMakeLists.txt
@@ -0,0 +1,19 @@
+SET( headers tnlExactGradientNorm.h
+             tnlExactGradientNormInverse.h
+             tnlFDMGradientNorm.h
+             tnlGradientNormInverse.h
+             tnlTwoSidedGradientNorm.h )
+
+SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/operators/geometric )
+
+if( BUILD_CUDA)
+      set( tnl_operators_geometric_CUDA__SOURCES
+        ${common_SOURCES}
+        PARENT_SCOPE )
+endif()
+
+set( tnl_operators_geometric_SOURCES
+     ${common_SOURCES}
+     PARENT_SCOPE )   
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/operators/geometric )
diff --git a/src/operators/geometric/tnlCoFVMGradientNorm.h b/src/operators/geometric/tnlCoFVMGradientNorm.h
new file mode 100644
index 0000000000000000000000000000000000000000..1402747bca7f941fd092bcf50a10cbdcfc16e613
--- /dev/null
+++ b/src/operators/geometric/tnlCoFVMGradientNorm.h
@@ -0,0 +1,510 @@
+/***************************************************************************
+                          tnlCoFVMGradientNorm.h  -  description
+                             -------------------
+    begin                : Jan 21, 2016
+    copyright            : (C) 2016 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 TNLCOFVMGRADIENTNORM_H
+#define	TNLCOFVMGRADIENTNORM_H
+
+#include <mesh/tnlGrid.h>
+#include <operators/geometric/tnlExactGradientNorm.h>
+#include <operators/interpolants/tnlMeshEntitiesInterpolants.h>
+#include <operators/tnlOperator.h>
+#include <operators/tnlOperatorComposition.h>
+
+template< typename Mesh,
+          int MeshEntityDimensions = Mesh::getMeshDimensions(),
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class tnlCoFVMGradientNorm
+{   
+};
+
+template< int MeshDimensions,
+          typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlCoFVMGradientNorm< tnlGrid< MeshDimensions, MeshReal, Device, MeshIndex >, MeshDimensions, Real, Index >
+: public tnlOperatorComposition< 
+   tnlMeshEntitiesInterpolants< tnlGrid< MeshDimensions, MeshReal, Device, MeshIndex >,
+                                MeshDimensions - 1,
+                                MeshDimensions >,
+   tnlCoFVMGradientNorm< tnlGrid< MeshDimensions, MeshReal, Device, MeshIndex >, MeshDimensions - 1, Real, Index > >
+{  
+   public:
+      typedef tnlGrid< MeshDimensions, MeshReal, Device, MeshIndex > MeshType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlCoFVMGradientNorm< MeshType, MeshDimensions - 1, Real, Index > InnerOperator;
+      typedef tnlMeshEntitiesInterpolants< MeshType, MeshDimensions - 1, MeshDimensions > OuterOperator;
+      typedef tnlOperatorComposition< OuterOperator, InnerOperator > BaseType;
+      typedef tnlExactGradientNorm< MeshDimensions, RealType > ExactOperatorType;
+         
+      tnlCoFVMGradientNorm( const OuterOperator& outerOperator,
+                            InnerOperator& innerOperator,
+                            const MeshType& mesh )
+      : BaseType( outerOperator, innerOperator, mesh )
+      {}
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlCoFVMGradientNorm< " ) +
+            MeshType::getType() + ", " +
+            tnlString( MeshDimensions ) + ", " +
+            ::getType< Real >() + ", " +
+            ::getType< Index >() + " >";
+      }
+      
+      void setEps( const RealType& eps )
+      {
+         this->getInnerOperator().setEps( eps );
+      }
+      
+      static constexpr int getPreimageEntitiesDimensions() { return MeshDimensions; };
+      static constexpr int getImageEntitiesDimensions() { return MeshDimensions; };
+
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlCoFVMGradientNorm< tnlGrid< 1,MeshReal, Device, MeshIndex >, 0, Real, Index >
+   : public tnlOperator< tnlGrid< 1,MeshReal, Device, MeshIndex >, MeshInteriorDomain, 1, 0, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef tnlExactGradientNorm< 1, RealType > ExactOperatorType;
+   
+   constexpr static int getPreimageEntitiesDimensions() { return MeshType::getMeshDimensions(); };
+   constexpr static int getImageEntitiesDimensions() { return MeshType::getMeshDimensions() - 1; };
+   
+   tnlCoFVMGradientNorm()
+   : epsSquare( 0.0 ){}
+
+   static tnlString getType()
+   {
+      return tnlString( "tnlCoFVMGradientNorm< " ) +
+         MeshType::getType() + ", 0, " +
+         ::getType< Real >() + ", " +
+         ::getType< Index >() + " >";
+   }
+
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const
+   {
+      static_assert( MeshFunction::getDimensions() == 1, 
+         "The mesh function u must be stored on mesh cells.." );
+      static_assert( MeshEntity::getDimensions() == 0,
+         "The complementary finite volume gradient norm may be evaluated only on faces." );
+      const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.template getNeighbourEntities< 1 >();
+      
+      const RealType& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1 >();      
+      const RealType& u_x = ( u[ neighbourEntities.template getEntityIndex<  1 >() ] -
+                              u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * hxDiv;
+      return sqrt( this->epsSquare + ( u_x * u_x ) );          
+   }
+                
+   void setEps( const Real& eps )
+   {
+      this->epsSquare = eps*eps;
+   }
+      
+   private:
+   
+   RealType epsSquare;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlCoFVMGradientNorm< tnlGrid< 2, MeshReal, Device, MeshIndex >, 1, Real, Index >
+   : public tnlOperator< tnlGrid< 2,MeshReal, Device, MeshIndex >, MeshInteriorDomain, 2, 1, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef tnlExactGradientNorm< 2, RealType > ExactOperatorType;
+   
+   constexpr static int getPreimageEntitiesDimensions() { return MeshType::getMeshDimensions(); };
+   constexpr static int getImageEntitiesDimensions() { return MeshType::getMeshDimensions() - 1; };
+   
+   tnlCoFVMGradientNorm()
+   : epsSquare( 0.0 ){}
+
+
+   static tnlString getType()
+   {
+      return tnlString( "tnlCoFVMGradientNorm< " ) +
+         MeshType::getType() + ", 1, " +
+         ::getType< Real >() + ", " +
+         ::getType< Index >() + " >";
+
+   }
+      
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const
+   {      
+      static_assert( MeshFunction::getDimensions() == 2, 
+         "The mesh function u must be stored on mesh cells.." );
+      static_assert( MeshEntity::getDimensions() == 1,
+         "The complementary finite volume gradient norm may be evaluated only on faces." );
+      const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.template getNeighbourEntities< 2 >();
+      const RealType& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1,  0 >();
+      const RealType& hyDiv = entity.getMesh().template getSpaceStepsProducts<  0, -1 >();
+      if( entity.getOrientation().x() != 0.0 )
+      {
+         const RealType u_x =
+            ( u[ neighbourEntities.template getEntityIndex<  1, 0 >()] -
+              u[ neighbourEntities.template getEntityIndex< -1, 0 >()] ) * hxDiv;         
+         RealType u_y;
+         if( entity.getCoordinates().y() > 0 )
+         {
+            if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
+               u_y = 0.25 * 
+                  ( u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] + 
+                    u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] - 
+                    u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] -
+                    u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] ) * hyDiv;
+            else // if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
+               u_y = 0.5 * 
+                  ( u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] + 
+                    u[ neighbourEntities.template getEntityIndex< -1,  0 >() ] - 
+                    u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] -
+                    u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] ) * hyDiv;
+         }
+         else // if( entity.getCoordinates().y() > 0 )
+         {
+            u_y = 0.5 * 
+               ( u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] + 
+                 u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] - 
+                 u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] -
+                 u[ neighbourEntities.template getEntityIndex< -1,  0 >() ] ) * hyDiv;
+         }
+         return sqrt( this->epsSquare + u_x * u_x + u_y * u_y );
+      }
+      RealType u_x;
+      if( entity.getCoordinates().x() > 0 )
+      {
+         if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
+            u_x = 0.25 * 
+            ( u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] + 
+              u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] - 
+              u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] -
+              u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] ) * hxDiv;
+         else // if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
+            u_x = 0.5 * 
+            ( u[ neighbourEntities.template getEntityIndex<  0,  1 >() ] + 
+              u[ neighbourEntities.template getEntityIndex<  0, -1 >() ] - 
+              u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] -
+              u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] ) * hxDiv;
+      }
+      else // if( entity.getCoordinates().x() > 0 )
+      {
+         u_x = 0.5 * 
+            ( u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] + 
+              u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] - 
+              u[ neighbourEntities.template getEntityIndex<  0,  1 >() ] -
+              u[ neighbourEntities.template getEntityIndex<  0, -1 >() ] ) * hxDiv;
+      }
+      const RealType u_y =
+         ( u[ neighbourEntities.template getEntityIndex< 0,  1 >()] -
+           u[ neighbourEntities.template getEntityIndex< 0, -1 >()] ) * hyDiv;
+      return sqrt( this->epsSquare + u_x * u_x + u_y * u_y );
+   }
+           
+   void setEps( const Real& eps )
+   {
+      this->epsSquare = eps*eps;
+   }   
+   
+   private:
+   
+   RealType epsSquare;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlCoFVMGradientNorm< tnlGrid< 3, MeshReal, Device, MeshIndex >, 2, Real, Index >
+   : public tnlOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >, MeshInteriorDomain, 3, 2, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef tnlExactGradientNorm< 3, RealType > ExactOperatorType;
+   
+   constexpr static int getPreimageEntitiesDimensions() { return MeshType::getMeshDimensions(); };
+   constexpr static int getImageEntitiesDimensions() { return MeshType::getMeshDimensions() - 1; };
+   
+   tnlCoFVMGradientNorm()
+   : epsSquare( 0.0 ){}   
+
+   static tnlString getType()
+   {
+      return tnlString( "tnlCoFVMGradientNorm< " ) +
+         MeshType::getType() + ", 2, " +
+         ::getType< Real >() + ", " +
+         ::getType< Index >() + " >";      
+   }
+
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const
+   {
+      static_assert( MeshFunction::getDimensions() == 3, 
+         "The mesh function u must be stored on mesh cells.." );
+      static_assert( MeshEntity::getDimensions() == 2,
+         "The complementary finite volume gradient norm may be evaluated only on faces." );
+      const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.template getNeighbourEntities< 3 >();
+      const RealType& hxDiv = entity.getMesh().template getSpaceStepsProducts< -1,  0,  0 >();
+      const RealType& hyDiv = entity.getMesh().template getSpaceStepsProducts<  0, -1,  0 >();
+      const RealType& hzDiv = entity.getMesh().template getSpaceStepsProducts<  0,  0, -1 >();
+      if( entity.getOrientation().x() != 0.0 )
+      {
+         const RealType u_x =
+            ( u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >()] -
+              u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >()] ) * hxDiv;         
+         RealType u_y;
+         if( entity.getCoordinates().y() > 0 )
+         {
+            if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
+            {
+               u_y = 0.25 * 
+               ( u[ neighbourEntities.template getEntityIndex<  1,  1,  0 >() ] + 
+                 u[ neighbourEntities.template getEntityIndex< -1,  1,  0 >() ] - 
+                 u[ neighbourEntities.template getEntityIndex<  1, -1,  0 >() ] -
+                 u[ neighbourEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hyDiv;
+            }
+            else // if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
+            {
+               u_y = 0.5 * 
+               ( u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] + 
+                 u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] - 
+                 u[ neighbourEntities.template getEntityIndex<  1, -1,  0 >() ] -
+                 u[ neighbourEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hyDiv;
+
+            }
+         }
+         else // if( entity.getCoordinates().y() > 0 )
+         {
+            u_y = 0.5 * 
+            ( u[ neighbourEntities.template getEntityIndex<  1,  1,  0 >() ] + 
+              u[ neighbourEntities.template getEntityIndex< -1,  1,  0 >() ] - 
+              u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] -
+              u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] ) * hyDiv;
+
+         }
+         RealType u_z;
+         if( entity.getCoordinates().z() > 0 )
+         {
+            if( entity.getCoordinates().z() < entity.getMesh().getDimensions().z() - 1 )
+            {
+               u_z = 0.25 * 
+               ( u[ neighbourEntities.template getEntityIndex<  1,  0,  1 >() ] + 
+                 u[ neighbourEntities.template getEntityIndex< -1,  0,  1 >() ] - 
+                 u[ neighbourEntities.template getEntityIndex<  1,  0, -1 >() ] -
+                 u[ neighbourEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hzDiv;
+            }
+            else //if( entity.getCoordinates().z() < entity.getMesh().getDimensions().z() - 1 )
+            {
+               u_z = 0.5 * 
+               ( u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] + 
+                 u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] - 
+                 u[ neighbourEntities.template getEntityIndex<  1,  0, -1 >() ] -
+                 u[ neighbourEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hzDiv;
+            }
+         }
+         else //if( entity.getCoordinates().z() > 0 )
+         {
+            u_z = 0.5 * 
+            ( u[ neighbourEntities.template getEntityIndex<  1,  0,  1 >() ] + 
+              u[ neighbourEntities.template getEntityIndex< -1,  0,  1 >() ] - 
+              u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] -
+              u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] ) * hzDiv;
+         }
+         return sqrt( this->epsSquare + u_x * u_x + u_y * u_y + u_z * u_z );
+      }
+      if( entity.getOrientation().y() != 0.0 )
+      {
+         RealType u_x;
+         if( entity.getCoordinates().x() > 0 )
+         {
+            if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
+            {
+               u_x = 0.25 * 
+               ( u[ neighbourEntities.template getEntityIndex<  1,  1,  0 >() ] + 
+                 u[ neighbourEntities.template getEntityIndex<  1, -1,  0 >() ] - 
+                 u[ neighbourEntities.template getEntityIndex< -1,  1,  0 >() ] -
+                 u[ neighbourEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hxDiv;
+            }
+            else // if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
+            {
+               u_x = 0.5 * 
+               ( u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] + 
+                 u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] - 
+                 u[ neighbourEntities.template getEntityIndex< -1,  1,  0 >() ] -
+                 u[ neighbourEntities.template getEntityIndex< -1, -1,  0 >() ] ) * hxDiv;
+            }
+         }
+         else // if( entity.getCoordinates().x() > 0 )
+         {
+            u_x = 0.5 * 
+            ( u[ neighbourEntities.template getEntityIndex<  1,  1,  0 >() ] + 
+              u[ neighbourEntities.template getEntityIndex<  1, -1,  0 >() ] - 
+              u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] -
+              u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] ) * hxDiv;
+         }
+         const RealType u_y =
+            ( u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >()] -
+              u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >()] ) * hyDiv;
+         RealType u_z;
+         if( entity.getCoordinates().z() > 0 )
+         {
+            if( entity.getCoordinates().z() < entity.getMesh().getDimensions().z() - 1 )
+            {
+               u_z = 0.25 * 
+               ( u[ neighbourEntities.template getEntityIndex<  0,  1,  1 >() ] + 
+                 u[ neighbourEntities.template getEntityIndex<  0, -1,  1 >() ] - 
+                 u[ neighbourEntities.template getEntityIndex<  0,  1, -1 >() ] -
+                 u[ neighbourEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hzDiv;
+            }
+            else // if( entity.getCoordinates().z() < entity.getMesh().getDimensions().z() - 1 )
+            {
+               u_z = 0.5 * 
+               ( u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] + 
+                 u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] - 
+                 u[ neighbourEntities.template getEntityIndex<  0,  1, -1 >() ] -
+                 u[ neighbourEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hzDiv;
+            }
+         }
+         else // if( entity.getCoordinates().z() > 0 )
+         {
+            u_z = 0.5 * 
+            ( u[ neighbourEntities.template getEntityIndex<  0,  1,  1 >() ] + 
+              u[ neighbourEntities.template getEntityIndex<  0, -1,  1 >() ] - 
+              u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] -
+              u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] ) * hzDiv;
+         }
+         return sqrt( this->epsSquare + u_x * u_x + u_y * u_y + u_z * u_z );
+      }
+      RealType u_x;
+      if( entity.getCoordinates().x() > 0 )
+      {
+         if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
+         {
+            u_x = 0.25 * 
+            ( u[ neighbourEntities.template getEntityIndex<  1,  0,  1 >() ] + 
+              u[ neighbourEntities.template getEntityIndex<  1,  0, -1 >() ] - 
+              u[ neighbourEntities.template getEntityIndex< -1,  0,  1 >() ] -
+              u[ neighbourEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hxDiv;
+         }
+         else // if( entity.getCoordinates().x() < entity.getMesh().getDimensions().x() - 1 )
+         {
+            u_x = 0.5 * 
+            ( u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] + 
+              u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] - 
+              u[ neighbourEntities.template getEntityIndex< -1,  0,  1 >() ] -
+              u[ neighbourEntities.template getEntityIndex< -1,  0, -1 >() ] ) * hxDiv;
+
+         }
+      }
+      else // if( entity.getCoordinates().x() > 0 )
+      {
+         u_x = 0.5 * 
+         ( u[ neighbourEntities.template getEntityIndex<  1,  0,  1 >() ] + 
+           u[ neighbourEntities.template getEntityIndex<  1,  0, -1 >() ] - 
+           u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] -
+           u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] ) * hxDiv;         
+      }
+      RealType u_y;
+      if( entity.getCoordinates().y() > 0 )
+      {
+         if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
+         {      
+            u_y = 0.25 * 
+            ( u[ neighbourEntities.template getEntityIndex<  0,  1,  1 >() ] + 
+              u[ neighbourEntities.template getEntityIndex<  0,  1, -1 >() ] - 
+              u[ neighbourEntities.template getEntityIndex<  0, -1,  1 >() ] -
+              u[ neighbourEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hyDiv;
+         }
+         else //if( entity.getCoordinates().y() < entity.getMesh().getDimensions().y() - 1 )
+         {
+            u_y = 0.5 * 
+            ( u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] + 
+              u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] - 
+              u[ neighbourEntities.template getEntityIndex<  0, -1,  1 >() ] -
+              u[ neighbourEntities.template getEntityIndex<  0, -1, -1 >() ] ) * hyDiv;
+         }
+      }
+      else //if( entity.getCoordinates().y() > 0 )
+      {
+         u_y = 0.5 * 
+         ( u[ neighbourEntities.template getEntityIndex<  0,  1,  1 >() ] + 
+           u[ neighbourEntities.template getEntityIndex<  0,  1, -1 >() ] - 
+           u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] -
+           u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] ) * hyDiv;         
+      }
+      const RealType u_z =
+         ( u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >()] -
+           u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >()] ) * hzDiv;
+      return sqrt( this->epsSquare + u_x * u_x + u_y * u_y + u_z * u_z );
+   }
+   
+        
+   void setEps(const Real& eps)
+   {
+      this->epsSquare = eps*eps;
+   }   
+   
+   private:
+   
+   RealType epsSquare;
+};
+
+#endif	/* TNLCOFVMGRADIENTNORM_H */
+
diff --git a/src/operators/geometric/tnlExactGradientNorm.h b/src/operators/geometric/tnlExactGradientNorm.h
new file mode 100644
index 0000000000000000000000000000000000000000..42af00e87e9d86fa80d3fdbc5fed18237c5a6df3
--- /dev/null
+++ b/src/operators/geometric/tnlExactGradientNorm.h
@@ -0,0 +1,267 @@
+/***************************************************************************
+                          tnlExactGradientNorm.h  -  description
+                             -------------------
+    begin                : Jan 18, 2016
+    copyright            : (C) 2016 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 TNLEXACTGRADIENTTNORM_H
+#define	TNLEXACTGRADIENTTNORM_H
+
+#include <core/vectors/tnlVector.h>
+#include <core/vectors/tnlSharedVector.h>
+#include <mesh/tnlGrid.h>
+#include <functions/tnlDomain.h>
+
+template< int Dimensions,
+          typename Real = double >
+class tnlExactGradientNorm
+{};
+
+/****
+ * 1D
+ */
+template< typename Real >
+class tnlExactGradientNorm< 1, Real >
+   : public tnlDomain< 1, SpaceDomain >
+{
+   public:
+
+      static tnlString getType()
+      {
+         return "tnlExactGradientNorm< 1 >";
+      }
+      
+      tnlExactGradientNorm()
+      : epsilonSquare( 0.0 ){};
+
+      void setRegularization( const Real& epsilon )
+      {
+         this->epsilonSquare = epsilon*epsilon;
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+         operator()( const Function& function,
+                     const typename Function::VertexType& v, 
+                     const typename Function::RealType& time = 0.0 ) const
+      {
+         typedef typename Function::RealType RealType;
+         const RealType f_x = function.template getPartialDerivative< 1, 0, 0 >( v, time );
+         return sqrt( this->epsilonSquare + f_x * f_x );         
+      }
+      
+      template< typename Function, 
+                int XDerivative = 0,
+                int YDerivative = 0,
+                int ZDerivative = 0 >
+      __cuda_callable__
+      typename Function::RealType
+         getPartialDerivative( const Function& function,
+                               const typename Function::VertexType& v,
+                               const typename Function::RealType& time = 0.0 ) const
+      {
+         static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
+            "Partial derivative must be non-negative integer." );
+         static_assert( XDerivative < 2, "Partial derivative of higher order then 1 are not implemented yet." );
+         typedef typename Function::RealType RealType;
+         
+         if( XDerivative == 1 )
+         {
+            const RealType f_x = function.template getPartialDerivative< 1, 0, 0 >( v, time );
+            const RealType f_xx = function.template getPartialDerivative< 2, 0, 0 >( v, time ); 
+            const RealType Q = sqrt( this->epsilonSquare + f_x * f_x );
+            return ( f_x * f_xx ) / Q;         
+         }
+         if( XDerivative == 0 )
+            return this->operator()( function, v, time );         
+         if( YDerivative != 0 || ZDerivative != 0 )
+            return 0.0;         
+      }
+      
+      protected:
+         
+         Real epsilonSquare;      
+};
+
+
+/****
+ * 2D
+ */
+template< typename Real >
+class tnlExactGradientNorm< 2, Real >
+   : public tnlDomain< 2, SpaceDomain >
+{
+   public:
+
+      static tnlString getType()
+      {
+         return "tnlExactGradientNorm< 2 >";
+      }
+      
+      tnlExactGradientNorm()
+      : epsilonSquare( 0.0 ){};
+
+      void setRegularization( const Real& epsilon )
+      {
+         this->epsilonSquare = epsilon*epsilon;
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+         operator()( const Function& function,
+                     const typename Function::VertexType& v, 
+                     const typename Function::RealType& time = 0.0 ) const
+      {
+         typedef typename Function::RealType RealType;
+         const RealType f_x = function.template getPartialDerivative< 1, 0, 0 >( v, time );
+         const RealType f_y = function.template getPartialDerivative< 0, 1, 0 >( v, time );
+         return sqrt( this->epsilonSquare + f_x * f_x + f_y * f_y );
+      }
+      
+      template< typename Function, 
+                int XDerivative = 0,
+                int YDerivative = 0,
+                int ZDerivative = 0 >
+      __cuda_callable__
+      typename Function::RealType
+         getPartialDerivative( const Function& function,
+                               const typename Function::VertexType& v,
+                               const typename Function::RealType& time = 0.0 ) const
+      {
+         static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
+            "Partial derivative must be non-negative integer." );
+         static_assert( XDerivative < 2 && YDerivative < 2, "Partial derivative of higher order then 1 are not implemented yet." );
+         typedef typename Function::RealType RealType;
+         
+         if( XDerivative == 1 && YDerivative == 0 )
+         {
+            const RealType f_x  = function.template getPartialDerivative< 1, 0, 0 >( v, time );            
+            const RealType f_y  = function.template getPartialDerivative< 0, 1, 0 >( v, time );
+            const RealType f_xx = function.template getPartialDerivative< 2, 0, 0 >( v, time );
+            const RealType f_xy = function.template getPartialDerivative< 1, 1, 0 >( v, time );
+            return ( f_x *  f_xx + f_y * f_xy ) / sqrt( this->epsilonSquare + f_x * f_x + f_y * f_y );            
+         }
+         if( XDerivative == 0 && YDerivative == 1 )
+         {
+            const RealType f_x  = function.template getPartialDerivative< 1, 0, 0 >( v, time );            
+            const RealType f_y  = function.template getPartialDerivative< 0, 1, 0 >( v, time );
+            const RealType f_xy = function.template getPartialDerivative< 1, 1, 0 >( v, time );
+            const RealType f_yy = function.template getPartialDerivative< 0, 2, 0 >( v, time );
+            return ( f_x *  f_xy + f_y * f_yy ) / sqrt( this->epsilonSquare + f_x * f_x + f_y * f_y );                        
+         }         
+         if( XDerivative == 0 && YDerivative == 0 )
+            return this->operator()( function, v, time );         
+         if( ZDerivative > 0 )
+            return 0.0;         
+      }
+      
+      protected:
+         
+         Real epsilonSquare;      
+};
+
+template< typename Real >
+class tnlExactGradientNorm< 3, Real >
+   : public tnlDomain< 3, SpaceDomain >
+{
+   public:
+
+      static tnlString getType()
+      {
+         return "tnlExactGradientNorm< 3 >";
+      }
+      
+      tnlExactGradientNorm()
+      : epsilonSquare( 0.0 ){};
+
+      void setRegularization( const Real& epsilon )
+      {
+         this->epsilonSquare = epsilon*epsilon;
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+         operator()( const Function& function,
+                     const typename Function::VertexType& v, 
+                     const typename Function::RealType& time = 0.0 ) const
+      {
+         typedef typename Function::RealType RealType;
+         const RealType f_x = function.template getPartialDerivative< 1, 0, 0 >( v, time );
+         const RealType f_y = function.template getPartialDerivative< 0, 1, 0 >( v, time );
+         const RealType f_z = function.template getPartialDerivative< 0, 0, 1 >( v, time );
+         return sqrt( this->epsilonSquare + f_x * f_x + f_y * f_y + f_z * f_z );                           
+      }
+      
+      template< typename Function, 
+                int XDerivative = 0,
+                int YDerivative = 0,
+                int ZDerivative = 0 >
+      __cuda_callable__
+      typename Function::RealType
+         getPartialDerivative( const Function& function,
+                               const typename Function::VertexType& v,
+                               const typename Function::RealType& time = 0.0 ) const
+      {
+         static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
+            "Partial derivative must be non-negative integer." );
+         static_assert( XDerivative < 2 && YDerivative < 2 && ZDerivative < 2,
+            "Partial derivative of higher order then 1 are not implemented yet." );
+
+         typedef typename Function::RealType RealType;
+         if( XDerivative == 1 && YDerivative == 0 && ZDerivative == 0 )
+         {
+            const RealType f_x  = function.template getPartialDerivative< 1, 0, 0 >( v, time );            
+            const RealType f_y  = function.template getPartialDerivative< 0, 1, 0 >( v, time );
+            const RealType f_z  = function.template getPartialDerivative< 0, 0, 1 >( v, time );
+            const RealType f_xx = function.template getPartialDerivative< 2, 0, 0 >( v, time );
+            const RealType f_xy = function.template getPartialDerivative< 1, 1, 0 >( v, time );
+            const RealType f_xz = function.template getPartialDerivative< 1, 0, 1 >( v, time );
+            return ( f_x *  f_xx + f_y * f_xy + f_z * f_xz ) /
+               sqrt( this->epsilonSquare + f_x * f_x + f_y * f_y + f_z * f_z );            
+         }
+         if( XDerivative == 0 && YDerivative == 1 && ZDerivative == 0 )
+         {
+            const RealType f_x  = function.template getPartialDerivative< 1, 0, 0 >( v, time );            
+            const RealType f_y  = function.template getPartialDerivative< 0, 1, 0 >( v, time );
+            const RealType f_z  = function.template getPartialDerivative< 0, 0, 1 >( v, time );
+            const RealType f_xy = function.template getPartialDerivative< 1, 1, 0 >( v, time );
+            const RealType f_yy = function.template getPartialDerivative< 0, 2, 0 >( v, time );
+            const RealType f_yz = function.template getPartialDerivative< 0, 1, 1 >( v, time );
+            return ( f_x *  f_xy + f_y * f_yy + f_z * f_yz ) / 
+               sqrt( this->epsilonSquare + f_x * f_x + f_y * f_y + f_z * f_z );                        
+         }         
+         if( XDerivative == 0 && YDerivative == 0 && ZDerivative == 1 )
+         {
+            const RealType f_x  = function.template getPartialDerivative< 1, 0, 0 >( v, time );            
+            const RealType f_y  = function.template getPartialDerivative< 0, 1, 0 >( v, time );
+            const RealType f_z  = function.template getPartialDerivative< 0, 0, 1 >( v, time );
+            const RealType f_xz = function.template getPartialDerivative< 1, 0, 1 >( v, time );
+            const RealType f_yz = function.template getPartialDerivative< 0, 1, 1 >( v, time );
+            const RealType f_zz = function.template getPartialDerivative< 0, 0, 2 >( v, time );
+            return ( f_x *  f_xz + f_y * f_yz + f_z * f_zz ) / 
+               sqrt( this->epsilonSquare + f_x * f_x + f_y * f_y + f_z * f_z );                                    
+         }
+         if( XDerivative == 0 && YDerivative == 0 && ZDerivative == 0 )
+            return this->operator()( function, v, time );                  
+      }
+      
+      protected:
+         
+         Real epsilonSquare;      
+};
+
+#endif	/* TNLEXACTGRADIENTTNORM_H */
diff --git a/src/operators/geometric/tnlExactGradientNormInverse.h b/src/operators/geometric/tnlExactGradientNormInverse.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6864a6f26faa07d6dfcc9d489e862427b4773a6
--- /dev/null
+++ b/src/operators/geometric/tnlExactGradientNormInverse.h
@@ -0,0 +1,236 @@
+/***************************************************************************
+                          tnlExactGradientNormInverse.h  -  description
+                             -------------------
+    begin                : Jan 21, 2016
+    copyright            : (C) 2016 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 TNLEXACTGRADIENTTNORMINVERSE_H
+#define	TNLEXACTGRADIENTTNORMINVERSE_H
+
+#include <core/vectors/tnlVector.h>
+#include <core/vectors/tnlSharedVector.h>
+#include <mesh/tnlGrid.h>
+#include <functions/tnlDomain.h>
+#include <operators/geometric/tnlExactGradientNorm.h>
+
+template< typename ExactGradientNorm,
+          int Dimensions = ExactGradientNorm::getDimensions() >
+class tnlExactGradientNormInverse
+{};
+
+/****
+ * 1D
+ */
+template< typename ExactGradientNorm >
+class tnlExactGradientNormInverse< ExactGradientNorm, 1 >
+   : public tnlDomain< 1, SpaceDomain >
+{
+   public:
+
+      static tnlString getType()
+      {
+         return "tnlExactGradientNormInverse< 1 >";
+      }
+      
+      tnlExactGradientNormInverse(){};
+
+      void setRegularization( const Real& epsilon )
+      {
+         this->gradientNorm.setEps( epsilon );
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+         operator()( const Function& function,
+                     const typename Function::VertexType& v, 
+                     const typename Function::RealType& time = 0.0 ) const
+      {
+         return 1.0 / gradientNorm( function, v, time );
+      }
+      
+      template< typename Function, 
+                int XDerivative = 0,
+                int YDerivative = 0,
+                int ZDerivative = 0 >
+      __cuda_callable__
+      typename Function::RealType
+         getPartialDerivative( const Function& function,
+                               const typename Function::VertexType& v,
+                               const typename Function::RealType& time = 0.0 ) const
+      {
+         static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
+            "Partial derivative must be non-negative integer." );
+         static_assert( XDerivative < 2, "Partial derivative of higher order then 1 are not implemented yet." );
+         typedef typename Function::RealType RealType;
+         
+         if( XDerivative == 1 )
+         {
+            const RealType q = gradientNorm( function, v, time );
+            const RealType q_x = gradientNorm.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );            
+            return - q_x / q;         
+         }
+         if( XDerivative == 0 )
+            return this->operator()( function, v, time );         
+         if( YDerivative != 0 || ZDerivative != 0 )
+            return 0.0;         
+      }
+      
+      protected:
+         
+         ExactGradientNorm gradientNorm;      
+};
+
+
+/****
+ * 2D
+ */
+template< typename ExactGradientNorm >
+class tnlExactGradientNormInverse< ExactGradientNorm, 2 >
+   : public tnlDomain< 2, SpaceDomain >
+{
+   public:
+
+      static tnlString getType()
+      {
+         return "tnlExactGradientNormInverse< 2 >";
+      }
+      
+      tnlExactGradientNormInverse(){};
+
+      void setRegularization( const Real& epsilon )
+      {
+         this->gradientNorm.setEps( epsilon );
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+         operator()( const Function& function,
+                     const typename Function::VertexType& v, 
+                     const typename Function::RealType& time = 0.0 ) const
+      {
+         return 1.0 / gradientNorm( function, v, time );
+      }
+      
+      template< typename Function, 
+                int XDerivative = 0,
+                int YDerivative = 0,
+                int ZDerivative = 0 >
+      __cuda_callable__
+      typename Function::RealType
+         getPartialDerivative( const Function& function,
+                               const typename Function::VertexType& v,
+                               const typename Function::RealType& time = 0.0 ) const
+      {
+         static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
+            "Partial derivative must be non-negative integer." );
+         static_assert( XDerivative < 2 && YDerivative < 2, "Partial derivative of higher order then 1 are not implemented yet." );
+         typedef typename Function::RealType RealType;
+         
+         if( XDerivative == 1 && YDerivative == 0 )
+         {
+            const RealType q = gradientNorm( function, v, time );
+            const RealType q_x = gradientNorm.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );            
+            return - q_x / q;         
+         }
+         if( XDerivative == 0 && YDerivative == 1 )
+         {
+            const RealType q = gradientNorm( function, v, time );
+            const RealType q_y = gradientNorm.template getPartialDerivative< Function, 0, 1, 0 >( function, v, time );            
+            return - q_y / q;                     
+         }         
+         if( XDerivative == 0 && YDerivative == 0 )
+            return this->operator()( function, v, time );         
+         if( ZDerivative > 0 )
+            return 0.0;         
+      }
+      
+      protected:
+         
+         Real epsilonSquare;      
+};
+
+template< typename ExactGradientNorm >
+class tnlExactGradientNormInverse< ExactGradientNorm, 3 >
+   : public tnlDomain< 3, SpaceDomain >
+{
+   public:
+
+      static tnlString getType()
+      {
+         return "tnlExactGradientNormInverse< 3 >";
+      }
+      
+      tnlExactGradientNormInverse(){};
+
+      void setRegularization( const Real& epsilon )
+      {
+         this->gradientNorm.setEps( epsilon );
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+         operator()( const Function& function,
+                     const typename Function::VertexType& v, 
+                     const typename Function::RealType& time = 0.0 ) const
+      {
+         return 1.0 / gradientNorm( function, v, time );
+      }
+      
+      template< typename Function, 
+                int XDerivative = 0,
+                int YDerivative = 0,
+                int ZDerivative = 0 >
+      __cuda_callable__
+      typename Function::RealType
+         getPartialDerivative( const Function& function,
+                               const typename Function::VertexType& v,
+                               const typename Function::RealType& time = 0.0 ) const
+      {
+         static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
+            "Partial derivative must be non-negative integer." );
+         static_assert( XDerivative < 2 && YDerivative < 2 && ZDerivative < 2,
+            "Partial derivative of higher order then 1 are not implemented yet." );
+
+         typedef typename Function::RealType RealType;
+         if( XDerivative == 1 && YDerivative == 0 && ZDerivative == 0 )
+         {
+            const RealType q = gradientNorm( function, v, time );
+            const RealType q_x = gradientNorm.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );            
+            return - q_x / q;                     
+         }
+         if( XDerivative == 0 && YDerivative == 1 && ZDerivative == 0 )
+         {
+            const RealType q = gradientNorm( function, v, time );
+            const RealType q_y = gradientNorm.template getPartialDerivative< Function, 0, 1, 0 >( function, v, time );            
+            return - q_y / q;                     
+         }         
+         if( XDerivative == 0 && YDerivative == 0 && ZDerivative == 1 )
+         {
+            const RealType q = gradientNorm( function, v, time );
+            const RealType q_z = gradientNorm.template getPartialDerivative< Function, 0, 0, 1 >( function, v, time );            
+            return - q_z / q;                     
+         }
+         if( XDerivative == 0 && YDerivative == 0 && ZDerivative == 0 )
+            return this->operator()( function, v, time );                  
+      }
+      
+      protected:
+         
+         Real epsilonSquare;      
+};
+
+#endif	/* TNLEXACTGRADIENTTNORM_H */
diff --git a/src/operators/geometric/tnlFDMGradientNorm.h b/src/operators/geometric/tnlFDMGradientNorm.h
new file mode 100644
index 0000000000000000000000000000000000000000..08d8a0a4a8611ba696ba902a5be1b4e4d66c2763
--- /dev/null
+++ b/src/operators/geometric/tnlFDMGradientNorm.h
@@ -0,0 +1,218 @@
+/***************************************************************************
+                          tnlFDMGradientNorm.h  -  description
+                             -------------------
+    begin                : Jan 11, 2016
+    copyright            : (C) 2016 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 TNLFDMGRADIENTNORM_H
+#define	TNLFDMGRADIENTNORM_H
+
+#include <operators/fdm/tnlForwardFiniteDifference.h>
+#include <operators/geometric/tnlExactGradientNorm.h>
+#include <operators/tnlOperator.h>
+
+template< typename Mesh,
+          template< typename, int, int, int, typename, typename > class DifferenceOperatorTemplate = tnlForwardFiniteDifference,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType > 
+class tnlFDMGradientNorm
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          template< typename, int, int, int, typename, typename > class DifferenceOperatorTemplate,
+          typename Real,
+          typename Index >
+class tnlFDMGradientNorm< tnlGrid< 1,MeshReal, Device, MeshIndex >, DifferenceOperatorTemplate, Real, Index >
+   : public tnlOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >,
+                         MeshInteriorDomain, 1, 1, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef tnlExactGradientNorm< 1, RealType > ExactOperatorType;
+   
+   template< typename MeshEntity = typename MeshType::Cell >
+   using XDifferenceOperatorType = DifferenceOperatorTemplate< typename MeshEntity::MeshType, 1, 0, 0, Real, Index >;
+   
+   tnlFDMGradientNorm()
+   : epsSquare( 0.0 ){}
+
+   static tnlString getType()
+   {
+      return tnlString( "tnlFDMGradientNorm< " ) +
+         MeshType::getType() + ", " +
+         ::getType< Real >() + ", " +
+         ::getType< Index >() + " >";
+   }
+
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const
+   {
+      XDifferenceOperatorType< MeshEntity > XDifference;
+      const RealType u_x = XDifference( u, entity );
+      return sqrt( this->epsSquare + u_x * u_x );          
+   }
+                
+   void setEps( const Real& eps )
+   {
+      this->epsSquare = eps*eps;
+   }
+      
+   private:
+   
+   RealType epsSquare;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          template< typename, int, int, int, typename, typename > class DifferenceOperatorTemplate,
+          typename Real,
+          typename Index >
+class tnlFDMGradientNorm< tnlGrid< 2,MeshReal, Device, MeshIndex >, DifferenceOperatorTemplate, Real, Index >
+   : public tnlOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >,
+                         MeshInteriorDomain, 2, 2, Real, Index >
+{
+   public: 
+   
+      typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlExactGradientNorm< 2, RealType > ExactOperatorType;
+      
+      template< typename MeshEntity >
+      using XDifferenceOperatorType = DifferenceOperatorTemplate< typename MeshEntity::MeshType, 1, 0, 0, Real, Index >;
+      template< typename MeshEntity >
+      using YDifferenceOperatorType = DifferenceOperatorTemplate< typename MeshEntity::MeshType, 0, 1, 0, Real, Index >;
+
+      tnlFDMGradientNorm()
+      : epsSquare( 0.0 ){}
+
+
+      static tnlString getType()
+      {
+         return tnlString( "tnlFDMGradientNorm< " ) +
+            MeshType::getType() + ", " +
+            ::getType< Real >() + ", " +
+            ::getType< Index >() + " >";
+
+      }
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         XDifferenceOperatorType< MeshEntity > XDifference;
+         YDifferenceOperatorType< MeshEntity > YDifference;
+         const RealType u_x = XDifference( u, entity );
+         const RealType u_y = YDifference( u, entity );
+         return sqrt( this->epsSquare + u_x * u_x + u_y * u_y );       
+      }
+
+
+
+      void setEps( const Real& eps )
+      {
+         this->epsSquare = eps*eps;
+      }   
+   
+   private:
+   
+      RealType epsSquare;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          template< typename, int, int, int, typename, typename > class DifferenceOperatorTemplate,
+          typename Real,
+          typename Index >
+class tnlFDMGradientNorm< tnlGrid< 3, MeshReal, Device, MeshIndex >, DifferenceOperatorTemplate, Real, Index >
+   : public tnlOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >,
+                         MeshInteriorDomain, 3, 3, Real, Index >
+{
+   public: 
+   
+      typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      typedef tnlExactGradientNorm< 3, RealType > ExactOperatorType;
+   
+      template< typename MeshEntity >
+      using XDifferenceOperatorType = DifferenceOperatorTemplate< typename MeshEntity::MeshType, 1, 0, 0, Real, Index >;
+      template< typename MeshEntity >
+      using YDifferenceOperatorType = DifferenceOperatorTemplate< typename MeshEntity::MeshType, 0, 1, 0, Real, Index >;
+      template< typename MeshEntity >
+      using ZDifferenceOperatorType = DifferenceOperatorTemplate< typename MeshEntity::MeshType, 0, 0, 1, Real, Index >;
+
+   
+      tnlFDMGradientNorm()
+      : epsSquare( 0.0 ){}   
+
+      static tnlString getType()
+      {
+         return tnlString( "tnlFDMGradientNorm< " ) +
+            MeshType::getType() + ", " +
+            ::getType< Real >() + ", " +
+            ::getType< Index >() + " >";      
+      }
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         XDifferenceOperatorType< MeshEntity > XDifference;
+         YDifferenceOperatorType< MeshEntity > YDifference;
+         ZDifferenceOperatorType< MeshEntity > ZDifference;
+
+         const RealType u_x = XDifference( u, entity );
+         const RealType u_y = YDifference( u, entity );
+         const RealType u_z = ZDifference( u, entity );
+         return sqrt( this->epsSquare + u_x * u_x + u_y * u_y + u_z * u_z );             
+      }
+
+
+      void setEps(const Real& eps)
+      {
+         this->epsSquare = eps*eps;
+      }   
+   
+   private:
+   
+      RealType epsSquare;
+};
+
+
+#endif	/* TNLFDMGRADIENTNORM_H */
+
diff --git a/src/operators/geometric/tnlGradientNormInverse.h b/src/operators/geometric/tnlGradientNormInverse.h
new file mode 100644
index 0000000000000000000000000000000000000000..5449de12857ad39eb2c137ef679d1613f4c9e487
--- /dev/null
+++ b/src/operators/geometric/tnlGradientNormInverse.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+                          tnlGradientNormInverse.h  -  description
+                             -------------------
+    begin                : Jan 21, 2015
+    copyright            : (C) 2015 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 TNLGRADIENTNORMINVERSE_H
+#define	TNLGRADIENTNORMINVERSE_H
+
+template< typename GradientNormOperator >
+class tnlGradientNormInverse
+   : public tnlDomain< GradientNormOperator::getDimensions(), MeshInteriorDomain >
+{
+   public:
+      typedef GradientNormOperator GradientNormOperatorType;
+      typedef typename GradientNormOperatorType::MeshType MeshType;
+      typedef typename GradientNormOperatorType::RealType RealType;
+            
+      void setEps( const RealType& eps ) { gradientNorm.setEps( eps ); };
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         return 1.0 / gradientNorm( u, entity, time );
+      }
+        
+   protected:
+      GradientNormOperatorType gradientNorm;
+      
+};
+
+#endif	/* TNLGRADIENTNORMINVERSE_H */
+
diff --git a/src/operators/geometric/tnlTwoSidedGradientNorm.h b/src/operators/geometric/tnlTwoSidedGradientNorm.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b5157e2b4398dbd1e05eda3a9d7626a805f9e24
--- /dev/null
+++ b/src/operators/geometric/tnlTwoSidedGradientNorm.h
@@ -0,0 +1,217 @@
+/***************************************************************************
+                          tnlTwoSidedGradientNorm.h  -  description
+                             -------------------
+    begin                : Jan 11, 2016
+    copyright            : (C) 2016 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 TNLTWOSIDEDGRADIENTNORM_H
+#define	TNLTWOSIDEDGRADIENTNORM_H
+
+#include <operators/fdm/tnlForwardFiniteDifference.h>
+#include <operators/fdm/tnlBackwardFiniteDifference.h>
+#include <operators/geometric/tnlExactGradientNorm.h>
+#include <operators/tnlOperator.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType > 
+class tnlTwoSidedGradientNorm
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlTwoSidedGradientNorm< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >
+   : public tnlOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >,
+                         MeshInteriorDomain, 1, 1, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef tnlExactGradientNorm< 1, RealType > ExactOperatorType;
+   
+   tnlTwoSidedGradientNorm()
+   : epsSquare( 0.0 ){}
+
+   static tnlString getType()
+   {
+      return tnlString( "tnlTwoSidedGradientNorm< " ) +
+         MeshType::getType() + ", " +
+         ::getType< Real >() + ", " +
+         ::getType< Index >() + " >";
+   }
+
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const
+   {
+      tnlForwardFiniteDifference< typename MeshEntity::MeshType, 1, 0, 0, Real, Index > XForwardDifference;
+      tnlBackwardFiniteDifference< typename MeshEntity::MeshType, 1, 0, 0, Real, Index > XBackwardDifference;
+      const RealType u_x_f = XForwardDifference( u, entity );
+      const RealType u_x_b = XBackwardDifference( u, entity );
+      return sqrt( this->epsSquare + 0.5 * ( u_x_f * u_x_f + u_x_b * u_x_b ) );          
+   }
+                
+   void setEps( const Real& eps )
+   {
+      this->epsSquare = eps*eps;
+   }
+      
+   private:
+   
+   RealType epsSquare;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlTwoSidedGradientNorm< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+   : public tnlOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >,
+                         MeshInteriorDomain, 2, 2, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef tnlExactGradientNorm< 2, RealType > ExactOperatorType;
+   
+   tnlTwoSidedGradientNorm()
+   : epsSquare( 0.0 ){}
+
+
+   static tnlString getType()
+   {
+      return tnlString( "tnlTwoSidedGradientNorm< " ) +
+         MeshType::getType() + ", " +
+         ::getType< Real >() + ", " +
+         ::getType< Index >() + " >";
+
+   }
+      
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const
+   {      
+      tnlForwardFiniteDifference< typename MeshEntity::MeshType, 1, 0, 0, Real, Index > XForwardDifference;
+      tnlForwardFiniteDifference< typename MeshEntity::MeshType, 0, 1, 0, Real, Index > YForwardDifference;
+      tnlBackwardFiniteDifference< typename MeshEntity::MeshType, 1, 0, 0, Real, Index > XBackwardDifference;
+      tnlBackwardFiniteDifference< typename MeshEntity::MeshType, 0, 1, 0, Real, Index > YBackwardDifference;
+      const RealType u_x_f = XForwardDifference( u, entity );
+      const RealType u_x_b = XBackwardDifference( u, entity );
+      const RealType u_y_f = YForwardDifference( u, entity );
+      const RealType u_y_b = YBackwardDifference( u, entity );
+      
+      return sqrt( this->epsSquare +
+         0.5 * ( u_x_f * u_x_f + u_x_b * u_x_b + 
+                 u_y_f * u_y_f + u_y_b * u_y_b ) );          
+   }
+           
+   void setEps( const Real& eps )
+   {
+      this->epsSquare = eps*eps;
+   }   
+   
+   
+   private:
+   
+   RealType epsSquare;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlTwoSidedGradientNorm< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+   : public tnlOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >,
+                         MeshInteriorDomain, 3, 3, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef tnlExactGradientNorm< 3, RealType > ExactOperatorType;
+   
+   tnlTwoSidedGradientNorm()
+   : epsSquare( 0.0 ){}   
+
+   static tnlString getType()
+   {
+      return tnlString( "tnlTwoSidedGradientNorm< " ) +
+         MeshType::getType() + ", " +
+         ::getType< Real >() + ", " +
+         ::getType< Index >() + " >";      
+   }
+
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const
+   {
+      tnlForwardFiniteDifference< typename MeshEntity::MeshType, 1, 0, 0, Real, Index > XForwardDifference;
+      tnlForwardFiniteDifference< typename MeshEntity::MeshType, 0, 1, 0, Real, Index > YForwardDifference;
+      tnlForwardFiniteDifference< typename MeshEntity::MeshType, 0, 0, 1, Real, Index > ZForwardDifference;
+      tnlBackwardFiniteDifference< typename MeshEntity::MeshType, 1, 0, 0, Real, Index > XBackwardDifference;
+      tnlBackwardFiniteDifference< typename MeshEntity::MeshType, 0, 1, 0, Real, Index > YBackwardDifference;
+      tnlBackwardFiniteDifference< typename MeshEntity::MeshType, 0, 0, 1, Real, Index > ZBackwardDifference;
+      const RealType u_x_f = XForwardDifference( u, entity );
+      const RealType u_x_b = XBackwardDifference( u, entity );
+      const RealType u_y_f = YForwardDifference( u, entity );
+      const RealType u_y_b = YBackwardDifference( u, entity );
+      const RealType u_z_f = ZForwardDifference( u, entity );
+      const RealType u_z_b = ZBackwardDifference( u, entity );
+      
+      return sqrt( this->epsSquare +
+         0.5 * ( u_x_f * u_x_f + u_x_b * u_x_b +
+                 u_y_f * u_y_f + u_y_b * u_y_b +
+                 u_z_f * u_z_f + u_z_b * u_z_b ) );          
+      
+   }
+   
+        
+   void setEps(const Real& eps)
+   {
+      this->epsSquare = eps*eps;
+   }   
+   
+   private:
+   
+   RealType epsSquare;
+};
+
+
+#endif	/* TNLTWOSIDEDGRADIENTNORM_H */
+
diff --git a/src/operators/gradient/CMakeLists.txt b/src/operators/gradient/CMakeLists.txt
deleted file mode 100755
index fd1ef7fbfa6c1da7d619535fb5c96a6085425171..0000000000000000000000000000000000000000
--- a/src/operators/gradient/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-SET( headers tnlCentralFDMGradient.h
-             tnlCentralFDMGradient_impl.h )
-
-SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/schemes/gradient )
-
-if( BUILD_CUDA)
-      set( tnl_schemes_gradient_CUDA__SOURCES
-        ${common_SOURCES}
-        PARENT_SCOPE )
-endif()
-
-set( tnl_schemes_gradient_SOURCES
-     ${common_SOURCES}
-     PARENT_SCOPE )   
-   
-INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/schemes/gradient )
diff --git a/src/operators/gradient/tnlCentralFDMGradient.h b/src/operators/gradient/tnlCentralFDMGradient.h
deleted file mode 100644
index 754afb3b0cb4bee5e237a02f4c549ce33cfe1cf8..0000000000000000000000000000000000000000
--- a/src/operators/gradient/tnlCentralFDMGradient.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/***************************************************************************
-                          tnlCentralFDMGradient.h  -  description
-                             -------------------
-    begin                : Apr 26, 2013
-    copyright            : (C) 2013 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 TNLCENTRALFDMGRADIENT_H_
-#define TNLCENTRALFDMGRADIENT_H_
-
-#include <mesh/tnlGrid.h>
-#include <mesh/tnlIdenticalGridGeometry.h>
-#include <core/tnlHost.h>
-
-template< typename Mesh >
-class tnlCentralFDMGradient
-{
-};
-
-template< typename Real,
-          typename Device,
-          typename Index,
-          template< int, typename, typename, typename > class GridGeometry >
-class tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, GridGeometry > >
-{
-   public:
-
-   typedef Real RealType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef tnlGrid< 2, Real, Device, Index, GridGeometry > MeshType;
-   typedef typename MeshType :: CoordinatesType CoordinatesType;
-   typedef typename MeshType :: VertexType VertexType;
-
-   tnlCentralFDMGradient();
-
-   void bindMesh( const MeshType& mesh );
-
-   template< typename Vector >
-   void setFunction( Vector& f ); // TODO: add const
-
-   void getGradient( const Index& i,
-                     VertexType& grad_f ) const;
-   protected:
-
-   // TODO: change to ConstSharedVector
-   tnlSharedVector< RealType, DeviceType, IndexType > f;
-
-   const MeshType* mesh;
-};
-
-template< typename Real,
-          typename Device,
-          typename Index >
-class tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry > >
-{
-   public:
-
-   typedef Real RealType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry > MeshType;
-   typedef typename MeshType :: CoordinatesType CoordinatesType;
-   typedef typename MeshType :: VertexType VertexType;
-
-   tnlCentralFDMGradient();
-
-   void bindMesh( const MeshType& mesh );
-
-   template< typename Vector >
-   void setFunction( Vector& f ); // TODO: add const
-
-   void getGradient( const Index& i,
-                     VertexType& grad_f ) const;
-   protected:
-
-   // TODO: change to ConstSharedVector
-   tnlSharedVector< RealType, DeviceType, IndexType > f;
-
-   const MeshType* mesh;
-};
-
-
-#include <implementation/operators/gradient/tnlCentralFDMGradient_impl.h>
-
-#endif
diff --git a/src/operators/gradient/tnlCentralFDMGradient_impl.h b/src/operators/gradient/tnlCentralFDMGradient_impl.h
deleted file mode 100644
index 41eac268a450bd5f87f17b4f66a56314553cfaa4..0000000000000000000000000000000000000000
--- a/src/operators/gradient/tnlCentralFDMGradient_impl.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/***************************************************************************
-                          tnlCentralFDMGradient_impl.h  -  description
-                             -------------------
-    begin                : Apr 26, 2013
-    copyright            : (C) 2013 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 TNLCENTRALFDMGRADIENT_IMPL_H_
-#define TNLCENTRALFDMGRADIENT_IMPL_H_
-
-template< typename Real,
-          typename Device,
-          typename Index,
-          template< int, typename, typename, typename > class GridGeometry >
-tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, GridGeometry > > :: tnlCentralFDMGradient()
-: mesh( 0 )
-{
-}
-
-template< typename Real,
-          typename Device,
-          typename Index,
-          template< int, typename, typename, typename > class GridGeometry >
-void tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, GridGeometry > > :: bindMesh( const MeshType& mesh )
-{
-   this -> mesh = &mesh;
-}
-
-template< typename Real,
-          typename Device,
-          typename Index,
-          template< int, typename, typename, typename > class GridGeometry >
-   template< typename Vector >
-void tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, GridGeometry > > :: setFunction( Vector& f )
-{
-   this -> f. bind( f );
-}
-
-template< typename Real,
-          typename Device,
-          typename Index,
-          template< int, typename, typename, typename > class GridGeometry >
-void tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, GridGeometry > > :: getGradient( const Index& c,
-                                                                                              VertexType& grad_f  ) const
-{
-   tnlAssert( this -> mesh, cerr << "No mesh was set in tnlCentralFDMGradient. Use the bindMesh method." );
-
-   const Index e = mesh -> getElementNeighbour( c,  1,  0 );
-   const Index w = mesh -> getElementNeighbour( c, -1,  0 );
-   const Index n = mesh -> getElementNeighbour( c,  0,  1 );
-   const Index s = mesh -> getElementNeighbour( c,  0, -1 );
-   CoordinatesType cCoordinates;
-   mesh -> getElementCoordinates( c, cCoordinates );
-   CoordinatesType eCoordinates( cCoordinates ),
-                   wCoordinates( cCoordinates ),
-                   nCoordinates( cCoordinates ),
-                   sCoordinates( cCoordinates );
-   eCoordinates. x() ++;
-   wCoordinates. x() --;
-   nCoordinates. y() ++;
-   sCoordinates. y() --;
-
-
-   VertexType eNormal, nNormal, wNormal, sNormal;
-   mesh -> template getEdgeNormal<  1,  0 >( cCoordinates, eNormal );
-   mesh -> template getEdgeNormal<  0,  1 >( cCoordinates, nNormal );
-   mesh -> template getEdgeNormal< -1,  0 >( cCoordinates, wNormal );
-   mesh -> template getEdgeNormal<  0, -1 >( cCoordinates, sNormal );
-   const RealType cMu = mesh -> getElementMeasure( cCoordinates );
-   const RealType eMu = mesh -> getElementMeasure( eCoordinates );
-   const RealType nMu = mesh -> getElementMeasure( nCoordinates );
-   const RealType wMu = mesh -> getElementMeasure( wCoordinates );
-   const RealType sMu = mesh -> getElementMeasure( sCoordinates );
-   const RealType f_e = ( cMu * f[ c ] + eMu * f[ e ] ) / ( cMu + eMu );
-   const RealType f_n = ( cMu * f[ c ] + nMu * f[ n ] ) / ( cMu + nMu );
-   const RealType f_w = ( cMu * f[ c ] + wMu * f[ w ] ) / ( cMu + wMu );
-   const RealType f_s = ( cMu * f[ c ] + sMu * f[ s ] ) / ( cMu + sMu );
-   grad_f. x() = 1.0 / cMu * ( f_e * eNormal. x() + f_n * nNormal. x() + f_w * wNormal. x() + f_s * sNormal. x() );
-   grad_f. y() = 1.0 / cMu * ( f_e * eNormal. y() + f_n * nNormal. y() + f_w * wNormal. y() + f_s * sNormal. y() );
-
-
-   //grad_f. x() = ( f[ e ] - f[ w ] ) / ( mesh -> getElementsDistance( eCoordinates, wCoordinates ) );
-   //grad_f. y() = ( f[ n ] - f[ s ] ) / ( mesh -> getElementsDistance( nCoordinates, sCoordinates ) );
-}
-
-/****
- * Specialization for the grids with no deformations (Identical grid geometry)
- */
-
-template< typename Real, typename Device, typename Index >
-tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry > > :: tnlCentralFDMGradient()
-: mesh( 0 )
-{
-}
-
-template< typename Real, typename Device, typename Index >
-void tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry > > :: bindMesh( const MeshType& mesh )
-{
-   this -> mesh = &mesh;
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename Vector >
-void tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry > > :: setFunction( Vector& f )
-{
-   this -> f. bind( f );
-}
-
-template< typename Real, typename Device, typename Index >
-void tnlCentralFDMGradient< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry > > :: getGradient( const Index& i,
-                                                                                                          VertexType& grad_f  ) const
-{
-   tnlAssert( this -> mesh, cerr << "No mesh was set in tnlCentralFDMGradient. Use the bindMesh method." );
-
-   const Index e = mesh -> getElementNeighbour( i,  1,  0 );
-   const Index w = mesh -> getElementNeighbour( i, -1,  0 );
-   const Index n = mesh -> getElementNeighbour( i,  0,  1 );
-   const Index s = mesh -> getElementNeighbour( i,  0, -1 );
-
-   grad_f. x() = ( f[ e ] - f[ w ] ) / ( 2.0 * mesh -> getParametricStep(). x() );
-   grad_f. y() = ( f[ n ] - f[ s ] ) / ( 2.0 * mesh -> getParametricStep(). y() );
-}
-
-
-#endif
diff --git a/src/operators/interpolants/CMakeLists.txt b/src/operators/interpolants/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..70a754ea7c597bdd1802b25f7755d92086038136
--- /dev/null
+++ b/src/operators/interpolants/CMakeLists.txt
@@ -0,0 +1,15 @@
+SET( headers  )
+
+SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/operators/interpolants )
+
+if( BUILD_CUDA)
+      set( tnl_operators_interpolants_CUDA__SOURCES
+        ${common_SOURCES}
+        PARENT_SCOPE )
+endif()
+
+set( tnl_operators_interpolants_SOURCES
+     ${common_SOURCES}
+     PARENT_SCOPE )   
+   
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/operators/interpolants )
diff --git a/src/operators/interpolants/tnlMeshEntitiesInterpolants.h b/src/operators/interpolants/tnlMeshEntitiesInterpolants.h
new file mode 100644
index 0000000000000000000000000000000000000000..2baac346cd71a534e0cdf255e9280c49eb0d8894
--- /dev/null
+++ b/src/operators/interpolants/tnlMeshEntitiesInterpolants.h
@@ -0,0 +1,309 @@
+/***************************************************************************
+                          tnlMeshEntitiesInterpolants.h  -  description
+                             -------------------
+    begin                : Jan 25, 2016
+    copyright            : (C) 2016 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 TNLMESHENTITIESINTERPOLANTS_H
+#define	TNLMESHENTITIESINTERPOLANTS_H
+
+#include <type_traits>
+#include<functions/tnlDomain.h>
+
+template< typename Mesh,
+          int InEntityDimensions,
+          int OutEntityDimenions >
+class tnlMeshEntitiesInterpolants
+{   
+};
+
+/***
+ * 1D grid mesh entity interpolation: 1 -> 0 
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlMeshEntitiesInterpolants< tnlGrid< 1, Real, Device, Index >, 1, 0 >
+   : public tnlDomain< 1, MeshInteriorDomain >
+{
+   public:
+      
+      typedef tnlGrid< 1, Real, Device, Index > MeshType;
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntityDimensions() == 1,
+            "Mesh function must be defined on cells." );
+
+         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
+            "The mesh entity belongs to other mesh type then the interpolants." );
+         
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();      
+         
+         return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1 >() ] + 
+                        u[ neighbourEntities.template getEntityIndex<  1 >() ] );
+      }
+};
+
+/***
+ * 1D grid mesh entity interpolation: 0 -> 1 
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlMeshEntitiesInterpolants< tnlGrid< 1, Real, Device, Index >, 0, 1 >
+   : public tnlDomain< 1, MeshInteriorDomain >
+{
+   public:
+      
+      typedef tnlGrid< 1, Real, Device, Index > MeshType;
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntitiesDimensions() == 0,
+            "Mesh function must be defined on vertices (or faces in case on 1D grid)." );
+         
+         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
+            "The mesh entity belongs to other mesh type then the interpolants." );         
+         
+         const typename MeshEntity::template NeighbourEntities< 0 >& neighbourEntities = entity.template getNeighbourEntities< 0 >();      
+         
+         return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1 >() ] + 
+                        u[ neighbourEntities.template getEntityIndex<  1 >() ] );
+      }
+};
+
+/***
+ * 2D grid mesh entity interpolation: 2 -> 1 
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlMeshEntitiesInterpolants< tnlGrid< 2, Real, Device, Index >, 2, 1 >
+   : public tnlDomain< 2, MeshInteriorDomain >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+      
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntityDimensions() == 2,
+            "Mesh function must be defined on cells." );
+         
+         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
+            "The mesh entity belongs to other mesh type then the interpolants." );         
+         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+         
+         if( entity.getOrientation().x() == 1.0 )
+            return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] + 
+                           u[ neighbourEntities.template getEntityIndex<  1, 0 >() ] );
+         else
+            return 0.5 * ( u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] + 
+                           u[ neighbourEntities.template getEntityIndex< 0,  1 >() ] );
+      }
+};
+
+/***
+ * 2D grid mesh entity interpolation: 2 -> 0 
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlMeshEntitiesInterpolants< tnlGrid< 2, Real, Device, Index >, 2, 0 >
+   : public tnlDomain< 2, MeshInteriorDomain >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntityDimensions() == 2,
+            "Mesh function must be defined on cells." );
+         
+         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
+            "The mesh entity belongs to other mesh type then the interpolants." );         
+         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+                  
+         return 0.25 * ( u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] + 
+                         u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
+                         u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] + 
+                         u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] );
+      }
+};
+
+/***
+ * 2D grid mesh entity interpolation: 1 -> 2 
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlMeshEntitiesInterpolants< tnlGrid< 2, Real, Device, Index >, 1, 2 >
+   : public tnlDomain< 2, MeshInteriorDomain >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntitiesDimensions() == 1,
+            "Mesh function must be defined on faces." );
+         
+         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
+            "The mesh entity belongs to other mesh type then the interpolants." );         
+         
+         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.template getNeighbourEntities< 1 >();      
+                  
+         return 0.25 * ( u[ neighbourEntities.template getEntityIndex< -1,  0 >() ] + 
+                         u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] +
+                         u[ neighbourEntities.template getEntityIndex<  0,  1 >() ] + 
+                         u[ neighbourEntities.template getEntityIndex<  0, -1 >() ] );
+      }
+};
+
+/***
+ * 2D grid mesh entity interpolation: 0 -> 2 
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlMeshEntitiesInterpolants< tnlGrid< 2, Real, Device, Index >, 0, 2 >
+   : public tnlDomain< 2, MeshInteriorDomain >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntityDimensions() == 1,
+            "Mesh function must be defined on vertices." );
+
+         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
+            "The mesh entity belongs to other mesh type then the interpolants." );         
+         
+         const typename MeshEntity::template NeighbourEntities< 0 >& neighbourEntities = entity.getNeighbourEntities();      
+                  
+         return 0.25 * ( u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] + 
+                         u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
+                         u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] + 
+                         u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] );
+      }
+};
+
+/***
+ * 3D grid mesh entity interpolation: 3 -> 2 
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlMeshEntitiesInterpolants< tnlGrid< 3, Real, Device, Index >, 3, 2 >
+   : public tnlDomain< 3, MeshInteriorDomain >
+{
+   public:
+      
+      typedef tnlGrid< 3, Real, Device, Index > MeshType;
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntityDimensions() == 3,
+            "Mesh function must be defined on cells." );
+
+         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
+            "The mesh entity belongs to other mesh type then the interpolants." );         
+         
+         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();      
+                  
+         if( entity.getOrientation().x() == 1.0 )
+            return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] + 
+                           u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] );
+         if( entity.getOrientation().y() == 1.0 )
+            return 0.5 * ( u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] + 
+                           u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] );
+         else
+            return 0.5 * ( u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] + 
+                           u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] );            
+      }
+};
+
+/***
+ * 3D grid mesh entity interpolation: 2 -> 3 
+ */
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlMeshEntitiesInterpolants< tnlGrid< 3, Real, Device, Index >, 2, 3 >
+   : public tnlDomain< 3, MeshInteriorDomain >
+{
+   public:
+      
+      typedef tnlGrid< 3, Real, Device, Index > MeshType;
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getEntitiesDimensions() == 2,
+            "Mesh function must be defined on faces." );
+
+         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
+            "The mesh entity belongs to other mesh type then the interpolants." );         
+         
+         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.template getNeighbourEntities< 2 >();      
+                  
+         return 1.0 / 6.0 * ( u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] + 
+                              u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] +
+                              u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] + 
+                              u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] +
+                              u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] + 
+                              u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] );            
+      }
+};
+
+#endif	/* TNLMESHENTITIESINTERPOLANTS_H */
+
diff --git a/src/operators/operator-Q/CMakeLists.txt b/src/operators/operator-Q/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..877afe471ff0feaa3cfeb1d2a9177787adae2c6c
--- /dev/null
+++ b/src/operators/operator-Q/CMakeLists.txt
@@ -0,0 +1,6 @@
+SET( headers tnlOneSideDiffOperatorQ.h             
+             tnlOneSideDiffOperatorQ_impl.h
+	     tnlFiniteVolumeOperatorQ.h             
+             tnlFiniteVolumeOperatorQ_impl.h )
+
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/operators/operator-Q )
diff --git a/src/operators/operator-Q/tnlFiniteVolumeOperatorQ.h b/src/operators/operator-Q/tnlFiniteVolumeOperatorQ.h
new file mode 100644
index 0000000000000000000000000000000000000000..59306c15b6811c6ca14708420929718aeca73747
--- /dev/null
+++ b/src/operators/operator-Q/tnlFiniteVolumeOperatorQ.h
@@ -0,0 +1,343 @@
+#ifndef TNLFINITEVOLUMEOPERATORQ_H
+#define	TNLFINITEVOLUMEOPERATORQ_H
+
+#include <core/vectors/tnlVector.h>
+#include <core/vectors/tnlSharedVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType,
+          int Precomputation = 0 > 
+class tnlFiniteVolumeOperatorQ
+{
+
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteVolumeOperatorQ< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, 0 >
+{
+   public: 
+   
+   typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   static tnlString getType();
+
+   template< typename Vector >
+   IndexType bind( Vector& u) 
+   { return 0; }
+
+   __cuda_callable__
+   void update( const MeshType& mesh, const RealType& time ) 
+   {}
+   
+   template< typename MeshEntity, typename Vector >
+   __cuda_callable__
+   Real operator()( const MeshType& mesh,
+          const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx = 0, 
+          const IndexType& dy = 0,
+          const IndexType& dz = 0 ) const;
+          
+   bool setEps(const Real& eps);
+      
+   private:
+   
+      template< typename MeshEntity, typename Vector, int AxeX = 0, int AxeY = 0, int AxeZ = 0 >
+      __cuda_callable__
+      Real 
+      boundaryDerivative( 
+         const MeshEntity& entity,
+         const Vector& u,
+         const Real& time,
+         const IndexType& dx = 0, 
+         const IndexType& dy = 0,
+         const IndexType& dz = 0 ) const;
+
+      RealType eps;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteVolumeOperatorQ< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, 0 >
+{
+   public: 
+   
+   typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   static tnlString getType(); 
+
+   template< typename Vector >
+   IndexType bind( Vector& u)
+   { return 0; }
+
+   __cuda_callable__
+   void update( const MeshType& mesh, const RealType& time )
+   {}   
+   
+   template< typename MeshEntity, typename Vector >
+   __cuda_callable__
+   Real operator()( 
+      const MeshEntity& entity,
+      const Vector& u,
+      const Real& time,
+      const IndexType& dx = 0, 
+      const IndexType& dy = 0,
+      const IndexType& dz = 0 ) const;
+        
+   bool setEps(const Real& eps);
+   
+   private:
+
+   template< typename MeshEntity, typename Vector, int AxeX = 0, int AxeY = 0, int AxeZ = 0 >
+   __cuda_callable__
+   Real boundaryDerivative( const MeshType& mesh,
+          const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx = 0, 
+          const IndexType& dy = 0,
+          const IndexType& dz = 0 ) const;
+   
+   RealType eps;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteVolumeOperatorQ< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, 0 >
+{
+   public: 
+   
+   typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   static tnlString getType();
+
+   template< typename Vector >
+   IndexType bind( Vector& u)
+   { return 0; }
+
+   __cuda_callable__
+   void update( const MeshType& mesh, const RealType& time )
+   {}
+   
+   template< typename MeshEntity, typename Vector >
+   __cuda_callable__
+   Real operator()(
+          const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx = 0, 
+          const IndexType& dy = 0,
+          const IndexType& dz = 0 ) const;
+        
+   bool setEps(const Real& eps);
+   
+   private:
+
+   template< typename MeshEntity, typename Vector, int AxeX = 0, int AxeY = 0, int AxeZ = 0 >
+   __cuda_callable__
+   Real boundaryDerivative( const MeshType& mesh,
+          const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx = 0, 
+          const IndexType& dy = 0,
+          const IndexType& dz = 0 ) const;
+   
+   RealType eps;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteVolumeOperatorQ< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, 1 >
+{
+   public: 
+   
+   typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   static tnlString getType();
+
+   template< typename Vector >
+   Index bind( Vector& u);
+
+   __cuda_callable__
+   void update( const MeshType& mesh, const RealType& time );
+   
+   template< typename MeshEntity, typename Vector >
+   __cuda_callable__
+   Real operator()( const MeshType& mesh,
+          const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx = 0, 
+          const IndexType& dy = 0,
+          const IndexType& dz = 0 ) const;
+   
+   bool setEps(const Real& eps);
+   
+   private:
+   
+      template< typename MeshEntity, typename Vector, int AxeX = 0, int AxeY = 0, int AxeZ = 0 >
+      __cuda_callable__
+      Real boundaryDerivative( const MeshType& mesh,
+             const MeshEntity& entity,
+             const Vector& u,
+             const Real& time,
+             const IndexType& dx = 0, 
+             const IndexType& dy = 0,
+             const IndexType& dz = 0 ) const;    
+
+      tnlSharedVector< RealType, DeviceType, IndexType > u;
+      tnlVector< RealType, DeviceType, IndexType> q;
+      RealType eps;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteVolumeOperatorQ< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, 1 >
+{
+   public: 
+   
+   typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef tnlSharedVector< RealType, DeviceType, IndexType > DofVectorType;
+   
+   static tnlString getType(); 
+
+   template< typename Vector >
+   Index bind( Vector& u);
+
+   __cuda_callable__
+   void update( const MeshType& mesh, const RealType& time ); 
+   
+   template< typename MeshEntity, typename Vector >
+   __cuda_callable__
+   Real operator()( const MeshType& mesh,
+          const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx = 0, 
+          const IndexType& dy = 0,
+          const IndexType& dz = 0 ) const;
+          
+   bool setEps(const Real& eps);
+   
+   private:
+   
+   template< typename MeshEntity, typename Vector, int AxeX = 0, int AxeY = 0, int AxeZ = 0 >
+   __cuda_callable__
+   Real boundaryDerivative( const MeshType& mesh,
+          const IndexType cellIndex,
+          const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx = 0, 
+          const IndexType& dy = 0,
+          const IndexType& dz = 0 ) const;
+       
+   tnlSharedVector< RealType, DeviceType, IndexType > u;
+   tnlVector< RealType, DeviceType, IndexType> q;
+   RealType eps;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlFiniteVolumeOperatorQ< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, 1 >
+{
+   public: 
+   
+   typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   
+   static tnlString getType();
+
+   template< typename Vector >
+   Index bind( Vector& u);
+
+   __cuda_callable__
+   void update( const MeshType& mesh, const RealType& time );
+   
+   template< typename MeshEntity, typename Vector >
+   __cuda_callable__
+   Real operator()( const MeshType& mesh,
+          const IndexType cellIndex,
+          const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx = 0, 
+          const IndexType& dy = 0,
+          const IndexType& dz = 0 ) const;
+          
+   bool setEps(const Real& eps);
+   
+   private:
+   
+      template< typename MeshEntity, typename Vector, int AxeX = 0, int AxeY = 0, int AxeZ = 0 >
+      __cuda_callable__
+      Real boundaryDerivative( const MeshType& mesh,
+             const IndexType cellIndex,
+             const MeshEntity& entity,
+             const Vector& u,
+             const Real& time,
+             const IndexType& dx = 0, 
+             const IndexType& dy = 0,
+             const IndexType& dz = 0 ) const;
+
+      tnlSharedVector< RealType, DeviceType, IndexType > u;
+      tnlVector< RealType, DeviceType, IndexType> q;
+      RealType eps;
+};
+
+#include <operators/operator-Q/tnlFiniteVolumeOperatorQ_impl.h>
+
+
+#endif	/* TNLFINITEVOLUMEOPERATORQ_H */
diff --git a/src/operators/operator-Q/tnlFiniteVolumeOperatorQ_impl.h b/src/operators/operator-Q/tnlFiniteVolumeOperatorQ_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..e08da5fae295296cc5d8cbcec84c9e3b39454a01
--- /dev/null
+++ b/src/operators/operator-Q/tnlFiniteVolumeOperatorQ_impl.h
@@ -0,0 +1,617 @@
+
+#ifndef TNLFINITEVOLUMEOPERATORQ_IMPL_H
+#define	TNLFINITEVOLUMEOPERATORQ_IMPL_H
+
+#include <operators/operator-Q/tnlFiniteVolumeOperatorQ.h>
+#include <mesh/tnlGrid.h>
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 0 >::
+getType()
+{
+   return tnlString( "tnlFiniteVolumeOperatorQ< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", 0 >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+getType()
+{
+   return tnlString( "tnlFiniteVolumeOperatorQ< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", 1 >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 0 >::setEps( const Real& eps )
+{
+  this->eps = eps;
+  
+  return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 1 >::setEps( const Real& eps )
+{
+  this->eps = eps;
+  
+  return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >   
+__cuda_callable__
+void  
+tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+update( const MeshType& mesh, const RealType& time )
+{
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity, typename Vector, int AxeX, int AxeY, int AxeZ >
+__cuda_callable__
+Real
+tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 0 >::
+boundaryDerivative( const MeshEntity& entity,
+                    const Vector& u,
+                    const Real& time,
+                    const IndexType& dx, 
+                    const IndexType& dy,
+                    const IndexType& dz ) const
+{
+    return 0.0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity,
+          typename Vector >
+__cuda_callable__
+Real
+tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 0 >::
+operator()( 
+   const MeshType& mesh,
+   const MeshEntity& entity,
+   const Vector& u,
+   const Real& time,
+   const IndexType& dx, 
+   const IndexType& dy,
+   const IndexType& dz ) const
+{
+    return 0.0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity, typename Vector, int AxeX, int AxeY, int AxeZ >
+__cuda_callable__
+Real
+tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+boundaryDerivative( 
+   const MeshType& mesh,
+   const MeshEntity& entity,
+   const Vector& u,
+   const Real& time,
+   const IndexType& dx, 
+   const IndexType& dy,
+   const IndexType& dz ) const
+{
+    return 0.0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity, typename Vector >
+__cuda_callable__
+Real
+tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+operator()( 
+   const MeshType& mesh,
+   const MeshEntity& entity,
+   const Vector& u,
+   const Real& time,
+   const IndexType& dx, 
+   const IndexType& dy,
+   const IndexType& dz ) const
+{
+    return 0.0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+tnlFiniteVolumeOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, 0 >::
+getType()
+{
+   return tnlString( "tnlFiniteVolumeOperatorQ< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", 0 >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+tnlFiniteVolumeOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+getType()
+{
+   return tnlString( "tnlFiniteVolumeOperatorQ< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", 1 >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFiniteVolumeOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, 1 >::setEps( const Real& eps )
+{
+  this->eps = eps;
+  
+  return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFiniteVolumeOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, 0 >::setEps( const Real& eps )
+{
+  this->eps = eps;
+  
+  return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename Vector >
+Index 
+tnlFiniteVolumeOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+bind( Vector& u) 
+{
+    return 0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__cuda_callable__
+void 
+tnlFiniteVolumeOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+update( const MeshType& mesh, const RealType& time )
+{
+    CoordinatesType dimensions = mesh.getDimensions();
+    CoordinatesType coordinates;
+    
+    for( coordinates.x()=1; coordinates.x() < dimensions.x()-1; coordinates.x()++ )
+        for( coordinates.y()=1; coordinates.y() < dimensions.y()-1; coordinates.y()++  )
+        {
+            q.setElement( mesh.getCellIndex(coordinates), operator()( mesh, mesh.getCellIndex(coordinates), coordinates, u, time ) ); 
+        }
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity, typename Vector, int AxeX, int AxeY, int AxeZ >
+__cuda_callable__
+Real
+tnlFiniteVolumeOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, 0 >::
+boundaryDerivative( 
+   const MeshType& mesh,
+   const MeshEntity& entity,
+   const Vector& u,
+   const Real& time,
+   const IndexType& dx, 
+   const IndexType& dy,
+   const IndexType& dz ) const
+{
+   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+   const IndexType& cellIndex = entity.getIndex();
+    if ( ( AxeX == 1 ) && ( AxeY == 0 ) && ( AxeZ == 0 ) )
+    {
+        if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0 >() * ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] - u[ cellIndex ] );
+        if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< -1,0 >() ] );
+        if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 1,1 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< -1,1 >() ] );
+        if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 1,-1 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< -1,-1 >() ] );
+    }
+    if ( ( AxeX == 0 ) && ( AxeY == 1 ) && ( AxeZ == 0 ) )
+    {
+        if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1 >() * ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] - u[ cellIndex ] );
+        if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< 0,-1 >() ] );
+        if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< 1,-1 >() ] );
+        if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< -1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< -1,-1 >() ] );
+    }
+    return 0.0;
+}
+   
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity, typename Vector >
+__cuda_callable__
+Real
+tnlFiniteVolumeOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, 0 >::
+operator()( const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx, 
+          const IndexType& dy,
+          const IndexType& dz ) const
+{
+   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const IndexType& cellIndex = entity.getIndex();
+    if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 0 ) )
+        return sqrt( this->eps + ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] - u[ cellIndex ] ) * 
+                ( u[ neighbourEntities.template getEntityIndex< 0,1 >() ] - u[ cellIndex ] )
+                * mesh.template getSpaceStepsProducts< 0, -1 >() * mesh.template getSpaceStepsProducts< 0, -1 >() + ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] - u[ cellIndex ] ) 
+                * ( u[ neighbourEntities.template getEntityIndex< 1,0 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -1, 0 >() * mesh.template getSpaceStepsProducts< -1, 0 >() );
+    if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, 1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, 1, 0 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1 >( mesh, entity, u, time, 1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1 >( mesh, entity, u, time, 1, 0 ) );
+    if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, -1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, -1, 0 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1 >( mesh, entity, u, time, -1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1 >( mesh, entity, u, time, -1, 0 ) );
+    if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, 0, 1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, 0, 1 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1 >( mesh, entity, u, time, 0, 1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1 >( mesh, entity, u, time, 0, 1 ) );
+    if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, 0, -1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0 >( mesh, entity, u, time, 0, -1 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1 >( mesh, entity, u, time, 0, -1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1 >( mesh, entity, u, time, 0, -1 ) );
+    return 0.0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity, typename Vector >
+__cuda_callable__
+Real
+tnlFiniteVolumeOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+operator()( const MeshType& mesh,
+          const MeshEntity& entity,
+          const Vector& u,
+          const Real& time,
+          const IndexType& dx, 
+          const IndexType& dy,
+          const IndexType& dz ) const
+{
+   return q.getElement( entity.getIndex() );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+tnlFiniteVolumeOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, 0 >::
+getType()
+{
+   return tnlString( "tnlFiniteVolumeOperatorQ< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", 0 >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+tnlFiniteVolumeOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+getType()
+{
+   return tnlString( "tnlFiniteVolumeOperatorQ< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + ", 1 >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFiniteVolumeOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, 1 >::setEps( const Real& eps )
+{
+  this->eps = eps;
+  
+  return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+bool tnlFiniteVolumeOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, 0 >::setEps( const Real& eps )
+{
+  this->eps = eps;
+  
+  return true;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename Vector >
+Index 
+tnlFiniteVolumeOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+bind( Vector& u) 
+{
+    this->u.bind(u);
+    if(q.setSize(u.getSize()))
+        return 1;
+    q.setValue(0);
+    return 0;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+__cuda_callable__
+void 
+tnlFiniteVolumeOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, 1 >::
+update( const MeshType& mesh, const RealType& time )
+{
+    CoordinatesType dimensions = mesh.getDimensions();
+    CoordinatesType coordinates;
+    
+    for( coordinates.x()=1; coordinates.x() < dimensions.x()-1; coordinates.x()++ )
+        for( coordinates.y()=1; coordinates.y() < dimensions.y()-1; coordinates.y()++ )
+            for( coordinates.z()=1; coordinates.z() < dimensions.z()-1; coordinates.z()++ )
+                q.setElement( mesh.getCellIndex(coordinates), operator()( mesh, mesh.getCellIndex(coordinates), coordinates, u, time ) ); 
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity, typename Vector, int AxeX, int AxeY, int AxeZ >
+__cuda_callable__
+Real
+tnlFiniteVolumeOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, 0 >::
+boundaryDerivative( 
+   const MeshType& mesh,
+   const MeshEntity& entity,
+   const Vector& u,
+   const Real& time,
+   const IndexType& dx, 
+   const IndexType& dy,
+   const IndexType& dz ) const
+{
+   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+   const IndexType& cellIndex = entity.getIndex();    
+    if ( ( AxeX == 1 ) && ( AxeY == 0 ) && ( AxeZ == 0 ) )
+    {
+        if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ] );
+        if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] );
+        if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 1,1,0 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< -1,1,0 >() ] );
+        if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 1,-1,0 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< -1,-1,0 >() ] );
+        if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 1 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 1,0,1 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< -1,0,1 >() ] );
+        if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == -1 ) )
+            return mesh.template getSpaceStepsProducts< -1, 0, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 1,0,-1 >() ] - u[ neighbourEntities.template getEntityIndex< -1,0,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< -1,0,-1 >() ] );
+    }
+    if ( ( AxeX == 0 ) && ( AxeY == 1 ) && ( AxeZ == 0 ) )
+    {
+        if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ] );
+        if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] );
+        if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 1,1,0 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< 1,-1,0 >() ] );
+        if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< -1,1,0 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< -1,-1,0 >() ] );
+        if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 1 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 0,1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< 0,-1,1 >() ] );
+        if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == -1 ) )
+            return mesh.template getSpaceStepsProducts< 0, -1, 0 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 0,1,-1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,-1,0 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< 0,-1,-1 >() ] );
+    }
+    if ( ( AxeX == 0 ) && ( AxeY == 0 ) && ( AxeZ == 1 ) )
+    {
+        if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 1 ) )
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ] );
+        if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == -1 ) )
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * ( u[ cellIndex ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] );
+        if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 1,0,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< 1,0,-1 >() ] );
+        if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< -1,0,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< -1,0,-1 >() ] );
+        if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 0,1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< 0,1,-1 >() ] );
+        if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
+            return mesh.template getSpaceStepsProducts< 0, 0, -1 >() * 0.25 * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] + 
+                   u[ neighbourEntities.template getEntityIndex< 0,-1,1 >() ] - u[ neighbourEntities.template getEntityIndex< 0,0,-1 >() ] -
+                   u[ neighbourEntities.template getEntityIndex< 0,-1,-1 >() ] );
+    }
+    return 0.0;
+}
+   
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity, typename Vector >
+__cuda_callable__
+Real
+tnlFiniteVolumeOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, 0 >::
+operator()( 
+   const MeshEntity& entity,
+   const Vector& u,
+   const Real& time,
+   const IndexType& dx, 
+   const IndexType& dy,
+   const IndexType& dz ) const
+{
+   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const IndexType& cellIndex = entity.getIndex();     
+    if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 0 ) )
+        return sqrt( this->eps + ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ] ) * 
+                ( u[ neighbourEntities.template getEntityIndex< 0,1,0 >() ] - u[ cellIndex ] )
+                * mesh.template getSpaceStepsProducts< 0, -1, 0 >() * mesh.template getSpaceStepsProducts< 0, -1, 0 >() + ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ] ) 
+                * ( u[ neighbourEntities.template getEntityIndex< 1,0,0 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< -1, 0, 0 >() * mesh.template getSpaceStepsProducts< -1, 0, 0 >()
+                + ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ] ) 
+                * ( u[ neighbourEntities.template getEntityIndex< 0,0,1 >() ] - u[ cellIndex ] ) * mesh.template getSpaceStepsProducts< 0, 0, -1 >() * mesh.template getSpaceStepsProducts< 0, 0, -1 >() );
+    if ( ( dx == 1 ) && ( dy == 0 ) && ( dz == 0 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 1, 0, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 1, 0, 0 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 1, 0, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 1, 0, 0 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 1, 0, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 1, 0, 0 ) );
+    if ( ( dx == -1 ) && ( dy == 0 ) && ( dz == 0 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, -1, 0, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, -1, 0, 0 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, -1, 0, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, -1, 0, 0 ) +
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, -1, 0, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, -1, 0, 0 ) );
+    if ( ( dx == 0 ) && ( dy == 1 ) && ( dz == 0 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 0, 1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 0, 1, 0 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 0, 1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 0, 1, 0 ) +
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 0, 1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 0, 1, 0 ));
+    if ( ( dx == 0 ) && ( dy == -1 ) && ( dz == 0 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 0, -1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 0, -1, 0 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 0, -1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 0, -1, 0 ) +
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 0, -1, 0 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 0, -1, 0 ) );
+    if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == 1 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 0, 0, 1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 0, 0, 1 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 0, 0, 1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 0, 0, 1 ) +
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 0, 0, 1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 0, 0, 1 ));
+    if ( ( dx == 0 ) && ( dy == 0 ) && ( dz == -1 ) )
+        return sqrt( this->eps + this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 0, 0, -1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,1,0,0 >( mesh, entity, u, time, 0, 0, -1 ) + 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 0, 0, -1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,1,0 >( mesh, entity, u, time, 0, 0, -1 ) +
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 0, 0, -1 ) * 
+               this->template boundaryDerivative< MeshEntity, Vector,0,0,1 >( mesh, entity, u, time, 0, 0, -1 ) );
+    return 0.0;
+}
+#endif	/* TNLFINITEVOLUMEOPERATORQ_IMPL_H */
diff --git a/src/operators/operator-Q/tnlOneSideDiffOperatorQ.h b/src/operators/operator-Q/tnlOneSideDiffOperatorQ.h
new file mode 100644
index 0000000000000000000000000000000000000000..491fab0c91ef0438cec795ad451e3a66298d21d2
--- /dev/null
+++ b/src/operators/operator-Q/tnlOneSideDiffOperatorQ.h
@@ -0,0 +1,129 @@
+#ifndef TNLONESIDEDIFFOPERATORQ_H
+#define	TNLONESIDEDIFFOPERATORQ_H
+
+#include <core/vectors/tnlVector.h>
+#include <core/vectors/tnlSharedVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType > 
+class tnlOneSideDiffOperatorQ
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlOneSideDiffOperatorQ< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   static tnlString getType();
+
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const;
+      
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real getValueStriped( const MeshFunction& u,
+                         const MeshEntity& entity,   
+                         const Real& time = 0.0 ) const;
+          
+   void setEps(const Real& eps);
+      
+   private:
+   
+   RealType eps, epsSquare;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlOneSideDiffOperatorQ< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   static tnlString getType(); 
+      
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const;
+
+   
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real getValueStriped( const MeshFunction& u,
+                         const MeshEntity& entity,          
+                         const Real& time = 0.0 ) const;
+        
+   void setEps( const Real& eps );
+   
+   private:
+   
+   RealType eps, epsSquare;
+};
+
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class tnlOneSideDiffOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >
+{
+   public: 
+   
+   typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+
+   static tnlString getType();
+
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real operator()( const MeshFunction& u,
+                    const MeshEntity& entity,
+                    const Real& time = 0.0 ) const;
+   
+   template< typename MeshFunction, typename MeshEntity >
+   __cuda_callable__
+   Real getValueStriped( const MeshFunction& u,
+                         const MeshEntity& entity,          
+                         const Real& time ) const;
+        
+   void setEps(const Real& eps);
+   
+   private:
+   
+   RealType eps, epsSquare;
+};
+
+#include <operators/operator-Q/tnlOneSideDiffOperatorQ_impl.h>
+
+
+#endif	/* TNLONESIDEDIFFOPERATORQ_H */
diff --git a/src/operators/operator-Q/tnlOneSideDiffOperatorQ_impl.h b/src/operators/operator-Q/tnlOneSideDiffOperatorQ_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..19cacbe34faaad2884d194248d84b30847f17975
--- /dev/null
+++ b/src/operators/operator-Q/tnlOneSideDiffOperatorQ_impl.h
@@ -0,0 +1,260 @@
+
+#ifndef TNLONESIDEDIFFOPERATORQ_IMPL_H
+#define	TNLONESIDEDIFFOPERATORQ_IMPL_H
+
+#include <operators/operator-Q/tnlOneSideDiffOperatorQ.h>
+#include <mesh/tnlGrid.h>
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+tnlOneSideDiffOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "tnlOneSideDiffOperatorQ< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void
+tnlOneSideDiffOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+setEps( const Real& eps )
+{
+  this->eps = eps;
+  this->epsSquare = eps*eps;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+tnlOneSideDiffOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,          
+            const Real& time ) const
+{
+   const IndexType& cellIndex = entity.getIndex();
+   const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const RealType& u_x = ( u[ neighbourEntities.template getEntityIndex< 1 >() ] - u[ cellIndex ] ) *
+                         mesh.template getSpaceStepsProducts< -1 >();
+   return sqrt( this->epsSquare + u_x * u_x );          
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+tnlOneSideDiffOperatorQ< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getValueStriped( const MeshFunction& u,
+                 const MeshEntity& entity,                 
+                 const Real& time ) const
+{
+   const IndexType& cellIndex = entity.getIndex();
+   const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const RealType& u_c = u[ cellIndex ];
+   const RealType& u_x_f = ( u[ neighbourEntities.template getEntityIndex< 1 >() ] - u_c ) * 
+                           mesh.template getSpaceStepsProducts< -1 >();
+   const RealType& u_x_b = ( u_c - u[ neighbourEntities.template getEntityIndex< -1 >() ] ) * 
+                           mesh.template getSpaceStepsProducts< -1 >();   
+   return sqrt( this->epsSquare + 0.5 * ( u_x_f * u_x_f + u_x_b * u_x_b ) );
+}
+
+/***
+ * 2D
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+tnlOneSideDiffOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "tnlOneSideDiffOperatorQ< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void
+tnlOneSideDiffOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+setEps( const Real& eps )
+{
+  this->eps = eps;
+  this->epsSquare = eps*eps;
+}
+   
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+tnlOneSideDiffOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,          
+            const Real& time ) const
+{
+   const IndexType& cellIndex = entity.getIndex();
+   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const RealType& u_c = u[ cellIndex ];
+   const RealType u_x = ( u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - u_c ) *
+                         mesh.template getSpaceStepsProducts< -1, 0 >();
+   const RealType u_y = ( u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - u_c ) *
+                         mesh.template getSpaceStepsProducts< 0, -1 >();
+   return sqrt( this->epsSquare + u_x * u_x + u_y * u_y ); 
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+tnlOneSideDiffOperatorQ< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getValueStriped( const MeshFunction& u,
+                 const MeshEntity& entity,                 
+                 const Real& time ) const
+{
+   const IndexType& cellIndex = entity.getIndex();
+   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const RealType& u_c = u[ cellIndex ];
+   const RealType u_x_f = ( u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - u_c ) *
+                          mesh.template getSpaceStepsProducts< -1, 0 >();
+   const RealType u_y_f = ( u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - u_c ) *
+                          mesh.template getSpaceStepsProducts< 0, -1 >();
+   const RealType u_x_b = ( u_c - u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] ) *
+                          mesh.template getSpaceStepsProducts< -1, 0 >();
+   const RealType u_y_b = ( u_c - u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] ) *
+                          mesh.template getSpaceStepsProducts< 0, -1 >();
+   
+   return sqrt( this->epsSquare + 
+                0.5 * ( u_x_f * u_x_f + u_x_b * u_x_b +
+                        u_y_f * u_y_f + u_y_b * u_y_b ) );
+}
+/***
+ * 3D
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+tnlOneSideDiffOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "tnlOneSideDiffOperatorQ< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+void 
+tnlOneSideDiffOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+setEps( const Real& eps )
+{
+  this->eps = eps;
+  this->epsSquare = eps * eps;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+tnlOneSideDiffOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,            
+            const Real& time ) const
+{
+   const IndexType& cellIndex = entity.getIndex();
+   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const RealType& u_c =u[ cellIndex ];
+   
+   const RealType u_x = ( u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - u_c ) *
+                         mesh.template getSpaceStepsProducts< -1, 0, 0 >();
+   const RealType u_y = ( u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - u_c ) *
+                         mesh.template getSpaceStepsProducts< 0, -1, 0 >();
+   const RealType u_z = ( u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - u_c ) *
+                         mesh.template getSpaceStepsProducts< 0, 0, -1 >();
+   return sqrt( this->epsSquare + u_x * u_x + u_y * u_y + u_z * u_z ); 
+}
+   
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+tnlOneSideDiffOperatorQ< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getValueStriped( const MeshFunction& u,
+                 const MeshEntity& entity,                 
+                 const Real& time ) const
+{
+   const IndexType& cellIndex = entity.getIndex();
+   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();      
+   const typename MeshEntity::MeshType& mesh = entity.getMesh();
+   const RealType& u_c = u[ cellIndex ];
+   
+   const RealType u_x_f = ( u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - u_c ) *
+                          mesh.template getSpaceStepsProducts< -1, 0, 0 >();
+   const RealType u_y_f = ( u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - u_c ) *
+                          mesh.template getSpaceStepsProducts< 0, -1, 0 >();
+   const RealType u_z_f = ( u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - u_c ) *
+                          mesh.template getSpaceStepsProducts< 0, 0, -1 >();   
+   const RealType u_x_b = ( u_c - u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] ) *
+                          mesh.template getSpaceStepsProducts< -1, 0, 0 >();
+   const RealType u_y_b = ( u_c - u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] ) *
+                          mesh.template getSpaceStepsProducts< 0, -1, 0 >();
+   const RealType u_z_b = ( u_c - u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] ) *
+                          mesh.template getSpaceStepsProducts< 0, 0, -1 >();
+   
+   return sqrt( this->epsSquare + 
+                0.5 * ( u_x_f * u_x_f + u_x_b * u_x_b +
+                        u_y_f * u_y_f + u_y_b * u_y_b + 
+                        u_z_f * u_z_f + u_z_b * u_z_b ) );
+}   
+#endif	/* TNLONESIDEDIFFOPERATORQ_IMPL_H */
diff --git a/src/operators/operator-curvature/CMakeLists.txt b/src/operators/operator-curvature/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..7a877b91de5f8c353593c36068b382e3291ccb50
--- /dev/null
+++ b/src/operators/operator-curvature/CMakeLists.txt
@@ -0,0 +1,4 @@
+SET( headers tnlExactOperatorCurvature.h
+             tnlExactOperatorCurvature_impl.h )
+
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/operators/operator-curvature )
diff --git a/src/operators/operator-curvature/tnlExactOperatorCurvature.h b/src/operators/operator-curvature/tnlExactOperatorCurvature.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0fee9c1b07da3e455318d872fbd56dee599d4aa
--- /dev/null
+++ b/src/operators/operator-curvature/tnlExactOperatorCurvature.h
@@ -0,0 +1,93 @@
+#ifndef TNLEXACTOPERATORCURVATURE_H
+#define	TNLEXACTOPERATORCURVATURE_H
+
+#include <core/vectors/tnlVector.h>
+#include <core/vectors/tnlSharedVector.h>
+#include <mesh/tnlGrid.h>
+#include <functions/tnlFunction.h>
+
+template< typename ExactOperatorQ, int Dimensions >
+class tnlExactOperatorCurvature
+{};
+
+template< typename ExactOperatorQ >
+class tnlExactOperatorCurvature< OperatorQ, 1 >
+{
+   public:
+
+      enum { Dimensions = 1 };
+
+      static tnlString getType();
+
+#ifdef HAVE_NOT_CXX11      
+      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real >
+#else   
+      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real = typename Vertex::RealType >
+#endif
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      static Real getValue( const Function& function,
+                            const Vertex& v,
+                            const Real& time = 0.0, const Real& eps = 1.0 );
+      
+};
+
+template< typename ExactOperatorQ >
+class tnlExactOperatorCurvature< ExactOperatorQ, 2 >
+{
+   public:
+
+      enum { Dimensions = 2 };
+
+      static tnlString getType();
+         
+#ifdef HAVE_NOT_CXX11      
+      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real >
+#else   
+      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real = typename Vertex::RealType >
+#endif
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif      
+      static Real getValue( const Function& function,
+                            const Vertex& v,
+                            const Real& time = 0.0, const Real& eps = 1.0 );
+};
+
+template< typename ExactOperatorQ >
+class tnlExactOperatorCurvature< ExactOperatorQ, 3 >
+{
+   public:
+
+      enum { Dimensions = 3 };
+
+      static tnlString getType();
+   
+#ifdef HAVE_NOT_CXX11      
+      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real >
+#else   
+      template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0, typename Function, typename Vertex, typename Real = typename Vertex::RealType >
+#endif
+#ifdef HAVE_CUDA
+      __device__ __host__
+#endif
+      static Real getValue( const Function& function,
+                            const Vertex& v,
+                            const Real& time = 0.0, const Real& eps = 1.0 )
+      {
+         return 0;
+      }
+};
+
+template< typename ExactOperatorQ, int Dimensions >
+class tnlFunctionType< tnlExactOperatorCurvature< ExactOperatorQ, Dimensions > >
+{
+   public:
+      enum { Type = tnlSpaceDomain };
+};
+
+#include <operators/operator-curvature/tnlExactOperatorCurvature_impl.h>
+
+
+#endif	/* TNLEXACTOPERATORCURVATURE_H */
diff --git a/src/operators/operator-curvature/tnlExactOperatorCurvature_impl.h b/src/operators/operator-curvature/tnlExactOperatorCurvature_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..f09f59bd835afc9eddd78b5eb8d52e5702b3873d
--- /dev/null
+++ b/src/operators/operator-curvature/tnlExactOperatorCurvature_impl.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+                          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 TNLEXACTOPERATORCURVATURE_IMPL_H_
+#define TNLEXACTOPERATORCURVATURE_IMPL_H_
+
+#include <operators/operator-curvature/tnlExactOperatorCurvature.h>
+
+template< typename ExactOperatorQ >
+tnlString
+tnlExactOperatorCurvature< ExactOperatorQ, 1 >::
+getType()
+{
+   return "tnlExactOperatorCurvature< " + ExactOperatorQ::getType() + ",1 >";
+}
+
+template< typename OperatorQ >
+template< int XDiffOrder, int YDiffOrder, int ZDiffOrder, typename Function, typename Vertex, typename Real >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real
+tnlExactOperatorQ< 1 >::
+getValue( const Function& function,
+          const Vertex& v,
+          const Real& time, const Real& eps )
+{
+   if( YDiffOrder != 0 || ZDiffOrder != 0 )
+        return 0.0;
+   if (XDiffOrder == 0)
+        return function.template getValue< 2, 0, 0, Vertex >( v, time )/ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) -
+               ( function.template getValue< 1, 0, 0, Vertex >( v, time ) * ExactOperatorQ::template getValue< 1, 0, 0 >( function, v, time, eps ) )
+                / ( ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) * ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) );
+   return 0;
+}
+
+template< typename ExactOperatorQ >
+tnlString
+tnlExactOperatorCurvature< ExactOperatorQ, 2 >::
+getType()
+{
+   return "tnlExactOperatorCurvature< " + ExactOperatorQ::getType() + ",2 >";
+}
+
+template< int XDiffOrder, int YDiffOrder, int ZDiffOrder, typename Function, typename Vertex, typename Real >
+#ifdef HAVE_CUDA
+   __device__ __host__
+#endif
+Real
+tnlExactOperatorQ< 2 >::
+getValue( const Function& function,
+          const Vertex& v,
+          const Real& time, const Real& eps )
+{
+   if( ZDiffOrder != 0 )
+        return 0.0;
+   if (XDiffOrder == 0 && YDiffOrder == 0 )
+        return ( function.template getValue< 2, 0, 0, Vertex >( v, time ) * function.template getValue< 0, 2, 0, Vertex >( v, time ) )
+               /ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) - ( function.template getValue< 1, 0, 0, Vertex >( v, time ) * 
+               ExactOperatorQ::template getValue< 1, 0, 0 >( function, v, time, eps ) + function.template getValue< 0, 1, 0, Vertex >( v, time ) * 
+               ExactOperatorQ::template getValue< 0, 1, 0 >( function, v, time, eps ) )
+                / ( ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) * ExactOperatorQ::template getValue< 0, 0, 0 >( function, v, time, eps ) );
+   return 0;
+}
+
+template< typename ExactOperatorQ >
+tnlString
+tnlExactOperatorCurvature< ExactOperatorQ, 3 >::
+getType()
+{
+   return "tnlExactOperatorCurvature< " + ExactOperatorQ::getType() + ",3 >";
+}
+
+#endif /* TNLEXACTOPERATORCURVATURE_IMPL_H_ */
diff --git a/src/operators/tnlDirichletBoundaryConditions.h b/src/operators/tnlDirichletBoundaryConditions.h
index d718eaf6cec7e5967c604d1af82719dc44699771..01f55a1e8e6861f2db5d0a8f6458acbd70ee284b 100644
--- a/src/operators/tnlDirichletBoundaryConditions.h
+++ b/src/operators/tnlDirichletBoundaryConditions.h
@@ -18,37 +18,34 @@
 #ifndef TNLDIRICHLETBOUNDARYCONDITIONS_H_
 #define TNLDIRICHLETBOUNDARYCONDITIONS_H_
 
+#include <operators/tnlOperator.h>
+#include <functions/tnlConstantFunction.h>
+
 template< typename Mesh,
-          typename Function,
+          typename Function = tnlConstantFunction< Mesh::getMeshDimensions(), typename Mesh::RealType >,
+          int MeshEntitiesDimensions = Mesh::getMeshDimensions(),
           typename Real = typename Mesh::RealType,
           typename Index = typename Mesh::IndexType >
 class tnlDirichletBoundaryConditions
-{
-
-};
-
-template< int Dimensions,
-          typename MeshReal,
-          typename Device,
-          typename MeshIndex,
-          typename Function,
-          typename Real,
-          typename Index >
-class tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, MeshIndex >, Function, Real, Index >
+: public tnlOperator< Mesh,
+                      MeshBoundaryDomain,
+                      MeshEntitiesDimensions,
+                      MeshEntitiesDimensions,
+                      Real,
+                      Index >
 {
    public:
 
-   typedef tnlGrid< Dimensions, MeshReal, Device, MeshIndex > MeshType;
+   typedef Mesh MeshType;
    typedef Function FunctionType;
    typedef Real RealType;
-   typedef Device DeviceType;
+   typedef typename MeshType::DeviceType DeviceType;
    typedef Index IndexType;
-
-   
-   //typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector;
+  
    typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
-   typedef tnlStaticVector< Dimensions, RealType > VertexType;
-   //typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef typename MeshType::VertexType VertexType;
+   
+   static constexpr int getMeshDimensions() { return MeshType::meshDimensions; }
 
    static void configSetup( tnlConfigDescription& config,
                             const tnlString& prefix = "" );
@@ -61,15 +58,14 @@ class tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, Mes
    Function& getFunction();
 
    const Function& getFunction() const;
-
-   template< typename EntityType >
+   
+   template< typename EntityType,
+             typename MeshFunction >
    __cuda_callable__
-   void setBoundaryConditions( const RealType& time,
-                               const MeshType& mesh,
-                               const EntityType& entity,
-                               DofVectorType& u,
-                               DofVectorType& fu ) const;
-
+   const RealType operator()( const MeshFunction& u,
+                              const EntityType& entity,                            
+                              const RealType& time = 0 ) const;
+   
    template< typename EntityType >
    __cuda_callable__
    IndexType getLinearSystemRowLength( const MeshType& mesh,
@@ -77,13 +73,14 @@ class tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, Mes
                                        const EntityType& entity ) const;
 
    template< typename MatrixRow,
-             typename EntityType >
+             typename EntityType,
+             typename MeshFunction >
    __cuda_callable__
       void updateLinearSystem( const RealType& time,
                                const MeshType& mesh,
                                const IndexType& index,
                                const EntityType& entity,
-                               DofVectorType& u,
+                               const MeshFunction& u,
                                DofVectorType& b,
                                MatrixRow& matrixRow ) const;
 
diff --git a/src/operators/tnlDirichletBoundaryConditions_impl.h b/src/operators/tnlDirichletBoundaryConditions_impl.h
index c91c15c7750677991fcc1dbabb40bae4eea9ab24..09ad0f26b9e69a01c0f6f0195ca56038e328def0 100644
--- a/src/operators/tnlDirichletBoundaryConditions_impl.h
+++ b/src/operators/tnlDirichletBoundaryConditions_impl.h
@@ -20,113 +20,96 @@
 
 #include <functions/tnlFunctionAdapter.h>
 
-template< int Dimensions,
-          typename MeshReal,
-          typename Device,
-          typename MeshIndex,
+template< typename Mesh,
           typename Function,
+          int MeshEntitiesDimensions,
           typename Real,
           typename Index >
 void
-tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
 configSetup( tnlConfigDescription& config,
              const tnlString& prefix )
 {
    Function::configSetup( config );
 }
 
-template< int Dimensions,
-          typename MeshReal,
-          typename Device,
-          typename MeshIndex,
+template< typename Mesh,
           typename Function,
+          int MeshEntitiesDimensions,
           typename Real,
           typename Index >
 bool
-tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
 setup( const tnlParameterContainer& parameters,
        const tnlString& prefix )
 {
    return this->function.setup( parameters );
 }
 
-template< int Dimensions,
-          typename MeshReal,
-          typename Device,
-          typename MeshIndex,
+template< typename Mesh,
           typename Function,
+          int MeshEntitiesDimensions,
           typename Real,
           typename Index >
 void
-tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
 setFunction( const Function& function )
 {
    this->function = function;
 }
 
-
-template< int Dimensions,
-          typename MeshReal,
-          typename Device,
-          typename MeshIndex,
+template< typename Mesh,
           typename Function,
+          int MeshEntitiesDimensions,
           typename Real,
           typename Index >
 Function&
-tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
 getFunction()
 {
    return this->function;
 }
 
-template< int Dimensions,
-          typename MeshReal,
-          typename Device,
-          typename MeshIndex,
+template< typename Mesh,
           typename Function,
+          int MeshEntitiesDimensions,
           typename Real,
           typename Index >
 const Function&
-tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
 getFunction() const
 {
    return *this->function;
 }
 
 
-template< int Dimensions,
-          typename MeshReal,
-          typename Device,
-          typename MeshIndex,
+template< typename Mesh,
           typename Function,
+          int MeshEntitiesDimensions,
           typename Real,
           typename Index >
-   template< typename EntityType >
+template< typename EntityType,
+          typename MeshFunction >
 __cuda_callable__
-void
-tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, MeshIndex >, Function, Real, Index >::
-setBoundaryConditions( const RealType& time,
-                       const MeshType& mesh,
-                       const EntityType& entity,
-                       DofVectorType& u,
-                       DofVectorType& fu ) const
+const Real
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
+operator()( const MeshFunction& u,
+            const EntityType& entity,            
+            const RealType& time ) const
 {
-   const IndexType& index = entity.getIndex();
-   fu[ index ] = 0;
-   u[ index ] = tnlFunctionAdapter< MeshType, Function >::template getValue( this->function, entity, time );
+   //static_assert( EntityType::getDimensions() == MeshEntitiesDimensions, "Wrong mesh entity dimensions." );
+   return tnlFunctionAdapter< MeshType, Function >::template getValue( this->function, entity, time );
 }
 
-template< int Dimensions,
-          typename MeshReal,
-          typename Device,
-          typename MeshIndex,
+template< typename Mesh,
           typename Function,
+          int MeshEntitiesDimensions,
           typename Real,
           typename Index >
    template< typename EntityType >
 __cuda_callable__
 Index
-tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
 getLinearSystemRowLength( const MeshType& mesh,
                           const IndexType& index,
                           const EntityType& entity ) const
@@ -134,23 +117,22 @@ getLinearSystemRowLength( const MeshType& mesh,
    return 1;
 }
 
-template< int Dimensions,
-          typename MeshReal,
-          typename Device,
-          typename MeshIndex,
+template< typename Mesh,
           typename Function,
+          int MeshEntitiesDimensions,
           typename Real,
           typename Index >
    template< typename Matrix,
-             typename EntityType >
+             typename EntityType,
+             typename MeshFunction >
 __cuda_callable__
 void
-tnlDirichletBoundaryConditions< tnlGrid< Dimensions, MeshReal, Device, MeshIndex >, Function, Real, Index >::
+tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >::
 updateLinearSystem( const RealType& time,
                     const MeshType& mesh,
                     const IndexType& index,
                     const EntityType& entity,
-                    DofVectorType& u,
+                    const MeshFunction& u,
                     DofVectorType& b,
                     Matrix& matrix ) const
 {
@@ -159,6 +141,4 @@ updateLinearSystem( const RealType& time,
    b[ index ] = tnlFunctionAdapter< MeshType, Function >::getValue( this->function, entity, time );
 }
 
-
-
 #endif /* TNLDIRICHLETBOUNDARYCONDITIONS_IMPL_H_ */
diff --git a/src/operators/tnlExactFunctionInverseOperator.h b/src/operators/tnlExactFunctionInverseOperator.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b9084528c47e8ecb2ba0b136a402e30562ce631
--- /dev/null
+++ b/src/operators/tnlExactFunctionInverseOperator.h
@@ -0,0 +1,101 @@
+/***************************************************************************
+                          tnlExactFunctionInverseOperator.h  -  description
+                             -------------------
+    begin                : Feb 17, 2016
+    copyright            : (C) 2016 by 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 TNLEXACTFUNCTIONINVERSEOPERATOR_H
+#define	TNLEXACTFUNCTIONINVERSEOPERATOR_H
+
+#include <core/tnlString.h>
+#include <core/tnlCuda.h>
+#include <operators/tnlOperator.h>
+#include <operators/tnlExactIdentityOperator.h>
+
+template< int Dimensions,
+          typename InnerOperator= tnlExactIdentityOperator< Dimensions > >
+class tnlExactFunctionInverseOperator
+   : public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+           
+      static tnlString getType()
+      {
+         return tnlString( "tnlExactFunctionInverseOperator< " ) + 
+                tnlString( Dimensions) + " >";         
+      }
+                        
+      InnerOperator& getInnerOperator()
+      {
+         return this->innerOperator;
+      }
+      
+      const InnerOperator& getInnerOperator() const
+      {
+         return this->innerOperator;
+      }      
+
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+         operator()( const Function& function,
+                     const typename Function::VertexType& v, 
+                     const typename Function::RealType& time = 0.0 ) const
+      {
+         typedef typename Function::RealType RealType;
+         return 1.0 / innerOperator( function, v, time );
+      }
+      
+      template< typename Function, 
+                int XDerivative = 0,
+                int YDerivative = 0,
+                int ZDerivative = 0 >
+      __cuda_callable__
+      typename Function::RealType
+         getPartialDerivative( const Function& function,
+                               const typename Function::VertexType& v,
+                               const typename Function::RealType& time = 0.0 ) const
+      {
+         static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
+            "Partial derivative must be non-negative integer." );
+         static_assert( XDerivative + YDerivative + ZDerivative < 2, "Partial derivative of higher order then 1 are not implemented yet." );
+         typedef typename Function::RealType RealType;
+         
+         if( XDerivative == 1 )
+         {
+            const RealType f = innerOperator( function, v, time );
+            const RealType f_x = innerOperator.template getPartialDerivative< Function, 1, 0, 0 >( function, v, time );
+            return -f_x / ( f * f );
+         }
+         if( YDerivative == 1 )
+         {
+            const RealType f = innerOperator( function, v, time );
+            const RealType f_y = innerOperator.template getPartialDerivative< Function, 0, 1, 0 >( function, v, time );
+            return -f_y / ( f * f );            
+         }
+         if( ZDerivative == 1 )
+         {
+            const RealType f = innerOperator( function, v, time );
+            const RealType f_z = innerOperator.template getPartialDerivative< Function, 0, 0, 1 >( function, v, time );
+            return -f_z / ( f * f );            
+         }         
+      }
+      
+   protected:
+      
+      InnerOperator innerOperator;           
+};
+
+#endif	/* TNLEXACTFUNCTIONINVERSEOPERATOR_H */
+
diff --git a/src/operators/tnlExactIdentityOperator.h b/src/operators/tnlExactIdentityOperator.h
new file mode 100644
index 0000000000000000000000000000000000000000..aab4488d8c9498597ed6f897d7036836e9d33dd7
--- /dev/null
+++ b/src/operators/tnlExactIdentityOperator.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+                          tnlExactIdentityOperator.h  -  description
+                             -------------------
+    begin                : Feb 18, 2016
+    copyright            : (C) 2016 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 TNLEXACTIDENTITYOPERATOR_H
+#define TNLEXACTIDENTITYOPERATOR_H
+
+#include <core/tnlString.h>
+#include <core/tnlCuda.h>
+#include <operators/tnlOperator.h>
+
+template< int Dimensions >
+class tnlExactIdentityOperator
+   : public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+     
+      static tnlString getType()
+      {
+         return tnlString( "tnlExactIdentityOperator< " ) + 
+                tnlString( Dimensions) + " >";         
+      }
+      
+      template< typename Function >
+      __cuda_callable__
+      typename Function::RealType 
+         operator()( const Function& function,
+                     const typename Function::VertexType& v, 
+                     const typename Function::RealType& time = 0.0 ) const
+      {
+         return function( v, time );
+      }
+      
+      template< typename Function, 
+                int XDerivative = 0,
+                int YDerivative = 0,
+                int ZDerivative = 0 >
+      __cuda_callable__
+      typename Function::RealType
+         getPartialDerivative( const Function& function,
+                               const typename Function::VertexType& v,
+                               const typename Function::RealType& time = 0.0 ) const
+      {
+         static_assert( XDerivative >= 0 && YDerivative >= 0 && ZDerivative >= 0,
+            "Partial derivative must be non-negative integer." );
+         
+         return function.template getPartialDerivative< XDerivative, YDerivative, ZDerivative >( v, time );         
+      }
+};
+
+
+
+#endif /* TNLEXACTIDENTITYOPERATOR_H */
+
diff --git a/src/operators/tnlExactOperatorComposition.h b/src/operators/tnlExactOperatorComposition.h
new file mode 100644
index 0000000000000000000000000000000000000000..99d9240dcd78232ec1b605654a50fd28a4d3f971
--- /dev/null
+++ b/src/operators/tnlExactOperatorComposition.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+                          tnlExactOperatorComposition.h  -  description
+                             -------------------
+    begin                : Feb 17, 2016
+    copyright            : (C) 2016 by 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 TNLEXACTOPERATORCOMPOSITION_H
+#define TNLEXACTOPERATORCOMPOSITION_H
+
+template< typename OuterOperator,
+          typename InnerOperator >
+class tnlExactOperatorComposition
+{
+   public:
+      
+      template< typename Function >
+      __cuda_callable__ inline
+      typename Function::RealType operator()( const Function& function,
+                                              const typename Function::VertexType& v,
+                                              const typename Function::RealType& time = 0.0 ) const
+      {
+         return OuterOperator( innerOperator( function, v, time), v, time );
+      }
+      
+   protected:
+      
+      InnerOperator innerOperator;
+      
+      OuterOperator outerOperator;
+};
+
+#endif /* TNLEXACTOPERATORCOMPOSITION_H */
+
diff --git a/src/operators/tnlExactOperatorEvaluator.h b/src/operators/tnlExactOperatorEvaluator.h
deleted file mode 100644
index c9c5d2eac922a82b73becaebb86ddba35835c0ec..0000000000000000000000000000000000000000
--- a/src/operators/tnlExactOperatorEvaluator.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/***************************************************************************
-                          tnlExactOperatorEvaluator.h  -  description
-                             -------------------
-    begin                : Nov 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 TNLEXACTOPERATOREVALUATOR_H_
-#define TNLEXACTOPERATOREVALUATOR_H_
-
-#include <mesh/tnlGrid.h>
-
-template< typename Real,
-          typename DofVector,
-          typename DifferentialOperator,
-          typename Function,
-          typename BoundaryConditions >
-class tnlExactOperatorEvaluatorTraversalUserData
-{
-   public:
-
-      const Real &time;
-
-      const DifferentialOperator& differentialOperator;
-
-      const BoundaryConditions& boundaryConditions;
-
-      const Function& function;
-
-      DofVector &fu;
-
-      tnlExactOperatorEvaluatorTraversalUserData( const Real& time,
-                                                  const DifferentialOperator& differentialOperator,
-                                                  const Function& function,
-                                                  const BoundaryConditions& boundaryConditions,
-                                                  DofVector& fu )
-      : time( time ),
-        differentialOperator( differentialOperator ),
-        boundaryConditions( boundaryConditions ),
-        function( function ),
-        fu( fu )
-      {};
-};
-
-template< typename Mesh,
-          typename DofVector,
-          typename DifferentialOperator,
-          typename Function,
-          typename BoundaryConditions >
-class tnlExactOperatorEvaluator
-{
-   public:
-      typedef Mesh MeshType;
-      typedef typename DofVector::RealType RealType;
-      typedef typename DofVector::DeviceType DeviceType;
-      typedef typename DofVector::IndexType IndexType;
-      typedef tnlExactOperatorEvaluatorTraversalUserData< RealType,
-                                                          DofVector,
-                                                          DifferentialOperator,
-                                                          Function,
-                                                          BoundaryConditions > TraversalUserData;
-
-      template< typename EntityType >
-      void evaluate( const RealType& time,
-                     const MeshType& mesh,
-                     const DifferentialOperator& differentialOperator,
-                     const Function& function,
-                     const BoundaryConditions& boundaryConditions,
-                     DofVector& fu ) const;
-
-      class TraversalBoundaryEntitiesProcessor
-      {
-         public:
-
-            template< int EntityDimension >
-            __cuda_callable__
-            static void processEntity( const MeshType& mesh,
-                                       TraversalUserData& userData,
-                                       const IndexType index )
-            {
-               userData.boundaryConditions.setBoundaryConditions( userData.time,
-                                                                  mesh,
-                                                                  index,
-                                                                  userData.u,
-                                                                  userData.fu );
-            }
-
-      };
-
-      class TraversalInteriorEntitiesProcessor
-      {
-         public:
-
-            template< int EntityDimensions >
-            __cuda_callable__
-            static void processEntity( const MeshType& mesh,
-                                       TraversalUserData& userData,
-                                       const IndexType index )
-            {
-               userData.fu[ index ] = 
-                  userData.differentialOperator.template getValue
-                  ( userData.function,
-                    mesh.template getEntityCenter< EntityDimensions >( index ),
-                    userData.time );
-            }
-
-      };
-
-};
-
-template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index,
-          typename DofVector,
-          typename DifferentialOperator,
-          typename Function,
-          typename BoundaryConditions >
-class tnlExactOperatorEvaluator< tnlGrid< Dimensions, Real, Device, Index >, DofVector, DifferentialOperator, Function, BoundaryConditions >
-{
-   public:
-      typedef tnlGrid< Dimensions, Real, Device, Index > MeshType;
-      typedef typename DofVector::RealType RealType;
-      typedef typename DofVector::DeviceType DeviceType;
-      typedef typename DofVector::IndexType IndexType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef tnlExactOperatorEvaluatorTraversalUserData< RealType,
-                                                          DofVector,
-                                                          DifferentialOperator,
-                                                          Function,
-                                                          BoundaryConditions > TraversalUserData;
-
-      template< typename EntityType >
-      void evaluate( const RealType& time,
-                     const MeshType& mesh,
-                     const DifferentialOperator& differentialOperator,
-                     const Function& function,
-                     const BoundaryConditions& boundaryConditions,
-                     DofVector& fu ) const;
-
-      class TraversalBoundaryEntitiesProcessor
-      {
-         public:
-
-            template< typename EntityType >
-            __cuda_callable__
-            static void processEntity( const MeshType& mesh,
-                                       TraversalUserData& userData,
-                                       const EntityType& entity )
-            {
-               userData.boundaryConditions.setBoundaryConditions
-                  ( userData.time,
-                    mesh,
-                    entity,
-                    userData.fu,
-                    userData.fu );
-            }
-      };
-
-      class TraversalInteriorEntitiesProcessor
-      {
-         public:
-            
-            template< typename EntityType >
-            __cuda_callable__
-            static void processEntity( const MeshType& mesh,
-                                       TraversalUserData& userData,
-                                       const EntityType& entity )
-            {
-               userData.fu[ entity.getIndex() ] = 
-                  userData.differentialOperator.getValue
-                     ( userData.function,
-                       entity.getCenter(),                                                                           
-                       userData.time );
-            }
-
-            
-            __cuda_callable__
-            static void processCell( const MeshType& mesh,
-                                     TraversalUserData& userData,
-                                     const IndexType index,
-                                     const CoordinatesType& c )
-            {
-               userData.fu[ index ] = userData.differentialOperator.getValue( userData.function,
-                                                                              mesh.template getCellCenter( index ),                                                                           
-                                                                              userData.time );
-            }
-
-      };
-
-};
-
-
-#include <operators/tnlExactOperatorEvaluator_impl.h>
-
-#endif /* TNLEXACTOPERATOREVALUATOR_H_ */
diff --git a/src/operators/tnlExactOperatorEvaluator_impl.h b/src/operators/tnlExactOperatorEvaluator_impl.h
deleted file mode 100644
index 19e22c9ce3a8aded6cfdc24c97acf08fa9e90a71..0000000000000000000000000000000000000000
--- a/src/operators/tnlExactOperatorEvaluator_impl.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/***************************************************************************
-                          tnlExactOperatorEvaluator_impl.h  -  description
-                             -------------------
-    begin                : Nov 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 TNLEXACTOPERATOREVALUATOR_IMPL_H_
-#define TNLEXACTOPERATOREVALUATOR_IMPL_H_
-
-template< typename Mesh,
-          typename DofVector,
-          typename DifferentialOperator,
-          typename Function,
-          typename BoundaryConditions >
-   template< typename EntityType >
-void
-tnlExactOperatorEvaluator< Mesh, DofVector, DifferentialOperator, Function, BoundaryConditions >::
-evaluate( const RealType& time,
-          const Mesh& mesh,
-          const DifferentialOperator& differentialOperator,
-          const Function& function,
-          const BoundaryConditions& boundaryConditions,
-          DofVector& fu ) const
-{
-   TraversalUserData userData( time, differentialOperator, function, boundaryConditions, fu );
-   TraversalBoundaryEntitiesProcessor boundaryEntitiesProcessor;
-   TraversalInteriorEntitiesProcessor interiorEntitiesProcessor;
-   tnlTraverser< MeshType, EntityType > meshTraversal;
-   meshTraversal.template processEntities< TraversalUserData,
-                                           TraversalBoundaryEntitiesProcessor,
-                                           TraversalInteriorEntitiesProcessor >
-                                          ( mesh,
-                                            userData,
-                                            boundaryEntitiesProcessor,
-                                            interiorEntitiesProcessor );
-}
-
-template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index,
-          typename DofVector,
-          typename DifferentialOperator,
-          typename Function,
-          typename BoundaryConditions >
-   template< typename EntityType >
-void
-tnlExactOperatorEvaluator< tnlGrid< Dimensions, Real, Device, Index >, DofVector, DifferentialOperator, Function, BoundaryConditions >::
-evaluate( const RealType& time,
-          const tnlGrid< Dimensions, Real, Device, Index >& mesh,
-          const DifferentialOperator& differentialOperator,
-          const Function& function,
-          const BoundaryConditions& boundaryConditions,
-          DofVector& fu ) const
-{
-   TraversalUserData userData( time, differentialOperator, function, boundaryConditions, fu );
-   tnlTraverser< MeshType, EntityType > meshTraverser;
-   meshTraverser.template processBoundaryEntities< TraversalUserData,
-                                                   TraversalBoundaryEntitiesProcessor >
-                                                 ( mesh,
-                                                   userData );
-   meshTraverser.template processInteriorEntities< TraversalUserData,
-                                                   TraversalInteriorEntitiesProcessor >
-                                                 ( mesh,
-                                                   userData );
-}
-
-
-
-#endif /* TNLEXACTOPERATOREVALUATOR_IMPL_H_ */
diff --git a/src/operators/tnlFunctionInverseOperator.h b/src/operators/tnlFunctionInverseOperator.h
new file mode 100644
index 0000000000000000000000000000000000000000..bc109559ee2fca58092b5948f36d29a9ac274d5f
--- /dev/null
+++ b/src/operators/tnlFunctionInverseOperator.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+                          tnlFunctionInverseOperator.h  -  description
+                             -------------------
+    begin                : Feb 17, 2016
+    copyright            : (C) 2016 by 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 TNLFUNCTIONINVERSEOPERATOR_H
+#define	TNLFUNCTIONINVERSEOPERATOR_H
+
+#include <core/tnlString.h>
+#include <core/tnlCuda.h>
+#include <operators/tnlOperator.h>
+
+template< typename Operator >
+class tnlFunctionInverseOperator
+: public tnlOperator< typename Operator::MeshType,
+                      Operator::getDomainType(),
+                      Operator::getPreimageEntitiesDimensions(),
+                      Operator::getImageEntitiesDimensions(),
+                      typename Operator::RealType,
+                      typename Operator::IndexType >
+{
+   public:
+      
+      typedef Operator OperatorType;
+      typedef typename OperatorType::RealType RealType;
+      typedef typename OperatorType::IndexType IndexType;
+      typedef tnlFunctionInverseOperator< Operator > ThisType;
+      typedef ThisType ExactOperatorType;
+      
+      
+      tnlFunctionInverseOperator( const OperatorType& operator_ )
+      : operator_( operator_ ) {};
+      
+      static tnlString getType()
+      {
+         return tnlString( "tnlFunctionInverseOperator< " ) + Operator::getType() + " >";         
+      }
+      
+      const OperatorType& getOperator() const { return this->operator_; }
+      
+      template< typename MeshFunction,
+                typename MeshEntity >
+      __cuda_callable__
+      typename MeshFunction::RealType
+      operator()( const MeshFunction& u,
+                  const MeshEntity& entity,
+                  const typename MeshFunction::RealType& time = 0.0 ) const
+      {
+         return 1.0 / operator_( u, entity, time );
+      }
+      
+   protected:
+      
+      const OperatorType& operator_;
+};
+
+
+#endif	/* TNLINVERSEFUNCTIONOPERATOR_H */
+
diff --git a/src/operators/tnlIdentityOperator.h b/src/operators/tnlIdentityOperator.h
new file mode 100644
index 0000000000000000000000000000000000000000..f175d036c35659ecb2ab642d1b17e76b22616098
--- /dev/null
+++ b/src/operators/tnlIdentityOperator.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+                          tnlIdentityOperator.h  -  description
+                             -------------------
+    begin                : Feb 9, 2016
+    copyright            : (C) 2016 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 TNLIDENTITYOPERATOR_H
+#define	TNLIDENTITYOPERATOR_H
+
+#include<functions/tnlMeshFunction.h>
+
+template< typename MeshFunction >
+class tnlIdentityOperator
+   : public tnlDomain< MeshFunction::getDimensions(), MeshFunction::getDomainType() >
+{
+   public:
+      
+      typedef typename MeshFunction::MeshType MeshType;
+      typedef typename MeshFunction::RealType RealType;
+      typedef typename MeshFunction::IndexType IndexType;
+      
+      tnlOperatorComposition( const MeshFunction& meshFunction )
+      : meshFunction( meshFunction ) {};
+      
+      template< typename MeshEntity >
+      __cuda_callable__
+      RealType operator()(
+         const MeshFunction& function,
+         const MeshEntity& meshEntity,
+         const RealType& time = 0 ) const
+      {
+         static_assert( MeshFunction::getDimensions() == InnerOperator::getDimensions(),
+            "Mesh function and operator have both different number of dimensions." );
+         return this->meshFunction( meshEntity, time );
+      }
+      
+   
+   protected:
+      
+      const MeshFunction& meshFunction;      
+};
+
+#endif	/* TNLIDENTITYOPERATOR_H */
+
diff --git a/src/operators/tnlNeumannBoundaryConditions.h b/src/operators/tnlNeumannBoundaryConditions.h
index dc87909308d51c4ce42ef4a640cf66bd0169ae18..06e109e36e6082bb8a9a4f452c52adfedaa9f7d6 100644
--- a/src/operators/tnlNeumannBoundaryConditions.h
+++ b/src/operators/tnlNeumannBoundaryConditions.h
@@ -48,7 +48,8 @@ template< typename MeshReal,
           typename Real,
           typename Index >
 class tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >
-   : public tnlNeumannBoundaryConditionsBase< Function >
+   : public tnlNeumannBoundaryConditionsBase< Function >,
+     public tnlDomain< 1, MeshBoundaryDomain >
 {
    public:
 
@@ -58,18 +59,17 @@ class tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, F
    typedef Index IndexType;
 
    typedef Function FunctionType;
-   typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector;
    typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
    typedef tnlStaticVector< 1, RealType > VertexType;
    typedef typename MeshType::CoordinatesType CoordinatesType;
 
-   template< typename EntityType >
+   template< typename EntityType,
+             typename MeshFunction >
    __cuda_callable__
-   void setBoundaryConditions( const RealType& time,
-                               const MeshType& mesh,
-                               const EntityType& entity,
-                               DofVectorType& u,
-                               DofVectorType& fu ) const;
+   const RealType operator()( const MeshFunction& u,
+                              const EntityType& entity,   
+                              const RealType& time = 0 ) const;
+
 
    template< typename EntityType >
    __cuda_callable__
@@ -78,13 +78,14 @@ class tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, F
                                    const EntityType& entity ) const;
 
    template< typename MatrixRow,
-             typename EntityType >
+             typename EntityType,
+             typename MeshFunction >
    __cuda_callable__
       void updateLinearSystem( const RealType& time,
                                const MeshType& mesh,
                                const IndexType& index,
                                const EntityType& entity,
-                               DofVectorType& u,
+                               const MeshFunction& u,
                                DofVectorType& b,
                                MatrixRow& matrixRow ) const;
 };
@@ -99,7 +100,8 @@ template< typename MeshReal,
           typename Real,
           typename Index >
 class tnlNeumannBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index >
-   : public tnlNeumannBoundaryConditionsBase< Function >
+   : public tnlNeumannBoundaryConditionsBase< Function >,
+     public tnlDomain< 2, MeshBoundaryDomain >
 {
    public:
 
@@ -109,19 +111,17 @@ class tnlNeumannBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, F
    typedef Index IndexType;
 
    typedef Function FunctionType;
-   typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector;
    typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
    typedef tnlStaticVector< 2, RealType > VertexType;
    typedef typename MeshType::CoordinatesType CoordinatesType;
 
-   template< typename EntityType >
+   template< typename EntityType,
+             typename MeshFunction >
    __cuda_callable__
-   void setBoundaryConditions( const RealType& time,
-                               const MeshType& mesh,
-                               const EntityType& entity,
-                               DofVectorType& u,
-                               DofVectorType& fu ) const;
-   
+   const RealType operator()( const MeshFunction& u,
+                              const EntityType& entity,                            
+                              const RealType& time = 0 ) const;
+      
    template< typename EntityType >
    __cuda_callable__
    Index getLinearSystemRowLength( const MeshType& mesh,
@@ -129,13 +129,14 @@ class tnlNeumannBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, F
                                    const EntityType& entity ) const;
 
    template< typename MatrixRow,
-             typename EntityType >
+             typename EntityType,
+             typename MeshFunction >
    __cuda_callable__
       void updateLinearSystem( const RealType& time,
                                const MeshType& mesh,
                                const IndexType& index,
                                const EntityType& entity,
-                               DofVectorType& u,
+                               const MeshFunction& u,
                                DofVectorType& b,
                                MatrixRow& matrixRow ) const;
 };
@@ -150,7 +151,8 @@ template< typename MeshReal,
           typename Real,
           typename Index >
 class tnlNeumannBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index >
-   : public tnlNeumannBoundaryConditionsBase< Function >
+   : public tnlNeumannBoundaryConditionsBase< Function >,
+     public tnlDomain< 3, MeshBoundaryDomain >
 {
    public:
 
@@ -160,18 +162,17 @@ class tnlNeumannBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, F
    typedef Index IndexType;
 
    typedef Function FunctionType;
-   typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector;
    typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
    typedef tnlStaticVector< 3, RealType > VertexType;
    typedef typename MeshType::CoordinatesType CoordinatesType;
 
-   template< typename EntityType >
+   template< typename EntityType,
+             typename MeshFunction >
    __cuda_callable__
-   void setBoundaryConditions( const RealType& time,
-                               const MeshType& mesh,
-                               const EntityType& entity,
-                               DofVectorType& u,
-                               DofVectorType& fu ) const;
+   const RealType operator()( const MeshFunction& u,
+                              const EntityType& entity,
+                              const RealType& time = 0 ) const;
+   
 
    template< typename EntityType >
    __cuda_callable__
@@ -180,13 +181,14 @@ class tnlNeumannBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, F
                                    const EntityType& entity ) const;
 
    template< typename MatrixRow,
-             typename EntityType >
+             typename EntityType,
+             typename MeshFunction >
    __cuda_callable__
       void updateLinearSystem( const RealType& time,
                                const MeshType& mesh,
                                const IndexType& index,
                                const EntityType& entity,
-                               DofVectorType& u,
+                               const MeshFunction& u,
                                DofVectorType& b,
                                MatrixRow& matrixRow ) const;
 };
@@ -197,7 +199,7 @@ template< typename Mesh,
           typename Index >
 ostream& operator << ( ostream& str, const tnlNeumannBoundaryConditions< Mesh, Function, Real, Index >& bc )
 {
-   str << "Dirichlet boundary conditions: vector = " << bc.getFunction();
+   str << "Neumann boundary conditions: function = " << bc.getFunction();
    return str;
 }
 
diff --git a/src/operators/tnlNeumannBoundaryConditions_impl.h b/src/operators/tnlNeumannBoundaryConditions_impl.h
index 4133edda92bb15246d1b0ed8c3ae38bf99a82cf1..a29c5cac1322356cb11d27a7d03195b166f4d9f5 100644
--- a/src/operators/tnlNeumannBoundaryConditions_impl.h
+++ b/src/operators/tnlNeumannBoundaryConditions_impl.h
@@ -1,6 +1,8 @@
 #ifndef TNLNEUMANNBOUNDARYCONDITIONS_IMPL_H
 #define	TNLNEUMANNBOUNDARYCONDITIONS_IMPL_H
 
+#include <functions/tnlFunctionAdapter.h>
+
 template< typename Function >
 void
 tnlNeumannBoundaryConditionsBase< Function >::
@@ -47,33 +49,34 @@ getFunction() const
 /****
  * 1D grid
  */
+
 template< typename MeshReal,
           typename Device,
           typename MeshIndex,
           typename Function,
           typename Real,
           typename Index >
-   template< typename EntityType >          
+   template< typename EntityType,
+             typename MeshFunction >
 __cuda_callable__
-void
+const Real
 tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >::
-setBoundaryConditions( const RealType& time,
-                       const MeshType& mesh,
-                       const EntityType& entity,
-                       DofVectorType& u,
-                       DofVectorType& fu ) const
+operator()( const MeshFunction& u,
+            const EntityType& entity,
+            const RealType& time ) const
 {
+   const MeshType& mesh = entity.getMesh();
    auto neighbourEntities = entity.getNeighbourEntities();
    const IndexType& index = entity.getIndex();
-   fu[ index ] = 0;
    if( entity.getCoordinates().x() == 0 )
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< 1 >() ] - mesh.getSpaceSteps().x() * 
+      return u[ neighbourEntities.template getEntityIndex< 1 >() ] - mesh.getSpaceSteps().x() * 
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
    else
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< -1 >() ] + mesh.getSpaceSteps().x() * 
-         tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+      return u[ neighbourEntities.template getEntityIndex< -1 >() ] + mesh.getSpaceSteps().x() * 
+         tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );   
 }
 
+
 template< typename MeshReal,
           typename Device,
           typename MeshIndex,
@@ -98,7 +101,8 @@ template< typename MeshReal,
           typename Real,
           typename Index >
    template< typename Matrix,
-             typename EntityType >
+             typename EntityType,
+             typename MeshFunction >
 __cuda_callable__
 void
 tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >::
@@ -106,7 +110,7 @@ updateLinearSystem( const RealType& time,
                     const MeshType& mesh,
                     const IndexType& index,
                     const EntityType& entity,
-                    DofVectorType& u,
+                    const MeshFunction& u,
                     DofVectorType& b,
                     Matrix& matrix ) const
 {
@@ -137,43 +141,38 @@ template< typename MeshReal,
           typename Function,
           typename Real,
           typename Index >
-   template< typename EntityType >          
+   template< typename EntityType,
+             typename MeshFunction >
 __cuda_callable__
-void
+const Real
 tnlNeumannBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index >::
-setBoundaryConditions( const RealType& time,
-                       const MeshType& mesh,
-                       const EntityType& entity,
-                       DofVectorType& u,
-                       DofVectorType& fu ) const
+operator()( const MeshFunction& u,
+            const EntityType& entity,
+            const RealType& time ) const
 {
+   const MeshType& mesh = entity.getMesh();
    auto neighbourEntities = entity.getNeighbourEntities();
    const IndexType& index = entity.getIndex();
-   fu[ index ] = 0;
    if( entity.getCoordinates().x() == 0 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - mesh.getSpaceSteps().x() *
+      return u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - mesh.getSpaceSteps().x() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
    }
    if( entity.getCoordinates().x() == mesh.getDimensions().x() - 1 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] + mesh.getSpaceSteps().x() *
+      return u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] + mesh.getSpaceSteps().x() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
    }
    if( entity.getCoordinates().y() == 0 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - mesh.getSpaceSteps().y() *
+      return u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - mesh.getSpaceSteps().y() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
    }
    if( entity.getCoordinates().y() == mesh.getDimensions().y() - 1 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] + mesh.getSpaceSteps().y() *
+      return u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] + mesh.getSpaceSteps().y() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
-   }
+   }   
 }
 
 template< typename MeshReal,
@@ -200,7 +199,8 @@ template< typename MeshReal,
           typename Real,
           typename Index >
    template< typename Matrix,
-             typename EntityType >
+             typename EntityType,
+             typename MeshFunction >
 __cuda_callable__
 void
 tnlNeumannBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index >::
@@ -208,7 +208,7 @@ updateLinearSystem( const RealType& time,
                     const MeshType& mesh,
                     const IndexType& index,
                     const EntityType& entity,
-                    DofVectorType& u,
+                    const MeshFunction& u,
                     DofVectorType& b,
                     Matrix& matrix ) const
 {
@@ -253,55 +253,48 @@ template< typename MeshReal,
           typename Function,
           typename Real,
           typename Index >
-   template< typename EntityType >          
+   template< typename EntityType,
+             typename MeshFunction >
 __cuda_callable__
-void
+const Real
 tnlNeumannBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index >::
-setBoundaryConditions( const RealType& time,
-                       const MeshType& mesh,
-                       const EntityType& entity,
-                       DofVectorType& u,
-                       DofVectorType& fu ) const
+operator()( const MeshFunction& u,
+            const EntityType& entity,            
+            const RealType& time ) const
 {
+   const MeshType& mesh = entity.getMesh();
    auto neighbourEntities = entity.getNeighbourEntities();
    const IndexType& index = entity.getIndex();
-   fu[ index ] = 0;
    if( entity.getCoordinates().x() == 0 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - mesh.getSpaceSteps().x() *
+      return u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - mesh.getSpaceSteps().x() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
    }
    if( entity.getCoordinates().x() == mesh.getDimensions().x() - 1 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] + mesh.getSpaceSteps().x() *
+      return u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] + mesh.getSpaceSteps().x() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
    }
    if( entity.getCoordinates().y() == 0 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - mesh.getSpaceSteps().y() *
+      return u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - mesh.getSpaceSteps().y() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
    }
    if( entity.getCoordinates().y() == mesh.getDimensions().y() - 1 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] + mesh.getSpaceSteps().y() *
+      return u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] + mesh.getSpaceSteps().y() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
    }
    if( entity.getCoordinates().z() == 0 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - mesh.getSpaceSteps().z() *
+      return u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - mesh.getSpaceSteps().z() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
    }
    if( entity.getCoordinates().z() == mesh.getDimensions().z() - 1 )
    {
-      u[ index ] = u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] + mesh.getSpaceSteps().z() *
+      return u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] + mesh.getSpaceSteps().z() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
-      return;
-   }
+   }   
 }
 
 template< typename MeshReal,
@@ -328,7 +321,8 @@ template< typename MeshReal,
           typename Real,
           typename Index >
    template< typename Matrix,
-             typename EntityType >
+             typename EntityType,
+             typename MeshFunction >
 __cuda_callable__
 void
 tnlNeumannBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index >::
@@ -336,7 +330,7 @@ updateLinearSystem( const RealType& time,
                     const MeshType& mesh,
                     const IndexType& index,
                     const EntityType& entity,                    
-                    DofVectorType& u,
+                    const MeshFunction& u,
                     DofVectorType& b,
                     Matrix& matrix ) const
 {
diff --git a/src/operators/tnlOperator.h b/src/operators/tnlOperator.h
new file mode 100644
index 0000000000000000000000000000000000000000..112e6ff7747a337c03eb4aee9c2d041867f0c84f
--- /dev/null
+++ b/src/operators/tnlOperator.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+                          tnlOperator.h  -  description
+                             -------------------
+    begin                : Feb 10, 2016
+    copyright            : (C) 2016 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 TNLOPERATOR_H
+#define	TNLOPERATOR_H
+
+#include <functions/tnlDomain.h>
+
+template< typename Mesh,
+          tnlDomainType DomainType = MeshInteriorDomain,
+          int PreimageEntitiesDimensions = Mesh::getMeshDimensions(),
+          int ImageEntitiesDimensions = Mesh::getMeshDimensions(),
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class tnlOperator : public tnlDomain< Mesh::getMeshDimensions(), DomainType >
+{
+   public:
+      
+      typedef Mesh MeshType;
+      typedef typename MeshType::RealType MeshRealType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::IndexType MeshIndexType;
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef void ExactOperatorType;
+      
+      constexpr static int getMeshDimensions() { return MeshType::getMeshDimensions(); }
+      constexpr static int getPreimageEntitiesDimensions() { return PreimageEntitiesDimensions; }
+      constexpr static int getImageEntitiesDimensions() { return ImageEntitiesDimensions; }
+      
+      bool refresh( const RealType& time = 0.0 ) { return true; }
+      
+      bool deepRefresh( const RealType& time = 0.0 ) { return true; }
+    
+      template< typename MeshFunction > 
+      void setPreimageFunction( const MeshFunction& f ){}
+};
+#endif	/* TNLOPERATOR_H */
+
diff --git a/src/operators/tnlOperatorComposition.h b/src/operators/tnlOperatorComposition.h
new file mode 100644
index 0000000000000000000000000000000000000000..e9f7558bae25610addd292c596d1a5f9af510378
--- /dev/null
+++ b/src/operators/tnlOperatorComposition.h
@@ -0,0 +1,199 @@
+/***************************************************************************
+                          tnlOperatorComposition.h  -  description
+                             -------------------
+    begin                : Jan 30, 2016
+    copyright            : (C) 2016 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 TNLOPERATORCOMPOSITION_H
+#define	TNLOPERATORCOMPOSITION_H
+
+#include<functions/tnlOperatorFunction.h>
+#include<functions/tnlMeshFunction.h>
+#include<operators/tnlOperator.h>
+#include<operators/tnlExactOperatorComposition.h>
+
+/****
+ * This object serves for composition of two operators F and G into an operator F( G( u ) ).
+ * The function u must be set in the constructor or by a method setPreimageFunction.
+ * Each time the function u is changed, the method refresh() or deepRefresh() must be called
+ * before using the operator(). The function u which is passed to the operator() is,in fact,
+ * omitted in this case.
+ */
+
+template< typename OuterOperator,
+          typename InnerOperator,
+          typename InnerBoundaryConditions = void >
+class tnlOperatorComposition
+   : public tnlOperator< typename InnerOperator::MeshType,
+                         InnerOperator::getDomainType(),
+                         InnerOperator::getPreimageEntitiesDimensions(),
+                         OuterOperator::getImageEntitiesDimensions(),
+                         typename InnerOperator::RealType,
+                         typename OuterOperator::IndexType >   
+{
+      static_assert( is_same< typename OuterOperator::MeshType, typename InnerOperator::MeshType >::value,
+         "Both operators have different mesh types." );
+   public:
+      
+      typedef typename InnerOperator::MeshType MeshType;
+      typedef tnlMeshFunction< MeshType, InnerOperator::getPreimageEntitiesDimensions() > PreimageFunctionType;
+      typedef tnlMeshFunction< MeshType, InnerOperator::getImageEntitiesDimensions() > ImageFunctionType;
+      typedef tnlOperatorFunction< InnerOperator, PreimageFunctionType, InnerBoundaryConditions > InnerOperatorFunction;
+      typedef tnlOperatorFunction< InnerOperator, ImageFunctionType > OuterOperatorFunction;
+      typedef typename InnerOperator::RealType RealType;
+      typedef typename InnerOperator::IndexType IndexType;
+      typedef tnlExactOperatorComposition< typename OuterOperator::ExactOperatorType,
+                                           typename InnerOperator::ExactOperatorType > ExactOperatorType;
+      
+      static constexpr int getPreimageEntitiesDimensions() { return InnerOperator::getImageEntitiesDimensions(); };
+      static constexpr int getImageEntitiesDimensions() { return OuterOperator::getImageEntitiesDimensions(); };
+      
+      tnlOperatorComposition( OuterOperator& outerOperator,
+                              InnerOperator& innerOperator,
+                              const InnerBoundaryConditions& innerBoundaryConditions,
+                              const MeshType& mesh )
+      : outerOperator( outerOperator ),
+        innerOperatorFunction( innerOperator, innerBoundaryConditions, mesh ){};
+        
+      void setPreimageFunction( const PreimageFunctionType& preimageFunction )
+      {
+         this->innerOperatorFunction.setPreimageFunction( preimageFunction );
+      }
+        
+      PreimageFunctionType& getPreimageFunction()
+      {
+         return this->innerOperatorFunction.getPreimageFunction();
+      }
+
+      const PreimageFunctionType& getPreimageFunction() const
+      {
+         return this->innerOperatorFunction.getPreimageFunction();
+      }      
+      
+      InnerOperator& getInnerOperator() { return this->innerOperatorFunction.getOperator(); }
+      
+      const InnerOperator& getInnerOperator() const { return this->innerOperatorFunction.getOperator(); }
+      
+      OuterOperator& getOuterOperator() { return this->outerOperator(); };
+      
+      const OuterOperator& getOuterOperator() const { return this->outerOperator(); };
+      
+      bool refresh( const RealType& time = 0.0 )
+      {
+         return this->innerOperatorFunction.refresh( time );
+      }
+      
+      bool deepRefresh( const RealType& time = 0.0 )
+      {
+         return this->innerOperatorFunction.deepRefresh( time );
+      }
+        
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      RealType operator()(
+         const MeshFunction& function,
+         const MeshEntity& meshEntity,
+         const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getDimensions() == InnerOperator::getDimensions(),
+            "Mesh function and operator have both different number of dimensions." );
+         //InnerOperatorFunction innerOperatorFunction( innerOperator, function );
+         return outerOperator( innerOperatorFunction, meshEntity, time );
+      }      
+   
+   protected:
+      
+      OuterOperator& outerOperator;
+      
+      InnerOperatorFunction innerOperatorFunction;      
+};
+
+template< typename OuterOperator,
+          typename InnerOperator >
+class tnlOperatorComposition< OuterOperator, InnerOperator, void >
+   : public tnlDomain< InnerOperator::getDimensions(), InnerOperator::getDomainType() >   
+{
+      static_assert( is_same< typename OuterOperator::MeshType, typename InnerOperator::MeshType >::value,
+         "Both operators have different mesh types." );
+   public:
+      
+      typedef typename InnerOperator::MeshType MeshType;
+      typedef tnlMeshFunction< MeshType, InnerOperator::getPreimageEntitiesDimensions() > PreimageFunctionType;
+      typedef tnlMeshFunction< MeshType, InnerOperator::getImageEntitiesDimensions() > ImageFunctionType;
+      typedef tnlOperatorFunction< InnerOperator, PreimageFunctionType, void > InnerOperatorFunction;
+      typedef tnlOperatorFunction< InnerOperator, ImageFunctionType > OuterOperatorFunction;
+      typedef typename InnerOperator::RealType RealType;
+      typedef typename InnerOperator::IndexType IndexType;
+      
+      tnlOperatorComposition( const OuterOperator& outerOperator,
+                              InnerOperator& innerOperator,
+                              const MeshType& mesh )
+      : outerOperator( outerOperator ),
+        innerOperatorFunction( innerOperator, mesh ){};
+        
+      void setPreimageFunction( PreimageFunctionType& preimageFunction )
+      {
+         this->innerOperatorFunction.setPreimageFunction( preimageFunction );
+      }        
+        
+      PreimageFunctionType& getPreimageFunction()
+      {
+         return this->innerOperatorFunction.getPreimageFunction();
+      }
+
+      const PreimageFunctionType& getPreimageFunction() const
+      {
+         return this->innerOperatorFunction.getPreimageFunction();
+      }      
+      
+      bool refresh( const RealType& time = 0.0 )
+      {
+         return this->innerOperatorFunction.refresh( time );
+         /*tnlMeshFunction< MeshType, MeshType::getMeshDimensions() - 1 > f( this->innerOperatorFunction.getMesh() );
+         f = this->innerOperatorFunction;
+         this->innerOperatorFunction.getPreimageFunction().write( "preimageFunction", "gnuplot" );
+         f.write( "innerFunction", "gnuplot" );
+         return true;*/
+      }
+      
+      bool deepRefresh( const RealType& time = 0.0 )
+      {
+         return this->innerOperatorFunction.deepRefresh( time );
+         /*this->innerOperatorFunction.write( "innerFunction", "gnuplot" );
+          return true;*/
+      }
+        
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      RealType operator()(
+         const MeshFunction& function,
+         const MeshEntity& meshEntity,
+         const RealType& time = 0.0 ) const
+      {
+         static_assert( MeshFunction::getDimensions() == InnerOperator::getDimensions(),
+            "Mesh function and operator have both different number of dimensions." );
+         //InnerOperatorFunction innerOperatorFunction( innerOperator, function );
+         return outerOperator( innerOperatorFunction, meshEntity, time );
+      }      
+   
+   protected:
+      
+      const OuterOperator& outerOperator;
+      
+      InnerOperatorFunction innerOperatorFunction;      
+};
+
+
+#endif	/* TNLOPERATORCOMPOSITION_H */
+
diff --git a/src/operators/tnlOperatorEnumerator.h b/src/operators/tnlOperatorEnumerator.h
deleted file mode 100644
index 050a23b72d489d1e977df6fe0b1f3783b5f3e6ef..0000000000000000000000000000000000000000
--- a/src/operators/tnlOperatorEnumerator.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/***************************************************************************
-                          tnlOperatorEnumerator.h  -  description
-                             -------------------
-    begin                : Mar 8, 2015
-    copyright            : (C) 2015 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 SRC_OPERATORS_TNLOPERATORENUMERATOR_H_
-#define SRC_OPERATORS_TNLOPERATORENUMERATOR_H_
-
-//#include <_operators/tnlOperatorAdapter.h>
-
-template< typename Operator,
-          typename DofVector >
-class tnlOperatorEnumeratorTraverserUserData
-{
-   public:
-
-      typedef typename DofVector::RealType RealType;
-
-      const RealType *time;
-
-      const Operator* _operator;
-
-      DofVector *u;
-
-      const RealType* _operatorCoefficient;
-
-      const RealType* dofVectorCoefficient;
-
-      tnlOperatorEnumeratorTraverserUserData( const RealType& time,
-                                              const Operator& _operator,
-                                              DofVector& u,
-                                              const RealType& _operatorCoefficient,
-                                              const RealType& dofVectorCoefficient )
-      : time( &time ),
-        _operator( &_operator ),
-        u( &u ),
-        _operatorCoefficient( &_operatorCoefficient ),
-        dofVectorCoefficient( &dofVectorCoefficient )
-      {};
-};
-
-
-template< typename Mesh,
-          typename Operator,
-          typename DofVector >
-class tnlOperatorEnumerator
-{
-   public:
-      typedef Mesh MeshType;
-      typedef typename DofVector::RealType RealType;
-      typedef typename DofVector::DeviceType DeviceType;
-      typedef typename DofVector::IndexType IndexType;
-      typedef tnlOperatorEnumeratorTraverserUserData< Operator,
-                                                      DofVector > TraverserUserData;
-
-      template< int EntityDimensions >
-      void enumerate( const MeshType& mesh,
-                      const Operator& _operator,
-                      DofVector& u,
-                      const RealType& _operatorCoefficient = 1.0,
-                      const RealType& dofVectorCoefficient = 0.0,
-                      const RealType& time = 0.0 ) const;
-
-
-      class TraverserEntitiesProcessor
-      {
-         public:
-
-            template< int EntityDimensions >
-#ifdef HAVE_CUDA
-            __host__ __device__
-#endif
-            static void processEntity( const MeshType& mesh,
-                                       TraverserUserData& userData,
-                                       const IndexType index )
-            {
-               //typedef tnlOperatorAdapter< MeshType, Operator > OperatorAdapter;
-               ( *userData.u )[ index ] =
-                        ( *userData.dofVectorCoefficient ) * ( *userData.u )[ index ] +
-                        ( *userData._operatorCoefficient ) * userData._operator ->getValue( mesh,
-                                                                                            index,
-                                                                                            *userData.time );
-            }
-
-      };
-
-};
-
-template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index,
-          typename Operator,
-          typename DofVector >
-class tnlOperatorEnumerator< tnlGrid< Dimensions, Real, Device, Index >,
-                             Operator,
-                             DofVector >
-{
-   public:
-
-      typedef tnlGrid< Dimensions, Real, Device, Index > MeshType;
-      typedef typename MeshType::RealType RealType;
-      typedef typename MeshType::DeviceType DeviceType;
-      typedef typename MeshType::IndexType IndexType;
-      typedef typename MeshType::CoordinatesType CoordinatesType;
-      typedef tnlOperatorEnumeratorTraverserUserData< Operator,
-                                                      DofVector > TraverserUserData;
-
-      template< int EntityDimensions >
-      void enumerate( const MeshType& mesh,
-                      const Operator& _operator,
-                      DofVector& u,
-                      const RealType& _operatorCoefficient = 1.0,
-                      const RealType& dofVectorCoefficient = 0.0,
-                      const RealType& time = 0.0 ) const;
-
-      class TraverserEntitiesProcessor
-      {
-         public:
-
-         typedef typename MeshType::VertexType VertexType;
-
-#ifdef HAVE_CUDA
-            __host__ __device__
-#endif
-            static void processCell( const MeshType& mesh,
-                                     TraverserUserData& userData,
-                                     const IndexType index,
-                                     const CoordinatesType& coordinates )
-            {
-               //printf( "Enumerator::processCell mesh =%p \n", &mesh );
-               //typedef tnlOperatorAdapter< MeshType, Operator > OperatorAdapter;
-               ( *userData.u )[ index ] =
-                        ( *userData.dofVectorCoefficient ) * ( *userData.u )[ index ] +
-                        ( *userData._operatorCoefficient ) * userData._operator->getValue( mesh,
-                                                                                           index,
-                                                                                           coordinates,
-                                                                                           *userData.time );
-
-            }
-
-#ifdef HAVE_CUDA
-            __host__ __device__
-#endif
-            static void processFace( const MeshType& mesh,
-                                     TraverserUserData& userData,
-                                     const IndexType index,
-                                     const CoordinatesType& coordinates )
-            {
-               //typedef tnlOperatorAdapter< MeshType, Operator > OperatorAdapter;
-               ( *userData.u )[ index ] =
-                        ( *userData.dofVectorCoefficient ) * ( *userData.u )[ index ] +
-                        ( *userData._operatorCoefficient ) * userData._operator->getValue( mesh,
-                                                                                           index,
-                                                                                           coordinates,
-                                                                                           *userData.time );
-            }
-      };
-
-};
-
-#include <operators/tnlOperatorEnumerator_impl.h>
-
-#endif /* SRC_OPERATORS_TNLOPERATORENUMERATOR_H_ */
diff --git a/src/operators/tnlOperatorEnumerator_impl.h b/src/operators/tnlOperatorEnumerator_impl.h
deleted file mode 100644
index ffe3f21a7a7235cd0c63c545400dd2bf86afa901..0000000000000000000000000000000000000000
--- a/src/operators/tnlOperatorEnumerator_impl.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/***************************************************************************
-                          tnlOperatorEnumerator_impl.h  -  description
-                             -------------------
-    begin                : Mar 8, 2015
-    copyright            : (C) 2015 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 SRC_OPERATORS_TNLOPERATORENUMERATOR_IMPL_H_
-#define SRC_OPERATORS_TNLOPERATORENUMERATOR_IMPL_H_
-
-#include <operators/tnlOperatorEnumerator.h>
-#include <mesh/tnlTraverser_Grid1D.h>
-#include <mesh/tnlTraverser_Grid2D.h>
-#include <mesh/tnlTraverser_Grid3D.h>
-
-template< typename Mesh,
-          typename Operator,
-          typename DofVector >
-   template< int EntityDimensions >
-void
-tnlOperatorEnumerator< Mesh, Operator, DofVector >::
-enumerate( const MeshType& mesh,
-           const Operator& _operator,
-           DofVector& u,
-           const RealType& _operatorCoefficient,
-           const RealType& dofVectorCoefficient,
-           const RealType& time ) const
-
-{
-   if( DeviceType::DeviceType == tnlHostDevice )
-   {
-      TraverserUserData userData( time, _operator, u, _operatorCoefficient, dofVectorCoefficient );
-      tnlTraverser< MeshType, EntityDimensions > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-
-   }
-   if( DeviceType::DeviceType == tnlCudaDevice )
-   {
-      RealType* kernelTime = tnlCuda::passToDevice( time );
-      Operator* kernelOperator = tnlCuda::passToDevice( _operator );
-      DofVector* kernelU = tnlCuda::passToDevice( u );
-      RealType* kernelOperatorCoefficient = tnlCuda::passToDevice( _operatorCoefficient );
-      RealType* kernelDofVectorCoefficient = tnlCuda::passToDevice( dofVectorCoefficient );
-      TraverserUserData userData( *kernelTime, *kernelOperator, *kernelU, *kernelOperatorCoefficient, *kernelDofVectorCoefficient );
-      checkCudaDevice;
-      tnlTraverser< MeshType, EntityDimensions > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-
-      checkCudaDevice;
-      tnlCuda::freeFromDevice( kernelTime );
-      tnlCuda::freeFromDevice( kernelOperator );
-      tnlCuda::freeFromDevice( kernelU );
-      tnlCuda::freeFromDevice( kernelOperatorCoefficient );
-      tnlCuda::freeFromDevice( kernelDofVectorCoefficient );
-      checkCudaDevice;
-   }
-}
-
-template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index,
-          typename Operator,
-          typename DofVector >
-   template< int EntityDimensions >
-void
-tnlOperatorEnumerator< tnlGrid< Dimensions, Real, Device, Index >, Operator, DofVector  >::
-enumerate( const tnlGrid< Dimensions, Real, Device, Index >& mesh,
-           const Operator& _operator,
-           DofVector& u,
-           const RealType& _operatorCoefficient,
-           const RealType& dofVectorCoefficient,
-           const RealType& time ) const
-{
-   if( DeviceType::DeviceType == tnlHostDevice )
-   {
-      TraverserUserData userData( time, _operator, u, _operatorCoefficient, dofVectorCoefficient );
-      tnlTraverser< MeshType, EntityDimensions > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-
-   }
-   if( DeviceType::DeviceType == tnlCudaDevice )
-   {
-      RealType* kernelTime = tnlCuda::passToDevice( time );
-      Operator* kernelOperator = tnlCuda::passToDevice( _operator );
-      DofVector* kernelU = tnlCuda::passToDevice( u );
-      RealType* kernelOperatorCoefficient = tnlCuda::passToDevice( _operatorCoefficient );
-      RealType* kernelDofVectorCoefficient = tnlCuda::passToDevice( dofVectorCoefficient );
-      TraverserUserData userData( *kernelTime, *kernelOperator, *kernelU, *kernelOperatorCoefficient, *kernelDofVectorCoefficient );
-      checkCudaDevice;
-      tnlTraverser< MeshType, EntityDimensions > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-
-      checkCudaDevice;
-      tnlCuda::freeFromDevice( kernelTime );
-      tnlCuda::freeFromDevice( kernelOperator );
-      tnlCuda::freeFromDevice( kernelU );
-      tnlCuda::freeFromDevice( kernelOperatorCoefficient );
-      tnlCuda::freeFromDevice( kernelDofVectorCoefficient );
-      checkCudaDevice;
-   }
-}
-
-#endif /* SRC_OPERATORS_TNLOPERATORENUMERATOR_IMPL_H_ */
diff --git a/src/problems/CMakeLists.txt b/src/problems/CMakeLists.txt
index f64f63997d219f8e70f1e07452525e606dad70e5..44bc4b55b6b2ffd9c38d19882e6731766d5c8672 100755
--- a/src/problems/CMakeLists.txt
+++ b/src/problems/CMakeLists.txt
@@ -5,7 +5,12 @@ SET( headers tnlProblem.h
              tnlHeatEquationProblem_impl.h
              tnlHeatEquationEocProblem.h
              tnlHeatEquationEocProblem_impl.h             
-             tnlHeatEquationEocRhs.h             
+             tnlHeatEquationEocRhs.h 
+	     tnlMeanCurvatureFlowEocProblem.h
+	     tnlMeanCurvatureFlowEocProblem_impl.h
+	     tnlMeanCurvatureFlowEocRhs.h
+	     tnlMeanCurvatureFlowProblem.h
+	     tnlMeanCurvatureFlowProblem_impl.h            
    )
    
 INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/problems )
diff --git a/src/problems/tnlHeatEquationEocRhs.h b/src/problems/tnlHeatEquationEocRhs.h
index 494962f055d8902f7f5f7b8224f708219b61e83c..803d97f051e4c430bc9333841d8dbfc04f6452d5 100644
--- a/src/problems/tnlHeatEquationEocRhs.h
+++ b/src/problems/tnlHeatEquationEocRhs.h
@@ -24,12 +24,12 @@
 #ifndef TNLHEATEQUATIONEOCRHS_H_
 #define TNLHEATEQUATIONEOCRHS_H_
 
-#include <functions/tnlFunction.h>
+#include <functions/tnlDomain.h>
 
 template< typename ExactOperator,
           typename TestFunction >
-class tnlHeatEquationEocRhs : public tnlFunction< TestFunction::Dimensions,
-                                                  AnalyticFunction >
+class tnlHeatEquationEocRhs
+ : public tnlDomain< TestFunction::Dimensions, SpaceDomain >
 {
    public:
 
@@ -38,23 +38,21 @@ class tnlHeatEquationEocRhs : public tnlFunction< TestFunction::Dimensions,
       typedef typename TestFunction::RealType RealType;
       typedef typename TestFunction::VertexType VertexType;
 
-      static constexpr tnlFunctionType getFunctionType() { return AnalyticFunction; }     
-      
       bool setup( const tnlParameterContainer& parameters,
                   const tnlString& prefix = "" )
       {
          if( ! testFunction.setup( parameters, prefix ) )
             return false;
          return true;
-      };
+      }
 
       __cuda_callable__
-      RealType getValue( const VertexType& vertex,
+      RealType operator()( const VertexType& vertex,
                          const RealType& time = 0.0 ) const
       {
          return testFunction.getTimeDerivative( vertex, time )
-                - exactOperator.getValue( testFunction, vertex, time );
-      };
+                - exactOperator( testFunction, vertex, time );
+      }
 
    protected:
       ExactOperator exactOperator;
@@ -62,15 +60,4 @@ class tnlHeatEquationEocRhs : public tnlFunction< TestFunction::Dimensions,
       TestFunction testFunction;
 };
 
-/*
-template< typename ExactOperator,
-          typename TestFunction >
-class tnlFunctionType< tnlHeatEquationEocRhs< ExactOperator, TestFunction > >
-{
-   public:
-
-      enum { Type = tnlAnalyticFunction };
-};
-*/
-
 #endif /* TNLHEATEQUATIONEOCRHS_H_ */
diff --git a/src/problems/tnlHeatEquationProblem.h b/src/problems/tnlHeatEquationProblem.h
index 7e32aa65f97a2dae146be50687b6714a6ff3fca9..704f25ca27fc749d388cb2d50495d576e64b0d57 100644
--- a/src/problems/tnlHeatEquationProblem.h
+++ b/src/problems/tnlHeatEquationProblem.h
@@ -28,6 +28,7 @@
 #include <problems/tnlPDEProblem.h>
 #include <operators/diffusion/tnlLinearDiffusion.h>
 #include <matrices/tnlEllpackMatrix.h>
+#include <functions/tnlMeshFunction.h>
 
 template< typename Mesh,
           typename BoundaryCondition,
@@ -44,6 +45,7 @@ class tnlHeatEquationProblem : public tnlPDEProblem< Mesh,
       typedef typename DifferentialOperator::RealType RealType;
       typedef typename Mesh::DeviceType DeviceType;
       typedef typename DifferentialOperator::IndexType IndexType;
+      typedef tnlMeshFunction< Mesh > MeshFunctionType;
       typedef tnlPDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType;
       typedef tnlCSRMatrix< RealType, DeviceType, IndexType > MatrixType;
 
@@ -78,7 +80,7 @@ class tnlHeatEquationProblem : public tnlPDEProblem< Mesh,
       IndexType getDofs( const MeshType& mesh ) const;
 
       void bindDofs( const MeshType& mesh,
-                     DofVectorType& dofs );
+                     const DofVectorType& dofs );
 
       void getExplicitRHS( const RealType& time,
                            const RealType& tau,
@@ -91,21 +93,21 @@ class tnlHeatEquationProblem : public tnlPDEProblem< Mesh,
       void assemblyLinearSystem( const RealType& time,
                                  const RealType& tau,
                                  const MeshType& mesh,
-                                 DofVectorType& dofs,                                 
+                                 const DofVectorType& dofs,                                 
                                  Matrix& matrix,
                                  DofVectorType& rightHandSide,
 				 MeshDependentDataType& meshDependentData );
 
 
       protected:
+         
+         MeshFunctionType u;
+      
+         DifferentialOperator differentialOperator;
 
-      tnlSharedVector< RealType, DeviceType, IndexType > solution;
+         BoundaryCondition boundaryCondition;
 
-      DifferentialOperator differentialOperator;
-
-      BoundaryCondition boundaryCondition;
-   
-      RightHandSide rightHandSide;
+         RightHandSide rightHandSide;
 };
 
 #include <problems/tnlHeatEquationProblem_impl.h>
diff --git a/src/problems/tnlHeatEquationProblem_impl.h b/src/problems/tnlHeatEquationProblem_impl.h
index 1ef92d07e20673446b1be5b6dc39246b11163377..babe598635786625b9886385079d7a7dcaed901a 100644
--- a/src/problems/tnlHeatEquationProblem_impl.h
+++ b/src/problems/tnlHeatEquationProblem_impl.h
@@ -28,10 +28,13 @@
 #include <matrices/tnlMatrixSetter.h>
 #include <matrices/tnlMultidiagonalMatrixSetter.h>
 #include <core/tnlLogger.h>
+#include <solvers/pde/tnlBoundaryConditionsSetter.h>
 #include <solvers/pde/tnlExplicitUpdater.h>
 #include <solvers/pde/tnlLinearSystemAssembler.h>
 #include <solvers/pde/tnlBackwardTimeDiscretisation.h>
 
+#include "tnlHeatEquationProblem.h"
+
 
 template< typename Mesh,
           typename BoundaryCondition,
@@ -100,10 +103,10 @@ template< typename Mesh,
 void
 tnlHeatEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
 bindDofs( const MeshType& mesh,
-          DofVectorType& dofVector )
+          const DofVectorType& dofVector )
 {
    const IndexType dofs = mesh.template getEntitiesCount< typename MeshType::Cell >();
-   this->solution.bind( dofVector.getData(), dofs );
+   this->u.bind( mesh, dofVector );
 }
 
 template< typename Mesh,
@@ -119,7 +122,7 @@ setInitialCondition( const tnlParameterContainer& parameters,
 {
    this->bindDofs( mesh, dofs );
    const tnlString& initialConditionFile = parameters.getParameter< tnlString >( "initial-condition" );
-   if( ! this->solution.load( initialConditionFile ) )
+   if( ! this->u.boundLoad( initialConditionFile ) )
    {
       cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << endl;
       return false;
@@ -173,7 +176,7 @@ makeSnapshot( const RealType& time,
    //cout << "dofs = " << dofs << endl;
    tnlString fileName;
    FileNameBaseNumberEnding( "u-", step, 5, ".tnl", fileName );
-   if( ! this->solution.save( fileName ) )
+   if( ! this->u.save( fileName ) )
       return false;
    return true;
 }
@@ -187,8 +190,8 @@ tnlHeatEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOper
 getExplicitRHS( const RealType& time,
                 const RealType& tau,
                 const MeshType& mesh,
-                DofVectorType& u,
-		DofVectorType& fu,
+                DofVectorType& uDofs,
+		          DofVectorType& fuDofs,
                 MeshDependentDataType& meshDependentData )
 {
    /****
@@ -199,18 +202,24 @@ getExplicitRHS( const RealType& time,
     *
     * You may use supporting vectors again if you need.
     */
-
+   
    //cout << "u = " << u << endl;
-   this->bindDofs( mesh, u );
-   tnlExplicitUpdater< Mesh, DofVectorType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
+   this->bindDofs( mesh, uDofs );
+   MeshFunctionType fu( mesh, fuDofs );
+   tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
    explicitUpdater.template update< typename Mesh::Cell >( 
       time,
       mesh,
       this->differentialOperator,
       this->boundaryCondition,
       this->rightHandSide,
-      u,
+      this->u,
       fu );
+   tnlBoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter;
+   boundaryConditionsSetter.template apply< typename Mesh::Cell >(
+      this->boundaryCondition,
+      time + tau,
+      this->u );
    /*cout << "u = " << u << endl;
    cout << "fu = " << fu << endl;
    u.save( "u.tnl" );
@@ -228,18 +237,20 @@ tnlHeatEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOper
 assemblyLinearSystem( const RealType& time,
                       const RealType& tau,
                       const MeshType& mesh,
-                      DofVectorType& u,                      
+                      const DofVectorType& dofs,                      
                       Matrix& matrix,
                       DofVectorType& b,
 		      MeshDependentDataType& meshDependentData )
 {
+   this->bindDofs( mesh, dofs );
    tnlLinearSystemAssembler< Mesh,
-                             DofVectorType,
+                             MeshFunctionType,
                              DifferentialOperator,
                              BoundaryCondition,
                              RightHandSide,
                              tnlBackwardTimeDiscretisation,
-                             Matrix > systemAssembler;
+                             Matrix,
+                             DofVectorType > systemAssembler;
    systemAssembler.template assembly< typename Mesh::Cell >(
       time,
       tau,
@@ -247,7 +258,7 @@ assemblyLinearSystem( const RealType& time,
       this->differentialOperator,
       this->boundaryCondition,
       this->rightHandSide,
-      u,
+      this->u,
       matrix,
       b );
    /*matrix.print( cout );
diff --git a/src/problems/tnlMeanCurvatureFlowEocProblem.h b/src/problems/tnlMeanCurvatureFlowEocProblem.h
new file mode 100644
index 0000000000000000000000000000000000000000..948b7c95a2e17847b503b8fc708096dad84a9d30
--- /dev/null
+++ b/src/problems/tnlMeanCurvatureFlowEocProblem.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+                          tnlHeatEquationEocProblem.h  -  description
+                             -------------------
+    begin                : Nov 22, 2014
+    copyright            : (C) 2014 by 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 TNLMEANCURVATUREFLOWEOCPROBLEM_H_
+#define TNLMEANCURVATUREFLOWEOCPROBLEM_H_
+
+#include <problems/tnlMeanCurvatureFlowProblem.h>
+#include <operators/operator-Q/tnlOneSideDiffOperatorQ.h>
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator = tnlNonlinearDiffusion< Mesh,
+                                                          tnlOneSideDiffNonlinearOperator< Mesh, tnlOneSideDiffOperatorQ<Mesh, typename BoundaryCondition::RealType,
+                                                          typename BoundaryCondition::IndexType >, typename BoundaryCondition::RealType, typename BoundaryCondition::IndexType >, 
+                                                          typename BoundaryCondition::RealType, typename BoundaryCondition::IndexType > >
+class tnlMeanCurvatureFlowEocProblem : public tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator > 
+{
+   public:
+
+      static tnlString getTypeStatic();
+
+      bool setup( const tnlParameterContainer& parameters );
+};
+
+#include <problems/tnlMeanCurvatureFlowEocProblem_impl.h>
+
+#endif /* TNLMEANCURVATUREFLOWEOCPROBLEM_H_ */
diff --git a/src/problems/tnlMeanCurvatureFlowEocProblem_impl.h b/src/problems/tnlMeanCurvatureFlowEocProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..50c4ddcd7dfbd4554cba0da08262b41b67e06087
--- /dev/null
+++ b/src/problems/tnlMeanCurvatureFlowEocProblem_impl.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+                          tnlHeatEquationEocProblem_impl.h  -  description
+                             -------------------
+    begin                : Nov 22, 2014
+    copyright            : (C) 2014 by 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 TNLMEANCURVATUREFLOWEOCPROBLEM_IMPL_H_
+#define TNLMEANCURVATUREFLOWEOCPROBLEM_IMPL_H_
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+tnlMeanCurvatureFlowEocProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getTypeStatic()
+{
+   return tnlString( "tnlHeatEquationEocProblem< " ) + Mesh :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+tnlMeanCurvatureFlowEocProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator  >::
+setup( const tnlParameterContainer& parameters )
+{
+   if( ! this->boundaryCondition.setup( parameters ) ||
+       ! this->rightHandSide.setup( parameters ) || 
+       ! this->differentialOperator.nonlinearDiffusionOperator.operatorQ.setEps(parameters.getParameter< double >("eps")) )
+      return false;
+   
+   return true;
+}
+
+#endif /* TNLMEANCURVATUREFLOWEOCPROBLEM_IMPL_H_ */
diff --git a/src/problems/tnlMeanCurvatureFlowEocRhs.h b/src/problems/tnlMeanCurvatureFlowEocRhs.h
new file mode 100644
index 0000000000000000000000000000000000000000..49a29d47b1436c52da12b6a7b1cd27be956a48c4
--- /dev/null
+++ b/src/problems/tnlMeanCurvatureFlowEocRhs.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+                          tnlHeatEquationEocRhs.h  -  description
+                             -------------------
+    begin                : Sep 8, 2014
+    copyright            : (C) 2014 by 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 TNLMEANCURVATUREFLOWEOCRHS_H_
+#define TNLMEANCURVATUREFLOWEOCRHS_H_
+
+#include <functions/tnlDomain.h>
+
+template< typename ExactOperator,
+          typename TestFunction,
+          int Dimensions >
+class tnlMeanCurvatureFlowEocRhs : public tnlDomain< Dimensions, SpaceDomain >
+{
+   public:
+
+      typedef ExactOperator ExactOperatorType;
+      typedef TestFunction TestFunctionType;
+      typedef typename TestFunctionType::RealType RealType;
+      typedef tnlStaticVector< Dimensions, RealType > VertexType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                  const tnlString& prefix = "" )
+      {
+         if( ! testFunction.setup( parameters, prefix ) )
+            return false;
+         return true;
+      };
+
+      template< typename Vertex,
+                typename Real >
+      __cuda_callable__
+      Real operator()( const Vertex& vertex,
+                       const Real& time ) const
+      {
+         return testFunction.getTimeDerivative( vertex, time )
+                - exactOperator( testFunction, vertex, time );
+      };
+
+   protected:
+      
+      ExactOperator exactOperator;
+
+      TestFunction testFunction;
+};
+
+
+#endif /* TNLMEANCURVATUREFLOWEOCRHS_H_ */
diff --git a/src/problems/tnlMeanCurvatureFlowProblem.h b/src/problems/tnlMeanCurvatureFlowProblem.h
new file mode 100644
index 0000000000000000000000000000000000000000..e317449789a97e3ddb2d8dc5746ec18f8658eaf3
--- /dev/null
+++ b/src/problems/tnlMeanCurvatureFlowProblem.h
@@ -0,0 +1,112 @@
+/***************************************************************************
+                          tnlHeatEquationProblem.h  -  description
+                             -------------------
+    begin                : Feb 23, 2013
+    copyright            : (C) 2013 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 TNLMEANCURVATUREFLOWPROBLEM_H_
+#define TNLMEANCURVATUREFLOWPROBLEM_H_
+
+#include <operators/diffusion/tnlOneSidedMeanCurvature.h>
+#include <problems/tnlPDEProblem.h>
+#include <operators/operator-Q/tnlOneSideDiffOperatorQ.h>
+#include <matrices/tnlCSRMatrix.h>
+#include <functions/tnlMeshFunction.h>
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator = 
+            tnlOneSidedMeanCurvature< Mesh,
+                                      typename Mesh::RealType,
+                                      typename Mesh::IndexType,
+                                      false > >
+class tnlMeanCurvatureFlowProblem : public tnlPDEProblem< Mesh,
+                                                     typename DifferentialOperator::RealType,
+                                                     typename Mesh::DeviceType,
+                                                     typename DifferentialOperator::IndexType >
+{
+   public:
+
+      typedef typename DifferentialOperator::RealType RealType;
+      typedef typename Mesh::DeviceType DeviceType;
+      typedef typename DifferentialOperator::IndexType IndexType;
+      typedef tnlMeshFunction< Mesh > MeshFunctionType;
+      typedef tnlPDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType;
+      typedef tnlCSRMatrix< RealType, DeviceType, IndexType> MatrixType;
+
+      using typename BaseType::MeshType;
+      using typename BaseType::DofVectorType;
+      using typename BaseType::MeshDependentDataType;
+
+      static tnlString getTypeStatic();
+
+      tnlString getPrologHeader() const;
+
+      void writeProlog( tnlLogger& logger,
+                        const tnlParameterContainer& parameters ) const;
+
+      bool setup( const tnlParameterContainer& parameters );
+
+      bool setInitialCondition( const tnlParameterContainer& parameters,
+                                const MeshType& mesh,
+                                DofVectorType& dofs,
+                                MeshDependentDataType& meshDependentData );
+
+      template< typename Matrix >
+      bool setupLinearSystem( const MeshType& mesh,
+                              Matrix& matrix );
+      
+      bool makeSnapshot( const RealType& time,
+                         const IndexType& step,
+                         const MeshType& mesh,
+                         DofVectorType& dofs,
+                         MeshDependentDataType& meshDependentData );
+
+      IndexType getDofs( const MeshType& mesh ) const;
+
+      void bindDofs( const MeshType& mesh,
+                     DofVectorType& dofs );
+
+      void getExplicitRHS( const RealType& time,
+                           const RealType& tau,
+                           const MeshType& mesh,
+                           DofVectorType& _u,
+                           DofVectorType& _fu,
+			   MeshDependentDataType& meshDependentData );
+
+      template< typename Matrix >
+      void assemblyLinearSystem( const RealType& time,
+                                 const RealType& tau,
+                                 const MeshType& mesh,
+                                 DofVectorType& dofs,
+                                 Matrix& matrix,
+                                 DofVectorType& rightHandSide,
+                                 MeshDependentDataType& meshDependentData );
+
+
+      protected:
+
+      tnlSharedVector< RealType, DeviceType, IndexType > solution;
+
+      DifferentialOperator differentialOperator;
+
+      BoundaryCondition boundaryCondition;
+   
+      RightHandSide rightHandSide;
+};
+
+#include "tnlMeanCurvatureFlowProblem_impl.h"
+
+#endif /* TNLMEANCURVATUREFLOWPROBLEM_H_ */
diff --git a/src/problems/tnlMeanCurvatureFlowProblem_impl.h b/src/problems/tnlMeanCurvatureFlowProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..f1e7bd91a37ae82ca51479bbbaccee09180f7842
--- /dev/null
+++ b/src/problems/tnlMeanCurvatureFlowProblem_impl.h
@@ -0,0 +1,274 @@
+/***************************************************************************
+                          tnlHeatEquationProblem_impl.h  -  description
+                             -------------------
+    begin                : Mar 10, 2013
+    copyright            : (C) 2013 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 TNLMEANCURVATUREFLOWPROBLEM_IMPL_H_
+#define TNLMEANCURVATUREFLOWPROBLEM_IMPL_H_
+
+#include <core/mfilename.h>
+#include <matrices/tnlMatrixSetter.h>
+#include <matrices/tnlMultidiagonalMatrixSetter.h>
+#include <core/tnlLogger.h>
+#include <solvers/pde/tnlExplicitUpdater.h>
+#include <solvers/pde/tnlBoundaryConditionsSetter.h>
+#include <solvers/pde/tnlLinearSystemAssembler.h>
+#include <solvers/pde/tnlBackwardTimeDiscretisation.h>
+
+#include "tnlMeanCurvatureFlowProblem.h"
+
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getTypeStatic()
+{
+   return tnlString( "tnlMeanCurvativeFlowProblem< " ) + Mesh :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getPrologHeader() const
+{
+   return tnlString( "Mean Curvative Flow" );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const
+{
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setup( const tnlParameterContainer& parameters )
+{
+   if( ! this->boundaryCondition.setup( parameters, "boundary-conditions-" ) ||
+       ! this->rightHandSide.setup( parameters, "right-hand-side-" ) )
+      return false;
+   this->differentialOperator.nonlinearDiffusionOperator.operatorQ.setEps( parameters.getParameter< double >( "eps" ) );
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+typename tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getDofs( const MeshType& mesh ) const
+{
+   /****
+    * Set-up DOFs and supporting grid functions
+    */
+   return mesh.template getEntitiesCount< typename Mesh::Cell >();
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+bindDofs( const MeshType& mesh,
+          DofVectorType& dofVector )
+{
+   const IndexType dofs = mesh.template getEntitiesCount< typename Mesh::Cell >();
+   this->solution.bind( dofVector.getData(), dofs );
+   //differentialOperator.nonlinearDiffusionOperator.operatorQ.bind(solution);
+//   this->differentialOperator.setupDofs(mesh);
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setInitialCondition( const tnlParameterContainer& parameters,
+                     const MeshType& mesh,
+                     DofVectorType& dofs,
+                     MeshDependentDataType& meshDependentData )
+{
+   this->bindDofs( mesh, dofs );
+   const tnlString& initialConditionFile = parameters.getParameter< tnlString >( "initial-condition" );
+   if( ! this->solution.load( initialConditionFile ) )
+   {
+      cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << endl;
+      return false;
+   }
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+template< typename Matrix >          
+bool
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setupLinearSystem( const MeshType& mesh,
+                   Matrix& matrix )
+{
+   const IndexType dofs = this->getDofs( mesh );
+   typedef typename MatrixType::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
+   CompressedRowsLengthsVectorType rowLengths;
+   if( ! rowLengths.setSize( dofs ) )
+      return false;
+   tnlMatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter;
+   matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >(
+      mesh,
+      differentialOperator,
+      boundaryCondition,
+      rowLengths 
+   );
+   matrix.setDimensions( dofs, dofs );
+   if( ! matrix.setCompressedRowsLengths( rowLengths ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+makeSnapshot( const RealType& time,
+              const IndexType& step,
+              const MeshType& mesh,
+              DofVectorType& dofs,
+              MeshDependentDataType& meshDependentData )
+{
+   cout << endl << "Writing output at time " << time << " step " << step << "." << endl;
+
+   this->bindDofs( mesh, dofs );
+   //cout << "dofs = " << dofs << endl;
+   tnlString fileName;
+   FileNameBaseNumberEnding( "u-", step, 5, ".tnl", fileName );
+   if( ! this->solution.save( fileName ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getExplicitRHS( const RealType& time,
+                const RealType& tau,
+                const MeshType& mesh,
+                DofVectorType& inDofs,
+                DofVectorType& outDofs,
+		MeshDependentDataType& meshDependentData )
+{
+   /****
+    * If you use an explicit solver like tnlEulerSolver or tnlMersonSolver, you
+    * need to implement this method. Compute the right-hand side of
+    *
+    *   d/dt u(x) = fu( x, u )
+    *
+    * You may use supporting vectors again if you need.
+    */
+
+//   this->differentialOperator.computeFirstGradient(mesh,time,u);
+   
+   //cout << "u = " << u << endl;
+   //this->bindDofs( mesh, u );
+   MeshFunctionType u( mesh, inDofs );
+   MeshFunctionType fu( mesh, outDofs );
+   //differentialOperator.nonlinearDiffusionOperator.operatorQ.update( mesh, time );
+   tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
+   explicitUpdater.template update< typename Mesh::Cell >(
+      time,
+      mesh,
+      this->differentialOperator,
+      this->boundaryCondition,
+      this->rightHandSide,
+      u,
+      fu );
+   
+   tnlBoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter;
+   boundaryConditionsSetter.template apply< typename Mesh::Cell >(
+      this->boundaryCondition,
+      time,
+      u );
+
+   /*cout << "u = " << u << endl;
+   cout << "fu = " << fu << endl;
+   u.save( "u.tnl" );
+   fu.save( "fu.tnl" );
+   getchar();*/
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+template< typename Matrix >          
+void
+tnlMeanCurvatureFlowProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+assemblyLinearSystem( const RealType& time,
+                      const RealType& tau,
+                      const MeshType& mesh,
+                      DofVectorType& dofsU,
+                      Matrix& matrix,
+                      DofVectorType& b,
+                      MeshDependentDataType& meshDependentData )
+{
+   MeshFunctionType u( mesh, dofsU );
+   tnlLinearSystemAssembler< Mesh, 
+			     MeshFunctionType, 
+			     DifferentialOperator, 
+			     BoundaryCondition, 
+			     RightHandSide, 
+			     tnlBackwardTimeDiscretisation, 
+			     MatrixType,
+			     DofVectorType > systemAssembler;
+   systemAssembler.template assembly< typename Mesh::Cell >(
+      time,
+      tau,
+      mesh,
+      this->differentialOperator,
+      this->boundaryCondition,
+      this->rightHandSide,
+      u,
+      matrix,
+      b );
+   /*matrix.print( cout );
+   cout << endl << b << endl;
+   cout << endl << u << endl;
+   getchar();
+   //abort();*/
+}
+
+#endif /* TNLMEANCURVATUREFLOWPROBLEM_IMPL_H_ */
diff --git a/src/solvers/linear/krylov/CMakeLists.txt b/src/solvers/linear/krylov/CMakeLists.txt
index a0e43b2e700a3ad91c0c1a3bfb136ab15731da4c..0bbe87701d7e2e21b7476ec0d52d7834d3653f5d 100644
--- a/src/solvers/linear/krylov/CMakeLists.txt
+++ b/src/solvers/linear/krylov/CMakeLists.txt
@@ -2,11 +2,13 @@ SET( headers tnlCGSolver.h
              tnlCGSolver_impl.h
              tnlBICGStabSolver.h
              tnlBICGStabSolver_impl.h
-             tnlGMRESSolver.h                         
-             tnlGMRESSolver_impl.h )
+             tnlGMRESSolver.h
+             tnlGMRESSolver_impl.h
+             tnlTFQMRSolver.h
+             tnlTFQMRSolver_impl.h )
 
 SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/solvers/linear/krylov )
-set( common_SOURCES ${CURRENT_DIR}/tnlGMRESSolver_impl.cpp )     
+set( common_SOURCES ${CURRENT_DIR}/tnlGMRESSolver_impl.cpp )
 set( tnl_solvers_linear_krylov_SOURCES
      ${common_SOURCES}
      PARENT_SCOPE )
@@ -15,6 +17,6 @@ if( BUILD_CUDA)
    set( tnl_solvers_linear_krylov_CUDA__SOURCES
         ${common_SOURCES}
         PARENT_SCOPE )
-endif() 
-   
+endif()
+
 INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/solvers/linear/krylov )
diff --git a/src/solvers/linear/krylov/tnlBICGStabSolver_impl.h b/src/solvers/linear/krylov/tnlBICGStabSolver_impl.h
index 4919d56bd612cee98420efcaa2136d0a4b9202f2..8532424ef49bdc2633f91e3aa36cd39cdc8f9177 100644
--- a/src/solvers/linear/krylov/tnlBICGStabSolver_impl.h
+++ b/src/solvers/linear/krylov/tnlBICGStabSolver_impl.h
@@ -193,7 +193,7 @@ bool tnlBICGStabSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vect
          this->setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
    }
    //this->setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
-   this->refreshSolverMonitor();
+   this->refreshSolverMonitor( true );
    return this->checkConvergence();
 };
 
diff --git a/src/solvers/linear/krylov/tnlCGSolver_impl.h b/src/solvers/linear/krylov/tnlCGSolver_impl.h
index ae599af1bbb4e6e51307bee5b9cf6d7df1a92efd..86bea9efd293ee7a9db34950d983bfbf70343f42 100644
--- a/src/solvers/linear/krylov/tnlCGSolver_impl.h
+++ b/src/solvers/linear/krylov/tnlCGSolver_impl.h
@@ -142,7 +142,7 @@ solve( const Vector& b, Vector& x )
          this -> setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
    }
    this -> setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
-   this -> refreshSolverMonitor();
+   this -> refreshSolverMonitor( true );
    return this->checkConvergence();
 };
 
diff --git a/src/solvers/linear/krylov/tnlGMRESSolver.h b/src/solvers/linear/krylov/tnlGMRESSolver.h
index 69745dc8fcdcee0ce84c300e5c72f4f8a12d9e34..8852c6ad9612a1c8f4154e0da1197d23f88de8b1 100644
--- a/src/solvers/linear/krylov/tnlGMRESSolver.h
+++ b/src/solvers/linear/krylov/tnlGMRESSolver.h
@@ -94,12 +94,10 @@ class tnlGMRESSolver : public tnlObject,
 
    bool setSize( IndexType _size, IndexType m );
 
-   tnlVector< RealType, DeviceType, IndexType > _r, _w, _v, _M_tmp;
+   tnlVector< RealType, DeviceType, IndexType > _r, w, _v, _M_tmp;
    tnlVector< RealType, tnlHost, IndexType > _s, _cs, _sn, _H;
 
-   IndexType size, restarting, maxIterations;
-
-   RealType maxResidue;
+   IndexType size, restarting;
 
    const MatrixType* matrix;
    const PreconditionerType* preconditioner;
diff --git a/src/solvers/linear/krylov/tnlGMRESSolver_impl.h b/src/solvers/linear/krylov/tnlGMRESSolver_impl.h
index 13582c94a8bfba630dd6d368a8a6fb3491f7dc38..87cc0a8a63b34fbbf3d2ad6fad051f78b044229c 100644
--- a/src/solvers/linear/krylov/tnlGMRESSolver_impl.h
+++ b/src/solvers/linear/krylov/tnlGMRESSolver_impl.h
@@ -104,9 +104,8 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
    }
 
    IndexType _size = size;
-
-   RealType *r = _r. getData();
-   RealType *w = _w. getData();
+   
+   //RealType *w = _w. getData();
    RealType *s = _s. getData();
    RealType *cs = _cs. getData();
    RealType *sn = _sn. getData();
@@ -185,10 +184,10 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
          if( preconditioner )
          {
             matrix->vectorProduct( vi, _M_tmp );
-            this->preconditioner->solve( _M_tmp, _w );
+            this->preconditioner->solve( _M_tmp, w );
          }
          else
-             matrix -> vectorProduct( vi, _w );
+             matrix->vectorProduct( vi, w );
          
          //cout << " i = " << i << " vi = " << vi << endl;
 
@@ -201,21 +200,21 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
                /***
                 * H_{k,i} = ( w, v_k )
                 */
-               RealType H_k_i = _w. scalarProduct( vk );
+               RealType H_k_i = w. scalarProduct( vk );
                H[ k + i * ( m + 1 ) ] += H_k_i;           
 
                /****
                 * w = w - H_{k,i} v_k
                 */
-               _w. addVector( vk, -H_k_i );
+               w. addVector( vk, -H_k_i );
 
                //cout << "H_ki = " << H_k_i << endl;
-               //cout << "w = " << _w << endl;
+               //cout << "w = " << w << endl;
             }
          /***
           * H_{i+1,i} = |w|
           */
-         RealType normw = _w. lpNorm( ( RealType ) 2.0 );
+         RealType normw = w. lpNorm( ( RealType ) 2.0 );
          H[ i + 1 + i * ( m + 1 ) ] = normw;
 
          //cout << "normw = " << normw << endl;
@@ -224,10 +223,10 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
           * v_{i+1} = w / |w|
           */
          vi. bind( &( _v. getData()[ ( i + 1 ) * size ] ), size );
-         vi. addVector( _w, ( RealType ) 1.0 / normw );
+         vi. addVector( w, ( RealType ) 1.0 / normw );
          
          //cout << "vi = " << vi << endl;
-
+         
          /****
           * Applying the Givens rotations
           */
@@ -251,17 +250,23 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
                              sn[ i ] );
 
          this->setResidue( fabs( s[ i + 1 ] ) / normb );
-         this->refreshSolverMonitor();
-
-         /*if( this->getResidue() < this->getConvergenceResidue() )
+         // The nextIteration() method should not be called here, because it increments
+         // the iteration counter. The condition below is slightly different than in
+         // nextIteration(), because it first increments and then compares.
+         if( this->getIterations() >= this->getMinIterations() && this->getResidue() < this->getConvergenceResidue() )
          {
             update( i, m, _H, _s, _v, x );
-            return true;
+            this->refreshSolverMonitor( true );
+            return this->checkConvergence();
+         }
+         else
+         {
+            this->refreshSolverMonitor();
          }
-         if( ! this->nextIteration() )
-            return false;*/
       }
+      //cout << "x = " << x << endl;
       update( m - 1, m, _H, _s, _v, x );
+      //cout << "x = " << x << endl;
 
       /****
        * r = M.solve(b - A * x);
@@ -270,11 +275,9 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
       if( preconditioner )
       {
          matrix -> vectorProduct( x, _M_tmp );
-         for( IndexType i = 0; i < _size; i ++ )
-            M_tmp[ i ] = b[ i ] - M_tmp[ i ];
-         //preconditioner -> solve( M_tmp, r );
-         for( IndexType i = 0; i < _size; i ++ )
-            beta += r[ i ] * r[ i ];
+         _M_tmp.addVector( b, ( RealType ) 1.0, -1.0 );
+         preconditioner -> solve( _M_tmp, _r );
+         beta = _r. lpNorm( ( RealType ) 2.0 );
       }
       else
       {
@@ -289,7 +292,7 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
       //cout << "residue = " << beta / normb << endl;
 
    }
-   this->refreshSolverMonitor();
+   this->refreshSolverMonitor( true );
    return this->checkConvergence();
 };
 
@@ -319,9 +322,10 @@ void tnlGMRESSolver< Matrix, Preconditioner > :: update( IndexType k,
    // Backsolve:
    for( i = k; i >= 0; i--)
    {
+      //cout << " y = " << y << endl;
       y[ i ] /= H[ i + i * ( m + 1 ) ];
       for( j = i - 1; j >= 0; j--)
-         y[ j ] -= H[ j + i * ( m + 1 ) ] * y[ i ];
+         y[ j ] -= H[ j + i * ( m + 1 ) ] * y[ i ];      
    }
 
    tnlSharedVector< RealType, DeviceType, IndexType > vi;
@@ -379,7 +383,7 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: setSize( IndexType _size, Index
    size = _size;
    restarting = m;
    if( ! _r. setSize( size ) ||
-       ! _w. setSize( size ) ||
+       ! w. setSize( size ) ||
        ! _s. setSize( restarting + 1 ) ||
        ! _cs. setSize( restarting + 1 ) ||
        ! _sn. setSize( restarting + 1 ) ||
@@ -387,7 +391,7 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: setSize( IndexType _size, Index
        ! _H. setSize( ( restarting + 1 ) * restarting ) ||
        ! _M_tmp. setSize( size ) )
    {
-      cerr << "I could not allocated all supporting arrays for the CG solver." << endl;
+      cerr << "I could not allocate all supporting arrays for the GMRES solver." << endl;
       return false;
    }
    return true;
diff --git a/src/solvers/linear/krylov/tnlTFQMRSolver.h b/src/solvers/linear/krylov/tnlTFQMRSolver.h
index de0ebb7b7accce0327aa825aa3704056f94e2c2a..ab25f3e349e752bdac403a2323fada4fe34aa30e 100644
--- a/src/solvers/linear/krylov/tnlTFQMRSolver.h
+++ b/src/solvers/linear/krylov/tnlTFQMRSolver.h
@@ -75,7 +75,7 @@ class tnlTFQMRSolver : public tnlObject,
 
    bool setSize( IndexType size );
 
-   tnlVector< RealType, Device, IndexType >  d, r, w, u, v, r_ast, u_new, Au, Au_new;
+   tnlVector< RealType, Device, IndexType >  d, r, w, u, v, r_ast, Au;
 
    const MatrixType* matrix;
    const PreconditionerType* preconditioner;
diff --git a/src/solvers/linear/krylov/tnlTFQMRSolver_impl.h b/src/solvers/linear/krylov/tnlTFQMRSolver_impl.h
index dfc6192a91f4b60e3ba8e8c748c244074dc2e74e..b5e72e6456d4fdb968d3d611d4b97985f87a51df 100644
--- a/src/solvers/linear/krylov/tnlTFQMRSolver_impl.h
+++ b/src/solvers/linear/krylov/tnlTFQMRSolver_impl.h
@@ -37,8 +37,8 @@ template< typename Matrix,
 tnlString tnlTFQMRSolver< Matrix, Preconditioner > :: getType() const
 {
    return tnlString( "tnlTFQMRSolver< " ) +
-          Matrix::getType() + ", " +
-          Preconditioner::getType() + " >";
+          this->matrix -> getType() + ", " +
+          this->preconditioner -> getType() + " >";
 }
 
 template< typename Matrix,
@@ -83,79 +83,76 @@ bool tnlTFQMRSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
    dbgFunctionName( "tnlTFQMRSolver", "Solve" );
    if( ! this -> setSize( matrix -> getRows() ) ) return false;
 
-   this -> resetIterations();
-   this -> setResidue( this -> getConvergenceResidue() + 1.0 );
+   RealType tau, theta, eta, rho, alpha, w_norm;
+   RealType b_norm = b. lpNorm( 2.0 );
+   if( b_norm == 0.0 )
+       b_norm = 1.0;
 
-   RealType tau, theta, eta, rho, alpha;
-   const RealType bNorm = b. lpNorm( 2.0 );
-   this -> setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
-
-   dbgCout( "Computing Ax" );
    this -> matrix -> vectorProduct( x, r );
-
-   /*if( M )
-   {
-   }
-   else*/
-   {
-      r. addVector( b, -1.0, -1.0 );
-      w = u = r;
-      matrix -> vectorProduct( u, v );
-      d. setValue( 0.0 );
-      tau = r. lpNorm( 2.0 );
-      theta = 0.0;
-      eta = 0.0;
-      r_ast = r;
-      //cerr << "r_ast = " << r_ast << endl;
-      rho = this -> r_ast. scalarProduct( this -> r_ast );
-   }
-
-   while( this -> getIterations() < this -> getMaxIterations() &&
-          this -> getResidue() > this -> getConvergenceResidue() )
+   r. addVector( b, 1.0, -1.0 );
+   w = u = r;
+   matrix -> vectorProduct( u, Au );
+   v = Au;
+   d. setValue( 0.0 );
+   tau = r. lpNorm( 2.0 );
+   theta = eta = 0.0;
+   r_ast = r;
+   rho = r_ast. scalarProduct( r );
+   // only to avoid compiler warning; alpha is initialized inside the loop
+   alpha = 0.0;
+
+   this->resetIterations();
+   this->setResidue( tau / b_norm );
+
+   while( this->nextIteration() )
    {
-      //dbgCout( "Starting TFQMR iteration " << iter + 1 );
+      const IndexType iter = this->getIterations();
 
-      if( this -> getIterations() % 2 == 0 )
-      {
-         //cerr << "rho = " << rho << endl;
+      if( iter % 2 == 1 ) {
          alpha = rho / v. scalarProduct( this -> r_ast );
-         //cerr << "new alpha = " << alpha << endl;
-         u_new.addVector( v, -alpha );
       }
-      matrix -> vectorProduct( u, Au );
+      else {
+         // not necessary in odd iter since the previous iteration
+         // already computed v_{m+1} = A*u_{m+1}
+         matrix -> vectorProduct( u, Au );
+      }
       w.addVector( Au, -alpha );
-      //cerr << "alpha = " << alpha << endl;
-      //cerr << "theta * theta / alpha * eta = " << theta * theta / alpha * eta << endl;
-      d. addVector( u, 1.0, theta * theta / alpha * eta );
-      theta = w. lpNorm( 2.0 ) / tau;
-      const RealType c = sqrt( 1.0 + theta * theta );
+      d.addVector( u, 1.0, theta * theta * eta / alpha );
+      w_norm = w. lpNorm( 2.0 );
+      theta = w_norm / tau;
+      const RealType c = 1.0 / sqrt( 1.0 + theta * theta );
       tau = tau * theta * c;
       eta = c * c  * alpha;
-      //cerr << "eta = " << eta << endl;
       x.addVector( d, eta );
-      if( this -> getIterations() % 2 == 1 )
-      {
+
+      this->setResidue( tau * sqrt(iter+1) / b_norm );
+      if( iter > this->getMinIterations() && this->getResidue() < this->getConvergenceResidue() ) {
+          break;
+      }
+
+      if( iter % 2 == 0 ) {
          const RealType rho_new  = w. scalarProduct( this -> r_ast );
          const RealType beta = rho_new / rho;
          rho = rho_new;
-         matrix -> vectorProduct( u, Au );
-         Au.addVector( v, beta );
+
          u.addVector( w, 1.0, beta );
-         matrix -> vectorProduct( u, Au_new );
-         v.addVectors( Au_new, 1.0, Au, beta );
+         v.addVector( Au, beta, beta * beta );
+         matrix -> vectorProduct( u, Au );
+         v.addVector( Au, 1.0 );
+      }
+      else {
+         u.addVector( v, -alpha );
       }
       
-      //this -> setResidue( residue );
-      //if( this -> getIterations() % 10 == 0 )
-         this -> setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
-      if( ! this -> nextIteration() )
-         return false;
       this -> refreshSolverMonitor();
    }
-   this -> setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
-   this -> refreshSolverMonitor();
-      if( this -> getResidue() > this -> getConvergenceResidue() ) return false;
-   return true;
+
+//   this->matrix->vectorProduct( x, r );
+//   r.addVector( b, 1.0, -1.0 );
+//   this->setResidue( r.lpNorm( 2.0 ) / b_norm );
+
+   this->refreshSolverMonitor( true );
+   return this->checkConvergence();
 };
 
 template< typename Matrix,
@@ -174,9 +171,7 @@ bool tnlTFQMRSolver< Matrix, Preconditioner > :: setSize( IndexType size )
        ! u. setSize( size ) ||
        ! v. setSize( size ) ||
        ! r_ast. setSize( size ) ||
-       ! u_new. setSize( size ) ||
-       ! Au. setSize( size ) ||
-       ! Au_new. setSize( size ) )
+       ! Au. setSize( size ) )
    {
       cerr << "I am not able to allocate all supporting vectors for the TFQMR solver." << endl;
       return false;
diff --git a/src/solvers/linear/stationary/tnlSORSolver_impl.h b/src/solvers/linear/stationary/tnlSORSolver_impl.h
index 419e190d55462ec8da4eb0d40b18f1f4c032e285..273bf9e81a3165525d851e641182e28e605cc4a2 100644
--- a/src/solvers/linear/stationary/tnlSORSolver_impl.h
+++ b/src/solvers/linear/stationary/tnlSORSolver_impl.h
@@ -107,9 +107,10 @@ bool tnlSORSolver< Matrix, Preconditioner > :: solve( const Vector& b,
                                       x,
                                       this->getOmega() );
       this -> setResidue( ResidueGetter :: getResidue( *matrix, x, b, bNorm ) );
+      this -> refreshSolverMonitor();
    }
    this -> setResidue( ResidueGetter :: getResidue( *matrix, x, b, bNorm ) );
-   this -> refreshSolverMonitor();
+   this -> refreshSolverMonitor( true );
    return this->checkConvergence();
 };
 
diff --git a/src/solvers/pde/tnlBoundaryConditionsSetter.h b/src/solvers/pde/tnlBoundaryConditionsSetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..2cb76bddbbd749e4b577e900def6429ac3c82f8f
--- /dev/null
+++ b/src/solvers/pde/tnlBoundaryConditionsSetter.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+                          tnlBoundaryConditionsSetter.h  -  description
+                             -------------------
+    begin                : Dec 30, 2015
+    copyright            : (C) 2015 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 TNLBOUNDARYCONDITIONSSETTER_H
+#define	TNLBOUNDARYCONDITIONSSETTER_H
+
+#include <core/tnlCuda.h>
+#include <functions/tnlFunctionAdapter.h>
+
+template< typename Real,
+          typename DofVector,
+          typename BoundaryConditions >
+class tnlBoundaryConditionsSetterTraverserUserData
+{
+   public:
+
+      const Real *time;
+
+      const BoundaryConditions* boundaryConditions;
+
+      DofVector *u;
+
+      tnlBoundaryConditionsSetterTraverserUserData( 
+         const Real& time,
+         const BoundaryConditions& boundaryConditions,
+         DofVector& u )
+      : time( &time ),
+        boundaryConditions( &boundaryConditions ),
+        u( &u )
+      {};
+};
+
+
+template< typename MeshFunction,
+          typename BoundaryConditions >
+class tnlBoundaryConditionsSetter
+{
+   public:
+      typedef typename MeshFunction::MeshType MeshType;
+      typedef typename MeshFunction::RealType RealType;
+      typedef typename MeshFunction::DeviceType DeviceType;
+      typedef typename MeshFunction::IndexType IndexType;
+      typedef tnlBoundaryConditionsSetterTraverserUserData< 
+         RealType,
+         MeshFunction,
+         BoundaryConditions > TraverserUserData;
+
+      template< typename EntityType = typename MeshType::Cell >
+      static void apply( const BoundaryConditions& boundaryConditions,
+                         const RealType& time,
+                         MeshFunction& u );      
+     
+      class TraverserBoundaryEntitiesProcessor
+      {
+         public:
+            
+            template< typename GridEntity >
+            __cuda_callable__
+            static inline void processEntity( const MeshType& mesh,
+                                              TraverserUserData& userData,
+                                              const GridEntity& entity )
+            {
+               ( *userData.u )( entity ) = userData.boundaryConditions->operator()
+               ( *userData.u,
+                 entity,
+                 *userData.time );
+            }
+
+      };
+};
+
+#include <solvers/pde/tnlBoundaryConditionsSetter_impl.h>
+
+#endif	/* TNLBOUNDARYCONDITIONSSETTER_H */
+
diff --git a/src/solvers/pde/tnlBoundaryConditionsSetter_impl.h b/src/solvers/pde/tnlBoundaryConditionsSetter_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..8dd600d393da2e09dcea07062e13cd764780dd88
--- /dev/null
+++ b/src/solvers/pde/tnlBoundaryConditionsSetter_impl.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+                          tnlBoundaryConditionsSetter_impl.h  -  description
+                             -------------------
+    begin                : Dec 30, 2015
+    copyright            : (C) 2015 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 TNLBOUNDARYCONDITIONSSETTER_IMPL_H
+#define	TNLBOUNDARYCONDITIONSSETTER_IMPL_H
+
+#include <type_traits>
+
+template< typename MeshFunction,
+          typename BoundaryConditions >
+   template< typename EntityType >
+void
+tnlBoundaryConditionsSetter< MeshFunction, BoundaryConditions >::
+apply( const BoundaryConditions& boundaryConditions,
+       const RealType& time,
+       MeshFunction& u )
+{
+   if( std::is_same< DeviceType, tnlHost >::value )
+   {
+      TraverserUserData userData( time, boundaryConditions, u );
+      tnlTraverser< MeshType, EntityType > meshTraverser;
+      meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                                      TraverserBoundaryEntitiesProcessor >
+                                                    ( u.getMesh(),
+                                                      userData );
+   }
+   if( std::is_same< DeviceType, tnlCuda >::value )
+   {
+      RealType* kernelTime = tnlCuda::passToDevice( time );
+      BoundaryConditions* kernelBoundaryConditions = tnlCuda::passToDevice( boundaryConditions );
+      MeshFunction* kernelU = tnlCuda::passToDevice( u );
+      TraverserUserData userData( *kernelTime, *kernelBoundaryConditions, *kernelU );
+      checkCudaDevice;
+      tnlTraverser< MeshType, EntityType > meshTraverser;
+      meshTraverser.template processBoundaryEntities< TraverserUserData,
+                                                      TraverserBoundaryEntitiesProcessor >
+                                                    ( u.getMesh(),
+                                                      userData );
+      tnlCuda::freeFromDevice( kernelTime );
+      tnlCuda::freeFromDevice( kernelBoundaryConditions );
+      tnlCuda::freeFromDevice( kernelU );
+      checkCudaDevice;
+   }
+}
+
+
+
+#endif	/* TNLBOUNDARYCONDITIONSSETTER_IMPL_H */
+
diff --git a/src/solvers/pde/tnlExplicitUpdater.h b/src/solvers/pde/tnlExplicitUpdater.h
index 0053b83203c2ec73bb2beb7e1f9680c768232132..c1869086686eccf733362f37faa468136c367d72 100644
--- a/src/solvers/pde/tnlExplicitUpdater.h
+++ b/src/solvers/pde/tnlExplicitUpdater.h
@@ -21,7 +21,7 @@
 #include <functions/tnlFunctionAdapter.h>
 
 template< typename Real,
-          typename DofVector,
+          typename MeshFunction,
           typename DifferentialOperator,
           typename BoundaryConditions,
           typename RightHandSide >
@@ -37,14 +37,14 @@ class tnlExplicitUpdaterTraverserUserData
 
       const RightHandSide* rightHandSide;
 
-      DofVector *u, *fu;
+      MeshFunction *u, *fu;
 
       tnlExplicitUpdaterTraverserUserData( const Real& time,
                                            const DifferentialOperator& differentialOperator,
                                            const BoundaryConditions& boundaryConditions,
                                            const RightHandSide& rightHandSide,
-                                           DofVector& u,
-                                           DofVector& fu )
+                                           MeshFunction& u,
+                                           MeshFunction& fu )
       : time( &time ),
         differentialOperator( &differentialOperator ),
         boundaryConditions( &boundaryConditions ),
@@ -56,7 +56,7 @@ class tnlExplicitUpdaterTraverserUserData
 
 
 template< typename Mesh,
-          typename DofVector,
+          typename MeshFunction,
           typename DifferentialOperator,
           typename BoundaryConditions,
           typename RightHandSide >
@@ -64,11 +64,11 @@ class tnlExplicitUpdater
 {
    public:
       typedef Mesh MeshType;
-      typedef typename DofVector::RealType RealType;
-      typedef typename DofVector::DeviceType DeviceType;
-      typedef typename DofVector::IndexType IndexType;
+      typedef typename MeshFunction::RealType RealType;
+      typedef typename MeshFunction::DeviceType DeviceType;
+      typedef typename MeshFunction::IndexType IndexType;
       typedef tnlExplicitUpdaterTraverserUserData< RealType,
-                                                   DofVector,
+                                                   MeshFunction,
                                                    DifferentialOperator,
                                                    BoundaryConditions,
                                                    RightHandSide > TraverserUserData;
@@ -79,8 +79,8 @@ class tnlExplicitUpdater
                    const DifferentialOperator& differentialOperator,
                    const BoundaryConditions& boundaryConditions,
                    const RightHandSide& rightHandSide,
-                   DofVector& u,
-                   DofVector& fu ) const;      
+                   MeshFunction& u,
+                   MeshFunction& fu ) const;      
       
             class TraverserBoundaryEntitiesProcessor
       {
@@ -92,12 +92,10 @@ class tnlExplicitUpdater
                                               TraverserUserData& userData,
                                               const GridEntity& entity )
             {
-               userData.boundaryConditions->setBoundaryConditions
-               ( *userData.time,
-                 mesh,
+               ( *userData.u )( entity ) = userData.boundaryConditions->operator()
+               ( *userData.u,
                  entity,
-                 *userData.u,
-                 *userData.fu );
+                 *userData.time );
             }
 
       };
@@ -114,15 +112,14 @@ class tnlExplicitUpdater
                                               TraverserUserData& userData,
                                               const EntityType& entity )
             {
-               ( *userData.fu)[ entity.getIndex() ] = 
-                  userData.differentialOperator->getValue(
-                     mesh,
-                     entity,
+               ( *userData.fu)( entity ) = 
+                  userData.differentialOperator->operator()(
                      *userData.u,
+                     entity,
                      *userData.time );
 
                typedef tnlFunctionAdapter< MeshType, RightHandSide > FunctionAdapter;
-               ( * userData.fu )[ entity.getIndex() ] += 
+               ( * userData.fu )( entity ) += 
                   FunctionAdapter::getValue(
                      *userData.rightHandSide,
                      entity,
diff --git a/src/solvers/pde/tnlExplicitUpdater_impl.h b/src/solvers/pde/tnlExplicitUpdater_impl.h
index e2fee05ad8b3667d85cf88b8099ae69e2d3d6487..9d8e33d12f54b13d25b94841f051e81fdc97bace 100644
--- a/src/solvers/pde/tnlExplicitUpdater_impl.h
+++ b/src/solvers/pde/tnlExplicitUpdater_impl.h
@@ -18,27 +18,28 @@
 #ifndef TNLEXPLICITUPDATER_IMPL_H_
 #define TNLEXPLICITUPDATER_IMPL_H_
 
+#include <type_traits>
 #include <mesh/grids/tnlTraverser_Grid1D.h>
 #include <mesh/grids/tnlTraverser_Grid2D.h>
 #include <mesh/grids/tnlTraverser_Grid3D.h>
 
 template< typename Mesh,
-          typename DofVector,
+          typename MeshFunction,
           typename DifferentialOperator,
           typename BoundaryConditions,
           typename RightHandSide >
    template< typename EntityType >
 void
-tnlExplicitUpdater< Mesh, DofVector, DifferentialOperator, BoundaryConditions, RightHandSide >::
+tnlExplicitUpdater< Mesh, MeshFunction, DifferentialOperator, BoundaryConditions, RightHandSide >::
 update( const RealType& time,
         const Mesh& mesh,
         const DifferentialOperator& differentialOperator,        
         const BoundaryConditions& boundaryConditions,
         const RightHandSide& rightHandSide,
-        DofVector& u,
-        DofVector& fu ) const
+        MeshFunction& u,
+        MeshFunction& fu ) const
 {
-   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlHostDevice )
+   if( std::is_same< DeviceType, tnlHost >::value )
    {
       TraverserUserData userData( time, differentialOperator, boundaryConditions, rightHandSide, u, fu );
       tnlTraverser< MeshType, EntityType > meshTraverser;
@@ -52,14 +53,14 @@ update( const RealType& time,
                                                       userData );
 
    }
-   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlCudaDevice )
+   if( std::is_same< DeviceType, tnlCuda >::value )
    {
       RealType* kernelTime = tnlCuda::passToDevice( time );
       DifferentialOperator* kernelDifferentialOperator = tnlCuda::passToDevice( differentialOperator );
       BoundaryConditions* kernelBoundaryConditions = tnlCuda::passToDevice( boundaryConditions );
       RightHandSide* kernelRightHandSide = tnlCuda::passToDevice( rightHandSide );
-      DofVector* kernelU = tnlCuda::passToDevice( u );
-      DofVector* kernelFu = tnlCuda::passToDevice( fu );
+      MeshFunction* kernelU = tnlCuda::passToDevice( u );
+      MeshFunction* kernelFu = tnlCuda::passToDevice( fu );
       TraverserUserData userData( *kernelTime, *kernelDifferentialOperator, *kernelBoundaryConditions, *kernelRightHandSide, *kernelU, *kernelFu );
       checkCudaDevice;
       tnlTraverser< MeshType, EntityType > meshTraverser;
diff --git a/src/solvers/pde/tnlLinearSystemAssembler.h b/src/solvers/pde/tnlLinearSystemAssembler.h
index 3d45c680b595e85ec3bf63c9f277bc2fa8723735..14753fb7877ae1f1126b541345099a1da28a916f 100644
--- a/src/solvers/pde/tnlLinearSystemAssembler.h
+++ b/src/solvers/pde/tnlLinearSystemAssembler.h
@@ -21,11 +21,12 @@
 #include <functions/tnlFunctionAdapter.h>
 
 template< typename Real,
-          typename DofVector,
+          typename MeshFunction,
           typename DifferentialOperator,
           typename BoundaryConditions,
           typename RightHandSide,
-          typename Matrix >
+          typename Matrix,
+          typename DofVector >
 class tnlLinearSystemAssemblerTraverserUserData
 {
    public:
@@ -36,24 +37,26 @@ class tnlLinearSystemAssemblerTraverserUserData
 
       const Real* tau;
 
+      const Real* timeDiscretisationCoefficient;
+
       const DifferentialOperator* differentialOperator;
 
       const BoundaryConditions* boundaryConditions;
 
       const RightHandSide* rightHandSide;
-
-      DofVector *u, *b;
+      
+      const MeshFunction *u;
+      
+      DofVector *b;
 
       Matrix *matrix;
 
-      const Real* timeDiscretisationCoefficient;
-
       tnlLinearSystemAssemblerTraverserUserData( const Real& time,
                                                  const Real& tau,
                                                  const DifferentialOperator& differentialOperator,
                                                  const BoundaryConditions& boundaryConditions,
                                                  const RightHandSide& rightHandSide,
-                                                 DofVector& u,
+                                                 const MeshFunction& u,
                                                  Matrix& matrix,
                                                  DofVector& b )
       : time( &time ),
@@ -72,26 +75,28 @@ class tnlLinearSystemAssemblerTraverserUserData
 
 
 template< typename Mesh,
-          typename DofVector,
+          typename MeshFunction,
           typename DifferentialOperator,
           typename BoundaryConditions,
           typename RightHandSide,
           typename TimeDiscretisation,
-          typename Matrix >
+          typename Matrix,
+          typename DofVector >
 class tnlLinearSystemAssembler
 {
    public:
    typedef Mesh MeshType;
-   typedef typename DofVector::RealType RealType;
-   typedef typename DofVector::DeviceType DeviceType;
-   typedef typename DofVector::IndexType IndexType;
+   typedef typename MeshFunction::RealType RealType;
+   typedef typename MeshFunction::DeviceType DeviceType;
+   typedef typename MeshFunction::IndexType IndexType;
    typedef Matrix MatrixType;
    typedef tnlLinearSystemAssemblerTraverserUserData< RealType,
-                                                      DofVector,
+                                                      MeshFunction,                                                      
                                                       DifferentialOperator,
                                                       BoundaryConditions,
                                                       RightHandSide,
-                                                      MatrixType > TraverserUserData;
+                                                      MatrixType,
+                                                      DofVector > TraverserUserData;
       
    template< typename EntityType >
    void assembly( const RealType& time,
@@ -100,7 +105,7 @@ class tnlLinearSystemAssembler
                   const DifferentialOperator& differentialOperator,
                   const BoundaryConditions& boundaryConditions,
                   const RightHandSide& rightHandSide,
-                  DofVector& u,
+                  const MeshFunction& u,
                   MatrixType& matrix,
                   DofVector& b ) const;
 
@@ -148,15 +153,16 @@ class tnlLinearSystemAssembler
                  *userData.b,
                  *userData.matrix );
             
-            typedef tnlFunctionAdapter< MeshType, RightHandSide > FunctionAdapter;
-            const RealType& rhs = FunctionAdapter::getValue
+            typedef tnlFunctionAdapter< MeshType, RightHandSide > RhsFunctionAdapter;
+            typedef tnlFunctionAdapter< MeshType, MeshFunction > MeshFunctionAdapter;
+            const RealType& rhs = RhsFunctionAdapter::getValue
                ( *userData.rightHandSide,
                  entity,
                  *userData.time );
             TimeDiscretisation::applyTimeDiscretisation( *userData.matrix,
                                                          ( *userData.b )[ entity.getIndex() ],
                                                          entity.getIndex(),
-                                                         ( *userData.u )[ entity.getIndex() ],
+                                                         MeshFunctionAdapter::getValue( *userData.u, entity, *userData.time ),
                                                          ( *userData.tau ),
                                                          rhs );
          }
diff --git a/src/solvers/pde/tnlLinearSystemAssembler_impl.h b/src/solvers/pde/tnlLinearSystemAssembler_impl.h
index 94b78f2b34537ed894cabae8c7e8ac608a25917c..30f779112edf61e909cd9f59718ad6efc73b51dd 100644
--- a/src/solvers/pde/tnlLinearSystemAssembler_impl.h
+++ b/src/solvers/pde/tnlLinearSystemAssembler_impl.h
@@ -18,123 +18,36 @@
 #ifndef TNLLINEARSYSTEMASSEMBLER_IMPL_H_
 #define TNLLINEARSYSTEMASSEMBLER_IMPL_H_
 
+#include <type_traits>
 #include <mesh/grids/tnlTraverser_Grid1D.h>
 #include <mesh/grids/tnlTraverser_Grid2D.h>
 #include <mesh/grids/tnlTraverser_Grid3D.h>
 
 template< typename Mesh,
-          typename DofVector,
+          typename MeshFunction,
           typename DifferentialOperator,
           typename BoundaryConditions,
           typename RightHandSide,
           typename TimeDiscretisation,
-          typename Matrix >
+          typename Matrix,
+          typename DofVector >
    template< typename EntityType >
 void
-tnlLinearSystemAssembler< Mesh, DofVector, DifferentialOperator, BoundaryConditions, RightHandSide, TimeDiscretisation, Matrix >::
+tnlLinearSystemAssembler< Mesh, MeshFunction, DifferentialOperator, BoundaryConditions, RightHandSide, TimeDiscretisation, Matrix, DofVector >::
 assembly( const RealType& time,
           const RealType& tau,
           const Mesh& mesh,
           const DifferentialOperator& differentialOperator,
           const BoundaryConditions& boundaryConditions,
           const RightHandSide& rightHandSide,
-          DofVector& u,
-          MatrixType& matrix,
-          DofVector& b ) const
-{
-      const IndexType maxRowLength = matrix.getMaxRowLength();
-   tnlAssert( maxRowLength > 0, );
-
-   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlHostDevice )
-   {
-      TraverserUserData userData( time,
-                                  tau,
-                                  differentialOperator,
-                                  boundaryConditions,
-                                  rightHandSide,
-                                  u,
-                                  matrix,
-                                  b );
-      tnlTraverser< MeshType, EntityType > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserBoundaryEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserInteriorEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-   }
-   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlCudaDevice )
-   {
-      RealType* kernelTime = tnlCuda::passToDevice( time );
-      RealType* kernelTau = tnlCuda::passToDevice( tau );
-      DifferentialOperator* kernelDifferentialOperator = tnlCuda::passToDevice( differentialOperator );
-      BoundaryConditions* kernelBoundaryConditions = tnlCuda::passToDevice( boundaryConditions );
-      RightHandSide* kernelRightHandSide = tnlCuda::passToDevice( rightHandSide );
-      DofVector* kernelU = tnlCuda::passToDevice( u );
-      DofVector* kernelB = tnlCuda::passToDevice( b );
-      MatrixType* kernelMatrix = tnlCuda::passToDevice( matrix );
-      TraverserUserData userData( *kernelTime,
-                                  *kernelTau,
-                                  *kernelDifferentialOperator,
-                                  *kernelBoundaryConditions,
-                                  *kernelRightHandSide,
-                                  *kernelU,
-                                  *kernelMatrix,
-                                  *kernelB );
-      checkCudaDevice;
-      tnlTraverser< MeshType, EntityType > meshTraverser;
-      meshTraverser.template processBoundaryEntities< TraverserUserData,
-                                                      TraverserBoundaryEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-      meshTraverser.template processInteriorEntities< TraverserUserData,
-                                                      TraverserInteriorEntitiesProcessor >
-                                                    ( mesh,
-                                                      userData );
-
-      checkCudaDevice;
-      tnlCuda::freeFromDevice( kernelTime );
-      tnlCuda::freeFromDevice( kernelTau );
-      tnlCuda::freeFromDevice( kernelDifferentialOperator );
-      tnlCuda::freeFromDevice( kernelBoundaryConditions );
-      tnlCuda::freeFromDevice( kernelRightHandSide );
-      tnlCuda::freeFromDevice( kernelU );
-      tnlCuda::freeFromDevice( kernelB );
-      tnlCuda::freeFromDevice( kernelMatrix );
-      checkCudaDevice;
-   }
-}
-
-/*
-template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index,
-          typename DofVector,
-          typename DifferentialOperator,
-          typename BoundaryConditions,
-          typename RightHandSide,
-          typename TimeDiscretisation,
-          typename Matrix >
-   template< typename EntityType >
-void
-tnlLinearSystemAssembler< tnlGrid< Dimensions, Real, Device, Index >, DofVector, DifferentialOperator, BoundaryConditions, RightHandSide, TimeDiscretisation, Matrix >::
-assembly( const RealType& time,
-          const RealType& tau,
-          const tnlGrid< Dimensions, Real, Device, Index >& mesh,
-          const DifferentialOperator& differentialOperator,
-          const BoundaryConditions& boundaryConditions,
-          const RightHandSide& rightHandSide,
-          DofVector& u,
+          const MeshFunction& u,
           MatrixType& matrix,
           DofVector& b ) const
 {
    const IndexType maxRowLength = matrix.getMaxRowLength();
    tnlAssert( maxRowLength > 0, );
 
-   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlHostDevice )
+   if( std::is_same< DeviceType, tnlHost >::value )
    {
       TraverserUserData userData( time,
                                   tau,
@@ -154,14 +67,14 @@ assembly( const RealType& time,
                                                     ( mesh,
                                                       userData );
    }
-   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlCudaDevice )
+   if( std::is_same< DeviceType, tnlCuda >::value )
    {
       RealType* kernelTime = tnlCuda::passToDevice( time );
       RealType* kernelTau = tnlCuda::passToDevice( tau );
       DifferentialOperator* kernelDifferentialOperator = tnlCuda::passToDevice( differentialOperator );
       BoundaryConditions* kernelBoundaryConditions = tnlCuda::passToDevice( boundaryConditions );
       RightHandSide* kernelRightHandSide = tnlCuda::passToDevice( rightHandSide );
-      DofVector* kernelU = tnlCuda::passToDevice( u );
+      MeshFunction* kernelU = tnlCuda::passToDevice( u );
       DofVector* kernelB = tnlCuda::passToDevice( b );
       MatrixType* kernelMatrix = tnlCuda::passToDevice( matrix );
       TraverserUserData userData( *kernelTime,
@@ -195,6 +108,5 @@ assembly( const RealType& time,
       checkCudaDevice;
    }
 }
-*/
 
 #endif /* TNLLINEARSYSTEMASSEMBLER_IMPL_H_ */
diff --git a/src/solvers/pde/tnlNoTimeDiscretisation.h b/src/solvers/pde/tnlNoTimeDiscretisation.h
index 27965ea03706c74da4cd1512ebfc1f732032bca3..ff90e1b9b29369f93b2dfceb4e1f912ce8e8533b 100644
--- a/src/solvers/pde/tnlNoTimeDiscretisation.h
+++ b/src/solvers/pde/tnlNoTimeDiscretisation.h
@@ -35,7 +35,7 @@ class tnlNoTimeDiscretisation
                                                                const RealType& rhs )
         {
             b += rhs;
-        };
+        }
 };
 
 #endif	/* TNLNOTIMEDISCRETISATION_H */
diff --git a/src/solvers/pde/tnlPDESolver_impl.h b/src/solvers/pde/tnlPDESolver_impl.h
index 8c1cf924762dca784d7637213106a247fdd84002..cb820815a14d99c2184ae9d56bbafa1c16dfa1a2 100644
--- a/src/solvers/pde/tnlPDESolver_impl.h
+++ b/src/solvers/pde/tnlPDESolver_impl.h
@@ -286,11 +286,8 @@ getTimeStepOrder() const
    return this->timeStepOrder;
 }
 
-template< typename Problem,
-         typename TimeStepper >
-void
-tnlPDESolver< Problem, TimeStepper >::
-setIoRtTimer( tnlTimerRT& ioRtTimer )
+template< typename Problem, typename TimeStepper >
+void tnlPDESolver< Problem, TimeStepper > :: setIoRtTimer( tnlTimerRT& ioRtTimer )
 {
    this->ioRtTimer = &ioRtTimer;
 }
@@ -332,12 +329,22 @@ solve()
    IndexType step( 0 );
    IndexType allSteps = ceil( ( this->finalTime - this->initialTime ) / this->snapshotPeriod );
 
+   this->ioRtTimer->start();
+   this->ioCpuTimer->start();
+   this->computeRtTimer->stop();
+   this->computeCpuTimer->stop();
+
    if( ! this->problem->makeSnapshot( t, step, mesh, this->dofs, this->meshDependentData ) )
    {
       cerr << "Making the snapshot failed." << endl;
       return false;
    }
 
+   this->ioRtTimer->stop();
+   this->ioCpuTimer->stop();
+   this->computeRtTimer->start();
+   this->computeCpuTimer->start();
+
    /****
     * Initialize the time stepper
     */
@@ -364,10 +371,10 @@ solve()
          return false;
       }
 
-      this-> ioRtTimer->stop();
-      this-> ioCpuTimer->stop();
-      this-> computeRtTimer->start();
-      this-> computeCpuTimer->start();
+      this->ioRtTimer->stop();
+      this->ioCpuTimer->stop();
+      this->computeRtTimer->start();
+      this->computeCpuTimer->start();
    }
    return true;
 }
diff --git a/src/solvers/pde/tnlSemiImplicitTimeStepper.h b/src/solvers/pde/tnlSemiImplicitTimeStepper.h
index ab23a123dd6639794142e0dad15bc25206a41bb8..05f16704e760f44ab54d433211a56ddaa5a29623 100644
--- a/src/solvers/pde/tnlSemiImplicitTimeStepper.h
+++ b/src/solvers/pde/tnlSemiImplicitTimeStepper.h
@@ -35,6 +35,7 @@ class tnlSemiImplicitTimeStepper
    typedef typename ProblemType::DofVectorType DofVectorType;
    typedef typename ProblemType::MeshDependentDataType MeshDependentDataType;
    typedef LinearSystemSolver LinearSystemSolverType;
+   typedef typename LinearSystemSolverType::PreconditionerType PreconditionerType;
    typedef typename ProblemType::MatrixType MatrixType;
 
    tnlSemiImplicitTimeStepper();
@@ -79,7 +80,7 @@ class tnlSemiImplicitTimeStepper
 
    RealType timeStep;
 
-   tnlTimerRT linearSystemAssemblerTimer, linearSystemSolverTimer;
+   tnlTimerRT preIterateTimer, linearSystemAssemblerTimer, linearSystemSolverTimer, postIterateTimer;
    
    bool verbose;
 };
diff --git a/src/solvers/pde/tnlSemiImplicitTimeStepper_impl.h b/src/solvers/pde/tnlSemiImplicitTimeStepper_impl.h
index 57c87ae1407ba0faed345ad8bae1aae1218f90b5..d13ef8050448da323e657cab41935696c8c9b4a4 100644
--- a/src/solvers/pde/tnlSemiImplicitTimeStepper_impl.h
+++ b/src/solvers/pde/tnlSemiImplicitTimeStepper_impl.h
@@ -141,10 +141,15 @@ solve( const RealType& time,
    tnlAssert( this->problem != 0, );
    RealType t = time;
    this->linearSystemSolver->setMatrix( this->matrix );
+   PreconditionerType preconditioner;
+   tnlSolverStarterSolverPreconditionerSetter< LinearSystemSolverType, PreconditionerType >
+       ::run( *(this->linearSystemSolver), preconditioner );
+
    while( t < stopTime )
    {
       RealType currentTau = Min( this->timeStep, stopTime - t );
 
+      this->preIterateTimer.start();
       if( ! this->problem->preIterate( t,
                                        currentTau,
                                        mesh,
@@ -154,8 +159,11 @@ solve( const RealType& time,
          cerr << endl << "Preiteration failed." << endl;
          return false;
       }
+      this->preIterateTimer.stop();
+
       if( verbose )
          cout << "                                                                  Assembling the linear system ... \r" << flush;
+
       this->linearSystemAssemblerTimer.start();
       this->problem->assemblyLinearSystem( t,
                                            currentTau,
@@ -165,8 +173,13 @@ solve( const RealType& time,
                                            this->rightHandSide,
                                            meshDependentData );
       this->linearSystemAssemblerTimer.stop();
+
       if( verbose )
-         cout << "                                                                  Solving the linear system for time " << t << "             \r" << flush;
+         cout << "                                                                  Solving the linear system for time " << t + currentTau << "             \r" << flush;
+
+      // TODO: add timer
+      preconditioner.update( this->matrix );
+
       this->linearSystemSolverTimer.start();
       if( ! this->linearSystemSolver->template solve< DofVectorType, tnlLinearResidueGetter< MatrixType, DofVectorType > >( this->rightHandSide, dofVector ) )
       {
@@ -174,8 +187,11 @@ solve( const RealType& time,
          return false;
       }
       this->linearSystemSolverTimer.stop();
+
       //if( verbose )
       //   cout << endl;
+
+      this->postIterateTimer.start();
       if( ! this->problem->postIterate( t,
                                         currentTau,
                                         mesh,
@@ -185,6 +201,8 @@ solve( const RealType& time,
          cerr << endl << "Postiteration failed." << endl;
          return false;
       }
+      this->postIterateTimer.stop();
+
       t += currentTau;
    }
    return true;
@@ -196,8 +214,10 @@ bool
 tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >::
 writeEpilog( tnlLogger& logger )
 {
+   logger.writeParameter< double >( "Pre-iterate time:", this->preIterateTimer.getTime() );
    logger.writeParameter< double >( "Linear system assembler time:", this->linearSystemAssemblerTimer.getTime() );
    logger.writeParameter< double >( "Linear system solver time:", this->linearSystemSolverTimer.getTime() );
+   logger.writeParameter< double >( "Post-iterate time:", this->postIterateTimer.getTime() );
    return true;
 }
 
diff --git a/src/solvers/preconditioners/CMakeLists.txt b/src/solvers/preconditioners/CMakeLists.txt
index 89470003ec21ddde4c88e677a3a973ec53d4c550..d5fdac93f462c6b38169ec165d3973e447975ece 100755
--- a/src/solvers/preconditioners/CMakeLists.txt
+++ b/src/solvers/preconditioners/CMakeLists.txt
@@ -1,4 +1,6 @@
 SET( headers tnlDummyPreconditioner.h
+             tnlDiagonalPreconditioner.h
+             tnlDiagonalPreconditioner_impl.h
    )
    
 INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/solvers/preconditioners )
diff --git a/src/solvers/preconditioners/tnlDiagonalPreconditioner.h b/src/solvers/preconditioners/tnlDiagonalPreconditioner.h
new file mode 100644
index 0000000000000000000000000000000000000000..d4af93a98b03f724e75f3c4fe15443eef558269f
--- /dev/null
+++ b/src/solvers/preconditioners/tnlDiagonalPreconditioner.h
@@ -0,0 +1,33 @@
+#ifndef TNLDIAGONALPRECONDITIONER_H_
+#define TNLDIAGONALPRECONDITIONER_H_
+
+#include <core/tnlObject.h>
+#include <core/vectors/tnlVector.h>
+
+template< typename Real, typename Device, typename Index >
+class tnlDiagonalPreconditioner
+{
+   public:
+   typedef Real RealType;
+   typedef Device DeviceType;
+   typedef Index IndexType;
+   typedef tnlVector< Real, Device, Index > VectorType;
+
+   template< typename Matrix >
+   void update( const Matrix& matrix );
+
+   template< typename Vector1, typename Vector2 >
+   bool solve( const Vector1& b, Vector2& x ) const;
+
+   tnlString getType() const
+   {
+      return tnlString( "tnlDiagonalPreconditioner" );
+   }
+
+   protected:
+   VectorType diagonal;
+};
+
+#include <solvers/preconditioners/tnlDiagonalPreconditioner_impl.h>
+
+#endif /* TNLDIAGONALPRECONDITIONER_H_ */
diff --git a/src/solvers/preconditioners/tnlDiagonalPreconditioner_impl.h b/src/solvers/preconditioners/tnlDiagonalPreconditioner_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..56b2e67933de545c1b8ec6a7544981f892013efc
--- /dev/null
+++ b/src/solvers/preconditioners/tnlDiagonalPreconditioner_impl.h
@@ -0,0 +1,110 @@
+#ifndef TNLDIAGONALPRECONDITIONER_IMPL_H_
+#define TNLDIAGONALPRECONDITIONER_IMPL_H_
+
+#include "tnlDiagonalPreconditioner.h"
+
+#ifdef HAVE_CUDA
+template< typename Real, typename Index, typename Matrix >
+__global__ void matrixDiagonalToVectorKernel( const Matrix* matrix,
+                                              Real* diagonal,
+                                              Index size ) {
+   Index elementIdx = blockDim. x * blockIdx. x + threadIdx. x;
+   const Index maxGridSize = blockDim. x * gridDim. x;
+   while( elementIdx < size )
+   {
+      diagonal[ elementIdx ] = matrix->getElementFast( elementIdx, elementIdx );
+      elementIdx += maxGridSize;
+   }
+}
+
+template< typename Real, typename Index >
+__global__ void elementwiseVectorDivisionKernel( const Real* left,
+                                                 const Real* right,
+                                                 Real* result,
+                                                 Index size )
+{
+   Index elementIdx = blockDim. x * blockIdx. x + threadIdx. x;
+   const Index maxGridSize = blockDim. x * gridDim. x;
+   while( elementIdx < size )
+   {
+      result[ elementIdx ] = left[ elementIdx ] / right[ elementIdx ];
+      elementIdx += maxGridSize;
+   }
+}
+#endif
+
+template< typename Real, typename Device, typename Index >
+   template< typename Matrix >
+void
+tnlDiagonalPreconditioner< Real, Device, Index >::
+update( const Matrix& matrix )
+{
+//   cout << getType() << "->setMatrix()" << endl;
+
+   tnlAssert( matrix.getRows() > 0 && matrix.getRows() == matrix.getColumns(), );
+
+   if( diagonal.getSize() != matrix.getRows() )
+      diagonal.setSize( matrix.getRows() );
+
+   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlHostDevice )
+   {
+      for( int i = 0; i < diagonal.getSize(); i++ ) {
+         diagonal[ i ] = matrix.getElement( i, i );
+      }
+   }
+   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlCudaDevice )
+   {
+#ifdef HAVE_CUDA
+      Matrix* kernelMatrix = tnlCuda::passToDevice( matrix );
+
+      const Index& size = diagonal.getSize();
+      dim3 cudaBlockSize( 256 );
+      dim3 cudaBlocks;
+      cudaBlocks.x = Min( tnlCuda::getMaxGridSize(), tnlCuda::getNumberOfBlocks( size, cudaBlockSize.x ) );      
+
+      matrixDiagonalToVectorKernel<<< cudaBlocks, cudaBlockSize >>>(
+            kernelMatrix,
+            diagonal.getData(),
+            size );
+
+      checkCudaDevice;
+      tnlCuda::freeFromDevice( kernelMatrix );
+      checkCudaDevice;
+#endif
+   }
+}
+
+template< typename Real, typename Device, typename Index >
+   template< typename Vector1, typename Vector2 >
+bool
+tnlDiagonalPreconditioner< Real, Device, Index >::
+solve( const Vector1& b, Vector2& x ) const
+{
+//   cout << getType() << "->solve()" << endl;
+   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlHostDevice )
+   {
+      for( int i = 0; i < diagonal.getSize(); i++ ) {
+         x[ i ] = b[ i ] / diagonal[ i ];
+      }
+   }
+   if( ( tnlDeviceEnum ) DeviceType::DeviceType == tnlCudaDevice )
+   {
+#ifdef HAVE_CUDA
+      const Index& size = diagonal.getSize();
+      dim3 cudaBlockSize( 256 );
+      dim3 cudaBlocks;
+      cudaBlocks.x = Min( tnlCuda::getMaxGridSize(), tnlCuda::getNumberOfBlocks( size, cudaBlockSize.x ) );      
+
+      elementwiseVectorDivisionKernel<<< cudaBlocks, cudaBlockSize >>>(
+            b.getData(),
+            diagonal.getData(),
+            x.getData(),
+            size );
+
+      checkCudaDevice;
+#endif
+   }
+   return true;
+}
+
+#endif /* TNLDIAGONALPRECONDITIONER_IMPL_H_ */
diff --git a/src/solvers/preconditioners/tnlDummyPreconditioner.h b/src/solvers/preconditioners/tnlDummyPreconditioner.h
index 17b08023d459184240a0d1f73e149ee0c7049468..ef5424e9171652a95a58b3983f3c2469fcee63e8 100644
--- a/src/solvers/preconditioners/tnlDummyPreconditioner.h
+++ b/src/solvers/preconditioners/tnlDummyPreconditioner.h
@@ -25,8 +25,11 @@ class tnlDummyPreconditioner
 {
    public:
 
+   template< typename Matrix >
+   void update( const Matrix& matrix ) {}
+
    template< typename Vector1, typename Vector2 >
-      bool solve( const Vector1& b, Vector2& x ) const { return true; }
+   bool solve( const Vector1& b, Vector2& x ) const { return true; }
 
    tnlString getType() const
    {
@@ -34,5 +37,25 @@ class tnlDummyPreconditioner
    }
 };
 
+template< typename LinearSolver, typename Preconditioner >
+class tnlSolverStarterSolverPreconditionerSetter
+{
+    public:
+        static void run( LinearSolver& solver, Preconditioner& preconditioner )
+        {
+            solver.setPreconditioner( preconditioner );
+        }
+};
+
+template< typename LinearSolver, typename Real, typename Device, typename Index >
+class tnlSolverStarterSolverPreconditionerSetter< LinearSolver, tnlDummyPreconditioner< Real, Device, Index > >
+{
+    public:
+        static void run( LinearSolver& solver, tnlDummyPreconditioner< Real, Device, Index >& preconditioner )
+        {
+            // do nothing
+        }
+};
+
 
 #endif /* TNLDUMMYPRECONDITIONER_H_ */
diff --git a/src/solvers/tnlBuildConfigTags.h b/src/solvers/tnlBuildConfigTags.h
index 6ab4d04ea4abc3fcb1abc1cf9f8e3c8c4c7242ae..38382489979dda6b647620f6826f0d813824f228 100644
--- a/src/solvers/tnlBuildConfigTags.h
+++ b/src/solvers/tnlBuildConfigTags.h
@@ -19,6 +19,14 @@
 #define TNLMeshConfigS_H_
 
 #include <mesh/tnlGrid.h>
+#include <solvers/ode/tnlMersonSolver.h>
+#include <solvers/ode/tnlEulerSolver.h>
+#include <solvers/linear/stationary/tnlSORSolver.h>
+#include <solvers/linear/krylov/tnlCGSolver.h>
+#include <solvers/linear/krylov/tnlBICGStabSolver.h>
+#include <solvers/linear/krylov/tnlGMRESSolver.h>
+#include <solvers/linear/krylov/tnlTFQMRSolver.h>
+#include <solvers/preconditioners/tnlDummyPreconditioner.h>
 
 class tnlDefaultBuildMeshConfig{};
 
@@ -37,7 +45,7 @@ template< typename MeshConfig > struct tnlMeshConfigDevice< MeshConfig, tnlCuda
 template< typename MeshConfig, typename Real > struct tnlMeshConfigReal{ enum { enabled = true }; };
 
 /****
- * All index types are enabled ba default.
+ * All index types are enabled by default.
  */
 template< typename MeshConfig, typename Index > struct tnlMeshConfigIndex{ enum { enabled = true }; };
 
@@ -60,11 +68,14 @@ template< typename MeshConfig, int Dimensions > struct tnlMeshConfigDimensions{
 template< typename MeshConfig, typename MeshType > struct tnlMeshConfigMesh{ enum { enabled = false }; };
 
 /****
- * Use of tnlGrid is enabled for allowed dimensions by default.
+ * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types.
  */
 template< typename MeshConfig, int Dimensions, typename Real, typename Device, typename Index >
    struct tnlMeshConfigMesh< MeshConfig, tnlGrid< Dimensions, Real, Device, Index > >
-      { enum { enabled = tnlMeshConfigDimensions< MeshConfig, Dimensions >::enabled }; };
+      { enum { enabled = tnlMeshConfigDimensions< MeshConfig, Dimensions >::enabled  &&
+                         tnlMeshConfigReal< MeshConfig, Real >::enabled &&
+                         tnlMeshConfigDevice< MeshConfig, Device >::enabled &&
+                         tnlMeshConfigIndex< MeshConfig, Index >::enabled }; };
 
 /****
  * All time discretisations (explicit, semi-impicit and implicit ) are
@@ -79,19 +90,69 @@ template< typename MeshConfig, typename TimeDiscretisation > struct tnlConfigTag
 /****
  * All explicit solvers are enabled by default
  */
-class tnlExplicitEulerSolverTag{};
-class tnlExplicitMersonSolverTag{};
+class tnlExplicitEulerSolverTag
+{
+public:
+    template< typename Problem >
+    using Template = tnlEulerSolver< Problem >;
+};
+
+class tnlExplicitMersonSolverTag
+{
+public:
+    template< typename Problem >
+    using Template = tnlMersonSolver< Problem >;
+};
 
 template< typename MeshConfig, typename ExplicitSolver > struct tnlMeshConfigExplicitSolver{ enum { enabled = true }; };
 
 /****
  * All semi-implicit solvers are enabled by default
  */
-
-class  tnlSemiImplicitSORSolverTag{};
-class  tnlSemiImplicitCGSolverTag{};
-class  tnlSemiImplicitBICGStabSolverTag{};
-class  tnlSemiImplicitGMRESSolverTag{};
+class  tnlSemiImplicitSORSolverTag
+{
+public:
+    template< typename Matrix, typename Preconditioner = tnlDummyPreconditioner< typename Matrix::RealType,
+                                                                                 typename Matrix::DeviceType,
+                                                                                 typename Matrix::IndexType > >
+    using Template = tnlSORSolver< Matrix, Preconditioner >;
+};
+
+class  tnlSemiImplicitCGSolverTag
+{
+public:
+    template< typename Matrix, typename Preconditioner = tnlDummyPreconditioner< typename Matrix::RealType,
+                                                                                 typename Matrix::DeviceType,
+                                                                                 typename Matrix::IndexType > >
+    using Template = tnlCGSolver< Matrix, Preconditioner >;
+};
+
+class  tnlSemiImplicitBICGStabSolverTag
+{
+public:
+    template< typename Matrix, typename Preconditioner = tnlDummyPreconditioner< typename Matrix::RealType,
+                                                                                 typename Matrix::DeviceType,
+                                                                                 typename Matrix::IndexType > >
+    using Template = tnlBICGStabSolver< Matrix, Preconditioner >;
+};
+
+class  tnlSemiImplicitGMRESSolverTag
+{
+public:
+    template< typename Matrix, typename Preconditioner = tnlDummyPreconditioner< typename Matrix::RealType,
+                                                                                 typename Matrix::DeviceType,
+                                                                                 typename Matrix::IndexType > >
+    using Template = tnlGMRESSolver< Matrix, Preconditioner >;
+};
+
+class  tnlSemiImplicitTFQMRSolverTag
+{
+public:
+    template< typename Matrix, typename Preconditioner = tnlDummyPreconditioner< typename Matrix::RealType,
+                                                                                 typename Matrix::DeviceType,
+                                                                                 typename Matrix::IndexType > >
+    using Template = tnlTFQMRSolver< Matrix, Preconditioner >;
+};
 
 template< typename MeshConfig, typename SemiImplicitSolver > struct tnlMeshConfigSemiImplicitSolver{ enum { enabled = true }; };
 
diff --git a/src/solvers/tnlIterativeSolver.h b/src/solvers/tnlIterativeSolver.h
index d79ab4bd59f863c044a32fecb9e44ba540485782..8c05287d8d31cbbfffcfd186d550484da9618466 100644
--- a/src/solvers/tnlIterativeSolver.h
+++ b/src/solvers/tnlIterativeSolver.h
@@ -67,7 +67,7 @@ class tnlIterativeSolver
 
    bool checkConvergence();
 
-   void refreshSolverMonitor();
+   void refreshSolverMonitor( bool force = false );
 
 
    protected:
diff --git a/src/solvers/tnlIterativeSolverMonitor.h b/src/solvers/tnlIterativeSolverMonitor.h
index b4c949ee78ffc3bd2db38b99e07075983f9738f8..5cca8ed68ac8bcc9afe365b8837ff92ecdd94537 100644
--- a/src/solvers/tnlIterativeSolverMonitor.h
+++ b/src/solvers/tnlIterativeSolverMonitor.h
@@ -44,7 +44,7 @@ class tnlIterativeSolverMonitor : public tnlSolverMonitor< Real, Index >
    
    void setRefreshRate( const IndexType& refreshRate );
 
-   virtual void refresh();
+   virtual void refresh( bool force = false );
 
    void resetTimers();
 
diff --git a/src/solvers/tnlIterativeSolverMonitor_impl.h b/src/solvers/tnlIterativeSolverMonitor_impl.h
index 1db4c8048b0749e63588ea2e39a43ae22bc0d737..7f65f9e596b3cbdc1d8101c3f35c33f6d011c5e7 100644
--- a/src/solvers/tnlIterativeSolverMonitor_impl.h
+++ b/src/solvers/tnlIterativeSolverMonitor_impl.h
@@ -69,9 +69,9 @@ void tnlIterativeSolverMonitor< Real, Index > :: setRefreshRate( const Index& re
 }
 
 template< typename Real, typename Index>
-void tnlIterativeSolverMonitor< Real, Index > :: refresh()
+void tnlIterativeSolverMonitor< Real, Index > :: refresh( bool force )
 {
-   if( this->verbose > 0 && this->getIterations() % this->refreshRate == 0 )
+   if( this->verbose > 0 && ( force || this->getIterations() % this->refreshRate == 0 ) )
    {
       cout << " ITER:" << setw( 8 ) << this->getIterations()
            << " RES:" << setprecision( 5 ) << setw( 12 ) << this -> getResidue()
diff --git a/src/solvers/tnlIterativeSolver_impl.h b/src/solvers/tnlIterativeSolver_impl.h
index 012a6da17141a62ba10514632a00daeab0bc6902..dc86d6179280a4fe66e0a83aee48b4562df89d4a 100644
--- a/src/solvers/tnlIterativeSolver_impl.h
+++ b/src/solvers/tnlIterativeSolver_impl.h
@@ -103,7 +103,7 @@ bool tnlIterativeSolver< Real, Index> :: nextIteration()
 
    if( std::isnan( this->getResidue() ) || 
        this->getIterations() > this->getMaxIterations()  ||
-       ( this->getResidue() > this->getDivergenceResidue() && this->getIterations() > this->minIterations ) ||
+       ( this->getResidue() > this->getDivergenceResidue() && this->getIterations() > this->getMinIterations() ) ||
        ( this->getResidue() < this->getConvergenceResidue() && this->getIterations() > this->minIterations ) ) 
       return false;
    return true;
@@ -196,14 +196,14 @@ void tnlIterativeSolver< Real, Index> :: setSolverMonitor( tnlIterativeSolverMon
 }
 
 template< typename Real, typename Index >
-void tnlIterativeSolver< Real, Index> :: refreshSolverMonitor()
+void tnlIterativeSolver< Real, Index> :: refreshSolverMonitor( bool force )
 {
    if( this -> solverMonitor )
    {
       this -> solverMonitor -> setIterations( this -> getIterations() );
       this -> solverMonitor -> setResidue( this -> getResidue() );
       this -> solverMonitor -> setRefreshRate( this-> refreshRate );
-      this -> solverMonitor -> refresh();
+      this -> solverMonitor -> refresh( force );
    }
 }
 
diff --git a/src/solvers/tnlMeshTypeResolver.h b/src/solvers/tnlMeshTypeResolver.h
index 702fab91e6bbc4dd9eafa5acdc5ed6c5e8a18d91..345bd38e721f43a5ffd415455ce913166a89076f 100644
--- a/src/solvers/tnlMeshTypeResolver.h
+++ b/src/solvers/tnlMeshTypeResolver.h
@@ -58,18 +58,48 @@ class tnlMeshTypeResolver< ProblemSetter, Real, Device, Index, MeshConfig, true
    static bool resolveMeshDimensions( const tnlParameterContainer& parameters,
                                       const tnlList< tnlString >& parsedMeshType );
 
-   template< int MeshDimensions >
+   // Overload for disabled dimensions
+   template< int MeshDimensions,
+             typename = typename std::enable_if< ! tnlMeshConfigDimensions<MeshConfig,MeshDimensions>::enabled >::type,
+             typename = void >
+   static bool resolveMeshRealType( const tnlParameterContainer& parameters,
+                                    const tnlList< tnlString >& parsedMeshType );
+
+   // Overload for enabled dimensions
+   template< int MeshDimensions,
+             typename = typename std::enable_if< tnlMeshConfigDimensions<MeshConfig,MeshDimensions>::enabled >::type >
    static bool resolveMeshRealType( const tnlParameterContainer& parameters,
                                     const tnlList< tnlString >& parsedMeshType );
 
+   // Overload for disabled real types
+   template< int MeshDimensions,
+             typename MeshRealType,
+             typename = typename std::enable_if< ! tnlMeshConfigReal<MeshConfig, MeshRealType>::enabled >::type,
+             typename = void >
+   static bool resolveMeshIndexType( const tnlParameterContainer& parameters,
+                                     const tnlList< tnlString >& parsedMeshType );
+
+   // Overload for enabled real types
    template< int MeshDimensions,
-             typename MeshRealType >
+             typename MeshRealType,
+             typename = typename std::enable_if< tnlMeshConfigReal<MeshConfig, MeshRealType>::enabled >::type >
    static bool resolveMeshIndexType( const tnlParameterContainer& parameters,
                                      const tnlList< tnlString >& parsedMeshType );
 
+   // Overload for disabled index types
+   template< int MeshDimensions,
+             typename MeshRealType,
+             typename MeshIndexType,
+             typename = typename std::enable_if< ! tnlMeshConfigIndex<MeshConfig, MeshIndexType>::enabled >::type,
+             typename = void >
+   static bool resolveMeshType( const tnlParameterContainer& parameters,
+                                const tnlList< tnlString >& parsedMeshType );
+
+   // Overload for enabled index types
    template< int MeshDimensions,
              typename MeshRealType,
-             typename MeshIndexType >
+             typename MeshIndexType,
+             typename = typename std::enable_if< tnlMeshConfigIndex<MeshConfig, MeshIndexType>::enabled >::type >
    static bool resolveMeshType( const tnlParameterContainer& parameters,
                                 const tnlList< tnlString >& parsedMeshType );
 
diff --git a/src/solvers/tnlMeshTypeResolver_impl.h b/src/solvers/tnlMeshTypeResolver_impl.h
index a50b15df3a3eeb5351cb1447622dc426d490bba2..d5baa5ce80a7f8e51889f41e1f72b170116c04b9 100644
--- a/src/solvers/tnlMeshTypeResolver_impl.h
+++ b/src/solvers/tnlMeshTypeResolver_impl.h
@@ -98,7 +98,20 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename Device,
           typename Index,
           typename MeshConfig >
-   template< int MeshDimensions >
+   template< int MeshDimensions, typename, typename >
+bool tnlMeshTypeResolver< ProblemSetter, Real, Device, Index, MeshConfig, true >::resolveMeshRealType( const tnlParameterContainer& parameters,
+                                                                                                      const tnlList< tnlString >& parsedMeshType )
+{
+   cerr << "Mesh dimension " << MeshDimensions << " is not supported." << endl;
+   return false;
+}
+
+template< template< typename Real, typename Device, typename Index, typename MeshType, typename MeshConfig, typename SolverStarter > class ProblemSetter,
+          typename Real,
+          typename Device,
+          typename Index,
+          typename MeshConfig >
+   template< int MeshDimensions, typename >
 bool tnlMeshTypeResolver< ProblemSetter, Real, Device, Index, MeshConfig, true >::resolveMeshRealType( const tnlParameterContainer& parameters,
                                                                                                       const tnlList< tnlString >& parsedMeshType )
 {
@@ -118,9 +131,25 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename Index,
           typename MeshConfig >
    template< int MeshDimensions,
-             typename MeshRealType >
-bool tnlMeshTypeResolver< ProblemSetter, Real, Device, Index, MeshConfig, 1 >::resolveMeshIndexType( const tnlParameterContainer& parameters,
-                                                                                                    const tnlList< tnlString >& parsedMeshType )
+             typename MeshRealType,
+             typename, typename >
+bool tnlMeshTypeResolver< ProblemSetter, Real, Device, Index, MeshConfig, true >::resolveMeshIndexType( const tnlParameterContainer& parameters,
+                                                                                                        const tnlList< tnlString >& parsedMeshType )
+{
+   cerr << "The type '" << parsedMeshType[ 4 ] << "' is not allowed for real type." << endl;
+   return false;
+}
+
+template< template< typename Real, typename Device, typename Index, typename MeshType, typename MeshConfig, typename SolverStarter > class ProblemSetter,
+          typename Real,
+          typename Device,
+          typename Index,
+          typename MeshConfig >
+   template< int MeshDimensions,
+             typename MeshRealType,
+             typename >
+bool tnlMeshTypeResolver< ProblemSetter, Real, Device, Index, MeshConfig, true >::resolveMeshIndexType( const tnlParameterContainer& parameters,
+                                                                                                        const tnlList< tnlString >& parsedMeshType )
 {
    if( parsedMeshType[ 4 ] == "short int" )
       return resolveMeshType< MeshDimensions, MeshRealType, short int >( parameters, parsedMeshType );
@@ -139,9 +168,26 @@ template< template< typename Real, typename Device, typename Index, typename Mes
           typename MeshConfig >
    template< int MeshDimensions,
              typename MeshRealType,
-             typename MeshIndexType >
+             typename MeshIndexType,
+             typename, typename >
+bool tnlMeshTypeResolver< ProblemSetter, Real, Device, Index, MeshConfig, true >::resolveMeshType( const tnlParameterContainer& parameters,
+                                                                                                   const tnlList< tnlString >& parsedMeshType )
+{
+   cerr << "The type '" << parsedMeshType[ 4 ] << "' is not allowed for indexing type." << endl;
+   return false;
+}
+
+template< template< typename Real, typename Device, typename Index, typename MeshType, typename MeshConfig, typename SolverStarter > class ProblemSetter,
+          typename Real,
+          typename Device,
+          typename Index,
+          typename MeshConfig >
+   template< int MeshDimensions,
+             typename MeshRealType,
+             typename MeshIndexType,
+             typename >
 bool tnlMeshTypeResolver< ProblemSetter, Real, Device, Index, MeshConfig, true >::resolveMeshType( const tnlParameterContainer& parameters,
-                                                                                                  const tnlList< tnlString >& parsedMeshType )
+                                                                                                   const tnlList< tnlString >& parsedMeshType )
 {
    if( parsedMeshType[ 0 ] == "tnlGrid" )
    {
diff --git a/src/solvers/tnlSolverConfig_impl.h b/src/solvers/tnlSolverConfig_impl.h
index 48657476096fe0d8c734102dcf10ca6bca371bbf..5bde38c816fe621ad657d8fd265af6b0608cf9d8 100644
--- a/src/solvers/tnlSolverConfig_impl.h
+++ b/src/solvers/tnlSolverConfig_impl.h
@@ -114,9 +114,14 @@ bool tnlSolverConfig< MeshConfig, ProblemConfig >::configSetup( tnlConfigDescrip
          config.addEntryEnum( "bicgstab" );
       if( tnlMeshConfigSemiImplicitSolver< MeshConfig, tnlSemiImplicitGMRESSolverTag >::enabled )
          config.addEntryEnum( "gmres" );
+      if( tnlMeshConfigSemiImplicitSolver< MeshConfig, tnlSemiImplicitTFQMRSolverTag >::enabled )
+         config.addEntryEnum( "tfqmr" );
       if( tnlMeshConfigSemiImplicitSolver< MeshConfig, tnlSemiImplicitSORSolverTag >::enabled )
          config.addEntryEnum( "sor" );
    }
+   config.addEntry< tnlString >( "preconditioner", "The preconditioner for the discrete solver:", "none" );
+   config.addEntryEnum( "none" );
+   config.addEntryEnum( "diagonal" );
    if( tnlConfigTagTimeDiscretisation< MeshConfig, tnlExplicitTimeDiscretisationTag >::enabled ||
        tnlConfigTagTimeDiscretisation< MeshConfig, tnlSemiImplicitTimeDiscretisationTag >::enabled )
    {
@@ -143,6 +148,8 @@ bool tnlSolverConfig< MeshConfig, ProblemConfig >::configSetup( tnlConfigDescrip
          tnlBICGStabSolver< MatrixType >::configSetup( config );
       if( tnlMeshConfigSemiImplicitSolver< MeshConfig, tnlSemiImplicitGMRESSolverTag >::enabled )
          tnlGMRESSolver< MatrixType >::configSetup( config );
+      if( tnlMeshConfigSemiImplicitSolver< MeshConfig, tnlSemiImplicitTFQMRSolverTag >::enabled )
+         tnlTFQMRSolver< MatrixType >::configSetup( config );
       if( tnlMeshConfigSemiImplicitSolver< MeshConfig, tnlSemiImplicitSORSolverTag >::enabled )
          tnlSORSolver< MatrixType >::configSetup( config );
    }
diff --git a/src/solvers/tnlSolverMonitor.h b/src/solvers/tnlSolverMonitor.h
index df946e3643cdba6110c841ae8caa253fc06909e5..b6263a27b03e39ce1c2afa5a0fc23fd681bf5d35 100644
--- a/src/solvers/tnlSolverMonitor.h
+++ b/src/solvers/tnlSolverMonitor.h
@@ -23,7 +23,7 @@ class tnlSolverMonitor
 {
    public:
 
-   virtual void refresh() = 0;
+   virtual void refresh( bool force = false ) = 0;
 
    ~tnlSolverMonitor() {};
       
diff --git a/src/solvers/tnlSolverStarter_impl.h b/src/solvers/tnlSolverStarter_impl.h
index f4913a160175485ef540f1310e73a1143f31369e..0920ceaa37a734edbf9629af2313aa423bff3224 100644
--- a/src/solvers/tnlSolverStarter_impl.h
+++ b/src/solvers/tnlSolverStarter_impl.h
@@ -27,6 +27,9 @@
 #include <solvers/linear/krylov/tnlCGSolver.h>
 #include <solvers/linear/krylov/tnlBICGStabSolver.h>
 #include <solvers/linear/krylov/tnlGMRESSolver.h>
+#include <solvers/linear/krylov/tnlTFQMRSolver.h>
+#include <solvers/preconditioners/tnlDummyPreconditioner.h>
+#include <solvers/preconditioners/tnlDiagonalPreconditioner.h>
 #include <solvers/pde/tnlExplicitTimeStepper.h>
 #include <solvers/pde/tnlSemiImplicitTimeStepper.h>
 #include <solvers/pde/tnlPDESolver.h>
@@ -52,11 +55,17 @@ class tnlSolverStarterExplicitSolverSetter{};
 
 template< typename Problem,
           typename SemiImplicitSolver,
+          template<typename, typename, typename> class Preconditioner,
           typename MeshConfig,
           bool enabled = tnlMeshConfigSemiImplicitSolver< MeshConfig, SemiImplicitSolver >::enabled >
 class tnlSolverStarterSemiImplicitSolverSetter{};
 
 
+template< typename Problem,
+          typename SemiImplicitSolverTag,
+          typename MeshConfig >
+class tnlSolverStarterPreconditionerSetter;
+
 template< typename Problem,
           typename ExplicitSolver,
           typename TimeStepper,
@@ -187,20 +196,23 @@ class tnlSolverStarterTimeDiscretisationSetter< Problem, tnlSemiImplicitTimeDisc
          if( discreteSolver != "sor" &&
              discreteSolver != "cg" &&
              discreteSolver != "bicgstab" &&
-             discreteSolver != "gmres" )
+             discreteSolver != "gmres" &&
+             discreteSolver != "tfqmr" )
          {
-            cerr << "Unknown explicit discrete solver " << discreteSolver << ". It can be only: sor, cg, bicgstab or gmres." << endl;
+            cerr << "Unknown semi-implicit discrete solver " << discreteSolver << ". It can be only: sor, cg, bicgstab, gmres or tfqmr." << endl;
             return false;
          }
 
          if( discreteSolver == "sor" )
-            return tnlSolverStarterSemiImplicitSolverSetter< Problem, tnlSemiImplicitSORSolverTag, MeshConfig >::run( problem, parameters );
+            return tnlSolverStarterPreconditionerSetter< Problem, tnlSemiImplicitSORSolverTag, MeshConfig >::run( problem, parameters );
          if( discreteSolver == "cg" )
-            return tnlSolverStarterSemiImplicitSolverSetter< Problem, tnlSemiImplicitCGSolverTag, MeshConfig >::run( problem, parameters );
+            return tnlSolverStarterPreconditionerSetter< Problem, tnlSemiImplicitCGSolverTag, MeshConfig >::run( problem, parameters );
          if( discreteSolver == "bicgstab" )
-            return tnlSolverStarterSemiImplicitSolverSetter< Problem, tnlSemiImplicitBICGStabSolverTag, MeshConfig >::run( problem, parameters );
+            return tnlSolverStarterPreconditionerSetter< Problem, tnlSemiImplicitBICGStabSolverTag, MeshConfig >::run( problem, parameters );
          if( discreteSolver == "gmres" )
-            return tnlSolverStarterSemiImplicitSolverSetter< Problem, tnlSemiImplicitGMRESSolverTag, MeshConfig >::run( problem, parameters );
+            return tnlSolverStarterPreconditionerSetter< Problem, tnlSemiImplicitGMRESSolverTag, MeshConfig >::run( problem, parameters );
+         if( discreteSolver == "tfqmr" )
+            return tnlSolverStarterPreconditionerSetter< Problem, tnlSemiImplicitTFQMRSolverTag, MeshConfig >::run( problem, parameters );
          return false;
       }
 };
@@ -223,9 +235,9 @@ class tnlSolverStarterTimeDiscretisationSetter< Problem, tnlImplicitTimeDiscreti
  */
 
 template< typename Problem,
-          typename ExplicitSolver,
+          typename ExplicitSolverTag,
           typename MeshConfig >
-class tnlSolverStarterExplicitSolverSetter< Problem, ExplicitSolver, MeshConfig, false >
+class tnlSolverStarterExplicitSolverSetter< Problem, ExplicitSolverTag, MeshConfig, false >
 {
    public:
       static bool run( Problem& problem,
@@ -237,32 +249,16 @@ class tnlSolverStarterExplicitSolverSetter< Problem, ExplicitSolver, MeshConfig,
 };
 
 template< typename Problem,
+          typename ExplicitSolverTag,
           typename MeshConfig >
-class tnlSolverStarterExplicitSolverSetter< Problem, tnlExplicitEulerSolverTag, MeshConfig, true >
+class tnlSolverStarterExplicitSolverSetter< Problem, ExplicitSolverTag, MeshConfig, true >
 {
    public:
       static bool run( Problem& problem,
                        const tnlParameterContainer& parameters )
       {
-         typedef tnlExplicitTimeStepper< Problem, tnlEulerSolver > TimeStepper;
-         typedef tnlEulerSolver< TimeStepper > ExplicitSolver;
-         return tnlSolverStarterExplicitTimeStepperSetter< Problem,
-                                                           ExplicitSolver,
-                                                           TimeStepper,
-                                                           MeshConfig >::run( problem, parameters );
-      }
-};
-
-template< typename Problem,
-          typename MeshConfig >
-class tnlSolverStarterExplicitSolverSetter< Problem, tnlExplicitMersonSolverTag, MeshConfig, true >
-{
-   public:
-      static bool run( Problem& problem,
-                       const tnlParameterContainer& parameters )
-      {
-         typedef tnlExplicitTimeStepper< Problem, tnlMersonSolver > TimeStepper;
-         typedef tnlMersonSolver< TimeStepper > ExplicitSolver;
+         typedef tnlExplicitTimeStepper< Problem, ExplicitSolverTag::template Template > TimeStepper;
+         typedef typename ExplicitSolverTag::template Template< TimeStepper > ExplicitSolver;
          return tnlSolverStarterExplicitTimeStepperSetter< Problem,
                                                            ExplicitSolver,
                                                            TimeStepper,
@@ -275,80 +271,56 @@ class tnlSolverStarterExplicitSolverSetter< Problem, tnlExplicitMersonSolverTag,
  */
 
 template< typename Problem,
-          typename SemiImplicitSolver,
+          typename SemiImplicitSolverTag,
           typename MeshConfig >
-class tnlSolverStarterSemiImplicitSolverSetter< Problem, SemiImplicitSolver, MeshConfig, false >
+class tnlSolverStarterPreconditionerSetter
 {
    public:
       static bool run( Problem& problem,
                        const tnlParameterContainer& parameters )
       {
-         cerr << "The semi-implicit solver " << parameters.getParameter< tnlString >( "discrete-solver" ) << " is not supported." << endl;
-         return false;
-      }
-};
+         const tnlString& preconditioner = parameters.getParameter< tnlString>( "preconditioner" );
 
-template< typename Problem,
-          typename MeshConfig >
-class tnlSolverStarterSemiImplicitSolverSetter< Problem, tnlSemiImplicitSORSolverTag, MeshConfig, true >
-{
-   public:
-      static bool run( Problem& problem,
-                       const tnlParameterContainer& parameters )
-      {
-         typedef typename Problem::MatrixType MatrixType;
-         typedef tnlSORSolver< MatrixType > LinearSystemSolver;
-         typedef tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver > TimeStepper;
-         return tnlSolverStarterSemiImplicitTimeStepperSetter< Problem,
-                                                               TimeStepper,
-                                                               MeshConfig >::run( problem, parameters );
-      }
-};
+         if( preconditioner == "none" )
+            return tnlSolverStarterSemiImplicitSolverSetter< Problem, SemiImplicitSolverTag, tnlDummyPreconditioner, MeshConfig >::run( problem, parameters );
+         if( preconditioner == "diagonal" )
+            return tnlSolverStarterSemiImplicitSolverSetter< Problem, SemiImplicitSolverTag, tnlDiagonalPreconditioner, MeshConfig >::run( problem, parameters );
 
-template< typename Problem,
-          typename MeshConfig >
-class tnlSolverStarterSemiImplicitSolverSetter< Problem, tnlSemiImplicitCGSolverTag, MeshConfig, true >
-{
-   public:
-      static bool run( Problem& problem,
-                       const tnlParameterContainer& parameters )
-      {
-         typedef typename Problem::MatrixType MatrixType;
-         typedef tnlCGSolver< MatrixType > LinearSystemSolver;
-         typedef tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver > TimeStepper;
-         return tnlSolverStarterSemiImplicitTimeStepperSetter< Problem,
-                                                               TimeStepper,
-                                                               MeshConfig >::run( problem, parameters );
+         cerr << "Unknown preconditioner " << preconditioner << ". It can be only: none, diagonal." << endl;
+         return false;
       }
 };
 
 template< typename Problem,
+          typename SemiImplicitSolverTag,
+          template<typename, typename, typename> class Preconditioner,
           typename MeshConfig >
-class tnlSolverStarterSemiImplicitSolverSetter< Problem, tnlSemiImplicitBICGStabSolverTag, MeshConfig, true >
+class tnlSolverStarterSemiImplicitSolverSetter< Problem, SemiImplicitSolverTag, Preconditioner, MeshConfig, false >
 {
    public:
       static bool run( Problem& problem,
                        const tnlParameterContainer& parameters )
       {
-         typedef typename Problem::MatrixType MatrixType;
-         typedef tnlBICGStabSolver< MatrixType > LinearSystemSolver;
-         typedef tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver > TimeStepper;
-         return tnlSolverStarterSemiImplicitTimeStepperSetter< Problem,
-                                                               TimeStepper,
-                                                               MeshConfig >::run( problem, parameters );
+         cerr << "The semi-implicit solver " << parameters.getParameter< tnlString >( "discrete-solver" ) << " is not supported." << endl;
+         return false;
       }
 };
 
 template< typename Problem,
+          typename SemiImplicitSolverTag,
+          template<typename, typename, typename> class Preconditioner,
           typename MeshConfig >
-class tnlSolverStarterSemiImplicitSolverSetter< Problem, tnlSemiImplicitGMRESSolverTag, MeshConfig, true >
+class tnlSolverStarterSemiImplicitSolverSetter< Problem, SemiImplicitSolverTag, Preconditioner, MeshConfig, true >
 {
    public:
       static bool run( Problem& problem,
                        const tnlParameterContainer& parameters )
       {
          typedef typename Problem::MatrixType MatrixType;
-         typedef tnlGMRESSolver< MatrixType > LinearSystemSolver;
+         typedef typename MatrixType::RealType RealType;
+         typedef typename MatrixType::DeviceType DeviceType;
+         typedef typename MatrixType::IndexType IndexType;
+         typedef typename SemiImplicitSolverTag::template Template< MatrixType, Preconditioner< RealType, DeviceType, IndexType > > LinearSystemSolver;
          typedef tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver > TimeStepper;
          return tnlSolverStarterSemiImplicitTimeStepperSetter< Problem,
                                                                TimeStepper,
@@ -412,6 +384,7 @@ class tnlSolverStarterSemiImplicitTimeStepperSetter
                        const tnlParameterContainer& parameters)
       {
          typedef typename TimeStepper::LinearSystemSolverType LinearSystemSolverType;
+         typedef typename LinearSystemSolverType::PreconditionerType PreconditionerType;
          typedef typename LinearSystemSolverType::MatrixType MatrixType;
          typedef typename Problem::RealType RealType;
          typedef typename Problem::IndexType IndexType;
diff --git a/tests/benchmarks/tnl-cuda-benchmarks.h b/tests/benchmarks/tnl-cuda-benchmarks.h
index 09993df3fbb2163268180269fca5a73d624f1892..437420c0df4864951fd34e51190073c1adcaaa29 100644
--- a/tests/benchmarks/tnl-cuda-benchmarks.h
+++ b/tests/benchmarks/tnl-cuda-benchmarks.h
@@ -139,24 +139,29 @@ int main( int argc, char* argv[] )
     cout << bandwidth << " GB/sec." << endl;
     */
 
-   Real resultHost, resultDevice;
+   Real resultHost, resultDevice, timeHost, timeDevice;
+
    cout << "Benchmarking scalar product on CPU: ";
    timer.reset();
    timer.start();
    for( int i = 0; i < loops; i++ )
      resultHost = hostVector.scalarProduct( hostVector2 );
    timer.stop();
+   timeHost = timer.getTime();
    bandwidth = 2 * datasetSize / timer.getTime();
-   cout << bandwidth << " GB/sec." << endl;
+   cout << "bandwidth: " << bandwidth << " GB/sec, time: " << timer.getTime() << " sec." << endl;
     
-   cout << "Benchmarking scalar product on GPU: " << endl;
+   cout << "Benchmarking scalar product on GPU: ";
    timer.reset();
    timer.start();
    for( int i = 0; i < loops; i++ )
       resultDevice = deviceVector.scalarProduct( deviceVector2 );
    timer.stop();
+   timeDevice = timer.getTime();
    bandwidth = 2 * datasetSize / timer.getTime();
-   cout << "Time: " << timer.getTime() << " bandwidth: " << bandwidth << " GB/sec." << endl;
+   cout << "bandwidth: " << bandwidth << " GB/sec, time: " << timer.getTime() << " sec." << endl;
+   cout << "CPU/GPU speedup: " << timeHost / timeDevice << endl;
+
    if( resultHost != resultDevice )
    {
       cerr << "Error. " << resultHost << " != " << resultDevice << endl;
@@ -210,24 +215,28 @@ int main( int argc, char* argv[] )
    timer.reset();
    timer.start();
    hostVector.computePrefixSum();
-   cout << "Time: " << timer.getTime() << endl;
    timer.stop();
+   timeHost = timer.getTime();
    bandwidth = 2 * datasetSize / loops / timer.getTime();
-   cout << "Time: " << timer.getTime() << " bandwidth: " << bandwidth << " GB/sec." << endl;
+   cout << "bandwidth: " << bandwidth << " GB/sec, time: " << timer.getTime() << " sec." << endl;
    
-   cout << "Benchmarking prefix-sum on GPU ..." << endl;
+   cout << "Benchmarking prefix-sum on GPU: ";
    timer.reset();
    timer.start();
    deviceVector.computePrefixSum();
-   cout << "Time: " << timer.getTime() << endl;
    timer.stop();
+   timeDevice = timer.getTime();
    bandwidth = 2 * datasetSize / loops / timer.getTime();
-   cout << "Time: " << timer.getTime() << " bandwidth: " << bandwidth << " GB/sec." << endl;
+   cout << "bandwidth: " << bandwidth << " GB/sec, time: " << timer.getTime() << " sec." << endl;
+   cout << "CPU/GPU speedup: " << timeHost / timeDevice << endl;
 
+   HostVector auxHostVector;
+   auxHostVector.setLike( deviceVector );
+   auxHostVector = deviceVector;
    for( int i = 0; i < size; i++ )
-      if( hostVector.getElement( i ) != deviceVector.getElement( i ) )
+      if( hostVector.getElement( i ) != auxHostVector.getElement( i ) )
       {
-         cerr << "Error in prefix sum at position " << i << ":  " << hostVector.getElement( i ) << " != " << deviceVector.getElement( i ) << endl;
+         cerr << "Error in prefix sum at position " << i << ":  " << hostVector.getElement( i ) << " != " << auxHostVector.getElement( i ) << endl;
       }
 */
    /****
diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt
index d3ac6430a934c53876072e1e079823a67eeb2daa..f5ae81cf39e2c2f70e6b78413ad512f12988ab52 100755
--- a/tests/unit-tests/CMakeLists.txt
+++ b/tests/unit-tests/CMakeLists.txt
@@ -1,6 +1,7 @@
 ADD_SUBDIRECTORY( core )
 ADD_SUBDIRECTORY( matrices )
 ADD_SUBDIRECTORY( mesh )
+ADD_SUBDIRECTORY( functions )
 ADD_SUBDIRECTORY( operators )
 ADD_SUBDIRECTORY( solver )
 
@@ -29,7 +30,10 @@ ADD_TEST( mesh/tnlGridTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/tnlGrid
 ADD_TEST( mesh/tnlMeshEntityTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/tnlMeshEntityTest${mpiExt}${debugExt} )
 ADD_TEST( mesh/tnlMeshTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/tnlMeshTest${mpiExt}${debugExt} )
 
+ADD_TEST( functions/tnlOperatorFunctionTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/tnlOperatorFunctionTest${mpiExt}${debugExt} )
+
 ADD_TEST( operators/diffusion/tnlLinearDiffusionTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/tnlLinearDiffusionTest${mpiExt}${debugExt} )
+ADD_TEST( operators/diffusion/tnlFiniteDifferencesTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/tnlFiniteDifferencesTest${mpiExt}${debugExt} )
 
 if( BUILD_CUDA )
    ADD_TEST( core/cuda/tnlCudaTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/tnlCudaTest${mpiExt}${debugExt} )
diff --git a/tests/unit-tests/core/tnlObjectTester.h b/tests/unit-tests/core/tnlObjectTester.h
index 3d99af2d3866389400b6d46c089b1193b85dcaee..dd3812b09d7547688c182f6a677134c43b64cb82 100644
--- a/tests/unit-tests/core/tnlObjectTester.h
+++ b/tests/unit-tests/core/tnlObjectTester.h
@@ -48,10 +48,10 @@ class tnlObjectTester : public CppUnit :: TestCase
 
    void testObjectSave()
    {
-      tnlObject obj( "testing-object" );
+      tnlObject obj;
       tnlFile file;
       file. open( "test-file.tnl", tnlWriteMode );
-      obj. save( file );
+      obj.save( file );
    };
 
 };
diff --git a/tests/unit-tests/functions/CMakeLists.txt b/tests/unit-tests/functions/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b75e61219d1e58505526af6184951c693b3843f9
--- /dev/null
+++ b/tests/unit-tests/functions/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_EXECUTABLE( tnlOperatorFunctionTest${mpiExt}${debugExt} tnlOperatorFunctionTest.cpp )
+TARGET_LINK_LIBRARIES( tnlOperatorFunctionTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                 tnl${mpiExt}${debugExt}-0.1 )
diff --git a/tests/unit-tests/functions/tnlOperatorFunctionTest.cpp b/tests/unit-tests/functions/tnlOperatorFunctionTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..850396cd0b5e51e029a041d0f9671e828c836432
--- /dev/null
+++ b/tests/unit-tests/functions/tnlOperatorFunctionTest.cpp
@@ -0,0 +1,19 @@
+/***************************************************************************
+                          tnlOperatorFunctionTest.cpp  -  description
+                             -------------------
+    begin                : Feb 11, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlOperatorFunctionTest.h"
+
diff --git a/tests/unit-tests/functions/tnlOperatorFunctionTest.h b/tests/unit-tests/functions/tnlOperatorFunctionTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea98605deab17b60e74396cce7368cd1078f04ce
--- /dev/null
+++ b/tests/unit-tests/functions/tnlOperatorFunctionTest.h
@@ -0,0 +1,155 @@
+/***************************************************************************
+                          tnlOperatorFunctionTest.h  -  description
+                             -------------------
+    begin                : Feb 11, 2016
+    copyright            : (C) 2016 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 TNLOPERATORFUNCTIONTEST_H
+#define	TNLOPERATORFUNCTIONTEST_H
+
+#include <functions/tnlOperatorFunction.h>
+#include <mesh/tnlGrid.h>
+#include <functions/tnlExpBumpFunction.h>
+#include <operators/diffusion/tnlLinearDiffusion.h>
+#include <operators/tnlDirichletBoundaryConditions.h>
+#include "../tnlUnitTestStarter.h"
+
+#ifdef HAVE_CPPUNIT
+#include <cppunit/TestSuite.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestCaller.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/Message.h>
+
+
+template< typename Operator,
+          bool EvaluateOnFly >
+class tnlOperatorFunctionTest
+   : public CppUnit::TestCase
+{
+   public:
+   typedef tnlOperatorFunctionTest< Operator, EvaluateOnFly > TesterType;
+   typedef typename CppUnit::TestCaller< TesterType > TestCallerType;
+   typedef Operator OperatorType;
+   typedef typename OperatorType::MeshType MeshType;
+   typedef typename OperatorType::RealType RealType;
+   typedef typename OperatorType::IndexType IndexType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef typename MeshType::VertexType VertexType;
+   typedef tnlExpBumpFunction< MeshType::getMeshDimensions(), RealType > TestFunctionType;
+   typedef tnlMeshFunction< MeshType, MeshType::getMeshDimensions() > MeshFunctionType;   
+
+   tnlOperatorFunctionTest(){};
+
+   virtual
+   ~tnlOperatorFunctionTest(){};
+
+   static CppUnit::Test* suite()
+   {
+      CppUnit::TestSuite* suiteOfTests = new CppUnit :: TestSuite( "tnlOperatorFunctionTest" );
+      CppUnit::TestResult result;
+
+      suiteOfTests -> addTest( new TestCallerType( "testWithNoBoundaryConditions", &TesterType::testWithNoBoundaryConditions ) );
+      suiteOfTests -> addTest( new TestCallerType( "testWithBoundaryConditions", &TesterType::testWithBoundaryConditions ) );
+      return suiteOfTests;
+   }
+   
+   void testWithNoBoundaryConditions()
+   {
+      MeshType mesh;
+      typedef tnlOperatorFunction< Operator, MeshFunctionType, void, EvaluateOnFly > OperatorFunctionType;
+      mesh.setDimensions( CoordinatesType( 25 ) );
+      mesh.setDomain( VertexType( -1.0 ), VertexType( 2.0 ) );
+      TestFunctionType testFunction;
+      testFunction.setAmplitude( 1.0 );
+      testFunction.setSigma( 1.0 );
+      MeshFunctionType f1( mesh );
+      f1 = testFunction;
+      OperatorType operator_;
+      OperatorFunctionType operatorFunction( operator_, f1 );
+      operatorFunction.refresh();
+      //cerr << f1.getData() << endl;
+      for( IndexType i = 0; i < mesh.template getEntitiesCount< typename MeshType::Cell >(); i++ )
+      {
+         auto entity = mesh.template getEntity< typename MeshType::Cell >( i );
+         entity.refresh();
+         
+         if( ! entity.isBoundaryEntity() )
+         {
+            //cerr << entity.getIndex() << " " << operator_( f1, entity ) << " " << operatorFunction( entity ) << endl;
+            CPPUNIT_ASSERT( operator_( f1, entity ) == operatorFunction( entity ) );
+         }
+      }            
+   }
+   
+   void testWithBoundaryConditions()
+   {
+      MeshType mesh;
+      typedef tnlDirichletBoundaryConditions< MeshType > BoundaryConditionsType;
+      typedef tnlOperatorFunction< Operator, MeshFunctionType, BoundaryConditionsType, EvaluateOnFly > OperatorFunctionType;
+      mesh.setDimensions( CoordinatesType( 25 ) );
+      mesh.setDomain( VertexType( -1.0 ), VertexType( 2.0 ) );
+      TestFunctionType testFunction;
+      testFunction.setAmplitude( 1.0 );
+      testFunction.setSigma( 1.0 );      
+      MeshFunctionType f1( mesh );
+      f1 = testFunction;
+      OperatorType operator_;
+      BoundaryConditionsType boundaryConditions;      
+      OperatorFunctionType operatorFunction( operator_, boundaryConditions, f1 );
+      operatorFunction.refresh();
+      //cerr << f1.getData() << endl;
+      for( IndexType i = 0; i < mesh.template getEntitiesCount< typename MeshType::Cell >(); i++ )
+      {
+         auto entity = mesh.template getEntity< typename MeshType::Cell >( i );
+         entity.refresh();
+         if( entity.isBoundaryEntity() )
+            CPPUNIT_ASSERT( boundaryConditions( f1, entity ) == operatorFunction( entity ) );
+         else
+         {
+            //cerr << entity.getIndex() << " " << operator_( f1, entity ) << " " << operatorFunction( entity ) << endl;
+            CPPUNIT_ASSERT( operator_( f1, entity ) == operatorFunction( entity ) );
+         }
+      }            
+   }   
+};
+#endif
+   
+template< typename MeshType >
+bool runTest()
+{
+#ifdef HAVE_CPPUNIT
+   typedef tnlLinearDiffusion< MeshType > OperatorType;
+   tnlOperatorFunctionTest< OperatorType, false > test;
+   //test.testWithBoundaryConditions();
+   if( //! tnlUnitTestStarter::run< tnlOperatorFunctionTest< OperatorType, true > >() ||
+       ! tnlUnitTestStarter::run< tnlOperatorFunctionTest< OperatorType, false > >() )
+     return false;
+   return true;
+#else
+   return false;
+#endif        
+}
+
+int main( int argc, char* argv[] )
+{
+   if( ! runTest< tnlGrid< 1, double, tnlHost, int > >() ||
+       ! runTest< tnlGrid< 2, double, tnlHost, int > >() ||
+       ! runTest< tnlGrid< 3, double, tnlHost, int > >() )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
+#endif	/* TNLOPERATORFUNCTIONTEST_H */
+
diff --git a/tests/unit-tests/mesh/tnlGrid2DTester.h b/tests/unit-tests/mesh/tnlGrid2DTester.h
index 382f161b23bfbdbd06b3850e77362eea42150a93..da9bcfc652455084d2652962374967f09c189db1 100644
--- a/tests/unit-tests/mesh/tnlGrid2DTester.h
+++ b/tests/unit-tests/mesh/tnlGrid2DTester.h
@@ -88,7 +88,7 @@ class tnlGridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCas
       GridType grid;      
       grid.setDimensions( xSize, ySize );
 
-      typedef typename GridType::template GridEntity< 1 > FaceType;
+      typedef typename GridType::template MeshEntity< 1 > FaceType;
       typedef typename FaceType::EntityOrientationType OrientationType;
       typedef typename FaceType::EntityBasisType BasisType;
       FaceType face( grid );
@@ -135,7 +135,7 @@ class tnlGridTester< 2, RealType, Device, IndexType >: public CppUnit :: TestCas
       const IndexType ySize( 17 );
       GridType grid;
       
-      typedef typename GridType::template GridEntity< 0 > VertexType;
+      typedef typename GridType::template MeshEntity< 0 > VertexType;
       typedef typename VertexType::EntityBasisType BasisType;
       VertexType vertex( grid );
       
diff --git a/tests/unit-tests/mesh/tnlGrid3DTester.h b/tests/unit-tests/mesh/tnlGrid3DTester.h
index b5672cf822f6c33eb30cc3f419ace70e84bdea64..6f76eb78ea4d43ff91520b91b23134be23e1ddbe 100644
--- a/tests/unit-tests/mesh/tnlGrid3DTester.h
+++ b/tests/unit-tests/mesh/tnlGrid3DTester.h
@@ -96,7 +96,7 @@ class tnlGridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCas
       GridType grid;
       grid.setDimensions( xSize, ySize, zSize );
             
-      typedef typename GridType::template GridEntity< 2 > FaceType;
+      typedef typename GridType::template MeshEntity< 2 > FaceType;
       typedef typename FaceType::EntityOrientationType OrientationType;
       typedef typename FaceType::EntityBasisType BasisType;
       FaceType face( grid );
@@ -172,7 +172,7 @@ class tnlGridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCas
       GridType grid;
       grid.setDimensions( xSize, ySize, zSize );
       
-      typedef typename GridType::template GridEntity< 1 > EdgeType;
+      typedef typename GridType::template MeshEntity< 1 > EdgeType;
       typedef typename EdgeType::EntityOrientationType OrientationType;
       typedef typename EdgeType::EntityBasisType BasisType;
       EdgeType edge( grid );
@@ -246,7 +246,7 @@ class tnlGridTester< 3, RealType, Device, IndexType >: public CppUnit :: TestCas
       GridType grid;
       grid.setDimensions( xSize, ySize, zSize );
       
-      typedef typename GridType::template GridEntity< 0 > VertexType;
+      typedef typename GridType::template MeshEntity< 0 > VertexType;
       typedef typename VertexType::EntityOrientationType OrientationType;
       typedef typename VertexType::EntityBasisType BasisType;
       VertexType vertex( grid );
diff --git a/tests/unit-tests/operators/CMakeLists.txt b/tests/unit-tests/operators/CMakeLists.txt
index 14abfb096e414dbf6f49fc4365f59ed6127b3855..516c67d0188920ea675b81868c6426a5b166a23d 100755
--- a/tests/unit-tests/operators/CMakeLists.txt
+++ b/tests/unit-tests/operators/CMakeLists.txt
@@ -1 +1,7 @@
 ADD_SUBDIRECTORY( diffusion )
+ADD_SUBDIRECTORY( fdm )
+ADD_SUBDIRECTORY( geometric )
+
+ADD_EXECUTABLE( tnlOperatorCompositionTest${mpiExt}${debugExt} tnlOperatorCompositionTest.cpp )
+TARGET_LINK_LIBRARIES( tnlOperatorCompositionTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                 tnl${mpiExt}${debugExt}-0.1 )
\ No newline at end of file
diff --git a/tests/unit-tests/operators/diffusion/CMakeLists.txt b/tests/unit-tests/operators/diffusion/CMakeLists.txt
old mode 100755
new mode 100644
index 85fef4eaaf8ec59fb0856aceb3d71f7a897bb794..44d626a4946483be0ff93bf76fb8515ef02e701c
--- a/tests/unit-tests/operators/diffusion/CMakeLists.txt
+++ b/tests/unit-tests/operators/diffusion/CMakeLists.txt
@@ -1,11 +1,20 @@
 ADD_EXECUTABLE( tnlLinearDiffusionTest${mpiExt}${debugExt} tnlLinearDiffusionTest.cpp )
 TARGET_LINK_LIBRARIES( tnlLinearDiffusionTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                  tnl${mpiExt}${debugExt}-0.1 )
+ADD_EXECUTABLE( tnlOneSidedMeanCurvatureTest${mpiExt}${debugExt} tnlOneSidedMeanCurvatureTest.cpp )
+TARGET_LINK_LIBRARIES( tnlOneSidedMeanCurvatureTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                             tnl${mpiExt}${debugExt}-0.1 )
+
 
 if( BUILD_CUDA )                                                           
    CUDA_ADD_EXECUTABLE( tnlLinearDiffusionTest-cuda${mpiExt}${debugExt} ${headers} tnlLinearDiffusionTest.cu
                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
    TARGET_LINK_LIBRARIES( tnlLinearDiffusionTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                           tnl${mpiExt}${debugExt}-0.1 )
+   CUDA_ADD_EXECUTABLE( tnlOneSidedMeanCurvatureTest-cuda${mpiExt}${debugExt} ${headers} tnlOneSidedMeanCurvatureTest.cu
+                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   TARGET_LINK_LIBRARIES( tnlOneSidedMeanCurvatureTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                          tnl${mpiExt}${debugExt}-0.1 )
+
 endif()                                                                      
 
diff --git a/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cpp b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cpp
index 687e485c2a8da7798dae95f3f253229d4a5a18d3..dc456b3092abddfb62c35b0ef81ec555738b3077 100644
--- a/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cpp
+++ b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cpp
@@ -15,94 +15,4 @@
  *                                                                         *
  ***************************************************************************/
 
-#include <tnlConfig.h>
-#include <core/tnlHost.h>
-#include <cstdlib>
-
-#include "../tnlPDEOperatorEocTester.h"
-#include "../../tnlUnitTestStarter.h"
-#include <mesh/tnlGrid.h>
-#include <operators/diffusion/tnlLinearDiffusion.h>
-#include <operators/diffusion/tnlExactLinearDiffusion.h>
-#include "../tnlPDEOperatorEocTestResult.h"
-#include <functions/tnlExpBumpFunction.h>
-
-template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index,
-          typename TestFunction,
-          typename ApproximationMethod >
-class tnlPDEOperatorEocTestResult< tnlLinearDiffusion< tnlGrid< Dimensions, Real, Device, Index >, Real, Index >,
-                                   ApproximationMethod,
-                                   TestFunction >
-{
-   public:
-      static Real getL1Eoc() { return ( Real ) 2.0; };
-      static Real getL1Tolerance() { return ( Real ) 0.05; };
-
-      static Real getL2Eoc() { return ( Real ) 2.0; };
-      static Real getL2Tolerance() { return ( Real ) 0.05; };
-
-      static Real getMaxEoc() { return ( Real ) 2.0; };
-      static Real getMaxTolerance() { return ( Real ) 0.05; };
-
-};
-
-int main( int argc, char* argv[] )
-{
-   const bool verbose( false );
-   const int MeshSize( 32 );
-#ifdef HAVE_CPPUNIT
-   /****
-    * Explicit approximation
-    */
-   if( ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 1, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 1 >,
-                                                             tnlExpBumpFunction< 1, double >,
-                                                             tnlExplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >() ||
-       ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 2, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 2 >,
-                                                             tnlExpBumpFunction< 2, double >,
-                                                             tnlExplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >() ||
-       ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 3, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 3 >,
-                                                             tnlExpBumpFunction< 3, double >,
-                                                             tnlExplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >()
-                                                              )
-      return EXIT_FAILURE;
-   /****
-    * Implicit (matrix) approximation
-    */
-   if( ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 1, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 1 >,
-                                                             tnlExpBumpFunction< 1, double >,
-                                                             tnlImplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >() ||
-       ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 2, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 2 >,
-                                                             tnlExpBumpFunction< 2, double >,
-                                                             tnlImplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >() ||
-       ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 3, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 3 >,
-                                                             tnlExpBumpFunction< 3, double >,
-                                                             tnlImplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >()
-       )
-     return EXIT_FAILURE;
-   return EXIT_SUCCESS;
-#else
-   return EXIT_FAILURE;
-#endif
-}
-
+#include "tnlLinearDiffusionTest.h"
diff --git a/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cu b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cu
index 912bd9214cddb49e63db55f8a16900751435a1b5..dd44de3206c2d417ab16485313dfa55be33188e3 100644
--- a/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cu
+++ b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cu
@@ -15,94 +15,4 @@
  *                                                                         *
  ***************************************************************************/
 
-#include <tnlConfig.h>
-#include <core/tnlHost.h>
-#include <cstdlib>
-
-#include "../tnlPDEOperatorEocTester.h"
-#include "../../tnlUnitTestStarter.h"
-#include <mesh/tnlGrid.h>
-#include <operators/diffusion/tnlLinearDiffusion.h>
-#include <operators/diffusion/tnlExactLinearDiffusion.h>
-#include "../tnlPDEOperatorEocTestResult.h"
-#include <functions/tnlExpBumpFunction.h>
-
-template< int Dimensions,
-          typename Real,
-          typename Device,
-          typename Index,
-          typename TestFunction,
-          typename ApproximationMethod >
-class tnlPDEOperatorEocTestResult< tnlLinearDiffusion< tnlGrid< Dimensions, Real, Device, Index >, Real, Index >,
-                                   ApproximationMethod,
-                                   TestFunction >
-{
-   public:
-      static Real getL1Eoc() { return ( Real ) 2.0; };
-      static Real getL1Tolerance() { return ( Real ) 0.05; };
-
-      static Real getL2Eoc() { return ( Real ) 2.0; };
-      static Real getL2Tolerance() { return ( Real ) 0.05; };
-
-      static Real getMaxEoc() { return ( Real ) 2.0; };
-      static Real getMaxTolerance() { return ( Real ) 0.05; };
-
-};
-
-int main( int argc, char* argv[] )
-{
-#ifdef HAVE_CPPUNIT
-   const bool verbose( true );
-   const int MeshSize( 64 );
-   /****
-    * Explicit approximation
-    */
-   if( ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 1, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 1 >,
-                                                             tnlExpBumpFunction< 1, double >,
-                                                             tnlExplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >()
-       /*! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 2, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 2 >,
-                                                             tnlExpBumpFunction< 2, double >,
-                                                             tnlExplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >() ||
-       ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 3, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 3 >,
-                                                             tnlExpBumpFunction< 3, double >,
-                                                             tnlExplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >() */
-                                                              );
-      //return EXIT_FAILURE;
-   /****
-    * Implicit (matrix) approximation
-    */
-   if( ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 1, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 1 >,
-                                                             tnlExpBumpFunction< 1, double >,
-                                                             tnlImplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >()
-       /*! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 2, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 2 >,
-                                                             tnlExpBumpFunction< 2, double >,
-                                                             tnlImplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >() ||
-       ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 3, double, tnlHost, int >, double, int >,
-                                                             tnlExactLinearDiffusion< 3 >,
-                                                             tnlExpBumpFunction< 3, double >,
-                                                             tnlImplicitApproximation,
-                                                             MeshSize,
-                                                             verbose > >() */
-       )
-     return EXIT_FAILURE;
-   return EXIT_SUCCESS;
-#else
-   return EXIT_FAILURE;
-#endif
-}
-
+#include "tnlLinearDiffusionTest.h"
diff --git a/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.h b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..663c0a9d9e5f8314bb464cd514ccc08e4b01d667
--- /dev/null
+++ b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.h
@@ -0,0 +1,139 @@
+/***************************************************************************
+                          tnlLinearDiffusionTest.h  -  description
+                             -------------------
+    begin                : Feb 1, 2016
+    copyright            : (C) 2016 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 TNLLINEARDIFFUSIONTEST_H
+#define	TNLLINEARDIFFUSIONTEST_H
+
+#include <operators/diffusion/tnlLinearDiffusion.h>
+#include <operators/diffusion/tnlExactLinearDiffusion.h>
+#include <mesh/tnlGrid.h>
+#include "../tnlPDEOperatorEocUnitTest.h"
+#include "../tnlPDEOperatorEocTest.h"
+#include "../../tnlUnitTestStarter.h"
+
+template< typename ApproximateOperator,
+          typename TestFunction,
+          bool write = false,
+          bool verbose = false >
+class tnlLinearDiffusionTest
+   : public tnlPDEOperatorEocTest< ApproximateOperator, TestFunction > 
+{
+   public:
+      
+      typedef ApproximateOperator ApproximateOperatorType;
+      typedef typename ApproximateOperator::ExactOperatorType ExactOperatorType;
+      typedef typename ApproximateOperator::MeshType MeshType;
+      typedef typename ApproximateOperator::RealType RealType;
+      typedef typename ApproximateOperator::IndexType IndexType;
+      
+      const IndexType coarseMeshSize[ 3 ] = { 1024, 256, 64 };
+      
+      const RealType  eoc[ 3 ] =       { 2.0,  2.0,  2.0 };
+      const RealType  tolerance[ 3 ] = { 0.05, 0.05, 0.05 };      
+   
+      static tnlString getType()
+      { 
+         return tnlString( "tnlLinearDiffusionTest< " ) + 
+                ApproximateOperator::getType() + ", " +
+                TestFunction::getType() + " >";
+      }
+      
+      void setupTest()
+      {
+         this->setupFunction();
+      }
+            
+      void getApproximationError( const IndexType meshSize,
+                                  RealType errors[ 3 ] )
+      {
+         this->setupMesh( meshSize );
+         this->performTest( this->approximateOperator,
+                            this->exactOperator,
+                            errors,
+                            write,
+                            verbose );
+
+      }
+      
+      void runUnitTest()
+      {  
+         RealType coarseErrors[ 3 ], fineErrors[ 3 ];
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->checkEoc( coarseErrors, fineErrors, eoc, tolerance, verbose );                            
+      }
+      
+   protected:
+
+      ApproximateOperator approximateOperator;
+      
+      ExactOperatorType exactOperator;
+
+};
+
+
+template< typename Mesh,
+          typename Function,
+          bool write,
+          bool verbose >
+bool runTest()
+{
+   typedef tnlLinearDiffusion< Mesh > ApproximateOperator;
+   typedef tnlLinearDiffusionTest< ApproximateOperator, Function, write, verbose > OperatorTest;
+#ifdef HAVE_CPPUNIT   
+   if( ! tnlUnitTestStarter::run< tnlPDEOperatorEocUnitTest< OperatorTest > >() )
+      return false;
+   return true;
+#else
+   return false;
+#endif      
+}
+
+template< typename Mesh,
+          bool write,
+          bool verbose >
+bool setTestFunction()
+{
+   return runTest< Mesh, tnlExpBumpFunction< Mesh::getMeshDimensions(), double >, write, verbose >();
+}
+
+template< typename Device,
+          bool write,
+          bool verbose >
+bool setMesh()
+{
+   return ( setTestFunction< tnlGrid< 1, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 2, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 3, double, Device, int >, write, verbose >() );
+}
+
+int main( int argc, char* argv[] )
+{
+   const bool verbose( false );
+   const bool write( false );
+   
+   if( ! setMesh< tnlHost, write, verbose  >() )
+      return EXIT_FAILURE;
+#ifdef HAVE_CUDA
+   if( ! setMesh< tnlCuda, write, verbose >() )
+      return EXIT_FAILURE;
+#endif   
+   return EXIT_SUCCESS;
+}
+
+#endif	/* TNLLINEARDIFFUSIONTEST_H */
+
diff --git a/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.cpp b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..526154ab4962dd34f07b301d20ffbfc3ab5f6683
--- /dev/null
+++ b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.cpp
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnlOneSidedMeanCurvatureTest.cpp  -  description
+                             -------------------
+    begin                : Jan 16, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlOneSidedMeanCurvatureTest.h"
diff --git a/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.cu b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.cu
new file mode 100644
index 0000000000000000000000000000000000000000..823198441ab0efb5891751667c5c3ed598a706fc
--- /dev/null
+++ b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.cu
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnlOneSidedMeanCurvatureTest.cu  -  description
+                             -------------------
+    begin                : Nov 15, 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlOneSidedMeanCurvatureTest.h"
diff --git a/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a82fed0f79fba18745cc8b8ecb40beaae0bac6b
--- /dev/null
+++ b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h
@@ -0,0 +1,143 @@
+/***************************************************************************
+                          tnlOneSidedMeanCurvatureTest.h  -  description
+                             -------------------
+    begin                : Feb 1, 2016
+    copyright            : (C) 2016 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 TNLMEANCURVATURETEST_H
+#define	TNLMEANCURVATURETEST_H
+
+#include <operators/diffusion/tnlOneSidedMeanCurvature.h>
+#include <operators/diffusion/tnlExactLinearDiffusion.h>
+#include <mesh/tnlGrid.h>
+#include "../tnlPDEOperatorEocUnitTest.h"
+#include "../tnlPDEOperatorEocTest.h"
+#include "../../tnlUnitTestStarter.h"
+
+template< typename ApproximateOperator,
+          typename TestFunction,
+          bool write = false,
+          bool verbose = false >
+class tnlOneSidedMeanCurvatureTest
+   : public tnlPDEOperatorEocTest< ApproximateOperator, TestFunction > 
+{
+   public:
+      
+      typedef ApproximateOperator ApproximateOperatorType;
+      typedef typename ApproximateOperatorType::ExactOperatorType ExactOperatorType;
+      typedef typename ApproximateOperator::MeshType MeshType;
+      typedef typename ApproximateOperator::RealType RealType;
+      typedef typename ApproximateOperator::IndexType IndexType;   
+      
+      const IndexType coarseMeshSize[ 3 ] = { 1024, 256, 64 };
+      
+      const RealType  eoc[ 3 ] =       { 2.0,  2.0,  2.0 };
+      const RealType  tolerance[ 3 ] = { 0.05, 0.05, 0.05 };
+      
+      tnlOneSidedMeanCurvatureTest(){};
+   
+      static tnlString getType()
+      { 
+         return tnlString( "tnlOneSidedMeanCurvatureTest< " ) + 
+                ApproximateOperator::getType() + ", " +
+                TestFunction::getType() + " >";
+      }
+      
+      void setupTest()
+      {
+         this->setupFunction();
+      }
+            
+      void getApproximationError( const IndexType meshSize,
+                                  RealType errors[ 3 ] )
+      {
+         this->setupMesh( meshSize );
+         ApproximateOperator approximateOperator( this->mesh );
+         ExactOperatorType exactOperator;
+         this->performTest( approximateOperator,
+                            exactOperator,
+                            errors,
+                            write,
+                            verbose );
+
+      }
+      
+      void runUnitTest()
+      {  
+         RealType coarseErrors[ 3 ], fineErrors[ 3 ];
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->checkEoc( coarseErrors, fineErrors, eoc, tolerance, verbose );                            
+      }
+      
+   protected:
+
+      
+
+};
+
+
+template< typename Mesh,
+          typename Function,
+          bool write,
+          bool verbose >
+bool runTest()
+{
+   typedef tnlOneSidedMeanCurvature< Mesh > ApproximateOperator;
+   typedef tnlOneSidedMeanCurvatureTest< ApproximateOperator, Function, write, verbose > OperatorTest;
+   OperatorTest test;
+   test.runUnitTest();
+#ifdef HAVE_CPPUNIT   
+   if( ! tnlUnitTestStarter::run< tnlPDEOperatorEocUnitTest< OperatorTest > >() )
+      return false;
+   return true;
+#else
+   return false;   
+#endif      
+}
+
+template< typename Mesh,
+          bool write,
+          bool verbose >
+bool setTestFunction()
+{
+   return runTest< Mesh, tnlExpBumpFunction< Mesh::getMeshDimensions(), double >, write, verbose >();
+}
+
+template< typename Device,
+          bool write,
+          bool verbose >
+bool setMesh()
+{
+   return ( setTestFunction< tnlGrid< 1, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 2, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 3, double, Device, int >, write, verbose >() );
+}
+
+int main( int argc, char* argv[] )
+{
+   const bool verbose( true );
+   const bool write( false );
+   
+   if( ! setMesh< tnlHost, write, verbose  >() )
+      return EXIT_FAILURE;
+#ifdef HAVE_CUDA
+   if( ! setMesh< tnlCuda, write, verbose >() )
+      return EXIT_FAILURE;
+#endif   
+   return EXIT_SUCCESS;
+}
+
+#endif	/* TNLMEANCURVATURETEST_H */
+
diff --git a/tests/unit-tests/operators/fdm/CMakeLists.txt b/tests/unit-tests/operators/fdm/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..a85d068b485abd21f1c29e27746c722684d9929e
--- /dev/null
+++ b/tests/unit-tests/operators/fdm/CMakeLists.txt
@@ -0,0 +1,11 @@
+ADD_EXECUTABLE( tnlFiniteDifferencesTest${mpiExt}${debugExt} tnlFiniteDifferencesTest.cpp )
+TARGET_LINK_LIBRARIES( tnlFiniteDifferencesTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                 tnl${mpiExt}${debugExt}-0.1 )
+
+if( BUILD_CUDA )                                                           
+   CUDA_ADD_EXECUTABLE( tnlFiniteDifferencesTest-cuda${mpiExt}${debugExt} ${headers} tnlFiniteDifferencesTest.cu
+                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   TARGET_LINK_LIBRARIES( tnlFiniteDifferencesTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                          tnl${mpiExt}${debugExt}-0.1 )
+endif()                                                                      
+
diff --git a/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.cpp b/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7649c3a4ace53c322306fd61becdcea7041743d2
--- /dev/null
+++ b/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.cpp
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnlFiniteDifferencesTest.cpp  -  description
+                             -------------------
+    begin                : Jan 12, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlFiniteDifferencesTest.h"
diff --git a/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.cu b/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.cu
new file mode 100644
index 0000000000000000000000000000000000000000..f4c526d729f3d15f16b270391378f42a06cb1023
--- /dev/null
+++ b/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.cu
@@ -0,0 +1,20 @@
+/***************************************************************************
+                          tnlFiniteDifferencesTest.cu  -  description
+                             -------------------
+    begin                : Jan 12, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlFiniteDifferencesTest.h"
+
+
diff --git a/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.h b/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b94f99f8ab4b6bd87e27f54db204ca9aac0fa5b
--- /dev/null
+++ b/tests/unit-tests/operators/fdm/tnlFiniteDifferencesTest.h
@@ -0,0 +1,221 @@
+/***************************************************************************
+                          tnlFiniteDifferencesTest.h  -  description
+                             -------------------
+    begin                : Jan 12, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include <tnlConfig.h>
+#include <core/tnlHost.h>
+#include <cstdlib>
+
+#include "../tnlPDEOperatorEocTest.h"
+#include "../tnlPDEOperatorEocUnitTest.h"
+#include "../../tnlUnitTestStarter.h"
+#include <mesh/tnlGrid.h>
+#include <operators/fdm/tnlBackwardFiniteDifference.h>
+#include <operators/fdm/tnlForwardFiniteDifference.h>
+#include <operators/fdm/tnlCentralFiniteDifference.h>
+#include <operators/fdm/tnlExactDifference.h>
+#include "../tnlPDEOperatorEocTestResult.h"
+#include <functions/tnlExpBumpFunction.h>
+
+template< typename ApproximateOperator >
+class tnlFinitDifferenceEocTestResults
+{
+   public:
+        
+      typedef typename ApproximateOperator::RealType RealType;
+      
+      const RealType  eoc[ 3 ] =       { 1.0,  1.0,  1.0 };
+      const RealType  tolerance[ 3 ] = { 0.05, 0.05, 0.05 };      
+
+};
+
+template< typename MeshType,
+          typename RealType,
+          int XDifference,
+          int YDifference,
+          int ZDifference,
+          typename IndexType >
+class tnlFinitDifferenceEocTestResults< tnlCentralFiniteDifference< MeshType, XDifference, YDifference, ZDifference, RealType, IndexType > >
+{
+   public:
+      
+      const RealType  eoc[ 3 ] =       { 2.0,  2.0,  2.0 };
+      const RealType  tolerance[ 3 ] = { 0.05, 0.05, 0.05 };         
+};
+
+template< typename ApproximateOperator,
+          typename TestFunction,
+          bool write = false,
+          bool verbose = false >
+class tnlFiniteDifferenceTest
+   : public tnlPDEOperatorEocTest< ApproximateOperator, TestFunction >,
+     public tnlFinitDifferenceEocTestResults< ApproximateOperator >
+{
+   public:
+      
+      typedef ApproximateOperator ApproximateOperatorType;
+      typedef typename ApproximateOperatorType::ExactOperatorType ExactOperatorType;
+      typedef typename ApproximateOperator::MeshType MeshType;
+      typedef typename ApproximateOperator::RealType RealType;
+      typedef typename ApproximateOperator::IndexType IndexType;
+      
+      const IndexType coarseMeshSize[ 3 ] = { 1024, 256, 64 };
+      
+   
+      static tnlString getType()
+      { 
+         return tnlString( "tnlLinearDiffusionTest< " ) + 
+                ApproximateOperator::getType() + ", " +
+                TestFunction::getType() + " >";
+      }
+      
+      void setupTest()
+      {
+         this->setupFunction();
+      }
+            
+      void getApproximationError( const IndexType meshSize,
+                                  RealType errors[ 3 ] )
+      {
+         this->setupMesh( meshSize );
+         this->performTest( this->approximateOperator,
+                            this->exactOperator,
+                            errors,
+                            write,
+                            verbose );
+
+      }
+      
+      void runUnitTest()
+      {  
+         RealType coarseErrors[ 3 ], fineErrors[ 3 ];
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->checkEoc( coarseErrors, fineErrors, this->eoc, this->tolerance, verbose );                            
+      }
+      
+   protected:
+
+      ApproximateOperator approximateOperator;
+      
+      ExactOperatorType exactOperator;
+
+};
+
+
+template< typename FiniteDifferenceOperator,
+          typename Function,
+          bool write,
+          bool verbose >
+bool testFiniteDifferenceOperator()
+{
+    typedef tnlFiniteDifferenceTest< FiniteDifferenceOperator, Function, write, verbose > OperatorTest;
+#ifdef HAVE_CPPUNIT   
+   if( ! tnlUnitTestStarter::run< tnlPDEOperatorEocUnitTest< OperatorTest > >() )
+      return false;
+   return true;
+#endif      
+    
+}
+
+template< typename Mesh,
+          typename Function,
+          typename RealType,
+          typename IndexType,
+          int XDifference,
+          int YDifference,
+          int ZDifference,
+          int MeshSize,
+          bool WriteFunctions,
+          bool Verbose >
+bool setFiniteDifferenceOperator()
+{
+    typedef tnlForwardFiniteDifference< Mesh, XDifference, YDifference, ZDifference, RealType, IndexType > ForwardFiniteDifference;
+    typedef tnlBackwardFiniteDifference< Mesh, XDifference, YDifference, ZDifference, RealType, IndexType > BackwardFiniteDifference;
+    typedef tnlCentralFiniteDifference< Mesh, XDifference, YDifference, ZDifference, RealType, IndexType > CentralFiniteDifference;
+    
+    if( XDifference < 2 && YDifference < 2 && ZDifference < 2 )
+      return ( testFiniteDifferenceOperator< ForwardFiniteDifference, Function, WriteFunctions, Verbose >() &&
+               testFiniteDifferenceOperator< BackwardFiniteDifference, Function, WriteFunctions, Verbose >() &&
+               testFiniteDifferenceOperator< CentralFiniteDifference, Function, WriteFunctions, Verbose >() );
+    else
+      return ( testFiniteDifferenceOperator< CentralFiniteDifference, Function, WriteFunctions, Verbose >() );
+}
+
+template< typename Mesh,
+          typename RealType,
+          typename IndexType,
+          int XDifference,
+          int YDifference,
+          int ZDifference,        
+          int MeshSize,
+          bool WriteFunctions,
+          bool Verbose >
+bool setFunction()
+{
+    const int Dimensions = Mesh::meshDimensions;
+    typedef tnlExpBumpFunction< Dimensions, RealType >  Function;
+    return setFiniteDifferenceOperator< Mesh, Function, RealType, IndexType, XDifference, YDifference, ZDifference, MeshSize, WriteFunctions, Verbose  >();
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename RealType,
+          typename IndexType,
+          int MeshSize,
+          bool WriteFunctions,
+          bool Verbose >
+bool setDifferenceOrder()
+{
+    typedef tnlGrid< 1, MeshReal, Device, MeshIndex > Grid1D;
+    typedef tnlGrid< 2, MeshReal, Device, MeshIndex > Grid2D;
+    typedef tnlGrid< 3, MeshReal, Device, MeshIndex > Grid3D;
+    return ( setFunction< Grid1D, RealType, IndexType, 1, 0, 0, MeshSize, WriteFunctions, Verbose >() &&
+             setFunction< Grid1D, RealType, IndexType, 2, 0, 0, MeshSize, WriteFunctions, Verbose >() &&
+             setFunction< Grid2D, RealType, IndexType, 1, 0, 0, MeshSize, WriteFunctions, Verbose >() &&
+             setFunction< Grid2D, RealType, IndexType, 0, 1, 0, MeshSize, WriteFunctions, Verbose >() &&
+             setFunction< Grid2D, RealType, IndexType, 2, 0, 0, MeshSize, WriteFunctions, Verbose >() &&            
+             setFunction< Grid2D, RealType, IndexType, 0, 2, 0, MeshSize, WriteFunctions, Verbose >() &&
+             setFunction< Grid3D, RealType, IndexType, 1, 0, 0, MeshSize, WriteFunctions, Verbose >() &&             
+             setFunction< Grid3D, RealType, IndexType, 0, 1, 0, MeshSize, WriteFunctions, Verbose >() &&
+             setFunction< Grid3D, RealType, IndexType, 0, 0, 1, MeshSize, WriteFunctions, Verbose >() &&
+             setFunction< Grid3D, RealType, IndexType, 2, 0, 0, MeshSize, WriteFunctions, Verbose >() &&
+             setFunction< Grid3D, RealType, IndexType, 0, 2, 0, MeshSize, WriteFunctions, Verbose >() &&             
+             setFunction< Grid3D, RealType, IndexType, 0, 0, 2, MeshSize, WriteFunctions, Verbose >() );            
+}
+
+bool test()
+{
+   const bool writeFunctions( false );
+   const bool verbose( true );
+   if( ! setDifferenceOrder< double, tnlHost, int, double, int, 64, writeFunctions, verbose >() )
+      return false;
+#ifdef HAVE_CUDA
+   if( ! setDifferenceOrder< double, tnlCuda, int, double, int, 64, writeFunctions, verbose >() )
+      return false;
+#endif    
+    return true;    
+}
+
+int main( int argc, char* argv[] )
+{
+#ifdef HAVE_CPPUNIT
+    return test();
+#else
+   return EXIT_FAILURE;
+#endif
+}
diff --git a/tests/unit-tests/operators/geometric/CMakeLists.txt b/tests/unit-tests/operators/geometric/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..71d62e19415fc60329923ad0e8a8247c82286800
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/CMakeLists.txt
@@ -0,0 +1,30 @@
+ADD_EXECUTABLE( tnlFDMGradientNormTest${mpiExt}${debugExt} tnlFDMGradientNormTest.cpp )
+TARGET_LINK_LIBRARIES( tnlFDMGradientNormTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                 tnl${mpiExt}${debugExt}-0.1 )
+
+ADD_EXECUTABLE( tnlTwoSidedGradientNormTest${mpiExt}${debugExt} tnlTwoSidedGradientNormTest.cpp )
+TARGET_LINK_LIBRARIES( tnlTwoSidedGradientNormTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                 tnl${mpiExt}${debugExt}-0.1 )
+
+ADD_EXECUTABLE( tnlCoFVMGradientNormTest${mpiExt}${debugExt} tnlCoFVMGradientNormTest.cpp )
+TARGET_LINK_LIBRARIES( tnlCoFVMGradientNormTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                 tnl${mpiExt}${debugExt}-0.1 )
+
+if( BUILD_CUDA )                                                           
+   CUDA_ADD_EXECUTABLE( tnlFDMGradientNormTest-cuda${mpiExt}${debugExt} ${headers} tnlFDMGradientNormTest.cu
+                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   TARGET_LINK_LIBRARIES( tnlFDMGradientNormTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                          tnl${mpiExt}${debugExt}-0.1 )
+   
+   CUDA_ADD_EXECUTABLE( tnlTwoSidedGradientNormTest-cuda${mpiExt}${debugExt} ${headers} tnlTwoSidedGradientNormTest.cu
+                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   TARGET_LINK_LIBRARIES( tnlTwoSidedGradientNormTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                          tnl${mpiExt}${debugExt}-0.1 )
+
+   CUDA_ADD_EXECUTABLE( tnlCoFVMGradientNormTest-cuda${mpiExt}${debugExt} ${headers} tnlCoFVMGradientNormTest.cu
+                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+   TARGET_LINK_LIBRARIES( tnlCoFVMGradientNormTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
+                                                                          tnl${mpiExt}${debugExt}-0.1 )
+
+endif()                                                                      
+
diff --git a/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.cpp b/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..de3df7a05c7b143b113d0290eb8971a10bbb83b5
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.cpp
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnlCoFVMGradientNormTest.cpp  -  description
+                             -------------------
+    begin                : Jan 17, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlCoFVMGradientNormTest.h"
diff --git a/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.cu b/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.cu
new file mode 100644
index 0000000000000000000000000000000000000000..f0223132842f96e9d0cd5f7c28c855a2c584fa11
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.cu
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnlCoFVMGradientNormTest.cu  -  description
+                             -------------------
+    begin                : Jan 17, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlCoFVMGradientNormTest.h"
diff --git a/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.h b/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f43de6841cd44729a3e1aaf4d6f283b14774ef0
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/tnlCoFVMGradientNormTest.h
@@ -0,0 +1,152 @@
+/***************************************************************************
+                          tnlCoFVMGradientNormTest.h  -  description
+                             -------------------
+    begin                : Jan 17, 2016
+    copyright            : (C) 2016 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 TNLTWOSIDEDGRADIENTNORMTEST_H
+#define	TNLTWOSIDEDGRADIENTNORMTEST_H
+
+#include <operators/geometric/tnlCoFVMGradientNorm.h>
+#include <operators/geometric/tnlExactGradientNorm.h>
+#include <operators/interpolants/tnlMeshEntitiesInterpolants.h>
+#include <operators/tnlOperatorComposition.h>
+#include "../../tnlUnitTestStarter.h"
+#include "../tnlPDEOperatorEocTest.h"
+#include "../tnlPDEOperatorEocUnitTest.h"
+
+template< typename ApproximateOperator,
+          typename TestFunction,
+          bool write = false,
+          bool verbose = false >
+class tnlCoFVMGradientNormTest
+   : public tnlPDEOperatorEocTest< ApproximateOperator, TestFunction >
+{
+   public:
+      
+      typedef ApproximateOperator ApproximateOperatorType;
+      typedef typename ApproximateOperatorType::ExactOperatorType ExactOperatorType;
+      typedef typename ApproximateOperator::MeshType MeshType;
+      typedef typename ApproximateOperator::RealType RealType;
+      typedef typename ApproximateOperator::IndexType IndexType;
+      
+      const IndexType coarseMeshSize[ 3 ] = { 1024, 256, 64 };
+
+      const RealType eoc[ 3 ] =       { 2.0,  2.0, 2.0 };
+      const RealType tolerance[ 3 ] = { 1.05, 1.1, 1.3 };      
+      
+      static tnlString getType()
+      { 
+         return tnlString( "tnlCoFVMGradientNormTest< " ) + 
+                ApproximateOperator::getType() + ", " +
+                TestFunction::getType() + " >";
+      }
+      
+      void setupTest()
+      {
+         this->setupFunction();
+      }
+            
+      void getApproximationError( const IndexType meshSize,
+                                  RealType errors[ 3 ] )
+      {
+         this->setupMesh( meshSize );
+         
+         tnlMeshFunction< MeshType > u;
+      
+         typename ApproximateOperator::InnerOperator gradientNorm;
+         typename ApproximateOperator::OuterOperator interpolant;
+         ApproximateOperator approximateOperator( interpolant, gradientNorm, this->mesh );      
+         typename ApproximateOperator::InnerOperator::ExactOperatorType exactOperator;
+
+         this->performTest( approximateOperator,
+                            exactOperator,
+                            errors,
+                            write,
+                            verbose );
+      }
+      
+      void runUnitTest()
+      {  
+         RealType coarseErrors[ 3 ], fineErrors[ 3 ];
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->checkEoc( coarseErrors, fineErrors, this->eoc, this->tolerance, verbose );                            
+      }
+      
+   protected:
+
+
+};
+
+
+template< typename Operator,
+          typename Function, 
+          bool write,
+          bool verbose >
+bool runTest()
+{
+   typedef tnlCoFVMGradientNormTest< Operator, Function, write, verbose > OperatorTest;
+#ifdef HAVE_CPPUNIT   
+   if( ! tnlUnitTestStarter::run< tnlPDEOperatorEocUnitTest< OperatorTest > >() )
+      return false;
+   return true;
+#endif      
+}
+
+template< typename Mesh,
+          typename Function,
+          bool write,
+          bool verbose >
+bool setDifferenceOperator()
+{
+   typedef tnlCoFVMGradientNorm< Mesh > GradientNorm;
+   return ( runTest< GradientNorm, Function, write, verbose >() );
+}
+
+template< typename Mesh,
+          bool write,
+          bool verbose >
+bool setTestFunction()
+{
+   return setDifferenceOperator< Mesh, tnlExpBumpFunction< Mesh::getMeshDimensions(), double >, write, verbose >();
+}
+
+template< typename Device,
+          bool write,
+          bool verbose >
+bool setMesh()
+{
+   return ( setTestFunction< tnlGrid< 1, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 2, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 3, double, Device, int >, write, verbose >() );
+}
+
+int main( int argc, char* argv[] )
+{
+   const bool verbose( true );
+   const bool write( false );
+   
+   if( ! setMesh< tnlHost, write, verbose  >() )
+      return EXIT_FAILURE;
+#ifdef HAVE_CUDA
+   if( ! setMesh< tnlCuda, write, verbose >() )
+      return EXIT_FAILURE;
+#endif   
+   return EXIT_SUCCESS;
+}
+
+
+#endif	/* TNLFDMGRADIENTNORMTEST_H */
+
diff --git a/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.cpp b/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0ffb834694f5e357f66392fe2d18a4cd990935e
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.cpp
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnlFDMGradientNormTest.cpp  -  description
+                             -------------------
+    begin                : Jan 17, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlFDMGradientNormTest.h"
diff --git a/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.cu b/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.cu
new file mode 100644
index 0000000000000000000000000000000000000000..5fb5b112b0fa230e5906e80f247cefdefd8d6f4e
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.cu
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnlFDMGradientNormTest.cu  -  description
+                             -------------------
+    begin                : Jan 17, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlFDMGradientNormTest.h"
diff --git a/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.h b/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..790cf0ec9a52a248c5e4e4316e9cba5ad4950873
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/tnlFDMGradientNormTest.h
@@ -0,0 +1,173 @@
+/***************************************************************************
+                          tnlFDMGradientNormTest.h  -  description
+                             -------------------
+    begin                : Jan 17, 2016
+    copyright            : (C) 2016 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 TNLFDMGRADIENTNORMTEST_H
+#define	TNLFDMGRADIENTNORMTEST_H
+
+#include <operators/geometric/tnlFDMGradientNorm.h>
+#include <operators/geometric/tnlExactGradientNorm.h>
+#include <operators/fdm/tnlBackwardFiniteDifference.h>
+#include <operators/fdm/tnlForwardFiniteDifference.h>
+#include <operators/fdm/tnlCentralFiniteDifference.h>
+#include "../../tnlUnitTestStarter.h"
+#include "../tnlPDEOperatorEocTest.h"
+#include "../tnlPDEOperatorEocUnitTest.h"
+
+
+template< typename ApproximateOperator >
+class tnlFDMGradientNormEocTestResults
+{
+   public:       
+ 
+      typedef typename ApproximateOperator::RealType RealType;
+           
+      const RealType eoc[ 3 ] =       { 1.0,  1.0,  1.0 };
+      const RealType tolerance[ 3 ] = { 0.05, 0.05, 0.05 };      
+};
+
+template< typename MeshType,
+          typename RealType,
+          typename IndexType >
+class tnlFDMGradientNormEocTestResults< tnlCentralFiniteDifference< MeshType, 1, 0, 0, RealType, IndexType > >
+{
+   public:
+      
+      const RealType eoc[ 3 ] =       { 2.0,  2.0,  2.0 };
+      const RealType tolerance[ 3 ] = { 0.05, 0.05, 0.05 };
+};
+
+template< typename ApproximateOperator,
+          typename TestFunction,
+          bool write = false,
+          bool verbose = false >
+class tnlFDMGradientNormTest
+   : public tnlPDEOperatorEocTest< ApproximateOperator, TestFunction >,
+     public tnlFDMGradientNormEocTestResults< typename ApproximateOperator::template XDifferenceOperatorType< typename ApproximateOperator::MeshType::Cell > >
+{
+   public:
+      
+      typedef ApproximateOperator ApproximateOperatorType;
+      typedef typename ApproximateOperatorType::ExactOperatorType ExactOperatorType;
+      typedef typename ApproximateOperator::MeshType MeshType;
+      typedef typename ApproximateOperator::RealType RealType;
+      typedef typename ApproximateOperator::IndexType IndexType;
+      
+      const IndexType coarseMeshSize[ 3 ] = { 1024, 256, 64 };
+      
+      static tnlString getType()
+      { 
+         return tnlString( "tnlFDMGradientNormTest< " ) + 
+                ApproximateOperator::getType() + ", " +
+                TestFunction::getType() + " >";
+      }
+      
+      void setupTest()
+      {
+         this->setupFunction();
+      }
+            
+      void getApproximationError( const IndexType meshSize,
+                                  RealType errors[ 3 ] )
+      {
+         this->setupMesh( meshSize );
+         this->performTest( this->approximateOperator,
+                            this->exactOperator,
+                            errors,
+                            write,
+                            verbose );
+
+      }
+      
+      void runUnitTest()
+      {  
+         RealType coarseErrors[ 3 ], fineErrors[ 3 ];
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->checkEoc( coarseErrors, fineErrors, this->eoc, this->tolerance, verbose );                            
+      }
+      
+   protected:
+
+      ApproximateOperator approximateOperator;
+      
+      ExactOperatorType exactOperator;
+
+};
+
+template< typename Operator,
+          typename Function, 
+          bool write,
+          bool verbose >
+bool runTest()
+{
+   typedef tnlFDMGradientNormTest< Operator, Function, write, verbose > OperatorTest;
+#ifdef HAVE_CPPUNIT   
+   if( ! tnlUnitTestStarter::run< tnlPDEOperatorEocUnitTest< OperatorTest > >() )
+      return false;
+   return true;
+#endif      
+}
+
+template< typename Mesh,
+          typename Function,
+          bool write,
+          bool verbose >
+bool setDifferenceOperator()
+{
+   typedef tnlFDMGradientNorm< Mesh, tnlForwardFiniteDifference > ForwardGradientNorm;
+   typedef tnlFDMGradientNorm< Mesh, tnlBackwardFiniteDifference > BackwardGradientNorm;
+   typedef tnlFDMGradientNorm< Mesh, tnlCentralFiniteDifference > CentralGradientNorm;
+   return ( runTest< ForwardGradientNorm, Function, write, verbose >() &&
+            runTest< BackwardGradientNorm, Function, write, verbose >() &&
+            runTest< CentralGradientNorm, Function, write, verbose >() );
+}
+
+template< typename Mesh,
+          bool write,
+          bool verbose >
+bool setTestFunction()
+{
+   return setDifferenceOperator< Mesh, tnlExpBumpFunction< Mesh::getMeshDimensions(), double >, write, verbose >();
+}
+
+template< typename Device,
+          bool write,
+          bool verbose >
+bool setMesh()
+{
+   return ( setTestFunction< tnlGrid< 1, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 2, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 3, double, Device, int >, write, verbose >() );
+}
+
+int main( int argc, char* argv[] )
+{
+   const bool verbose( false );
+   const bool write( false );
+   
+   if( ! setMesh< tnlHost, write, verbose  >() )
+      return EXIT_FAILURE;
+#ifdef HAVE_CUDA
+   if( ! setMesh< tnlCuda, write, verbose >() )
+      return EXIT_FAILURE;
+#endif   
+   return EXIT_SUCCESS;
+}
+
+
+#endif	/* TNLFDMGRADIENTNORMTEST_H */
+
diff --git a/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.cpp b/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2125cd13a7af6766146561913180ee64925fe6b9
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.cpp
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnlTwoSidedGradientNormTest.cpp  -  description
+                             -------------------
+    begin                : Jan 17, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlTwoSidedGradientNormTest.h"
diff --git a/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.cu b/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.cu
new file mode 100644
index 0000000000000000000000000000000000000000..040cbc91047bc62abf2a19654e73ed236c907452
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.cu
@@ -0,0 +1,18 @@
+/***************************************************************************
+                          tnlTwoSidedGradientNormTest.cu  -  description
+                             -------------------
+    begin                : Jan 17, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlTwoSidedGradientNormTest.h"
diff --git a/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.h b/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..d2d29c4b0817e941587095fdde428d380d1442d9
--- /dev/null
+++ b/tests/unit-tests/operators/geometric/tnlTwoSidedGradientNormTest.h
@@ -0,0 +1,145 @@
+/***************************************************************************
+                          tnlTwoSidedGradientNormTest.h  -  description
+                             -------------------
+    begin                : Jan 17, 2016
+    copyright            : (C) 2016 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 TNLTWOSIDEDGRADIENTNORMTEST_H
+#define	TNLTWOSIDEDGRADIENTNORMTEST_H
+
+#include <operators/geometric/tnlTwoSidedGradientNorm.h>
+#include <operators/geometric/tnlExactGradientNorm.h>
+#include "../../tnlUnitTestStarter.h"
+#include "../tnlPDEOperatorEocTest.h"
+#include "../tnlPDEOperatorEocUnitTest.h"
+
+template< typename ApproximateOperator,
+          typename TestFunction,
+          bool write = false,
+          bool verbose = false >
+class tnlTwoSidedGradientNormTest
+   : public tnlPDEOperatorEocTest< ApproximateOperator, TestFunction >
+{
+   public:
+      
+      typedef ApproximateOperator ApproximateOperatorType;
+      typedef typename ApproximateOperatorType::ExactOperatorType ExactOperatorType;
+      typedef typename ApproximateOperator::MeshType MeshType;
+      typedef typename ApproximateOperator::RealType RealType;
+      typedef typename ApproximateOperator::IndexType IndexType;
+      
+      const IndexType coarseMeshSize[ 3 ] = { 1024, 256, 64 };
+
+      const RealType eoc[ 3 ] =       { 1.0,  1.9, 1.75 };
+      const RealType tolerance[ 3 ] = { 0.05, 0.1, 0.3 };      
+      
+      static tnlString getType()
+      { 
+         return tnlString( "tnlTwoSidedGradientNormTest< " ) + 
+                ApproximateOperator::getType() + ", " +
+                TestFunction::getType() + " >";
+      }
+      
+      void setupTest()
+      {
+         this->setupFunction();
+      }
+            
+      void getApproximationError( const IndexType meshSize,
+                                  RealType errors[ 3 ] )
+      {
+         this->setupMesh( meshSize );
+         this->performTest( this->approximateOperator,
+                            this->exactOperator,
+                            errors,
+                            write,
+                            verbose );
+
+      }
+      
+      void runUnitTest()
+      {  
+         RealType coarseErrors[ 3 ], fineErrors[ 3 ];
+         this->getApproximationError( coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], coarseErrors );
+         this->getApproximationError( 2 * coarseMeshSize[ MeshType::getMeshDimensions() - 1 ], fineErrors );
+         this->checkEoc( coarseErrors, fineErrors, this->eoc, this->tolerance, verbose );                            
+      }
+      
+   protected:
+
+      ApproximateOperator approximateOperator;
+      
+      ExactOperatorType exactOperator;
+
+};
+
+
+template< typename Operator,
+          typename Function, 
+          bool write,
+          bool verbose >
+bool runTest()
+{
+   typedef tnlTwoSidedGradientNormTest< Operator, Function, write, verbose > OperatorTest;
+#ifdef HAVE_CPPUNIT   
+   if( ! tnlUnitTestStarter::run< tnlPDEOperatorEocUnitTest< OperatorTest > >() )
+      return false;
+   return true;
+#endif      
+}
+
+template< typename Mesh,
+          typename Function,
+          bool write,
+          bool verbose >
+bool setDifferenceOperator()
+{
+   typedef tnlTwoSidedGradientNorm< Mesh > GradientNorm;
+   return ( runTest< GradientNorm, Function, write, verbose >() );
+}
+
+template< typename Mesh,
+          bool write,
+          bool verbose >
+bool setTestFunction()
+{
+   return setDifferenceOperator< Mesh, tnlExpBumpFunction< Mesh::getMeshDimensions(), double >, write, verbose >();
+}
+
+template< typename Device,
+          bool write,
+          bool verbose >
+bool setMesh()
+{
+   return ( setTestFunction< tnlGrid< 1, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 2, double, Device, int >, write, verbose >() &&
+            setTestFunction< tnlGrid< 3, double, Device, int >, write, verbose >() );
+}
+
+int main( int argc, char* argv[] )
+{
+   const bool verbose( true );
+   const bool write( false );
+   
+   if( ! setMesh< tnlHost, write, verbose  >() )
+      return EXIT_FAILURE;
+#ifdef HAVE_CUDA
+   if( ! setMesh< tnlCuda, write, verbose >() )
+      return EXIT_FAILURE;
+#endif   
+   return EXIT_SUCCESS;
+}
+
+#endif	/* TNLFDMGRADIENTNORMTEST_H */
+
diff --git a/tests/unit-tests/operators/tnlApproximationError.h b/tests/unit-tests/operators/tnlApproximationError.h
new file mode 100644
index 0000000000000000000000000000000000000000..859dc2674efccec4769f835b28c47de8fc7a071e
--- /dev/null
+++ b/tests/unit-tests/operators/tnlApproximationError.h
@@ -0,0 +1,139 @@
+/***************************************************************************
+                          tnlApproximationError.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 TNLAPPROXIMATIONERROR_H_
+#define TNLAPPROXIMATIONERROR_H_
+
+#include <mesh/tnlGrid.h>
+#include <functions/tnlConstantFunction.h>
+#include <operators/tnlDirichletBoundaryConditions.h>
+#include <solvers/pde/tnlExplicitUpdater.h>
+#include <functions/tnlExactOperatorFunction.h>
+#include <functions/tnlMeshFunction.h>
+#include <solvers/pde/tnlBoundaryConditionsSetter.h>
+
+template< typename ExactOperator,
+          typename ApproximateOperator,
+          typename MeshEntity,
+          typename Function >
+class tnlApproximationError
+{
+   public:
+   
+      typedef typename ApproximateOperator::RealType RealType;
+      typedef typename ApproximateOperator::MeshType MeshType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::IndexType IndexType;
+      typedef typename MeshType::VertexType VertexType;
+      typedef tnlConstantFunction< MeshType::meshDimensions, RealType > ConstantFunctionType;
+      typedef tnlDirichletBoundaryConditions< MeshType, Function  > BoundaryConditionsType;
+
+      static void getError( const ExactOperator& exactOperator,
+                            ApproximateOperator& approximateOperator,
+                            const Function& function,
+                            const MeshType& mesh,
+                            RealType& l1Error,
+                            RealType& l2Error,
+                            RealType& maxError,
+                            bool writeFunctions )
+      {
+         typedef tnlMeshFunction< MeshType, MeshEntity::getDimensions() > MeshFunction;
+         typedef tnlDirichletBoundaryConditions< MeshType, tnlConstantFunction< MeshType::meshDimensions > > DirichletBoundaryConditions;
+         typedef tnlOperatorFunction< DirichletBoundaryConditions, MeshFunction > BoundaryOperatorFunction;
+         typedef tnlOperatorFunction< ApproximateOperator, MeshFunction > OperatorFunction;
+         typedef tnlExactOperatorFunction< ExactOperator, Function > ExactOperatorFunction;
+
+         tnlMeshFunction< MeshType, MeshEntity::getDimensions() > exactU( mesh ), u( mesh ), v( mesh );
+         OperatorFunction operatorFunction( approximateOperator, v );         
+         ExactOperatorFunction exactOperatorFunction( exactOperator, function );
+         DirichletBoundaryConditions boundaryConditions;
+         BoundaryOperatorFunction boundaryOperatorFunction( boundaryConditions, u );
+
+         tnlString meshSizeString( mesh.getDimensions().x() );
+         tnlString dimensionsString;
+         if( MeshType::getMeshDimensions() == 1 )
+            dimensionsString = "1D-";
+         if( MeshType::getMeshDimensions() == 2 )
+            dimensionsString = "2D-";
+         if( MeshType::getMeshDimensions() == 3 )
+            dimensionsString = "3D-";
+
+         //if( writeFunctions )
+         //   mesh.save( "mesh-" + dimensionsString + meshSizeString + ".tnl" );
+
+         //cerr << "Evaluating exact u... " << endl;
+         exactU = exactOperatorFunction;
+         if( writeFunctions )
+            exactU.write( "exact-result-" + dimensionsString + meshSizeString, "gnuplot" );
+
+         //cerr << "Projecting test function ..." << endl;
+         v = function;
+         if( writeFunctions )
+            v.write( "test-function-" + dimensionsString + meshSizeString, "gnuplot" ) ;
+
+         //cerr << "Evaluating approximate u ... " << endl;
+         operatorFunction.setPreimageFunction( v );
+         if( ! operatorFunction.deepRefresh() )
+         {
+            cerr << "Error in operator refreshing." << endl;
+            return;
+         }         
+         u = operatorFunction;
+         tnlBoundaryConditionsSetter< MeshFunction, DirichletBoundaryConditions >::template apply< MeshEntity >( boundaryConditions, 0.0, u );
+         if( writeFunctions )
+            u.write( "approximate-result-" + dimensionsString + meshSizeString, "gnuplot" ) ;
+
+         //cerr << "Evaluate difference ... " << endl;
+         u -= exactU;   
+         tnlBoundaryConditionsSetter< MeshFunction, DirichletBoundaryConditions >::template apply< MeshEntity >( boundaryConditions, 0.0, u );
+         if( writeFunctions )
+            u.write( "difference-" + dimensionsString + meshSizeString, "gnuplot" ) ;
+         l1Error = u.getLpNorm( 1.0 );
+         l2Error = u.getLpNorm( 2.0 );   
+         maxError = u.getMaxNorm();
+      }
+};
+
+/*
+template< typename Mesh,
+          typename ExactOperator,
+          typename ApproximateOperator,
+          typename Function >
+class tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlImplicitApproximation >
+{
+     public:
+
+      typedef typename ApproximateOperator::RealType RealType;
+      typedef Mesh MeshType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef typename MeshType::IndexType IndexType;
+      typedef typename MeshType::VertexType VertexType;
+      typedef tnlConstantFunction< MeshType::meshDimensions, RealType > ConstantFunctionType;
+      typedef tnlDirichletBoundaryConditions< MeshType, Function  > BoundaryConditionsType;
+
+      static void getError( const Mesh& mesh,
+                            const ExactOperator& exactOperator,
+                            const ApproximateOperator& approximateOperator,
+                            const Function& function,
+                            RealType& l1Err,
+                            RealType& l2Err,
+                            RealType& maxErr );
+};
+*/
+//#include "tnlApproximationError_impl.h"
+
+#endif /* TNLAPPROXIMATIONERROR_H_ */
diff --git a/tests/unit-tests/operators/tnlOperatorCompositionTest.cpp b/tests/unit-tests/operators/tnlOperatorCompositionTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c489cbec436ac32aa1942a5ee176839453da653d
--- /dev/null
+++ b/tests/unit-tests/operators/tnlOperatorCompositionTest.cpp
@@ -0,0 +1,19 @@
+/***************************************************************************
+                          tnlOperatorCompositionTest.cpp  -  description
+                             -------------------
+    begin                : Feb 13, 2016
+    copyright            : (C) 2016 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "tnlOperatorCompositionTest.h"
+
diff --git a/tests/unit-tests/operators/tnlOperatorCompositionTest.h b/tests/unit-tests/operators/tnlOperatorCompositionTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..31396690009405d4ec5575fb581ef2a2fa88bd9d
--- /dev/null
+++ b/tests/unit-tests/operators/tnlOperatorCompositionTest.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+                          tnlOperatorCompositionTest.h  -  description
+                             -------------------
+    begin                : Feb 11, 2016
+    copyright            : (C) 2016 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 TNLOPERATORFUNCTIONTEST_H
+#define	TNLOPERATORFUNCTIONTEST_H
+
+#include <operators/tnlOperatorComposition.h>
+#include <mesh/tnlGrid.h>
+#include <functions/tnlExpBumpFunction.h>
+#include <functions/tnlConstantFunction.h>
+#include <operators/diffusion/tnlLinearDiffusion.h>
+#include <operators/tnlNeumannBoundaryConditions.h>
+#include "../tnlUnitTestStarter.h"
+
+#ifdef HAVE_CPPUNIT
+#include <cppunit/TestSuite.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestCaller.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/Message.h>
+
+
+template< typename Operator >
+class tnlOperatorCompositionTest
+   : public CppUnit::TestCase
+{
+   public:
+   typedef tnlOperatorCompositionTest< Operator > TesterType;
+   typedef typename CppUnit::TestCaller< TesterType > TestCallerType;
+   typedef Operator OperatorType;
+   typedef typename OperatorType::MeshType MeshType;
+   typedef typename OperatorType::RealType RealType;
+   typedef typename OperatorType::IndexType IndexType;
+   typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef typename MeshType::VertexType VertexType;
+   typedef tnlExpBumpFunction< MeshType::getMeshDimensions(), typename MeshType::RealType > TestFunctionType;
+   typedef tnlConstantFunction< MeshType::getMeshDimensions(), typename MeshType::RealType > ConstantFunction;
+   typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunction > BoundaryConditions;
+   typedef tnlOperatorComposition< OperatorType, OperatorType, BoundaryConditions > OperatorComposition;   
+   typedef tnlMeshFunction< MeshType, MeshType::getMeshDimensions() > MeshFunctionType;
+   typedef tnlOperatorFunction< OperatorType, MeshFunctionType, BoundaryConditions > OperatorFunction;
+   typedef tnlOperatorFunction< OperatorType, OperatorFunction, BoundaryConditions > OperatorFunction2;
+
+   tnlOperatorCompositionTest(){};
+
+   virtual
+   ~tnlOperatorCompositionTest(){};
+
+   static CppUnit::Test* suite()
+   {
+      CppUnit::TestSuite* suiteOfTests = new CppUnit :: TestSuite( "tnlOperatorCompositionTest" );
+      CppUnit::TestResult result;
+
+      suiteOfTests -> addTest( new TestCallerType( "test", &TesterType::test ) );
+      return suiteOfTests;
+   }
+   
+   void test()
+   {      
+      MeshType mesh;
+      mesh.setDimensions( CoordinatesType( 25 ) );
+      mesh.setDomain( VertexType( -1.0 ), VertexType( 2.0 ) );
+      TestFunctionType testFunction;
+      testFunction.setAmplitude( 1.0 );
+      testFunction.setSigma( 1.0 );
+      MeshFunctionType f1( mesh );
+      f1 = testFunction;
+      OperatorType operator_;
+      BoundaryConditions boundaryConditions;
+      OperatorFunction operatorFunction1( operator_, boundaryConditions, f1 );
+      operatorFunction1.refresh();
+      OperatorFunction2 operatorFunction2( operator_, boundaryConditions, operatorFunction1 );
+      operatorFunction2.refresh();
+      
+      //f1 = testFunction;
+      OperatorComposition operatorComposition( operator_, operator_, boundaryConditions, mesh );
+      //operatorComposition.refresh();
+      tnlOperatorFunction< OperatorComposition, MeshFunctionType, BoundaryConditions > operatorFunction3( operatorComposition, boundaryConditions, f1 );
+      operatorFunction3.refresh();
+      
+      /*f1 = testFunction;
+      f1.write( "testFunction", "gnuplot" );
+      f1 = operatorFunction1;
+      f1.write( "operator1", "gnuplot" );
+      f1 = operatorFunction2;
+      f1.write( "operator2", "gnuplot" );
+      
+      f1 = operatorFunction3;
+      f1.write( "operatorComposition", "gnuplot" );      */
+      
+      //CPPUNIT_ASSERT( operatorFunction2 == operatorFunction3 );
+      for( IndexType i = 0; i < mesh.template getEntitiesCount< typename MeshType::Cell >(); i++ )
+      {
+         auto entity = mesh.template getEntity< typename MeshType::Cell >( i );
+         entity.refresh();
+         //cerr << entity.getIndex() << " " << operatorFunction2( entity ) << " " << operatorFunction3( entity ) << endl;
+         CPPUNIT_ASSERT( operatorFunction2( entity ) == operatorFunction3( entity ) );
+         /*if( entity.isBoundaryEntity() )
+            CPPUNIT_ASSERT( boundaryConditions( f1, entity ) == operatorFunction( entity ) );
+         else
+         {
+            
+            
+         }*/
+      }      
+   }   
+};
+#endif
+   
+template< typename Operator >
+bool runTest()
+{
+   //tnlOperatorCompositionTest< Operator > test;
+#ifdef HAVE_CPPUNIT
+   if( ! tnlUnitTestStarter::run< tnlOperatorCompositionTest< Operator > >() )
+     return false;
+   return true;
+#else
+   return false;
+#endif        
+}
+
+template< typename MeshType >
+bool setOperator()
+{
+   return runTest< tnlLinearDiffusion< MeshType > >();
+}
+
+int main( int argc, char* argv[] )
+{
+   if( ! setOperator< tnlGrid< 1, double, tnlHost, int > >() ||
+       ! setOperator< tnlGrid< 2, double, tnlHost, int > >() ||
+       ! setOperator< tnlGrid< 3, double, tnlHost, int > >() )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
+#endif	/* TNLOPERATORFUNCTIONTEST_H */
+
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTest.h b/tests/unit-tests/operators/tnlPDEOperatorEocTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..07af09254827fb2da5ab930f75b1db484557390d
--- /dev/null
+++ b/tests/unit-tests/operators/tnlPDEOperatorEocTest.h
@@ -0,0 +1,129 @@
+/***************************************************************************
+                          tnlPDEOperatorEocTest.h  -  description
+                             -------------------
+    begin                : Feb 1, 2016
+    copyright            : (C) 2016 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 TNLPDEOPERATOREOSTEST_H
+#define	TNLPDEOPERATOREOSTEST_H
+
+#include "tnlPDEOperatorEocTestMeshSetter.h"
+#include "tnlPDEOperatorEocTestFunctionSetter.h"
+#include "tnlApproximationError.h"
+
+#ifdef HAVE_CPPUNIT
+#include <cppunit/TestSuite.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestCaller.h>
+#include <cppunit/TestCase.h>
+#endif
+
+
+template< typename ApproximateOperator,
+          typename TestFunction,
+          typename ExactOperator = typename ApproximateOperator::ExactOperatorType >
+class tnlPDEOperatorEocTest
+{
+   public:      
+      
+      typedef ApproximateOperator ApproximateOperatorType;
+      typedef TestFunction TestFunctionType;
+      typedef ExactOperator ExactOperatorType;
+      typedef typename ApproximateOperator::MeshType MeshType;
+      typedef typename ApproximateOperator::RealType RealType;
+      typedef typename ApproximateOperator::IndexType IndexType;
+      
+      //static_assert( std::is_same< ExactOperatorType, void >::value,
+      //   "Exact operator type is not defined (it is void in fact)." );
+   
+      void setupMesh( const IndexType meshSize )
+      {
+         tnlPDEOperatorEocTestMeshSetter< MeshType >::setup( mesh, meshSize );
+      }
+      
+      void setupFunction()
+      {
+         tnlPDEOperatorEocTestFunctionSetter< TestFunction >::setup( function );
+      }
+     
+      template< typename MeshEntityType = typename MeshType::Cell > 
+      void performTest( ApproximateOperator& approximateOperator,
+                        ExactOperatorType& exactOperator,
+                        RealType errors[ 3 ],
+                        bool writeFunctions = false,
+                        bool verbose = false )
+      {
+         tnlApproximationError< ExactOperatorType,
+                                ApproximateOperator,
+                                MeshEntityType,
+                                TestFunction >
+         ::getError( exactOperator,
+                     approximateOperator,
+                     function,
+                     mesh,
+                     errors[ 1 ], //l1Error,
+                     errors[ 2 ], //l2Error,
+                     errors[ 0 ], //maxError,
+                     writeFunctions );
+         if( verbose )
+            std::cout << "L1 err. " << errors[ 1 ] << " L2 err. " << errors[ 2 ] << " Max. err. " << errors[ 0 ] << std::endl;
+      }
+      
+      void checkEoc( const RealType coarse[ 3 ],
+                     const RealType fine[ 3 ],
+                     const RealType eoc[ 3 ],
+                     const RealType tolerance[ 3 ],
+                     bool verbose = false)
+      {
+         /****
+          * Max error
+          */
+         RealType maxEoc = log( coarse[ 0 ] / fine[ 0 ] ) / log( 2.0 );
+         if( verbose )
+            std::cout << "Max error EOC = " << maxEoc << " expected " << eoc[ 0 ] << std::endl;
+#ifdef HAVE_CPPUNIT
+         CPPUNIT_ASSERT( fabs( maxEoc - eoc[ 0 ] ) < tolerance[ 0 ] );
+#endif
+         
+         /****
+          * Max error
+          */
+         RealType l1Eoc = log( coarse[ 1 ] / fine[ 1 ] ) / log( 2.0 );
+         if( verbose )
+            std::cout << "L1 error EOC = " << l1Eoc << " expected " << eoc[ 1 ]  << std::endl;         
+#ifdef HAVE_CPPUNIT
+         CPPUNIT_ASSERT( fabs( l1Eoc - eoc[ 1 ] ) < tolerance[ 1 ] );
+#endif         
+         
+         /****
+          * L2 error
+          */
+         RealType l2Eoc = log( coarse[ 2 ] / fine[ 2 ] ) / log( 2.0 );
+         if( verbose )
+            std::cout << "L2 error EOC = " << l2Eoc << " expected " << eoc[ 2 ] << std::endl;
+#ifdef HAVE_CPPUNIT         
+         CPPUNIT_ASSERT( fabs( l2Eoc - eoc[ 2 ] ) < tolerance[ 2 ] );
+#endif         
+      }
+      
+   protected:
+      
+      MeshType mesh;
+      
+      TestFunction function;               
+};
+
+
+#endif	/* TNLPDEOPERATOREOSTEST_H */
+
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTestFunctionSetter.h b/tests/unit-tests/operators/tnlPDEOperatorEocTestFunctionSetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..8004c93884798af119a04db4a1ef79dd70ad92f4
--- /dev/null
+++ b/tests/unit-tests/operators/tnlPDEOperatorEocTestFunctionSetter.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+                          tnlPDEOperatorEocTestFunctionSetter.h  -  description
+                             -------------------
+    begin                : Feb 1, 2016
+    copyright            : (C) 2016 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 TNLPDEOPERATOREOCTESTFUNCTIONSETTER_H
+#define	TNLPDEOPERATOREOCTESTFUNCTIONSETTER_H
+
+#include<functions/tnlExpBumpFunction.h>
+
+template< typename Function >
+class tnlPDEOperatorEocTestFunctionSetter
+{
+};
+
+template< int Dimensions,
+          typename Real >
+class tnlPDEOperatorEocTestFunctionSetter< tnlExpBumpFunction< Dimensions, Real > >
+{
+   static_assert( Dimensions >= 0 && Dimensions <= 3,
+      "Wrong parameter Dimensions." );
+   public:      
+      
+      typedef tnlExpBumpFunction< Dimensions, Real > FunctionType;
+      
+      static void setup( FunctionType& function )
+      {
+         function.setAmplitude( 1.5 );
+         function.setSigma( 0.5 );
+      }
+};
+
+#endif	/* TNLPDEOPERATOREOCTESTFUNCTIONSETTER_H */
+
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTestMeshSetter.h b/tests/unit-tests/operators/tnlPDEOperatorEocTestMeshSetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..06a1244adf8b6a60aaca553525bcc91d39113f7f
--- /dev/null
+++ b/tests/unit-tests/operators/tnlPDEOperatorEocTestMeshSetter.h
@@ -0,0 +1,127 @@
+/***************************************************************************
+                          tnlPDEOperatorEocTestMeshSetter.h  -  description
+                             -------------------
+    begin                : Feb 1, 2016
+    copyright            : (C) 2016 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 TNLPDEOPERATOREOCTESTMESHSETTER_H
+#define	TNLPDEOPERATOREOCTESTMESHSETTER_H
+
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh >
+class tnlPDEOperatorEocTestMeshSetter
+{
+};
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlPDEOperatorEocTestMeshSetter< tnlGrid< 1, Real, Device, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 1, Real, Device, Index > MeshType;
+      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      
+      static bool setup( MeshType& mesh, const IndexType meshSize )
+      {
+         VertexType origin, proportions;
+         origin.x() = -2.0;
+         proportions.x() = 4.0;
+         mesh.setDomain( origin, proportions );
+
+         CoordinatesType dimensions;
+         dimensions.x() = meshSize;
+         mesh.setDimensions( dimensions );
+
+         return true;
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlPDEOperatorEocTestMeshSetter< tnlGrid< 2, Real, Device, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 2, Real, Device, Index > MeshType;
+      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+      
+      static bool setup( MeshType& mesh, const IndexType meshSize )
+      {
+         VertexType origin, proportions;
+         origin.x() = -1.0;
+         origin.y() = -1.0;
+         proportions.x() = 2.0;
+         proportions.y() = 2.0;
+         mesh.setDomain( origin, proportions );
+
+         CoordinatesType dimensions;
+         dimensions.x() = meshSize;
+         dimensions.y() = meshSize;
+         mesh.setDimensions( dimensions );         
+
+         return true;
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index >
+class tnlPDEOperatorEocTestMeshSetter< tnlGrid< 3, Real, Device, Index > >
+{
+   public:
+      
+      typedef tnlGrid< 3, Real, Device, Index > MeshType;
+      typedef typename MeshType::VertexType VertexType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+
+      static bool setup( MeshType& mesh, const IndexType meshSize )      
+      {
+         VertexType origin, proportions;
+         origin.x() = -1.0;
+         origin.y() = -1.0;
+         origin.z() = -1.0;
+         proportions.x() = 2.0;
+         proportions.y() = 2.0;
+         proportions.z() = 2.0;
+         mesh.setDomain( origin, proportions );
+
+         CoordinatesType dimensions;
+         dimensions.x() = meshSize;
+         dimensions.y() = meshSize;
+         dimensions.z() = meshSize;
+         mesh.setDimensions( dimensions );         
+         
+         return true;
+      }
+};
+
+
+
+#endif	/* TNLPDEOPERATOREOCTESTMESHSETTER_H */
+
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTestResult.h b/tests/unit-tests/operators/tnlPDEOperatorEocTestResult.h
index 7e1954dcf262a418ea87d415f9a7b2ac7964a88a..0214a086e02688b8a017cfd2b897c76a4cd0d817 100644
--- a/tests/unit-tests/operators/tnlPDEOperatorEocTestResult.h
+++ b/tests/unit-tests/operators/tnlPDEOperatorEocTestResult.h
@@ -19,7 +19,6 @@
 #define TNLPDEOPERATOREOCTESTRESULT_H_
 
 template< typename ApproximateOperator,
-          typename ApproximationMethod,
           typename TestFunction >
 class tnlPDEOperatorEocTestResult
 {
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h b/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h
index 16542c201dd6c1bcc4348d91e762425fdc0b630c..d4922b7f8493643465237b170562ffbfadaf5273 100644
--- a/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h
+++ b/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h
@@ -23,7 +23,6 @@
 
 template< typename ApproximateOperator,
           typename ExactOperator,
-          typename ApproximationMethod,
           typename Mesh,
           typename TestFunction >
 class tnlPDEOperatorEocTestSetter
@@ -32,13 +31,11 @@ class tnlPDEOperatorEocTestSetter
 
 template< typename ApproximateOperator,
           typename ExactOperator,
-          typename ApproximationMethod,
           typename Real,
           typename Device,
           typename Index >
 class tnlPDEOperatorEocTestSetter< ApproximateOperator,
                                    ExactOperator,
-                                   ApproximationMethod,
                                    tnlGrid< 1, Real, Device, Index >,
                                    tnlExpBumpFunction< 1, Real > >
 {
@@ -57,8 +54,8 @@ class tnlPDEOperatorEocTestSetter< ApproximateOperator,
                         const IndexType& size )
    {
       VertexType origin, proportions;
-      origin.x() = -1.0;
-      proportions.x() = 2.0;
+      origin.x() = -2.0;
+      proportions.x() = 4.0;
       mesh.setDomain( origin, proportions );
 
       CoordinatesType dimensions;
@@ -68,20 +65,18 @@ class tnlPDEOperatorEocTestSetter< ApproximateOperator,
 
    static void setFunction( FunctionType& function )
    {
-      function.setAmplitude( 1.0 );
+      function.setAmplitude( 1.5 );
       function.setSigma( 0.5 );
    };
 };
 
 template< typename ApproximateOperator,
           typename ExactOperator,
-          typename ApproximationMethod,
           typename Real,
           typename Device,
           typename Index >
 class tnlPDEOperatorEocTestSetter< ApproximateOperator,
                                    ExactOperator,
-                                   ApproximationMethod,
                                    tnlGrid< 2, Real, Device, Index >,
                                    tnlExpBumpFunction< 2, Real > >
 {
@@ -121,13 +116,11 @@ class tnlPDEOperatorEocTestSetter< ApproximateOperator,
 
 template< typename ApproximateOperator,
           typename ExactOperator,
-          typename ApproximationMethod,
           typename Real,
           typename Device,
           typename Index >
 class tnlPDEOperatorEocTestSetter< ApproximateOperator,
                                    ExactOperator,
-                                   ApproximationMethod,
                                    tnlGrid< 3, Real, Device, Index >,
                                    tnlExpBumpFunction< 3, Real > >
 {
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTester.h b/tests/unit-tests/operators/tnlPDEOperatorEocTester.h
deleted file mode 100644
index e1335eb9fedf9f110807d997bf568cb98a30105e..0000000000000000000000000000000000000000
--- a/tests/unit-tests/operators/tnlPDEOperatorEocTester.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/***************************************************************************
-                          tnlPDEOperatorEocTester.h  -  description
-                             -------------------
-    begin                : Aug 30, 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 TNLPDEOPERATOREOCTESTER_H_
-#define TNLPDEOPERATOREOCTESTER_H_
-
-#ifdef HAVE_CPPUNIT
-#include <cppunit/TestSuite.h>
-#include <cppunit/TestResult.h>
-#include <cppunit/TestCaller.h>
-#include <cppunit/TestCase.h>
-#include <cppunit/Message.h>
-#include <unit-tests/tnlApproximationError.h>
-#include <unit-tests/operators/tnlPDEOperatorEocTestSetter.h>
-#include <unit-tests/operators/tnlPDEOperatorEocTestResult.h>
-
-template< typename ApproximateOperator,
-          typename ExactOperator,
-          typename TestFunction,
-          typename ApproximationMethod,
-          int MeshSize,
-          bool verbose = false >
-class tnlPDEOperatorEocTester : public CppUnit :: TestCase
-{
-   public:
-   typedef tnlPDEOperatorEocTester< ApproximateOperator, ExactOperator, TestFunction, ApproximationMethod, MeshSize, verbose > TesterType;
-   typedef typename CppUnit::TestCaller< TesterType > TestCallerType;
-   typedef typename ApproximateOperator::MeshType MeshType;
-   typedef typename ApproximateOperator::RealType RealType;
-   typedef typename ApproximateOperator::IndexType IndexType;
-   typedef tnlPDEOperatorEocTestSetter< ApproximateOperator, ExactOperator, ApproximationMethod, MeshType, TestFunction > TestSetter;
-   typedef tnlPDEOperatorEocTestResult< ApproximateOperator, ApproximationMethod, TestFunction > TestResult;
-
-   tnlPDEOperatorEocTester(){};
-
-   virtual
-   ~tnlPDEOperatorEocTester(){};
-
-   static CppUnit :: Test* suite()
-   {
-      tnlString testName = tnlString( "tnlPDEOperatorEocTester< " ) +
-                           ApproximateOperator::getType() + ", " +
-                           ExactOperator::getType() + ", " +
-                           TestFunction::getType() + ", " +
-                           ApproximationMethod::getType() + ", " +
-                           tnlString( MeshSize ) + ", " +
-                           tnlString( verbose ) + " >";
-      CppUnit :: TestSuite* suiteOfTests = new CppUnit :: TestSuite( testName.getString() );
-      CppUnit :: TestResult result;
-
-      suiteOfTests -> addTest( new TestCallerType( "approximationTest", &TesterType::approximationTest ) );
-
-      return suiteOfTests;
-   }
-
-   void approximationTest()
-   {
-      TestFunction testFunction;
-      TestSetter::setFunction( testFunction );
-
-      MeshType mesh;
-
-      ExactOperator exactOperator;
-      ApproximateOperator approximateOperator;
-
-      TestSetter::setMesh( mesh, MeshSize );
-      RealType coarseL1Err, coarseL2Err, coarseMaxErr;
-      tnlApproximationError< MeshType,
-                             ExactOperator,
-                             ApproximateOperator,
-                             TestFunction,
-                             ApproximationMethod >
-         ::getError( mesh,
-                     exactOperator,
-                     approximateOperator,
-                     testFunction,
-                     coarseL1Err,
-                     coarseL2Err,
-                     coarseMaxErr );
-
-      TestSetter::setMesh( mesh, 2*MeshSize );
-      RealType fineL1Err, fineL2Err, fineMaxErr;
-      tnlApproximationError< MeshType,
-                             ExactOperator,
-                             ApproximateOperator,
-                             TestFunction,
-                             ApproximationMethod >
-         ::getError( mesh,
-                     exactOperator,
-                     approximateOperator,
-                     testFunction,
-                     fineL1Err,
-                     fineL2Err,
-                     fineMaxErr );
-      RealType l1Eoc = log( coarseL1Err / fineL1Err) / log( 2.0 );
-      RealType l2Eoc = log( coarseL2Err / fineL2Err) / log( 2.0 );
-      RealType maxEoc = log( coarseMaxErr / fineMaxErr) / log( 2.0 );
-
-      if( verbose )
-      {
-         cerr << "Coarse mesh: L1Err = " << coarseL1Err << " L2Err = " << coarseL2Err << " maxErr = " << coarseMaxErr << endl;
-         cerr << "Fine mesh: L1Err = " << fineL1Err << " L2Err = " << fineL2Err << " maxErr = " << fineMaxErr << endl;
-         cerr << "L1Eoc = " << l1Eoc << " L2Eoc = " << l2Eoc << " maxEoc = " << maxEoc << endl;
-      }
-
-      CPPUNIT_ASSERT( fabs( l1Eoc - TestResult::getL1Eoc() ) < TestResult::getL1Tolerance() );
-      CPPUNIT_ASSERT( fabs( l2Eoc - TestResult::getL2Eoc() ) < TestResult::getL2Tolerance() );
-      CPPUNIT_ASSERT( fabs( maxEoc - TestResult::getMaxEoc() ) < TestResult::getMaxTolerance() );
-   }
-};
-
-#endif /* HAVE_CPPUNIT */
-#endif /* TNLPDEOPERATOREOCTESTER_H_ */
diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocUnitTest.h b/tests/unit-tests/operators/tnlPDEOperatorEocUnitTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c3aa09736de4c351396783395352bb1062afef0
--- /dev/null
+++ b/tests/unit-tests/operators/tnlPDEOperatorEocUnitTest.h
@@ -0,0 +1,60 @@
+/***************************************************************************
+                          tnlPDEOperatorEocUnitTest.h  -  description
+                             -------------------
+    begin                : Aug 30, 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 TNLPDEOPERATOREOCUNITTEST_H_
+#define TNLPDEOPERATOREOCUNITTEST_H_
+
+#ifdef HAVE_CPPUNIT
+#include <cppunit/TestSuite.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestCaller.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/Message.h>
+
+template< typename OperatorTest >
+class tnlPDEOperatorEocUnitTest : public CppUnit :: TestCase
+{
+   public:
+   typedef tnlPDEOperatorEocUnitTest< OperatorTest > TesterType;
+   typedef typename CppUnit::TestCaller< TesterType > TestCallerType;
+
+   tnlPDEOperatorEocUnitTest(){};
+
+   virtual
+   ~tnlPDEOperatorEocUnitTest(){};
+
+   static CppUnit :: Test* suite()
+   {
+      tnlString testName = OperatorTest::getType();
+      CppUnit :: TestSuite* suiteOfTests = new CppUnit :: TestSuite( testName.getString() );
+      CppUnit :: TestResult result;
+
+      suiteOfTests -> addTest( new TestCallerType( testName.getString(), &TesterType::approximationTest ) );
+
+      return suiteOfTests;
+   }
+
+   void approximationTest()
+   {
+      OperatorTest operatorTest;
+      operatorTest.setupTest();
+      operatorTest.runUnitTest();
+   }
+};
+
+#endif /* HAVE_CPPUNIT */
+#endif /* TNLPDEOPERATOREOCUNITTEST_H_ */
diff --git a/tests/unit-tests/tnlApproximationError.h b/tests/unit-tests/tnlApproximationError.h
deleted file mode 100644
index 6210c505949ec3aa37ef14b80171463f1f0911b9..0000000000000000000000000000000000000000
--- a/tests/unit-tests/tnlApproximationError.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/***************************************************************************
-                          tnlApproximationError.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 TNLAPPROXIMATIONERROR_H_
-#define TNLAPPROXIMATIONERROR_H_
-
-#include <mesh/tnlGrid.h>
-#include <functions/tnlConstantFunction.h>
-#include <operators/tnlDirichletBoundaryConditions.h>
-#include <solvers/pde/tnlExplicitUpdater.h>
-
-class tnlExplicitApproximation
-{
-   public:
-
-   static tnlString getType()
-   {
-      return tnlString( "tnlExplicitApproximation" );
-   };
-};
-
-class tnlImplicitApproximation
-{
-   public:
-
-   static tnlString getType()
-   {
-      return tnlString( "tnlImplicitApproximation" );
-   };
-};
-
-template< typename Mesh,
-          typename ExactOperator,
-          typename ApproximateOperator,
-          typename Function,
-          typename ApproximationMethod >
-class tnlApproximationError
-{
-};
-
-template< typename Mesh,
-          typename ExactOperator,
-          typename ApproximateOperator,
-          typename Function >
-class tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlExplicitApproximation >
-{
-     public:
-
-      typedef typename ApproximateOperator::RealType RealType;
-      typedef Mesh MeshType;
-      typedef typename MeshType::DeviceType DeviceType;
-      typedef typename MeshType::IndexType IndexType;
-      typedef typename MeshType::VertexType VertexType;
-      typedef tnlConstantFunction< MeshType::meshDimensions, RealType > ConstantFunctionType;
-      typedef tnlDirichletBoundaryConditions< MeshType, Function  > BoundaryConditionsType;
-
-      static void getError( const Mesh& mesh,
-                            const ExactOperator& exactOperator,
-                            const ApproximateOperator& approximateOperator,
-                            const Function& function,
-                            RealType& l1Err,
-                            RealType& l2Err,
-                            RealType& maxErr );
-};
-
-template< typename Mesh,
-          typename ExactOperator,
-          typename ApproximateOperator,
-          typename Function >
-class tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlImplicitApproximation >
-{
-     public:
-
-      typedef typename ApproximateOperator::RealType RealType;
-      typedef Mesh MeshType;
-      typedef typename MeshType::DeviceType DeviceType;
-      typedef typename MeshType::IndexType IndexType;
-      typedef typename MeshType::VertexType VertexType;
-      typedef tnlConstantFunction< MeshType::meshDimensions, RealType > ConstantFunctionType;
-      typedef tnlDirichletBoundaryConditions< MeshType, Function  > BoundaryConditionsType;
-
-      static void getError( const Mesh& mesh,
-                            const ExactOperator& exactOperator,
-                            const ApproximateOperator& approximateOperator,
-                            const Function& function,
-                            RealType& l1Err,
-                            RealType& l2Err,
-                            RealType& maxErr );
-};
-
-#include "tnlApproximationError_impl.h"
-
-#endif /* TNLAPPROXIMATIONERROR_H_ */
diff --git a/tests/unit-tests/tnlApproximationError_impl.h b/tests/unit-tests/tnlApproximationError_impl.h
deleted file mode 100644
index f171e2ffb5598f655dbf94bf4e5bd23212430dd3..0000000000000000000000000000000000000000
--- a/tests/unit-tests/tnlApproximationError_impl.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/***************************************************************************
-                          tnlApproximationError_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 TNLAPPROXIMATIONERROR_IMPL_H_
-#define TNLAPPROXIMATIONERROR_IMPL_H_
-
-#include <mesh/tnlTraverser.h>
-#include <core/vectors/tnlVector.h>
-#include <functions/tnlFunctionDiscretizer.h>
-#include <matrices/tnlCSRMatrix.h>
-#include <matrices/tnlMatrixSetter.h>
-#include <solvers/pde/tnlLinearSystemAssembler.h>
-#include <solvers/pde/tnlNoTimeDiscretisation.h>
-#include <operators/tnlExactOperatorEvaluator.h>
-
-template< typename Mesh,
-          typename ExactOperator,
-          typename ApproximateOperator,
-          typename Function >
-void
-tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlExplicitApproximation >::
-getError( const Mesh& mesh,
-          const ExactOperator& exactOperator,
-          const ApproximateOperator& approximateOperator,
-          const Function& function,
-          RealType& l1Err,
-          RealType& l2Err,
-          RealType& maxErr )
-{
-   typedef tnlVector< RealType, DeviceType, IndexType > Vector;
-   Vector functionData, exactData, approximateData, aux;
-   const IndexType entities = mesh.template getEntitiesCount< typename Mesh::Cell >();
-   BoundaryConditionsType boundaryConditions;
-   boundaryConditions.setFunction( function );
-   ConstantFunctionType zeroFunction;
-
-   if( ! functionData.setSize( entities ) ||
-       ! exactData.setSize( entities ) ||
-       ! approximateData.setSize( entities ) ||
-       ! aux.setSize( entities) )
-      return;
-
-   tnlFunctionDiscretizer< Mesh, Function, Vector >::template discretize< 0, 0, 0 >( mesh, function, functionData );
-
-   tnlExplicitUpdater< Mesh, Vector, ApproximateOperator, BoundaryConditionsType, ConstantFunctionType > explicitUpdater;
-   explicitUpdater.template update< typename Mesh::Cell >( 0.0,
-                                                        mesh,
-                                                        approximateOperator,
-                                                        boundaryConditions,
-                                                        zeroFunction,
-                                                        functionData,
-                                                        approximateData );
-   tnlExactOperatorEvaluator< Mesh, Vector, ExactOperator, Function, BoundaryConditionsType > operatorEvaluator;
-   operatorEvaluator.template evaluate< typename Mesh::Cell >( 0.0, mesh, exactOperator, function, boundaryConditions, exactData );
-
-   typename Mesh::Cell cell( mesh );
-
-   for( cell.getCoordinates().x() = 0;
-        cell.getCoordinates().x() < entities;
-        cell.getCoordinates().x()++ )
-   {
-      //cell.setIndex( mesh.getEntityIndex( cell ) );
-      cell.refresh();
-      if( cell.isBoundaryEntity() )
-         approximateData.setElement( cell.getIndex(), exactData.getElement( cell.getIndex() ) );
-   }
-
-   l1Err = mesh.getDifferenceLpNorm( exactData, approximateData, ( RealType ) 1.0 );
-   l2Err = mesh.getDifferenceLpNorm( exactData, approximateData, ( RealType ) 2.0 );
-   maxErr = mesh.getDifferenceAbsMax( exactData, approximateData );
-}
-
-/****
- * Implicit (matrix) approximation
- */
-
-template< typename Mesh,
-          typename ExactOperator,
-          typename ApproximateOperator,
-          typename Function >
-void
-tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlImplicitApproximation >::
-getError( const Mesh& mesh,
-          const ExactOperator& exactOperator,
-          const ApproximateOperator& approximateOperator,
-          const Function& function,
-          RealType& l1Err,
-          RealType& l2Err,
-          RealType& maxErr )
-{
-   typedef tnlVector< RealType, DeviceType, IndexType > Vector;
-   typedef tnlCSRMatrix< RealType, DeviceType, IndexType > MatrixType;
-   typedef typename MatrixType::CompressedRowsLengthsVector CompressedRowsLengthsVectorType;
-   Vector functionData, exactData, approximateData;
-   MatrixType matrix;
-   CompressedRowsLengthsVectorType rowLengths;
-   BoundaryConditionsType boundaryConditions;
-   boundaryConditions.setFunction( function );
-   ConstantFunctionType zeroFunction;
-
-   const IndexType entities = mesh.template getEntitiesCount< typename Mesh::Cell >();
-
-   if( ! functionData.setSize( entities ) ||
-       ! exactData.setSize( entities ) ||
-       ! approximateData.setSize( entities ) ||
-       ! rowLengths.setSize( entities ) )
-      return;
-
-   tnlFunctionDiscretizer< Mesh, Function, Vector >::template discretize< 0, 0, 0 >( mesh, function, functionData );
-
-   tnlMatrixSetter< MeshType, ApproximateOperator, BoundaryConditionsType, CompressedRowsLengthsVectorType > matrixSetter;
-   matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >(
-      mesh,
-      approximateOperator,
-      boundaryConditions,
-      rowLengths );
-   matrix.setDimensions( entities, entities );
-   if( ! matrix.setCompressedRowsLengths( rowLengths ) )
-      return;
-
-   tnlLinearSystemAssembler< Mesh, Vector, ApproximateOperator, BoundaryConditionsType, ConstantFunctionType, tnlNoTimeDiscretisation, MatrixType > systemAssembler;
-   systemAssembler.template assembly< typename Mesh::Cell >( 0.0, // time
-                                                          1.0, // tau
-                                                          mesh,
-                                                          approximateOperator,
-                                                          boundaryConditions,
-                                                          zeroFunction,
-                                                          functionData,
-                                                          matrix,
-                                                          approximateData // this has no meaning here
-                                                          );
-
-   tnlExactOperatorEvaluator< Mesh, Vector, ExactOperator, Function, BoundaryConditionsType > operatorEvaluator;
-   operatorEvaluator.template evaluate< typename Mesh::Cell >( 0.0, mesh, exactOperator, function, boundaryConditions, exactData );
-
-   typename Mesh::Cell cell( mesh );
-   for( cell.getCoordinates().x() = 0;
-        cell.getCoordinates().x() < entities;
-        cell.getCoordinates().x()++ )
-   {
-      IndexType i = mesh.getEntityIndex( cell );
-      if( ! cell.isBoundaryEntity() )
-         matrix.setElement( i, i, matrix.getElement( i, i ) - 1.0 );
-   }
-   matrix.vectorProduct( functionData, approximateData );
-
-   // TODO: replace this when matrix.vectorProduct has multiplicator parameter
-   for( IndexType i = 0; i < entities; i++ )
-      approximateData.setElement( i, -1.0 * approximateData.getElement( i ) );
-
-   for( cell.getCoordinates().x() = 0;
-        cell.getCoordinates().x() < entities;
-        cell.getCoordinates().x()++ )
-   {
-      IndexType i = mesh.getEntityIndex( cell );
-      if( cell.isBoundaryEntity() )
-         approximateData.setElement( i, exactData.getElement( i ) );
-   }
-
-   l1Err = mesh.getDifferenceLpNorm( exactData, approximateData, ( RealType ) 1.0 );
-   l2Err = mesh.getDifferenceLpNorm( exactData, approximateData, ( RealType ) 2.0 );
-   maxErr = mesh.getDifferenceAbsMax( exactData, approximateData );
-}
-
-#endif /* TNLAPPROXIMATIONERROR_IMPL_H_ */
diff --git a/tests/unit-tests/tnlUnitTestStarter.h b/tests/unit-tests/tnlUnitTestStarter.h
index 9e3a543ba026b580b919cc9e0eeb1802c2514bd3..4a84861f5f892febc4d50c46625d8762fed19784 100644
--- a/tests/unit-tests/tnlUnitTestStarter.h
+++ b/tests/unit-tests/tnlUnitTestStarter.h
@@ -35,9 +35,9 @@ class tnlUnitTestStarter
    static bool run()
    {
 #ifdef HAVE_CPPUNIT
-      CppUnit :: TextTestRunner runner;
-      runner. addTest( Tester :: suite() );
-      runner. setOutputter( new CppUnit::CompilerOutputter(&runner.result(), std::cout) );
+      CppUnit::TextTestRunner runner;
+      runner.addTest( Tester :: suite() );
+      runner.setOutputter( new CppUnit::CompilerOutputter(&runner.result(), std::cout) );
       if( ! runner.run() )
          return false;
       return true;
diff --git a/tnlConfig.h.in b/tnlConfig.h.in
index 755f4efcc2f3ac5a4960fa2a7568956e8783918f..1c12017f5c864d80c369abe8739cf6f5a80960f0 100644
--- a/tnlConfig.h.in
+++ b/tnlConfig.h.in
@@ -1,12 +1,14 @@
-@HAVE_CUBLAS@
-
-@HAVE_CUSP@
-
 @HAVE_SYS_TIME_H@
 
 @HAVE_SYS_RESOURCE_H@
 
-@HAVE_CUSPARSE@
+#ifdef HAVE_CUDA
+    @HAVE_CUBLAS@
+
+    @HAVE_CUSP@
+
+    @HAVE_CUSPARSE@
+#endif
 
 @HAVE_CPPUNIT@
 
diff --git a/tools/Makefile b/tools/Makefile
deleted file mode 100644
index 8ee664bd980ab5a7eadb2863ac28e524670c12a8..0000000000000000000000000000000000000000
--- a/tools/Makefile
+++ /dev/null
@@ -1,197 +0,0 @@
-# CMAKE generated file: DO NOT EDIT!
-# Generated by "Unix Makefiles" Generator, CMake Version 2.8
-
-# Default target executed when no arguments are given to make.
-default_target: all
-.PHONY : default_target
-
-#=============================================================================
-# Special targets provided by cmake.
-
-# Disable implicit rules so canoncical targets will work.
-.SUFFIXES:
-
-# Remove some rules from gmake that .SUFFIXES does not remove.
-SUFFIXES =
-
-.SUFFIXES: .hpux_make_needs_suffix_list
-
-# Suppress display of executed commands.
-$(VERBOSE).SILENT:
-
-# A target that is always out of date.
-cmake_force:
-.PHONY : cmake_force
-
-#=============================================================================
-# Set environment variables for the build.
-
-# The shell in which to execute make rules.
-SHELL = /bin/sh
-
-# The CMake executable.
-CMAKE_COMMAND = /usr/bin/cmake
-
-# The command to remove a file.
-RM = /usr/bin/cmake -E remove -f
-
-# The top-level source directory on which CMake was run.
-CMAKE_SOURCE_DIR = /home/oberhuber/workspace/tnl
-
-# The top-level build directory on which CMake was run.
-CMAKE_BINARY_DIR = /home/oberhuber/workspace/tnl
-
-#=============================================================================
-# Targets provided globally by CMake.
-
-# Special rule for the target edit_cache
-edit_cache:
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..."
-	/usr/bin/cmake -i .
-.PHONY : edit_cache
-
-# Special rule for the target edit_cache
-edit_cache/fast: edit_cache
-.PHONY : edit_cache/fast
-
-# Special rule for the target install
-install: preinstall
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
-	/usr/bin/cmake -P cmake_install.cmake
-.PHONY : install
-
-# Special rule for the target install
-install/fast: preinstall/fast
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
-	/usr/bin/cmake -P cmake_install.cmake
-.PHONY : install/fast
-
-# Special rule for the target install/local
-install/local: preinstall
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
-	/usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
-.PHONY : install/local
-
-# Special rule for the target install/local
-install/local/fast: install/local
-.PHONY : install/local/fast
-
-# Special rule for the target install/strip
-install/strip: preinstall
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
-	/usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
-.PHONY : install/strip
-
-# Special rule for the target install/strip
-install/strip/fast: install/strip
-.PHONY : install/strip/fast
-
-# Special rule for the target list_install_components
-list_install_components:
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\""
-.PHONY : list_install_components
-
-# Special rule for the target list_install_components
-list_install_components/fast: list_install_components
-.PHONY : list_install_components/fast
-
-# Special rule for the target package
-package: preinstall
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Run CPack packaging tool..."
-	cd /home/oberhuber/workspace/tnl && /usr/bin/cpack --config ./CPackConfig.cmake
-.PHONY : package
-
-# Special rule for the target package
-package/fast: package
-.PHONY : package/fast
-
-# Special rule for the target package_source
-package_source:
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Run CPack packaging tool for source..."
-	cd /home/oberhuber/workspace/tnl && /usr/bin/cpack --config ./CPackSourceConfig.cmake /home/oberhuber/workspace/tnl/CPackSourceConfig.cmake
-.PHONY : package_source
-
-# Special rule for the target package_source
-package_source/fast: package_source
-.PHONY : package_source/fast
-
-# Special rule for the target rebuild_cache
-rebuild_cache:
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
-	/usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
-.PHONY : rebuild_cache
-
-# Special rule for the target rebuild_cache
-rebuild_cache/fast: rebuild_cache
-.PHONY : rebuild_cache/fast
-
-# Special rule for the target test
-test:
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running tests..."
-	/usr/bin/ctest --force-new-ctest-process $(ARGS)
-.PHONY : test
-
-# Special rule for the target test
-test/fast: test
-.PHONY : test/fast
-
-# The main all target
-all: cmake_check_build_system
-	cd /home/oberhuber/workspace/tnl && $(CMAKE_COMMAND) -E cmake_progress_start /home/oberhuber/workspace/tnl/CMakeFiles /home/oberhuber/workspace/tnl/tools/CMakeFiles/progress.marks
-	cd /home/oberhuber/workspace/tnl && $(MAKE) -f CMakeFiles/Makefile2 tools/all
-	$(CMAKE_COMMAND) -E cmake_progress_start /home/oberhuber/workspace/tnl/CMakeFiles 0
-.PHONY : all
-
-# The main clean target
-clean:
-	cd /home/oberhuber/workspace/tnl && $(MAKE) -f CMakeFiles/Makefile2 tools/clean
-.PHONY : clean
-
-# The main clean target
-clean/fast: clean
-.PHONY : clean/fast
-
-# Prepare targets for installation.
-preinstall: all
-	cd /home/oberhuber/workspace/tnl && $(MAKE) -f CMakeFiles/Makefile2 tools/preinstall
-.PHONY : preinstall
-
-# Prepare targets for installation.
-preinstall/fast:
-	cd /home/oberhuber/workspace/tnl && $(MAKE) -f CMakeFiles/Makefile2 tools/preinstall
-.PHONY : preinstall/fast
-
-# clear depends
-depend:
-	cd /home/oberhuber/workspace/tnl && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
-.PHONY : depend
-
-# Help Target
-help:
-	@echo "The following are some of the valid targets for this Makefile:"
-	@echo "... all (the default if no target is provided)"
-	@echo "... clean"
-	@echo "... depend"
-	@echo "... edit_cache"
-	@echo "... install"
-	@echo "... install/local"
-	@echo "... install/strip"
-	@echo "... list_install_components"
-	@echo "... package"
-	@echo "... package_source"
-	@echo "... rebuild_cache"
-	@echo "... test"
-.PHONY : help
-
-
-
-#=============================================================================
-# Special targets to cleanup operation of make.
-
-# Special rule to run CMake to check the build system integrity.
-# No rule that depends on this can have commands that come from listfiles
-# because they might be regenerated.
-cmake_check_build_system:
-	cd /home/oberhuber/workspace/tnl && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
-.PHONY : cmake_check_build_system
-
diff --git a/tools/share/CMakeLists.txt b/tools/share/CMakeLists.txt
index 0f11c087e790d019d66d18e21f88304938d077c0..ecb1ae470f003137ffc39b55f7f09783d29290b0 100755
--- a/tools/share/CMakeLists.txt
+++ b/tools/share/CMakeLists.txt
@@ -1,3 +1,5 @@
+add_subdirectory (pkgconfig)
+
 INSTALL( FILES tnl-matrix-convert.cfg.desc               
                tnlcurve2gnuplot.cfg.desc               
-         DESTINATION share/tnl-${tnlVersion} )
\ No newline at end of file
+         DESTINATION share/tnl-${tnlVersion} )
diff --git a/tools/share/pkgconfig/CMakeLists.txt b/tools/share/pkgconfig/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1de0c9439f200eb488de3e7d8d944c237a778ea9
--- /dev/null
+++ b/tools/share/pkgconfig/CMakeLists.txt
@@ -0,0 +1,17 @@
+CONFIGURE_FILE( "tnl.pc.in" "${PROJECT_TOOLS_PATH}/share/pkgconfig/tnl.pc" @ONLY )
+INSTALL( FILES ${PROJECT_TOOLS_PATH}/share/pkgconfig/tnl.pc
+         DESTINATION share/pkgconfig )
+
+if( CUDA_FOUND )
+    CONFIGURE_FILE( "cuda.pc.in" "${PROJECT_TOOLS_PATH}/share/pkgconfig/cuda.pc" @ONLY )
+    CONFIGURE_FILE( "tnl-cuda.pc.in" "${PROJECT_TOOLS_PATH}/share/pkgconfig/tnl-cuda.pc" @ONLY )
+    INSTALL( FILES ${PROJECT_TOOLS_PATH}/share/pkgconfig/cuda.pc
+                   ${PROJECT_TOOLS_PATH}/share/pkgconfig/tnl-cuda.pc
+             DESTINATION share/pkgconfig )
+endif()
+
+if( OPENMP_FOUND )
+    CONFIGURE_FILE( "tnl-openmp.pc.in" "${PROJECT_TOOLS_PATH}/share/pkgconfig/tnl-openmp.pc" @ONLY )
+    INSTALL( FILES ${PROJECT_TOOLS_PATH}/share/pkgconfig/tnl-openmp.pc
+             DESTINATION share/pkgconfig )
+endif()
diff --git a/tools/share/pkgconfig/cuda.pc.in b/tools/share/pkgconfig/cuda.pc.in
new file mode 100644
index 0000000000000000000000000000000000000000..268e2a927fd761a32bf3767f8734825325c59aef
--- /dev/null
+++ b/tools/share/pkgconfig/cuda.pc.in
@@ -0,0 +1,11 @@
+prefix=@CUDA_TOOLKIT_ROOT_DIR@
+libdir=${prefix}/lib
+includedir=${prefix}/include
+version=@CUDA_VERSION_STRING@
+
+Name: CUDA
+Description: A parallel programming framework by Nvidia
+URL: https://www.nvidia.com/object/cuda_home_new.html
+Version: ${version}
+Libs:
+Cflags: -I${includedir}
diff --git a/tools/share/pkgconfig/tnl-cuda.pc.in b/tools/share/pkgconfig/tnl-cuda.pc.in
new file mode 100644
index 0000000000000000000000000000000000000000..bc3d5f50f991d72104644d82a68880d4a9caa437
--- /dev/null
+++ b/tools/share/pkgconfig/tnl-cuda.pc.in
@@ -0,0 +1,9 @@
+version=@tnlVersion@
+
+Name: TNL (with CUDA support)
+Description: Template Numerical Library (with CUDA support)
+URL:
+Version: ${version}
+Libs:
+Cflags: -DHAVE_CUDA -DHAVE_NOT_CXX11
+Requires: cuda, tnl = ${version}
diff --git a/tools/share/pkgconfig/tnl-openmp.pc.in b/tools/share/pkgconfig/tnl-openmp.pc.in
new file mode 100644
index 0000000000000000000000000000000000000000..cb00b5c5fe86728da1bb6e01389367be196c6d23
--- /dev/null
+++ b/tools/share/pkgconfig/tnl-openmp.pc.in
@@ -0,0 +1,9 @@
+version=@tnlVersion@
+
+Name: TNL (with OpenMP support)
+Description: Template Numerical Library (with OpenMP support)
+URL:
+Version: ${version}
+Libs: -lgomp
+Cflags: -DHAVE_OPENMP -fopenmp
+Requires: tnl = ${version}
diff --git a/tools/share/pkgconfig/tnl.pc.in b/tools/share/pkgconfig/tnl.pc.in
new file mode 100644
index 0000000000000000000000000000000000000000..0c5e5d8f0ba9fc528c7ce4881b81b5ce50563fbc
--- /dev/null
+++ b/tools/share/pkgconfig/tnl.pc.in
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+libdir=${prefix}/lib
+includedir=${prefix}/include
+version=@tnlVersion@
+
+Name: TNL
+Description: Template Numerical Library
+URL:
+Version: ${version}
+Libs: -L${libdir} -ltnl-${version}
+Cflags: -I${includedir}/tnl-${version}
diff --git a/tools/src/tnl-cuda-arch.cu b/tools/src/tnl-cuda-arch.cu
index f394059f76b6f66ee9f17d43937042e9a8ce6957..7f1fb17496601adc5ffc84467a9c5db25feae244 100644
--- a/tools/src/tnl-cuda-arch.cu
+++ b/tools/src/tnl-cuda-arch.cu
@@ -1,13 +1,19 @@
 #include <stdio.h> 
 
 int main() {
-    int num_devices;
-    if( cudaGetDeviceCount( &num_devices ) == cudaSuccess )
-        for( int i = 0; i < num_devices; i++ )
-        {
-            cudaDeviceProp prop;
-            cudaGetDeviceProperties( &prop, i );
+    int num_devices = 0;
+    cudaError_t error_id = cudaGetDeviceCount( &num_devices );
 
+    if( error_id != cudaSuccess ) {
+        fprintf(stderr, "cudaGetDeviceCount returned error %d (%s)\n",
+                (int) error_id, cudaGetErrorString(error_id));
+        exit(EXIT_FAILURE);
+    }
+
+    for( int i = 0; i < num_devices; i++ )
+    {
+        cudaDeviceProp prop;
+        cudaGetDeviceProperties( &prop, i );
             int compute_minor = prop.minor;
             // sm_21 is the only 'real' architecture that does not have 'virtual' counterpart
             if( prop.major == 2 )
@@ -17,6 +23,6 @@ int main() {
                 printf(" ");
             printf( "-gencode arch=compute_%d%d,code=sm_%d%d",
                     prop.major, compute_minor, prop.major, prop.minor );
-        }
+    }
     printf("\n");
 }
diff --git a/tools/src/tnl-err2eoc b/tools/src/tnl-err2eoc
index 4582ef2efbbd1aa60027406f69586e7529f1cfc3..f7f501d1055d2c6a430c08a8ec75aac6600749fa 100644
--- a/tools/src/tnl-err2eoc
+++ b/tools/src/tnl-err2eoc
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
 
 import sys, string, math
 
diff --git a/tools/src/tnl-init.h b/tools/src/tnl-init.h
index 57bca2bfd04d49ea0eb76625eb5743bd3ffaca1d..7f5fba252c11410f7a03e861ce39d1460a0c9cd7 100644
--- a/tools/src/tnl-init.h
+++ b/tools/src/tnl-init.h
@@ -21,10 +21,10 @@
 #include <config/tnlParameterContainer.h>
 #include <core/vectors/tnlVector.h>
 #include <mesh/tnlGrid.h>
-#include <functions/tnlFunctionDiscretizer.h>
 #include <functions/tnlTestFunction.h>
 #include <operators/tnlFiniteDifferences.h>
 #include <core/mfilename.h>
+#include <functions/tnlMeshFunction.h>
 
 template< typename MeshType,
           typename RealType,
@@ -45,10 +45,10 @@ bool renderFunction( const tnlParameterContainer& parameters )
    if( ! function.setup( parameters, "" ) )
       return false;
    cout << "done." << endl;
-   typedef tnlVector< RealType, tnlHost, typename MeshType::IndexType > DiscreteFunctionType;
-   DiscreteFunctionType discreteFunction;
-   if( ! discreteFunction.setSize( mesh.template getEntitiesCount< typename MeshType::Cell >() ) )
-      return false;
+   typedef tnlMeshFunction< MeshType, MeshType::meshDimensions > MeshFunctionType;
+   MeshFunctionType meshFunction( mesh );
+   //if( ! discreteFunction.setSize( mesh.template getEntitiesCount< typename MeshType::Cell >() ) )
+   //   return false;
    
    double finalTime = parameters.getParameter< double >( "final-time" );
    double initialTime = parameters.getParameter< double >( "initial-time" );
@@ -64,15 +64,15 @@ bool renderFunction( const tnlParameterContainer& parameters )
       if( numericalDifferentiation )
       {
          cout << "+ -> Computing the finite differences ... " << endl;
-         DiscreteFunctionType auxDiscreteFunction;
-         if( ! auxDiscreteFunction.setSize( mesh.template getEntitiesCount< typename MeshType::Cell >() ) )
-            return false;
-         tnlFunctionDiscretizer< MeshType, FunctionType, DiscreteFunctionType >::template discretize< 0, 0, 0 >( mesh, function, auxDiscreteFunction, time );
-         tnlFiniteDifferences< MeshType >::template getDifference< DiscreteFunctionType, xDiff, yDiff, zDiff, 0, 0, 0 >( mesh, auxDiscreteFunction, discreteFunction );
+         MeshFunctionType auxDiscreteFunction;
+         //if( ! auxDiscreteFunction.setSize( mesh.template getEntitiesCount< typename MeshType::Cell >() ) )
+         //   return false;
+         //tnlFunctionDiscretizer< MeshType, FunctionType, DiscreteFunctionType >::template discretize< 0, 0, 0 >( mesh, function, auxDiscreteFunction, time );
+         //tnlFiniteDifferences< MeshType >::template getDifference< DiscreteFunctionType, xDiff, yDiff, zDiff, 0, 0, 0 >( mesh, auxDiscreteFunction, discreteFunction );
       }
       else
       {
-         tnlFunctionDiscretizer< MeshType, FunctionType, DiscreteFunctionType >::template discretize< xDiff, yDiff, zDiff >( mesh, function, discreteFunction, time );
+         tnlMeshFunctionEvaluator< MeshFunctionType, FunctionType >::evaluate( meshFunction, function, time );
       }
 
       tnlString outputFile = parameters.getParameter< tnlString >( "output-file" );
@@ -92,7 +92,7 @@ bool renderFunction( const tnlParameterContainer& parameters )
       }
       else
          cout << "+ -> Writing the function to " << outputFile << " ... " << endl;
-      if( ! discreteFunction.save( outputFile) )
+      if( ! meshFunction.save( outputFile) )
          return false;
       time += tau;
       step ++;
diff --git a/tools/src/tnl-view.cpp b/tools/src/tnl-view.cpp
index ef63be37367c2aebfc21313eb340a3e90ff56683..90fd1ce802b967fa533495828e7fadda0249cc9d 100644
--- a/tools/src/tnl-view.cpp
+++ b/tools/src/tnl-view.cpp
@@ -24,12 +24,6 @@
 #include <mesh/tnlDummyMesh.h>
 #include <mesh/tnlGrid.h>
 
-// TODO: Remove
-/*#include <mesh/tnlMesh.h>
-#include <mesh/tnlMeshWriterNetgen.h>
-#include <mesh/config/tnlMeshConfigBase.h>
-#include <mesh/topologies/tnlMeshTriangleTopology.h>*/
-
 void setupConfig( tnlConfigDescription& config )
 {
    config.addDelimiter                            ( "General settings:" );
@@ -74,9 +68,9 @@ int main( int argc, char* argv[] )
    tnlString meshFile = parameters. getParameter< tnlString >( "mesh" );
    if( meshFile == "" )
    {
-      if( ! processFiles< tnlDummyMesh< double, tnlHost, int > >( parameters ) )
-         return EXIT_FAILURE;
-      return EXIT_SUCCESS;
+      //if( ! processFiles< tnlDummyMesh< double, tnlHost, int > >( parameters ) )
+      //   return EXIT_FAILURE;
+      //return EXIT_SUCCESS;
    }
    tnlString meshType;
    if( ! getObjectType( meshFile, meshType ) )
diff --git a/tools/src/tnl-view.h b/tools/src/tnl-view.h
index 82b3772c02a46f7af07a56f35583c27c281b0f86..f6760e202427c399002c76b7e56080d0edadf32b 100644
--- a/tools/src/tnl-view.h
+++ b/tools/src/tnl-view.h
@@ -25,6 +25,7 @@
 #include <core/vectors/tnlVector.h>
 #include <core/vectors/tnlMultiVector.h>
 #include <mesh/tnlGrid.h>
+#include <functions/tnlMeshFunction.h>
 
 using namespace std;
 
@@ -46,6 +47,152 @@ bool getOutputFileName( const tnlString& inputFileName,
    }
 }
 
+
+template< typename MeshFunction >
+bool writeMeshFunction( const typename MeshFunction::MeshType& mesh,
+                        const tnlString& inputFileName,
+                        const tnlParameterContainer& parameters  )
+{
+   MeshFunction function( mesh );
+   if( ! function.load( inputFileName ) )
+   {
+      std::cerr << "Unable to load mesh function from a file " << inputFileName << "." << std::endl;
+      return false;
+   }
+
+   int verbose = parameters. getParameter< int >( "verbose");
+   tnlString outputFormat = parameters. getParameter< tnlString >( "output-format" );
+   tnlString outputFileName;
+   if( ! getOutputFileName( inputFileName,
+                            outputFormat,
+                            outputFileName ) )
+      return false;
+   if( verbose )
+      cout << " writing to " << outputFileName << " ... " << flush;
+
+   return function.write( outputFileName, outputFormat );
+}
+
+template< typename Mesh,
+          int EntityDimensions,
+          typename Real >
+bool setMeshFunctionRealType( const Mesh& mesh,
+                              const tnlString& inputFileName,
+                              const tnlParameterContainer& parameters  )
+{
+   return writeMeshFunction< tnlMeshFunction< Mesh, EntityDimensions, Real > >( mesh, inputFileName, parameters );
+}
+
+template< typename Mesh,
+          int EntityDimensions >
+bool setMeshEntityType( const Mesh& mesh,
+                        const tnlString& inputFileName,
+                        const tnlList< tnlString >& parsedObjectType,
+                        const tnlParameterContainer& parameters )
+{
+   if( parsedObjectType[ 3 ] == "float" )
+      return setMeshFunctionRealType< Mesh, EntityDimensions, float >( mesh, inputFileName, parameters );
+   if( parsedObjectType[ 3 ] == "double" )
+      return setMeshFunctionRealType< Mesh, EntityDimensions, double >( mesh, inputFileName, parameters );
+   if( parsedObjectType[ 3 ] == "long double" )
+      return setMeshFunctionRealType< Mesh, EntityDimensions, long double >( mesh, inputFileName, parameters );
+   std::cerr << "Unsupported arithmetics " << parsedObjectType[ 3 ] << " in mesh function " << inputFileName << std::endl;
+   return false;
+}
+
+template< typename MeshReal,
+          typename MeshIndex >
+bool setMeshEntityDimensions( const tnlGrid< 1, MeshReal, tnlHost, MeshIndex >& mesh,
+                              const tnlString& inputFileName,
+                              const tnlList< tnlString >& parsedObjectType,
+                              const tnlParameterContainer& parameters )
+{
+   typedef tnlGrid< 1, MeshReal, tnlHost, MeshIndex > Mesh;
+   int meshEntityDimensions = atoi( parsedObjectType[ 2 ].getString() );
+   switch( meshEntityDimensions )
+   {
+      case 0:
+         return setMeshEntityType< Mesh, 0 >( mesh, inputFileName, parsedObjectType, parameters );
+         break;      
+      case 1:
+         return setMeshEntityType< Mesh, 1 >( mesh, inputFileName, parsedObjectType, parameters );
+         break;
+      default:
+         cerr << "Unsupported mesh functions entity dimensions count " << meshEntityDimensions << "." << endl;
+         return false;
+   }
+}
+
+template< typename MeshReal,
+          typename MeshIndex >
+bool setMeshEntityDimensions( const tnlGrid< 2, MeshReal, tnlHost, MeshIndex >& mesh,
+                              const tnlString& inputFileName,
+                              const tnlList< tnlString >& parsedObjectType,
+                              const tnlParameterContainer& parameters )
+{
+   typedef tnlGrid< 2, MeshReal, tnlHost, MeshIndex > Mesh;
+   int meshEntityDimensions = atoi( parsedObjectType[ 2 ].getString() );
+   switch( meshEntityDimensions )
+   {
+      case 0:
+         return setMeshEntityType< Mesh, 0 >( mesh, inputFileName, parsedObjectType, parameters );
+         break;            
+      case 1:
+         return setMeshEntityType< Mesh, 1 >( mesh, inputFileName, parsedObjectType, parameters );
+         break;
+      case 2:
+         return setMeshEntityType< Mesh, 2 >( mesh, inputFileName, parsedObjectType, parameters );
+         break;
+      default:
+         cerr << "Unsupported mesh functions entity dimensions count " << meshEntityDimensions << "." << endl;
+         return false;
+   }
+}
+
+template< typename MeshReal,
+          typename MeshIndex >
+bool setMeshEntityDimensions( const tnlGrid< 3, MeshReal, tnlHost, MeshIndex >& mesh,
+                              const tnlString& inputFileName,
+                              const tnlList< tnlString >& parsedObjectType,
+                              const tnlParameterContainer& parameters )
+{
+   typedef tnlGrid< 3, MeshReal, tnlHost, MeshIndex > Mesh;
+   int meshEntityDimensions = atoi( parsedObjectType[ 2 ].getString() );
+   switch( meshEntityDimensions )
+   {
+      case 0:
+         return setMeshEntityType< Mesh, 0 >( mesh, inputFileName, parsedObjectType, parameters );
+         break;      
+      case 1:
+         return setMeshEntityType< Mesh, 1 >( mesh, inputFileName, parsedObjectType, parameters );
+         break;
+      case 2:
+         return setMeshEntityType< Mesh, 2 >( mesh, inputFileName, parsedObjectType, parameters );
+         break;
+      case 3:
+         return setMeshEntityType< Mesh, 3 >( mesh, inputFileName, parsedObjectType, parameters );
+         break;
+      default:
+         cerr << "Unsupported mesh functions entity dimensions count " << meshEntityDimensions << "." << endl;
+         return false;
+   }
+}
+
+template< typename Mesh >
+bool setMeshFunction( const Mesh& mesh,
+                      const tnlString& inputFileName,
+                      const tnlList< tnlString >& parsedObjectType,
+                      const tnlParameterContainer& parameters )
+{
+   if( parsedObjectType[ 1 ] != mesh.getSerializationType() )
+   {
+      cerr << "Incompatible mesh type for the mesh function " << inputFileName << "." << endl;
+      return false;
+   }
+   return setMeshEntityDimensions( mesh, inputFileName, parsedObjectType, parameters );
+}
+
+
 template< typename Mesh, typename Element, typename Real, typename Index, int Dimensions >
 bool convertObject( const Mesh& mesh,
                     const tnlString& inputFileName,
@@ -283,7 +430,13 @@ bool processFiles( const tnlParameterContainer& parameters )
             error = true;
             continue;
          }
-         setElementType< Mesh >( mesh, inputFiles[ i ], parsedObjectType, parameters );
+         if( parsedObjectType[ 0 ] == "tnlMultiVector" ||
+             parsedObjectType[ 0 ] == "tnlSharedMultiVector" ||      
+             parsedObjectType[ 0 ] == "tnlSharedVector" ||
+             parsedObjectType[ 0 ] == "tnlVector" )
+            setElementType< Mesh >( mesh, inputFiles[ i ], parsedObjectType, parameters );
+         if( parsedObjectType[ 0 ] == "tnlMeshFunction" )
+            setMeshFunction< Mesh >( mesh, inputFiles[ i ], parsedObjectType, parameters );
          if( verbose )
             cout << "[ OK ].  " << endl;