diff --git a/.cproject b/.cproject
deleted file mode 100644
index 89a0873e084f7a0d00b9950c1919d6259972f95c..0000000000000000000000000000000000000000
--- a/.cproject
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
-	<storageModule moduleId="org.eclipse.cdt.core.settings">
-		<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.2134791445">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.2134791445" moduleId="org.eclipse.cdt.core.settings" name="Default">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.2134791445" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
-					<folderInfo id="cdt.managedbuild.toolchain.gnu.base.2134791445.1799170915" name="/" resourcePath="">
-						<toolChain id="cdt.managedbuild.toolchain.gnu.base.1762402759" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
-							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.840154721" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
-							<builder id="cdt.managedbuild.target.gnu.builder.base.573876641" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.archiver.base.958650307" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1237330740" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1856262209" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.315517693" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
-								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.950045328" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1786292703" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1133414639" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.692614544" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.assembler.base.336757143" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
-								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1329383797" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-							</tool>
-						</toolChain>
-					</folderInfo>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-		</cconfiguration>
-	</storageModule>
-	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-		<project id="tnl.null.219466708" name="tnl"/>
-	</storageModule>
-	<storageModule moduleId="scannerConfiguration">
-		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-	</storageModule>
-	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
-</cproject>
diff --git a/.gitignore b/.gitignore
index 95228a33e88d9365ddb32d498eea03a54192e3f0..26b082851c1968ea8a0896a009be495c73f884b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,44 +1,8 @@
-
-# /
-/build
-/missing
-/Makefile.in
-/ltmain.sh
-/install-sh
-/depcomp
-/configure
-/config.*
-/aclocal.m4
-/m4
-/autom4te.cache
+.settings
+/nbproject
 /Debug
 /Release
-.settings
-
-.settings
-
-# /src/
-/src/Makefile.in
-
-# /src/core/
-/src/core/Makefile.in
-
-# /src/debug/
-/src/debug/Makefile.in
-
-# /src/diff/
-/src/diff/Makefile.in
-
-# /src/matrix/
-/src/matrix/*.in
-
-# /tools/
-/tools/Makefile.in
-
-# /tools/share/
-/tools/share/Makefile.in
-
-# /tools/src/
-/tools/src/Makefile.in
 /Testing
 /CMakeLists.txt.user
+/doc/_build
+/Build
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 853803ec72fa07af3a533a48e72e78776d0e2f48..04257e1440198dacedbac7eb8adc924d79f17982 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,7 +12,7 @@
 # Vladimir Klement
 # Jakub Klinkovsky
 
-cmake_minimum_required( VERSION 2.8.10 )
+cmake_minimum_required( VERSION 3.4 )
 
 project( tnl )
 
@@ -33,22 +33,28 @@ 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( CMAKE_CXX_FLAGS "${CXXFLAGS} -g ")
-    #AddCompilerFlag( "-g" )
 else()
     set( PROJECT_BUILD_PATH ${PROJECT_SOURCE_DIR}/Release/src )
     set( PROJECT_TESTS_PATH ${PROJECT_SOURCE_DIR}/Release/tests )
     set( PROJECT_TOOLS_PATH ${PROJECT_SOURCE_DIR}/Release/tools )
     set( LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Release/lib)
     set( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/Release/bin)
-    #OptimizeForArchitecture()
-    AddCompilerFlag( "-O3 -march=native -DNDEBUG -g" )
 endif()
 
+# set Debug/Release options
+set( CMAKE_CXX_FLAGS "-std=c++11" )
+set( CMAKE_CXX_FLAGS_DEBUG "-g" )
+set( CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -DNDEBUG" )
+#set( CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -DNDEBUG -ftree-vectorizer-verbose=1 -ftree-vectorize -fopt-info-vec-missed -funroll-loops" )
+# pass -rdynamic only in Debug mode
+set( CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "" )
+set( CMAKE_SHARED_LIBRARY_LINK_C_FLAGS_DEBUG "-rdynamic" )
+set( CMAKE_SHARED_LIBRARY_LINK_C_FLAGS_RELEASE "" )
+
 get_filename_component( CXX_COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME )
 if( CXX_COMPILER_NAME MATCHES "icpc" )
    message( "Intel compiler detected..."    )
-   AddCompilerFlag( "-DHAVE_ICPC" )
+   set( CMAKE_CXX_FLAGS "${CXXFLAGS} -DHAVE_ICPC ")
 endif()
 
 #####
@@ -60,8 +66,8 @@ if( WITH_CUDA STREQUAL "yes" )
         set( BUILD_CUDA TRUE)
         set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE OFF)
         set(BUILD_SHARED_LIBS ON)
-        set(CUDA_SEPARABLE_COMPILATION ON)
-        set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ; -DHAVE_CUDA )
+        set(CUDA_SEPARABLE_COMPILATION ON)        
+        set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ;-DHAVE_CUDA  )
         #AddCompilerFlag( "-DHAVE_NOT_CXX11" ) # -U_GLIBCXX_ATOMIC_BUILTINS -U_GLIBCXX_USE_INT128 " )
         set( ALL_CUDA_ARCHS -gencode arch=compute_20,code=sm_20
                             -gencode arch=compute_30,code=sm_30
@@ -102,18 +108,29 @@ if( WITH_CUDA STREQUAL "yes" )
                 set( CUDA_ARCH -gencode arch=compute_${WITH_CUDA_ARCH},code=sm_${WITH_CUDA_ARCH} )
             endif()
         endif()
-        set( CUDA_ADD_EXECUTABLE_OPTIONS ${CUDA_ARCH} )
-        set( CUDA_ADD_LIBRARY_OPTIONS ${CUDA_ARCH} -shared )
-        set( CUDA_LINKER_OPTIONS "-arch sm_20 -shared" )
+        set( CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ; ${CUDA_ARCH} )
+        # TODO: this is necessary only due to a bug in cmake
+        set( CUDA_ADD_LIBRARY_OPTIONS -shared )
+        # TODO: workaround for a bug in cmake 3.5.0 (fixed in 3.5.1)
+        set( CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ; -ccbin "${CMAKE_CXX_COMPILER}" )
+        set( CUDA_HOST_COMPILER "" )
 
         ####
         # Check for cuBLAS
         #
-        if( WITH_CUBLAS STREQUAL "yes" ) 
-            message( "Enabling CUBLAS." )
-            set( HAVE_CUBLAS TRUE)
-            set( HAVE_CUBLAS "#define HAVE_CUBLAS 1" )
-        endif( WITH_CUBLAS STREQUAL "yes" )       
+        if( NOT WITH_CUBLAS STREQUAL "no" )
+            find_path( CUBLAS_INCLUDE_DIR cublas_v2.h
+                       /usr/local/cuda/include
+                       ${CUDA_INCLUDE_DIR}
+                       DOC "CUBLAS headers." )
+            if( ${CUBLAS_INCLUDE_DIR} STREQUAL "CUBLAS_INCLUDE_DIR-NOTFOUND" )
+                message( "CUBLAS not found." )
+                set( HAVE_CUBLAS "//#define HAVE_CUBLAS 1" )
+            else()
+                message( "CUBLAS found. -- ${CUBLAS_INCLUDE_DIR}" )
+                set( HAVE_CUBLAS "#define HAVE_CUBLAS 1" )
+            endif()
+        endif( NOT WITH_CUBLAS STREQUAL "no" )
 
         ####
         # Check for CUSP
@@ -133,7 +150,6 @@ if( WITH_CUDA STREQUAL "yes" )
         # Check for CUSPARSE
         #
         if( NOT WITH_CUSPARSE STREQUAL "no" )
-        
            find_path( CUSPARSE_INCLUDE_DIR cusparse.h
                       /usr/local/cuda/include                   
                       ${CUDA_INCLUDE_DIR}  
@@ -147,16 +163,10 @@ if( WITH_CUDA STREQUAL "yes" )
                cuda_include_directories( ${CUSPARSE_INCLUDE_DIR} )
                set( CUSPARSE_LIBRARY "${CUDA_cusparse_LIBRARY}" )
            endif()            
-        endif( NOT WITH_CUSPARSE STREQUAL "no" )
-   
-    #else( CUDA_FOUND )
-    #  AddCompilerFlag( "-std=c++11" )         
+        endif( NOT WITH_CUSPARSE STREQUAL "no" )        
     endif( CUDA_FOUND )
-#else( WITH_CUDA STREQUAL "yes" )
-   #AddCompilerFlag( "-std=gnu++0x -ftree-vectorizer-verbose=1" )       
-   #AddCompilerFlag( "-std=c++11" )       
 endif( WITH_CUDA STREQUAL "yes" )
-AddCompilerFlag( "-std=c++11" )       
+
 
 ####
 # Check for OpenMP
@@ -164,7 +174,7 @@ AddCompilerFlag( "-std=c++11" )
 find_package( OpenMP ) 
 if( OPENMP_FOUND )
    message( "Compiler supports OpenMP." )
-   set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_OPENMP -fopenmp")
+   set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_OPENMP -fopenmp" )
 endif()
 
 ####
@@ -318,27 +328,27 @@ endif( WITH_TESTS STREQUAL "yes" )
 #
 if( WITH_TEMPLATE_INSTANTIATION STREQUAL "yes" )
    AddCompilerFlag( "-DTEMPLATE_EXPLICIT_INSTANTIATION " )
-endif()   
 
-if( INSTANTIATE_INT STREQUAL "yes" )
-   AddCompilerFlag( "-DINSTANTIATE_INT " )
-endif()   
+   if( INSTANTIATE_INT STREQUAL "yes" )
+      AddCompilerFlag( "-DINSTANTIATE_INT " )
+   endif()
 
-if( INSTANTIATE_LONG_INT STREQUAL "yes" )
-   AddCompilerFlag( "-DINSTANTIATE_LONG_INT " )
-endif()   
+   if( INSTANTIATE_LONG_INT STREQUAL "yes" )
+      AddCompilerFlag( "-DINSTANTIATE_LONG_INT " )
+   endif()
 
-if( INSTANTIATE_FLOAT STREQUAL "yes" )
-   AddCompilerFlag( "-DINSTANTIATE_FLOAT " )
-endif()   
+   if( INSTANTIATE_FLOAT STREQUAL "yes" )
+      AddCompilerFlag( "-DINSTANTIATE_FLOAT " )
+   endif()
 
-if( INSTANTIATE_DOUBLE STREQUAL "yes" )
-   AddCompilerFlag( "-DINSTANTIATE_DOUBLE " )
-endif()   
+   if( INSTANTIATE_DOUBLE STREQUAL "yes" )
+      AddCompilerFlag( "-DINSTANTIATE_DOUBLE " )
+   endif()
 
-if( INSTANTIATE_LONG_DOUBLE STREQUAL "yes" )
-   AddCompilerFlag( "-DINSTANTIATE_LONG_DOUBLE " )
-endif()   
+   if( INSTANTIATE_LONG_DOUBLE STREQUAL "yes" )
+      AddCompilerFlag( "-DINSTANTIATE_LONG_DOUBLE " )
+   endif()
+endif()
 
 set( CXX_TEST_FLAGS "-fprofile-arcs -ftest-coverage" )
 set( LD_TEST_FLAGS "-lgcov -coverage" )
@@ -388,3 +398,13 @@ set(CPACK_SOURCE_STRIP_FILES "Release")
 
 #set(CPACK_PACKAGE_EXECUTABLES "MyExecutable" "My Executable")
 INCLUDE( CPack )
+
+# Print compiler options
+message( "-- Compiler options:" )
+message( "   CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}" )
+message( "   CMAKE_CXX_FLAGS_DEBUG = ${CMAKE_CXX_FLAGS_DEBUG}" )
+message( "   CMAKE_CXX_FLAGS_RELEASE = ${CMAKE_CXX_FLAGS_RELEASE}" )
+message( "   CMAKE_SHARED_LIBRARY_LINK_C_FLAGS = ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS}" )
+message( "   CMAKE_SHARED_LIBRARY_LINK_C_FLAGS_DEBUG = ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS_DEBUG}" )
+message( "   CMAKE_SHARED_LIBRARY_LINK_C_FLAGS_RELEASE = ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS_RELEASE}" )
+message( "   CUDA_NVCC_FLAGS = ${CUDA_NVCC_FLAGS}" )
diff --git a/TODO b/TODO
index 7619d268836f5bf97700a437fa452c3f83055ff9..43258d987301cfa9f5ffea2313de3244ad2a59a3 100644
--- a/TODO
+++ b/TODO
@@ -10,6 +10,8 @@ TODO:
  - data by se na hostu preskupila do souvisleho bloku dat a ten se prenesl najednou
 
 
+TODO:
+
 TODO:
  - zavest namespaces
 
diff --git a/build b/build
index 60e787a6be6f91dfbda466c6d00a5dcd809f50dc..8e3944caed3aca8e563d236ce74491e8151d78b1 100755
--- a/build
+++ b/build
@@ -6,7 +6,6 @@ WITH_CUDA="yes"
 WITH_TESTS="yes"
 
 WITH_CUDA_ARCH="auto"
-WITH_CUBLAS="no"
 WITH_TEMPLATE_INSTANTIATION="yes"
 INSTANTIATE_LONG_INT="no"
 INSTANTIATE_INT="yes"
@@ -28,7 +27,6 @@ do
         --build=*                        ) BUILD="${option#*=}" ;;
         --with-tests=*                   ) WITH_TESTS="${option#*=}" ;;
         --with-cuda=*                    ) WITH_CUDA="${option#*=}" ;;
-        --with-cublas=*                  ) WITH_CUBLAS="${option#*=}" ;;
         --with-cuda-arch=*               ) WITH_CUDA_ARCH="${option#*=}";;
         --with-templates-instantiation=* ) WITH_TEMPLATE_INSTANTIATION="${option#*=}" ;;
         --instantiate-long-int=*         ) INSTANTIATE_LONG_INT="${option#*=}" ;;
@@ -82,7 +80,6 @@ ${CMAKE} ${ROOT_DIR} \
          -DCMAKE_INSTALL_PREFIX=${PREFIX} \
          -DWITH_CUDA=${WITH_CUDA} \
          -DWITH_CUDA_ARCH=${WITH_CUDA_ARCH} \
-         -DWITH_CUBLAS=${WITH_CUBLAS} \
          -DWITH_TESTS=${WITH_TESTS} \
          -DPETSC_DIR=${PETSC_DIR} \
          -DDCMTK_DIR=${DCMTK_DIR} \
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index c80eb1f1a0a6864ae4e6d1a2012ad0d1ca7bd726..8d15cf0e81aa510d79edfbeca85f74f42bba17bd 100755
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,9 +1,14 @@
 add_subdirectory( heat-equation )
 add_subdirectory( navier-stokes )
+
 #add_subdirectory( mean-curvature-flow )
 add_subdirectory( hamilton-jacobi )
-add_subdirectory( hamilton-jacobi-parallel )
+#add_subdirectory( hamilton-jacobi-parallel )
 add_subdirectory( fast-sweeping )
 add_subdirectory( hamilton-jacobi-parallel-map )
 add_subdirectory( fast-sweeping-map )
-add_subdirectory( narrow-band )
+#add_subdirectory( narrow-band )
+add_subdirectory( advection )
+add_subdirectory( inviscid-flow )
+#add_subdirectory( mean-curvature-flow )
+
diff --git a/examples/advection/CMakeLists.txt b/examples/advection/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a09abadcdf99acf50e41f0909dfe02f4dfc31ea9
--- /dev/null
+++ b/examples/advection/CMakeLists.txt
@@ -0,0 +1,20 @@
+set( tnl_heat_equation_SOURCES     
+     advection.cpp
+     advection.cu )
+               
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnl-advection${debugExt} advection.cu)   
+   target_link_libraries( tnl-advection${debugExt} tnl${debugExt}-${tnlVersion}  ${CUSPARSE_LIBRARY} )
+ELSE(  BUILD_CUDA )               
+   ADD_EXECUTABLE( tnl-advection${debugExt} advection.cpp)     
+   target_link_libraries( tnl-advection${debugExt} tnl${debugExt}-${tnlVersion} )
+ENDIF( BUILD_CUDA )
+
+
+INSTALL( TARGETS tnl-advection${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+INSTALL( FILES tnl-run-advection
+               ${tnl_heat_equation_SOURCES}
+         DESTINATION share/tnl-${tnlVersion}/examples/advection )
diff --git a/examples/advection/LaxFridrichs.h b/examples/advection/LaxFridrichs.h
new file mode 100644
index 0000000000000000000000000000000000000000..4247058d05e67a9abc426684f06e59424fa59a18
--- /dev/null
+++ b/examples/advection/LaxFridrichs.h
@@ -0,0 +1,218 @@
+#ifndef LaxFridrichs_H
+#define LaxFridrichs_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichs
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichs< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+      Real tau;
+      Real artificalViscosity;
+      Real advectionSpeedX;
+      Real advectionSpeedY;
+
+      void setAdvectionSpeedY(const Real& advectionSpeed)
+      {
+	   this->advectionSpeedY = advectionSpeed;
+      }
+
+
+      void setAdvectionSpeedX(const Real& advectionSpeed)
+      {
+	   this->advectionSpeedX = advectionSpeed;
+      }
+
+      void setViscosity(const Real& artificalViscosity)
+      {
+	   this->artificalViscosity = artificalViscosity;
+      }
+      
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      static tnlString getType();
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichs< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+      Real tau;
+      Real artificalViscosity;
+      Real advectionSpeedX;
+      Real advectionSpeedY;
+
+      void setAdvectionSpeedY(const Real& advectionSpeed)
+      {
+	   this->advectionSpeedY = advectionSpeed;
+      }
+
+
+      void setAdvectionSpeedX(const Real& advectionSpeed)
+      {
+	   this->advectionSpeedX = advectionSpeed;
+      }
+
+      void setViscosity(const Real& artificalViscosity)
+      {
+	   this->artificalViscosity = artificalViscosity;
+      }
+      
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      static tnlString getType();
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichs< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+      Real tau;
+      Real artificalViscosity;
+      Real advectionSpeedX;
+      Real advectionSpeedY;
+
+      void setAdvectionSpeedY(const Real& advectionSpeed)
+      {
+	   this->advectionSpeedY = advectionSpeed;
+      }
+
+
+      void setAdvectionSpeedX(const Real& advectionSpeed)
+      {
+	   this->advectionSpeedX = advectionSpeed;
+      }
+
+      void setViscosity(const Real& artificalViscosity)
+      {
+	   this->artificalViscosity = artificalViscosity;
+      }
+      
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      static tnlString getType();
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "LaxFridrichs_impl.h"
+
+#endif	/* LaxFridrichs_H */
diff --git a/examples/advection/LaxFridrichs_impl.h b/examples/advection/LaxFridrichs_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc487e28187910cbbdfc037a21ba3327d167c311
--- /dev/null
+++ b/examples/advection/LaxFridrichs_impl.h
@@ -0,0 +1,357 @@
+#ifndef LaxFridrichs_IMPL_H
+#define LaxFridrichs_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichs< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   double a;
+   a = this->advectionSpeedX;
+   return   (0.5 / this->tau ) * this->artificalViscosity *
+	    ( u[ west ]- 2.0 * u[ center ] + u[ east ] )
+            - (a = this->advectionSpeedX * ( u[ east ] - u[west] ) ) * hxInverse * 0.5;
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichs< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); 
+   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); 
+   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 >(); 
+   double a;
+   double b;
+   a = this->advectionSpeedX;
+   b = this->advectionSpeedY;
+   return ( 0.25 / this->tau ) * this->artificalViscosity * 
+          ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4 * u[ center ] ) -
+          (a * ( u[ east ] - u[west] ) ) * hxInverse * 0.5 - 
+          (b * ( u[ north ] - u[ south ] ) ) * hyInverse * 0.5;
+
+
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichs< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   //return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+   /* const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );*/
+}
+
+#endif	/* LaxFridrichsIMPL_H */
+
diff --git a/examples/advection/advection.cpp b/examples/advection/advection.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..374d4714086168f7ebf1ed2a62664c4aaae0c4b7
--- /dev/null
+++ b/examples/advection/advection.cpp
@@ -0,0 +1 @@
+#include "advection.h"
diff --git a/examples/advection/advection.cu b/examples/advection/advection.cu
new file mode 100644
index 0000000000000000000000000000000000000000..374d4714086168f7ebf1ed2a62664c4aaae0c4b7
--- /dev/null
+++ b/examples/advection/advection.cu
@@ -0,0 +1 @@
+#include "advection.h"
diff --git a/examples/advection/advection.h b/examples/advection/advection.h
new file mode 100644
index 0000000000000000000000000000000000000000..3be5232725225cc15a40bc2487eede9cbc8412ef
--- /dev/null
+++ b/examples/advection/advection.h
@@ -0,0 +1,120 @@
+#include <tnlConfig.h>
+#include <solvers/tnlSolver.h>
+#include <solvers/tnlBuildConfigTags.h>
+#include <operators/tnlDirichletBoundaryConditions.h>
+#include <operators/tnlNeumannBoundaryConditions.h>
+#include <functions/tnlConstantFunction.h>
+#include "advectionProblem.h"
+#include "LaxFridrichs.h"
+#include "advectionRhs.h"
+#include "advectionBuildConfigTag.h"
+
+typedef advectionBuildConfigTag BuildConfig;
+
+/****
+ * Uncoment the following (and comment the previous line) for the complete build.
+ * This will include support for all floating point precisions, all indexing types
+ * and more solvers. You may then choose between them from the command line.
+ * The compile time may, however, take tens of minutes or even several hours,
+ * esppecially if CUDA is enabled. Use this, if you want, only for the final build,
+ * not in the development phase.
+ */
+//typedef tnlDefaultConfigTag BuildConfig;
+
+template< typename ConfigTag >class advectionConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription & config )
+      {
+         config.addDelimiter( "advection settings:" );
+         config.addEntry< tnlString >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
+            config.addEntryEnum< tnlString >( "dirichlet" );
+            config.addEntryEnum< tnlString >( "neumann" );
+         config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." );
+	 config.addEntry< double >( "artifical-viscosity", "This sets value of artifical viscosity (default 1)", 1.0);
+	 config.addEntry< tnlString >( "begin", "choose begin type", "sin");
+	    config.addEntryEnum< tnlString >( "sin");
+	    config.addEntryEnum< tnlString >( "sin_square");
+	 config.addEntry< double >( "advection-speedX", "This sets value of advection speed in X direction (default 1)" , 1.0);
+	 config.addEntry< double >( "advection-speedY", "This sets value of advection speed in Y direction (default 1)" , 1.0);
+	 config.addEntry< tnlString >( "move", "choose movement type", "advection");
+	    config.addEntryEnum< tnlString >( "advection");
+	    config.addEntryEnum< tnlString >( "rotation");
+	 config.addEntry< int >( "dimension", "choose movement typeproblem dimension", 1);
+	    config.addEntryEnum< int >( 1 );
+	    config.addEntryEnum< int >( 2 );
+	 config.addEntry< double >( "realSize", "Real size of scheme", 1.0);
+
+         /****
+          * Add definition of your solver command line arguments.
+          */
+
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename MeshType,
+          typename ConfigTag,
+          typename SolverStarter >
+class advectionSetter
+{
+   public:
+
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+
+      static bool run( const tnlParameterContainer & parameters )
+      {
+          enum { Dimensions = MeshType::getMeshDimensions() };
+          typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator;
+          typedef advectionRhs< MeshType, Real > RightHandSide;
+          typedef tnlStaticVector < MeshType::getMeshDimensions(), Real > Vertex;
+
+         /****
+          * Resolve the template arguments of your solver here.
+          * The following code is for the Dirichlet and the Neumann boundary conditions.
+          * Both can be constant or defined as descrete values of tnlVector.
+          */
+          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, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+                typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+                SolverStarter solverStarter;
+                return solverStarter.template run< Problem >( parameters );
+             }
+             typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunction, Real, Index > BoundaryConditions;
+             typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+             SolverStarter solverStarter;
+             return solverStarter.template run< Problem >( parameters );
+          }
+          typedef tnlMeshFunction< MeshType > MeshFunction;
+          if( boundaryConditionsType == "dirichlet" )
+          {
+             typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+             typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+             SolverStarter solverStarter;
+             return solverStarter.template run< Problem >( parameters );
+          }
+          typedef tnlNeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
+          typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+          SolverStarter solverStarter;
+          return solverStarter.template run< Problem >( parameters );
+      }
+
+};
+
+int main( int argc, char* argv[] )
+{
+   tnlSolver< advectionSetter, advectionConfig, BuildConfig > solver;
+   if( ! solver. run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
diff --git a/examples/advection/advectionBuildConfigTag.h b/examples/advection/advectionBuildConfigTag.h
new file mode 100644
index 0000000000000000000000000000000000000000..a8ea6ddef4eba8fa8802a3ae41f7ceefe1628273
--- /dev/null
+++ b/examples/advection/advectionBuildConfigTag.h
@@ -0,0 +1,43 @@
+#ifndef advectionBUILDCONFIGTAG_H_
+#define advectionBUILDCONFIGTAG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class advectionBuildConfigTag{};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< advectionBuildConfigTag, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< advectionBuildConfigTag, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< advectionBuildConfigTag, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< advectionBuildConfigTag, long int >{ enum { enabled = false }; };
+
+/****
+ * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types.
+ */
+
+template< int Dimensions, typename Real, typename Device, typename Index >
+   struct tnlConfigTagMesh< advectionBuildConfigTag, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = tnlConfigTagDimensions< advectionBuildConfigTag, Dimensions >::enabled  &&
+                         tnlConfigTagReal< advectionBuildConfigTag, Real >::enabled &&
+                         tnlConfigTagDevice< advectionBuildConfigTag, Device >::enabled &&
+                         tnlConfigTagIndex< advectionBuildConfigTag, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< advectionBuildConfigTag, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< advectionBuildConfigTag, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< advectionBuildConfigTag, tnlImplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< advectionBuildConfigTag, tnlExplicitEulerSolverTag >{ enum { enabled = true }; };
+
+#endif /* advectionBUILDCONFIGTAG_H_ */
diff --git a/examples/advection/advectionProblem.h b/examples/advection/advectionProblem.h
new file mode 100644
index 0000000000000000000000000000000000000000..64ae07480c584cacf3647d09c5bf075ad0f67ce8
--- /dev/null
+++ b/examples/advection/advectionProblem.h
@@ -0,0 +1,83 @@
+#ifndef advectionPROBLEM_H_
+#define advectionPROBLEM_H_
+
+#include <problems/tnlPDEProblem.h>
+#include <functions/tnlMeshFunction.h>
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+           typename DifferentialOperator >
+class advectionProblem:
+   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;
+
+      using typename BaseType::MeshType;
+      using typename BaseType::DofVectorType;
+      using typename BaseType::MeshDependentDataType;
+      tnlString velocityType;
+      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:
+
+      DifferentialOperator differentialOperator;
+      BoundaryCondition boundaryCondition;
+      RightHandSide rightHandSide;
+};
+
+#include "advectionProblem_impl.h"
+
+#endif /* advectionPROBLEM_H_ */
diff --git a/examples/advection/advectionProblem_impl.h b/examples/advection/advectionProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..6cb64dd3115df8856ca2c1aa94bf8b801f76e15e
--- /dev/null
+++ b/examples/advection/advectionProblem_impl.h
@@ -0,0 +1,325 @@
+#ifndef advectionPROBLEM_IMPL_H_
+#define advectionPROBLEM_IMPL_H_
+
+#include <core/mfilename.h>
+#include <matrices/tnlMatrixSetter.h>
+#include <solvers/pde/tnlExplicitUpdater.h>
+#include <solvers/pde/tnlLinearSystemAssembler.h>
+#include <solvers/pde/tnlBackwardTimeDiscretisation.h>
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getTypeStatic()
+{
+   return tnlString( "advectionProblem< " ) + Mesh :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getPrologHeader() const
+{
+   return tnlString( "advection" );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const
+{
+   /****
+    * Add data you want to have in the computation report (log) as follows:
+    * logger.writeParameter< double >( "Parameter description", parameter );
+    */
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setup( const tnlParameterContainer& parameters )
+{
+   if( ! this->boundaryCondition.setup( parameters, "boundary-conditions-" ) ||
+       ! this->rightHandSide.setup( parameters, "right-hand-side-" ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+typename advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getDofs( const MeshType& mesh ) const
+{
+   /****
+    * Return number of  DOFs (degrees of freedom) i.e. number
+    * of unknowns to be resolved by the main solver.
+    */
+   return mesh.template getEntitiesCount< typename MeshType::Cell >();
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+bindDofs( const MeshType& mesh,
+          DofVectorType& dofVector )
+{
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setInitialCondition( const tnlParameterContainer& parameters,
+                     const MeshType& mesh,
+                     DofVectorType& dofs,
+                     MeshDependentDataType& meshDependentData )
+{
+   cout << "vaules adding";
+   typedef typename MeshType::Cell Cell;
+   int dimensions = parameters.getParameter< int >( "dimension" );
+   int count = mesh.template getEntitiesCount< Cell >();
+   const RealType& size = parameters.getParameter< double >( "realSize" ) / pow(count, 1.0/dimensions);
+   const tnlString& beginChoice = parameters.getParameter< tnlString >( "begin" );
+   cout << beginChoice << " " << dimensions << "   " << size << "   " << count << "   "<< 1/dimensions << endl;
+   getchar();
+   if (beginChoice == "sin_square")
+      {
+	   double constantFunction;
+	   if (dimensions == 1)
+	       {
+                   cout << "adding DOFS" << endl;
+		   dofs[0] = 0;
+		   double expValue;
+		   for (IndexType i = 1; i < count-2; i++)
+		   {
+			expValue = exp(-pow(size*i-2,2));
+			if ((i>0.4*count) && (i<0.5*count)) constantFunction=1; else constantFunction=0;
+			if (expValue>constantFunction) dofs[i] = expValue; else dofs[i] = constantFunction;
+		   };
+		   dofs[count-1] = 0;
+		}
+	    else if (dimensions == 2)
+	       {
+                   count = sqrt(count);
+		   double expValue;
+		   for (IndexType i = 0; i < count-1; i++)
+                      for (IndexType j = 0; j < count-1; j++)
+		      {
+			expValue = exp(-pow(size*i-2,2)-pow(size*j-2,2));
+			if ((i>0.4*count) && (i<0.5*count) && (j>0.4*count) && (j<0.5*count)) constantFunction=1; else constantFunction=0;
+			if (expValue>constantFunction) dofs[i * count + j] = expValue; else dofs[i * count + j] = constantFunction;
+		      };
+		};
+       }
+   else if (beginChoice == "sin")
+      {
+	   if (dimensions == 1)
+	      {
+		   dofs[0] = 0;
+		   for (IndexType i = 1; i < count-2; i++)
+		   {
+			dofs[i] = exp(-pow(size*i-2,2));
+		   };
+		   dofs[count-1] = 0;
+		}
+	    else if (dimensions == 2)
+	       {
+                   count = sqrt(count);
+		   for (IndexType i = 1; i < count-1; i++)
+		      for (IndexType j = 1; j < count-1; j++)
+		      {
+			   dofs[i * count + j] = exp(-pow(size*i-2,2)-pow(size*j-2,2));
+		      };
+		};
+     };
+   //setting velocity field
+   cout << dofs << endl;
+   getchar();
+   /*const tnlString& initialConditionFile = parameters.getParameter< tnlString >( "initial-condition" );
+   if( ! dofs.load( initialConditionFile ) )
+   {
+      cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << endl;
+      return false;
+   }
+   return true;*/
+   dofs.save( "dofs.tnl" );
+   this->velocityType = parameters.getParameter< tnlString >( "move" );
+   const double artificalViscosity = parameters.getParameter< double >( "artifical-viscosity" );
+   differentialOperator.setViscosity(artificalViscosity);
+   const double advectionSpeedX = parameters.getParameter< double >( "advection-speedX" );
+   differentialOperator.setAdvectionSpeedX(advectionSpeedX);
+   const double advectionSpeedY = parameters.getParameter< double >( "advection-speedY" );
+   differentialOperator.setAdvectionSpeedY(advectionSpeedY);
+   cout << "vaules added";
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+   template< typename Matrix >
+bool
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setupLinearSystem( const MeshType& mesh,
+                   Matrix& matrix )
+{
+   const IndexType dofs = this->getDofs( mesh );
+   typedef typename Matrix::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
+advectionProblem< 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 );
+   tnlString fileName;
+   FileNameBaseNumberEnding( "u-", step, 5, ".tnl", fileName );
+   if( ! dofs.save( fileName ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getExplicitRHS( const RealType& time,
+                const RealType& tau,
+                const MeshType& mesh,
+                DofVectorType& _u,
+                DofVectorType& _fu,
+                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 mesh dependent data if you need.
+    */
+   typedef typename MeshType::Cell Cell;
+   int count = sqrt(mesh.template getEntitiesCount< Cell >());
+//   const RealType& size = parameters.getParameter< double >( "realSize" ) / pow(count, 0.5);
+/*   if (this->velocityType == "rotation")
+   {
+      double radius;
+      for (int i =1; i < count; i++)
+         for (int j =1; j < count; j++)
+            {
+               radius = sqrt(pow(i-1-(count/2.0),2) + pow(j-1-(count/2.0),2));
+            if (radius != 0.0)
+               _fu[(i-1)*count+j-1] =(0.25*tau)*differentialOperator.artificalViscosity*			//smoothening part
+               (_u[(i-1)*count-2+j]+_u[(i-1)*count+j]+
+               _u[i*count+j-1]+_u[(i-2)*count+j-1]- 
+               4.0*_u[(i-1)*count+j-1])
+               -((1.0/(2.0*count))*differentialOperator.advectionSpeedX						//X addition
+               *radius*(-1)*((j-1-(count/2.0))/radius)
+	       *(_u[(i-1)*count+j]-_u[(i-1)*count+j-2])) 
+	       -((1.0/(2.0*count))*differentialOperator.advectionSpeedY						//Y addition
+               *radius*((i-1-(count/2.0))/radius)
+	       *(_u[i*count+j-1]-_u[(i-2)*count+j-1]))
+            ;}
+  }
+   else if (this->velocityType == "advection")
+*/  { 
+   this->bindDofs( mesh, _u );
+   tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
+   MeshFunctionType u( mesh, _u ); 
+   MeshFunctionType fu( mesh, _fu );
+   differentialOperator.setTau(tau); 
+   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 + tau, 
+       u ); */
+ }
+}
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+   template< typename Matrix >
+void
+advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+assemblyLinearSystem( const RealType& time,
+                      const RealType& tau,
+                      const MeshType& mesh,
+                      DofVectorType& _u,
+                      Matrix& matrix,
+                      DofVectorType& b,
+                      MeshDependentDataType& meshDependentData )
+{
+   /*tnlLinearSystemAssembler< Mesh,
+                             MeshFunctionType,
+                             DifferentialOperator,
+                             BoundaryCondition,
+                             RightHandSide,
+                             tnlBackwardTimeDiscretisation,
+                             Matrix,
+                             DofVectorType > systemAssembler;
+
+   tnlMeshFunction< Mesh > u( mesh, _u );
+   systemAssembler.template assembly< typename Mesh::Cell >( time,
+                                                             tau,
+                                                             mesh,
+                                                             this->differentialOperator,
+                                                             this->boundaryCondition,
+                                                             this->rightHandSide,
+                                                             u,
+                                                             matrix,
+                                                             b );*/
+}
+
+#endif /* advectionPROBLEM_IMPL_H_ */
diff --git a/examples/advection/advectionRhs.h b/examples/advection/advectionRhs.h
new file mode 100644
index 0000000000000000000000000000000000000000..3bd2c294e142cac0779f66bdc99da51dc572222b
--- /dev/null
+++ b/examples/advection/advectionRhs.h
@@ -0,0 +1,29 @@
+#ifndef advectionRHS_H_
+#define advectionRHS_H_
+#include<functions/tnlDomain.h>
+template< typename Mesh, typename Real >class advectionRhs
+  : public tnlDomain< Mesh::meshDimensions, MeshDomain > 
+ {
+   public:
+
+      typedef Mesh MeshType;
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                  const tnlString& prefix = "" )
+      {
+         return true;
+      }
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         typedef typename MeshEntity::MeshType::VertexType VertexType;
+         VertexType v = entity.getCenter();
+         return 0.0;
+      };
+};
+
+#endif /* advectionRHS_H_ */
diff --git a/examples/advection/tnl-run-advection b/examples/advection/tnl-run-advection
new file mode 100644
index 0000000000000000000000000000000000000000..4ce2c6be3f3aea3c49e3619155cc489335bb2e25
--- /dev/null
+++ b/examples/advection/tnl-run-advection
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+tnl-grid-setup --dimensions 1 \
+               --origin-x 0.0 \
+               --proportions-x 10.0 \
+               --size-x 500 \
+ 
+#tnl-init --test-function sin-wave \
+#         --output-file init.tnl
+tnl-advection-dbg --time-discretisation explicit \
+	      --time-step 1.0e-3 \
+              --boundary-conditions-constant 0 \
+              --discrete-solver merson \
+              --snapshot-period 0.1 \
+              --final-time 1.0 \
+	      --artifical-viscosity 1.0 \
+	      --begin sin \
+	      --advection-speedX 2.0 \
+
+tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/advection/tnl-run-advection1 b/examples/advection/tnl-run-advection1
new file mode 100644
index 0000000000000000000000000000000000000000..fb5e81faf2e19ab8e6b19c02c0c441dd96a9c807
--- /dev/null
+++ b/examples/advection/tnl-run-advection1
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+tnl-grid-setup --dimensions 2 \
+               --origin-x 0.0 \
+               --origin-y 0.0 \
+               --proportions-x 10.0 \
+               --proportions-y 10.0 \
+               --size-x 500 \
+               --size-y 500 \
+ 
+#tnl-init --test-function sin-wave \
+#         --output-file init.tnl
+./advection --time-discretisation explicit \
+	      --time-step 1.0e-3 \
+              --boundary-conditions-constant 0 \
+              --discrete-solver euler \
+              --snapshot-period 0.1 \
+              --final-time 1.0 \
+	      --artifical-viscosity 0.2 \
+	      --begin sin_square \
+	      --advection-speedX 2.0 \
+	      --advection-speedY 2.0 \
+
+tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/advection/tnl-run-advectionrot1 b/examples/advection/tnl-run-advectionrot1
new file mode 100644
index 0000000000000000000000000000000000000000..5d3e3990a98ef64233a6b629b4002cc50b26a923
--- /dev/null
+++ b/examples/advection/tnl-run-advectionrot1
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+tnl-grid-setup --dimensions 2 \
+               --origin-x 0.0 \
+               --origin-y 0.0 \
+               --proportions-x 10.0 \
+               --proportions-y 10.0 \
+               --size-x 100 \
+               --size-y 100 \
+ 
+#tnl-init --test-function sin-wave \
+#         --output-file init.tnl
+./advection --time-discretisation explicit \
+	      --time-step 1.0e-2 \
+              --boundary-conditions-constant 0 \
+              --discrete-solver euler \
+              --snapshot-period 0.1 \
+              --final-time 1.0 \
+	      --artifical-viscosity 5.0 \
+	      --begin sin_square \
+	      --advection-speedX 2.0 \
+	      --advection-speedY 2.0 \
+              --move rotation \
+
+tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h b/examples/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h
index a7d7284a8c449f6e80fc8acefb5f345bc9881338..f08db8adbf79f203f33370f1cbe386437b909923 100644
--- a/examples/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h
+++ b/examples/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h
@@ -186,7 +186,6 @@ __global__ void synchronizeCUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevi
 template <typename SchemeHost, typename SchemeDevice, typename Device>
 __global__ void synchronize2CUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver);
 
-#endif
 
 
 __device__
@@ -213,6 +212,7 @@ double atomicFabsMin(double* address, double val)
 	return __longlong_as_double(old);
 }
 
+#endif
 
 #include "tnlParallelMapSolver2D_impl.h"
 #endif /* TNLPARALLELMAPSOLVER_H_ */
diff --git a/examples/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h b/examples/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h
index 17ff077e61c59b2295821f6537534063bceee263..de1bc3a3c510098f9d1687d0c5e976cc160c4f2e 100644
--- a/examples/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h
+++ b/examples/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h
@@ -602,7 +602,7 @@ void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::stre
 		}
 
 
-		if(abs(this->u0[i-k]) < mesh.template getSpaceStepsProducts< 1, 0 >()+mesh.template getSpaceStepsProducts< 0, 1 >() )
+		if(fabs(this->u0[i-k]) < mesh.template getSpaceStepsProducts< 1, 0 >()+mesh.template getSpaceStepsProducts< 0, 1 >() )
 			this->work_u[i] = this->u0[i-k];
 		else
 			this->work_u[i] = Sign(this->u0[i-k])*MAP_SOLVER_MAX_VALUE;
@@ -766,7 +766,7 @@ tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::runSubgri
 
 
       if(maxResidue != 0.0)
-    	  currentTau =  abs(this -> cflCondition / maxResidue);
+    	  currentTau =  fabs(this -> cflCondition / maxResidue);
 
 
       if(currentTau > 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >())
diff --git a/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h b/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h
index bafe34672b19b0ce63f77a8be4bb76c50068be84..4eb53beb42ad03716806e3999d687dbadf05f552 100644
--- a/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h
+++ b/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h
@@ -335,18 +335,19 @@ __global__ void synchronize2CUDA3D(tnlParallelEikonalSolver<3, SchemeHost, Schem
 #endif
 
 
-__device__
+#ifdef HAVE_CUDA
+__cuda_callable__
 double fabsMin( double x, double y)
 {
-	double fx = abs(x);
+	double fx = fabs(x);
 
-	if(Min(fx,abs(y)) == fx)
+	if(Min(fx,fabs(y)) == fx)
 		return x;
 	else
 		return y;
 }
 
-__device__
+__cuda_callable__
 double atomicFabsMin(double* address, double val)
 {
 	unsigned long long int* address_as_ull =
@@ -359,6 +360,7 @@ double atomicFabsMin(double* address, double val)
 	return __longlong_as_double(old);
 }
 
+#endif
 
 #include "tnlParallelEikonalSolver2D_impl.h"
 #include "tnlParallelEikonalSolver3D_impl.h"
diff --git a/examples/inviscid-flow/1d/CMakeLists.txt b/examples/inviscid-flow/1d/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6fe0766eec90a76d7888c56f615122804abf4bcc
--- /dev/null
+++ b/examples/inviscid-flow/1d/CMakeLists.txt
@@ -0,0 +1,20 @@
+set( tnl_heat_equation_SOURCES     
+     euler.cpp
+     euler.cu )
+               
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE(tnl-euler-1d${debugExt} euler.cu)
+   target_link_libraries (tnl-euler-1d${debugExt} tnl${debugExt}-${tnlVersion}  ${CUSPARSE_LIBRARY} )
+ELSE(  BUILD_CUDA )               
+   ADD_EXECUTABLE(tnl-euler-1d${debugExt} euler.cpp)     
+   target_link_libraries (tnl-euler-1d${debugExt} tnl${debugExt}-${tnlVersion} )
+ENDIF( BUILD_CUDA )
+
+
+INSTALL( TARGETS tnl-euler-1d${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+INSTALL( FILES tnl-run-euler-1d
+               ${tnl_heat_equation_SOURCES}
+         DESTINATION share/tnl-${tnlVersion}/examples/inviscid-flow-1d )
diff --git a/examples/inviscid-flow/1d/EulerPressureGetter.h b/examples/inviscid-flow/1d/EulerPressureGetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff007850870e130bacbd9e5fe7d54089b59f88d8
--- /dev/null
+++ b/examples/inviscid-flow/1d/EulerPressureGetter.h
@@ -0,0 +1,58 @@
+#ifndef EulerPressureGetter_H
+#define EulerPressureGetter_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+#include <functions/tnlDomain.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class EulerPressureGetter
+: public tnlDomain< Mesh::getMeshDimensions(), MeshDomain >
+{
+   public:
+      
+      typedef Mesh MeshType;
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      
+      EulerPressureGetter( const MeshFunctionType& velocity,
+                           const MeshFunctionType& rhoVel,
+                           const MeshFunctionType& energy,
+                           const RealType& gamma )
+      : rho( rho ), rhoVel( rhoVel ), energy( energy ), gamma( gamma )
+      {}
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         return this->operator[]( entity.getIndex() );
+      }
+      
+      __cuda_callable__
+      Real operator[]( const IndexType& idx ) const
+      {
+         return ( this->gamma - 1.0 ) * ( this->energy[ idx ] - 0.5 * this->rhoVel[ idx ] * this->rhoVel[ idx ] / this->rho[ idx ]);
+      }
+
+      
+   protected:
+      
+      Real gamma;
+      
+      const MeshFunctionType& rho;
+      
+      const MeshFunctionType& rhoVel;
+      
+      const MeshFunctionType& energy;
+
+};
+
+#endif	/* EulerPressureGetter_H */
diff --git a/examples/inviscid-flow/1d/EulerVelGetter.h b/examples/inviscid-flow/1d/EulerVelGetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a838627e80389e52cbe522814d3fddf0f2cb2f7
--- /dev/null
+++ b/examples/inviscid-flow/1d/EulerVelGetter.h
@@ -0,0 +1,51 @@
+#ifndef EulerVelGetter_H
+#define EulerVelGetter_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class EulerVelGetter
+: public tnlDomain< Mesh::getMeshDimensions(), MeshDomain >
+{
+   public:
+      
+      typedef Mesh MeshType;
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      
+      EulerVelGetter( const MeshFunctionType& rho,
+                      const MeshFunctionType& rhoVel)
+      : rho( rho ), rhoVel( rhoVel )
+      {}
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const
+      {
+         return this->operator[]( entity.getIndex() );
+      }
+      
+      __cuda_callable__
+      Real operator[]( const IndexType& idx ) const
+      {
+         return this->rho[ idx ] / this->rhoVel[ idx ];
+      }
+
+      
+   protected:
+      
+      const MeshFunctionType& rho;
+      
+      const MeshFunctionType& rhoVel;
+
+};
+
+#endif	/* EulerVelGetter_H */
diff --git a/examples/inviscid-flow/1d/LaxFridrichs.h b/examples/inviscid-flow/1d/LaxFridrichs.h
new file mode 100644
index 0000000000000000000000000000000000000000..eada21a9522638082da55a81e32df35d40cffcdd
--- /dev/null
+++ b/examples/inviscid-flow/1d/LaxFridrichs.h
@@ -0,0 +1,31 @@
+#ifndef LaxFridrichs_H
+#define LaxFridrichs_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+#include "LaxFridrichsContinuity.h"
+#include "LaxFridrichsMomentum.h"
+#include "LaxFridrichsEnergy.h"
+#include "EulerVelGetter.h"
+#include "EulerPressureGetter.h"
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichs
+{
+   public:
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef tnlMeshFunction< Mesh > MeshFunctionType;
+ 
+      typedef LaxFridrichsContinuity< Mesh, Real, Index > Continuity;
+      typedef LaxFridrichsMomentum< Mesh, Real, Index > Momentum;
+      typedef LaxFridrichsEnergy< Mesh, Real, Index > Energy;
+      typedef EulerVelGetter< Mesh, Real, Index > Velocity;
+      typedef EulerPressureGetter< Mesh, Real, Index > Pressure;
+   
+};
+
+#endif	/* LaxFridrichs_H */
diff --git a/examples/inviscid-flow/1d/LaxFridrichsContinuity.h b/examples/inviscid-flow/1d/LaxFridrichsContinuity.h
new file mode 100644
index 0000000000000000000000000000000000000000..6622d01e1c720c26a2fc42cd15bfe757086999c6
--- /dev/null
+++ b/examples/inviscid-flow/1d/LaxFridrichsContinuity.h
@@ -0,0 +1,181 @@
+#ifndef LaxFridrichsContinuity_H
+#define LaxFridrichsContinuity_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsContinuity
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsContinuity< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocity;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocity(const MeshFunctionType velocity)
+      {
+          //this->velocity = velocity;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsContinuity< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocity;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+	  this->velocity = velocity;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsContinuity< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocity;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+          this->velocity = velocity;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "LaxFridrichsContinuity_impl.h"
+
+#endif	/* LaxFridrichsContinuity_H */
diff --git a/examples/inviscid-flow/1d/LaxFridrichsContinuity_impl.h b/examples/inviscid-flow/1d/LaxFridrichsContinuity_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..59a5e420e4ce112fefc81229a493fdc30d179ff7
--- /dev/null
+++ b/examples/inviscid-flow/1d/LaxFridrichsContinuity_impl.h
@@ -0,0 +1,341 @@
+#ifndef LaxFridrichsContinuity_IMPL_H
+#define LaxFridrichsContinuity_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsContinuity< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsContinuity< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsContinuity< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+    //rho
+    const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+    const IndexType& center = entity.getIndex(); 
+    const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+    const IndexType& west = neighbourEntities.template getEntityIndex< -1 >();
+    return (0.5 * this->tau) * ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) 
+          - 0.5 * hxInverse * ( u[ west ] * this->velocity[ west ] - u[ east ] * this->velocity[ east ] );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsContinuity< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsContinuity< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsContinuity< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsContinuity< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsContinuity< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& hySquareInverse = entity.getMesh().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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsContinuity< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsContinuity< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsContinuity< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsContinuity< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsContinuity< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsContinuity< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsContinuity< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* LaxFridrichsContinuityIMPL_H */
+
diff --git a/examples/inviscid-flow/1d/LaxFridrichsEnergy.h b/examples/inviscid-flow/1d/LaxFridrichsEnergy.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4f668ec845d4e51d5bb6fca7d73a436a4313192
--- /dev/null
+++ b/examples/inviscid-flow/1d/LaxFridrichsEnergy.h
@@ -0,0 +1,197 @@
+#ifndef LaxFridrichsEnergy_H
+#define LaxFridrichsEnergy_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsEnergy
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsEnergy< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocity;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+          this->velocity = velocity;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsEnergy< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocity;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+	  this->velocity = velocity;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsEnergy< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocity;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+          this->velocity = velocity;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "LaxFridrichsEnergy_impl.h"
+
+#endif	/* LaxFridrichsEnergy_H */
diff --git a/examples/inviscid-flow/1d/LaxFridrichsEnergy_impl.h b/examples/inviscid-flow/1d/LaxFridrichsEnergy_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ffdb9e4b1e66a78c03418c928371aa2c85cbee0
--- /dev/null
+++ b/examples/inviscid-flow/1d/LaxFridrichsEnergy_impl.h
@@ -0,0 +1,348 @@
+#ifndef LaxFridrichsEnergy_IMPL_H
+#define LaxFridrichsEnergy_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsEnergy< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsEnergy< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsEnergy< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   //energy
+   const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >();
+   return (0.5 * this->tau) * ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) 
+          - 0.5 * hxInverse * 
+          (( u[ west ] + this->pressure[ west ] ) * velocity[ west ]  
+          - (u[ east ] + this->pressure[ east ] ) * velocity[ east ] );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsEnergy< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsEnergy< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsEnergy< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsEnergy< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsEnergy< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& hySquareInverse = entity.getMesh().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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsEnergy< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsEnergy< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsEnergy< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsEnergy< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsEnergy< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsEnergy< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsEnergy< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* LaxFridrichsEnergyIMPL_H */
+
diff --git a/examples/inviscid-flow/1d/LaxFridrichsMomentum.h b/examples/inviscid-flow/1d/LaxFridrichsMomentum.h
new file mode 100644
index 0000000000000000000000000000000000000000..e13232471ce4e643f330630f6db7d6a7f4338d38
--- /dev/null
+++ b/examples/inviscid-flow/1d/LaxFridrichsMomentum.h
@@ -0,0 +1,197 @@
+#ifndef LaxFridrichsMomentum_H
+#define LaxFridrichsMomentum_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsMomentum
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentum< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocity;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+          this->velocity = velocity;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentum< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocity;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+	  this->velocity = velocity;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentum< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocity;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+          this->velocity = velocity;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "LaxFridrichsMomentum_impl.h"
+
+#endif	/* LaxFridrichsMomentum_H */
diff --git a/examples/inviscid-flow/1d/LaxFridrichsMomentum_impl.h b/examples/inviscid-flow/1d/LaxFridrichsMomentum_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..30f42f22180bc7e6383354198d36b846facc8e46
--- /dev/null
+++ b/examples/inviscid-flow/1d/LaxFridrichsMomentum_impl.h
@@ -0,0 +1,343 @@
+#ifndef LaxFridrichsMomentum_IMPL_H
+#define LaxFridrichsMomentum_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsMomentum< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsMomentum< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsMomentum< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   //rhoVelocity
+   const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >();
+   return (0.5 * this->tau) * ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) 
+          - 0.5 * hxInverse * 
+          (( u[ west ] * this -> velocity[ west ] + this -> pressure [ west ] ) 
+          - (u[ east ] * this -> velocity[ east ] + this -> pressure [ east ] ));
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsMomentum< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsMomentum< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsMomentum< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsMomentum< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsMomentum< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& hySquareInverse = entity.getMesh().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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsMomentum< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsMomentum< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsMomentum< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsMomentum< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsMomentum< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsMomentum< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsMomentum< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* LaxFridrichsMomentumIMPL_H */
+
diff --git a/examples/inviscid-flow/1d/euler.cpp b/examples/inviscid-flow/1d/euler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4d76005cb1f70724be978ff0fa6fec63c4a8a76f
--- /dev/null
+++ b/examples/inviscid-flow/1d/euler.cpp
@@ -0,0 +1 @@
+#include "euler.h"
diff --git a/examples/inviscid-flow/1d/euler.cu b/examples/inviscid-flow/1d/euler.cu
new file mode 100644
index 0000000000000000000000000000000000000000..4d76005cb1f70724be978ff0fa6fec63c4a8a76f
--- /dev/null
+++ b/examples/inviscid-flow/1d/euler.cu
@@ -0,0 +1 @@
+#include "euler.h"
diff --git a/examples/inviscid-flow/1d/euler.h b/examples/inviscid-flow/1d/euler.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e8d584b572c5d2b527ffeae70093ea5678e08b5
--- /dev/null
+++ b/examples/inviscid-flow/1d/euler.h
@@ -0,0 +1,116 @@
+#include <tnlConfig.h>
+#include <solvers/tnlSolver.h>
+#include <solvers/tnlBuildConfigTags.h>
+#include <operators/tnlDirichletBoundaryConditions.h>
+#include <operators/tnlNeumannBoundaryConditions.h>
+#include <functions/tnlConstantFunction.h>
+#include "eulerProblem.h"
+#include "LaxFridrichs.h"
+
+#include "eulerRhs.h"
+#include "eulerBuildConfigTag.h"
+
+typedef eulerBuildConfigTag BuildConfig;
+
+/****
+ * Uncoment the following (and comment the previous line) for the complete build.
+ * This will include support for all floating point precisions, all indexing types
+ * and more solvers. You may then choose between them from the command line.
+ * The compile time may, however, take tens of minutes or even several hours,
+ * esppecially if CUDA is enabled. Use this, if you want, only for the final build,
+ * not in the development phase.
+ */
+//typedef tnlDefaultConfigTag BuildConfig;
+
+template< typename ConfigTag >class eulerConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription & config )
+      {
+         config.addDelimiter( "euler settings:" );
+         config.addEntry< tnlString >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
+            config.addEntryEnum< tnlString >( "dirichlet" );
+            config.addEntryEnum< tnlString >( "neumann" );
+         config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." );
+         config.addEntry< double >( "left-density", "This sets a value of left density." );
+         config.addEntry< double >( "left-velocity", "This sets a value of left velocity." );
+         config.addEntry< double >( "left-pressure", "This sets a value of left pressure." );
+         config.addEntry< double >( "riemann-border", "This sets a position of discontinuity." );
+         config.addEntry< double >( "right-density", "This sets a value of right density." );
+         config.addEntry< double >( "right-velocity", "This sets a value of right velocity." );
+         config.addEntry< double >( "right-pressure", "This sets a value of right pressure." );
+         config.addEntry< double >( "gamma", "This sets a value of gamma constant." );
+
+         /****
+          * Add definition of your solver command line arguments.
+          */
+
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename MeshType,
+          typename ConfigTag,
+          typename SolverStarter >
+class eulerSetter
+{
+   public:
+
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+
+      static bool run( const tnlParameterContainer & parameters )
+      {
+          enum { Dimensions = MeshType::getMeshDimensions() };
+          typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator;
+          typedef eulerRhs< MeshType, Real > RightHandSide;
+          typedef tnlStaticVector < MeshType::getMeshDimensions(), Real > Vertex;
+
+         /****
+          * Resolve the template arguments of your solver here.
+          * The following code is for the Dirichlet and the Neumann boundary conditions.
+          * Both can be constant or defined as descrete values of tnlVector.
+          */
+          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, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+                typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+                SolverStarter solverStarter;
+                return solverStarter.template run< Problem >( parameters );
+             }
+             typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunction, Real, Index > BoundaryConditions;
+             typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+             SolverStarter solverStarter;
+             return solverStarter.template run< Problem >( parameters );
+          }
+          typedef tnlMeshFunction< MeshType > MeshFunction;
+          if( boundaryConditionsType == "dirichlet" )
+          {
+             typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+             typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+             SolverStarter solverStarter;
+             return solverStarter.template run< Problem >( parameters );
+          }
+          typedef tnlNeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
+          typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+          SolverStarter solverStarter;
+          return solverStarter.template run< Problem >( parameters );
+      }
+
+};
+
+int main( int argc, char* argv[] )
+{
+   tnlSolver< eulerSetter, eulerConfig, BuildConfig > solver;
+   if( ! solver. run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
diff --git a/examples/inviscid-flow/1d/eulerBuildConfigTag.h b/examples/inviscid-flow/1d/eulerBuildConfigTag.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0fc2953ad7f66124a5824a35a873bbf850ec5ab
--- /dev/null
+++ b/examples/inviscid-flow/1d/eulerBuildConfigTag.h
@@ -0,0 +1,44 @@
+#ifndef eulerBUILDCONFIGTAG_H_
+#define eulerBUILDCONFIGTAG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class eulerBuildConfigTag{};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< eulerBuildConfigTag, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< eulerBuildConfigTag, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< eulerBuildConfigTag, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< eulerBuildConfigTag, long int >{ enum { enabled = false }; };
+
+template< int Dimensions > struct tnlConfigTagDimensions< eulerBuildConfigTag, Dimensions >{ enum { enabled = ( Dimensions == 1 ) }; };
+
+/****
+ * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types.
+ */
+template< int Dimensions, typename Real, typename Device, typename Index >
+   struct tnlConfigTagMesh< eulerBuildConfigTag, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = tnlConfigTagDimensions< eulerBuildConfigTag, Dimensions >::enabled  &&
+                         tnlConfigTagReal< eulerBuildConfigTag, Real >::enabled &&
+                         tnlConfigTagDevice< eulerBuildConfigTag, Device >::enabled &&
+                         tnlConfigTagIndex< eulerBuildConfigTag, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< eulerBuildConfigTag, tnlExplicitEulerSolverTag >{ enum { enabled = true }; };
+
+#endif /* eulerBUILDCONFIGTAG_H_ */
diff --git a/examples/inviscid-flow/1d/eulerProblem.h b/examples/inviscid-flow/1d/eulerProblem.h
new file mode 100644
index 0000000000000000000000000000000000000000..6bce37a02c4713f80343f8f40b05d08647851f11
--- /dev/null
+++ b/examples/inviscid-flow/1d/eulerProblem.h
@@ -0,0 +1,107 @@
+#ifndef eulerPROBLEM_H_
+#define eulerPROBLEM_H_
+
+#include <problems/tnlPDEProblem.h>
+#include <functions/tnlMeshFunction.h>
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+           typename DifferentialOperator >
+class eulerProblem:
+   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;
+
+      using typename BaseType::MeshType;
+      using typename BaseType::DofVectorType;
+      using typename BaseType::MeshDependentDataType;
+      typedef tnlMeshFunction<Mesh,Mesh::getMeshDimensions(),RealType>MeshFunction;
+      
+      typedef typename DifferentialOperator::Continuity Continuity;
+      typedef typename DifferentialOperator::Momentum Momentum;
+      typedef typename DifferentialOperator::Energy Energy;
+      typedef typename DifferentialOperator::Velocity Velocity;
+      typedef typename DifferentialOperator::Pressure Pressure;
+      
+
+
+      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 );
+      
+      bool postIterate( const RealType& time,
+                        const RealType& tau,
+                        const MeshType& mesh,
+                        DofVectorType& dofs,
+                        MeshDependentDataType& meshDependentData );
+
+   protected:
+
+      DifferentialOperator differentialOperator;
+      BoundaryCondition boundaryCondition;
+      RightHandSide rightHandSide;
+      
+      MeshFunctionType uRho, uRhoVelocity, uEnergy;
+      MeshFunctionType fuRho, fuRhoVelocity, fuEnergy;
+      
+      MeshFunctionType pressure, velocity, rho, rhoVel, energy;
+      
+      RealType gamma;
+
+
+};
+
+#include "eulerProblem_impl.h"
+
+#endif /* eulerPROBLEM_H_ */
diff --git a/examples/inviscid-flow/1d/eulerProblem_impl.h b/examples/inviscid-flow/1d/eulerProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..66768ef112e833fb7cc18172ba2d78860b184de7
--- /dev/null
+++ b/examples/inviscid-flow/1d/eulerProblem_impl.h
@@ -0,0 +1,374 @@
+#ifndef eulerPROBLEM_IMPL_H_
+#define eulerPROBLEM_IMPL_H_
+
+#include <core/mfilename.h>
+#include <matrices/tnlMatrixSetter.h>
+#include <solvers/pde/tnlExplicitUpdater.h>
+#include <solvers/pde/tnlLinearSystemAssembler.h>
+#include <solvers/pde/tnlBackwardTimeDiscretisation.h>
+#include "LaxFridrichsContinuity.h"
+#include "LaxFridrichsMomentum.h"
+#include "LaxFridrichsEnergy.h"
+#include "EulerVelGetter.h"
+#include "EulerPressureGetter.h"
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getTypeStatic()
+{
+   return tnlString( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getPrologHeader() const
+{
+   return tnlString( "euler" );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const
+{
+   /****
+    * Add data you want to have in the computation report (log) as follows:
+    * logger.writeParameter< double >( "Parameter description", parameter );
+    */
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setup( const tnlParameterContainer& parameters )
+{
+   if( ! this->boundaryCondition.setup( parameters, "boundary-conditions-" ) ||
+       ! this->rightHandSide.setup( parameters, "right-hand-side-" ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+typename eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getDofs( const MeshType& mesh ) const
+{
+   /****
+    * Return number of  DOFs (degrees of freedom) i.e. number
+    * of unknowns to be resolved by the main solver.
+    */
+   return 3*mesh.template getEntitiesCount< typename MeshType::Cell >();
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+bindDofs( const MeshType& mesh,
+          DofVectorType& dofVector )
+{
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setInitialCondition( const tnlParameterContainer& parameters,
+                     const MeshType& mesh,
+                     DofVectorType& dofs,
+                     MeshDependentDataType& meshDependentData )
+{
+   cout << endl << "get conditions from CML";
+   typedef typename MeshType::Cell Cell;
+   this->gamma = parameters.getParameter< RealType >( "gamma" );
+   RealType rhoL = parameters.getParameter< RealType >( "left-density" );
+   RealType velL = parameters.getParameter< RealType >( "left-velocity" );
+   RealType preL = parameters.getParameter< RealType >( "left-pressure" );
+   RealType eL = ( preL / (gamma - 1) ) + 0.5 * rhoL * velL * velL;
+   RealType rhoR = parameters.getParameter< RealType >( "right-density" );
+   RealType velR = parameters.getParameter< RealType >( "right-velocity" );
+   RealType preR = parameters.getParameter< RealType >( "right-pressure" );
+   RealType eR = ( preR / (gamma - 1) ) + 0.5 * rhoR * velR * velR;
+   RealType x0 = parameters.getParameter< RealType >( "riemann-border" );
+   cout <<endl << gamma << " " << rhoL << " " << velL << " " << preL << " " << eL << " " << rhoR << " " << velR << " " << preR << " " << eR << " " << x0 << " " << gamma << endl;
+   int count = mesh.template getEntitiesCount< Cell >();
+cout << count << endl;
+   uRho.bind(mesh, dofs, 0);
+   uRhoVelocity.bind(mesh, dofs, count);
+   uEnergy.bind(mesh, dofs, 2 * count);
+   tnlVector < RealType, DeviceType, IndexType > data;
+   data.setSize(2*count);
+   velocity.bind( mesh, data, 0);
+   pressure.bind( mesh, data, count );
+   cout << endl << "set conditions from CML"<< endl;   
+   for(IndexType i = 0; i < count; i++)
+      if (i < x0 * count )
+         {
+            uRho[i] = rhoL;
+            uRhoVelocity[i] = rhoL * velL;
+            uEnergy[i] = eL;
+            velocity[i] = velL;
+            pressure[i] = preL;
+         }
+      else
+         {
+            uRho[i] = rhoR;
+            uRhoVelocity[i] = rhoR * velR;
+            uEnergy[i] = eR;
+            velocity[i] = velR;
+            pressure[i] = preR;
+         };
+   cout << "dofs = " << dofs << endl;
+   getchar();
+  
+   
+   /*
+   const tnlString& initialConditionFile = parameters.getParameter< tnlString >( "initial-condition" );
+   if( ! dofs.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
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setupLinearSystem( const MeshType& mesh,
+                   Matrix& matrix )
+{
+/*   const IndexType dofs = this->getDofs( mesh );
+   typedef typename Matrix::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
+eulerProblem< 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 );
+   tnlString fileName;
+   typedef typename MeshType::Cell Cell;
+   int count = mesh.template getEntitiesCount< Cell >();
+   ofstream vysledek;
+/*   cout << "pressure:" << endl;
+   for (IndexType i = 0; i<count; i++) cout << this->pressure[i] << " " << i ;
+      vysledek.open("pressure" + to_string(step) + ".txt");
+   for (IndexType i = 0; i<count; i++)
+      vysledek << 0.01*i << " " << pressure[i] << endl;
+   vysledek.close();
+   cout << " " << endl;
+   cout << "velocity:" << endl;
+   for (IndexType i = 0; i<count; i++) cout << this->velocity[i] << " " ;
+      vysledek.open("velocity" + to_string(step) + ".txt");
+   for (IndexType i = 0; i<count; i++)
+      vysledek << 0.01*i << " " << pressure[i] << endl;
+   vysledek.close();
+   cout << "energy:" << endl;
+   for (IndexType i = 0; i<count; i++) cout << this->uEnergy[i] << " " ;
+      vysledek.open("energy" + to_string(step) + ".txt");
+   for (IndexType i = 0; i<count; i++)
+      vysledek << 0.01*i << " " << uEnergy[i] << endl;
+   vysledek.close();
+   cout << " " << endl;
+   cout << "density:" << endl;
+   for (IndexType i = 0; i<count; i++) cout << this->uRho[i] << " " ;
+      vysledek.open("density" + to_string(step) + ".txt");
+   for (IndexType i = 0; i<count; i++)
+      vysledek << 0.01*i << " " << uRho[i] << endl;
+   vysledek.close();
+*/   getchar();
+
+   FileNameBaseNumberEnding( "rho-", step, 5, ".tnl", fileName );
+   if( ! uRho.save( fileName ) )
+      return false;
+   FileNameBaseNumberEnding( "rhoVel-", step, 5, ".tnl", fileName );
+   if( ! uRhoVelocity.save( fileName ) )
+      return false;
+   FileNameBaseNumberEnding( "energy-", step, 5, ".tnl", fileName );
+   if( ! uEnergy.save( fileName ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getExplicitRHS( const RealType& time,
+                const RealType& tau,
+                const MeshType& mesh,
+                DofVectorType& _u,
+                DofVectorType& _fu,
+                MeshDependentDataType& meshDependentData )
+{
+    cout << "explicitRHS" << endl;
+    typedef typename MeshType::Cell Cell;
+    int count = mesh.template getEntitiesCount< Cell >();
+	//bind _u
+    this->uRho.bind(mesh, _u, 0);
+    this->uRhoVelocity.bind(mesh, _u ,count);
+    this->uEnergy.bind(mesh, _u, 2 * count);
+		
+	//bind _fu
+    this->fuRho.bind(mesh, _u, 0);
+    this->fuRhoVelocity.bind(mesh, _u, count);
+    this->fuEnergy.bind(mesh, _u, 2 * count);
+
+   //generating Differential operator object
+   Continuity lF1DContinuity;
+   Momentum lF1DMomentum;
+   Energy lF1DEnergy;
+
+   
+   
+   cout << "explicitRHSrho" << endl;   
+   //rho
+   this->bindDofs( mesh, _u );
+   lF1DContinuity.setTau(tau);
+   lF1DContinuity.setVelocity(velocity);
+   /*tnlExplicitUpdater< Mesh, MeshFunctionType, Continuity, BoundaryCondition, RightHandSide > explicitUpdaterContinuity;
+   explicitUpdaterContinuity.template update< typename Mesh::Cell >( time,
+                                                           mesh,
+                                                           lF1DContinuity,
+                                                           this->boundaryCondition,
+                                                           this->rightHandSide,
+                                                           uRho,
+                                                           fuRho );*/
+
+   cout << "explicitRHSrhovel" << endl;
+   //rhoVelocity
+   lF1DMomentum.setTau(tau);
+   lF1DMomentum.setVelocity(velocity);
+   lF1DMomentum.setPressure(pressure);
+   tnlExplicitUpdater< Mesh, MeshFunctionType, Momentum, BoundaryCondition, RightHandSide > explicitUpdaterMomentum;
+   explicitUpdaterMomentum.template update< typename Mesh::Cell >( time,
+                                                           mesh,
+                                                           lF1DMomentum,
+                                                           this->boundaryCondition,
+                                                           this->rightHandSide,
+                                                           uRhoVelocity,
+                                                           fuRhoVelocity );
+   
+   cout << "explicitRHSenergy" << endl;
+   //energy
+   lF1DEnergy.setTau(tau);
+   lF1DEnergy.setPressure(pressure);
+   lF1DEnergy.setVelocity(velocity);
+   tnlExplicitUpdater< Mesh, MeshFunctionType, Energy, BoundaryCondition, RightHandSide > explicitUpdaterEnergy;
+   explicitUpdaterEnergy.template update< typename Mesh::Cell >( time,
+                                                           mesh,
+                                                           lF1DEnergy,
+                                                           this->boundaryCondition,
+                                                           this->rightHandSide,
+                                                           uEnergy,
+                                                           fuEnergy );  
+ 
+ }
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+   template< typename Matrix >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+assemblyLinearSystem( const RealType& time,
+                      const RealType& tau,
+                      const MeshType& mesh,
+                      DofVectorType& _u,
+                      Matrix& matrix,
+                      DofVectorType& b,
+                      MeshDependentDataType& meshDependentData )
+{
+/*   tnlLinearSystemAssembler< Mesh,
+                             MeshFunctionType,
+                             DifferentialOperator,
+                             BoundaryCondition,
+                             RightHandSide,
+                             tnlBackwardTimeDiscretisation,
+                             Matrix,
+                             DofVectorType > systemAssembler;
+
+   tnlMeshFunction< Mesh > u( mesh, _u );
+   systemAssembler.template assembly< typename Mesh::Cell >( time,
+                                                             tau,
+                                                             mesh,
+                                                             this->differentialOperator,
+                                                             this->boundaryCondition,
+                                                             this->rightHandSide,
+                                                             u,
+                                                             matrix,
+                                                             b );*/
+}
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+postIterate( const RealType& time,
+             const RealType& tau,
+             const MeshType& mesh,
+             DofVectorType& dofs,
+             MeshDependentDataType& meshDependentData )
+{
+   //velocity
+   this->velocity.setMesh( mesh );
+   Velocity velocityGetter( uRho, uRhoVelocity );
+   this->velocity = velocityGetter;
+   //pressure
+   this->pressure.setMesh( mesh );
+   Pressure pressureGetter( uRho, uRhoVelocity, uEnergy, gamma );
+   this->pressure = pressureGetter;
+}
+
+#endif /* eulerPROBLEM_IMPL_H_ */
diff --git a/examples/inviscid-flow/1d/eulerRhs.h b/examples/inviscid-flow/1d/eulerRhs.h
new file mode 100644
index 0000000000000000000000000000000000000000..582dc36413ae36d78aa06a03be2ad745325263d6
--- /dev/null
+++ b/examples/inviscid-flow/1d/eulerRhs.h
@@ -0,0 +1,29 @@
+#ifndef eulerRHS_H_
+#define eulerRHS_H_
+#include<functions/tnlDomain.h>
+template< typename Mesh, typename Real >class eulerRhs
+  : public tnlDomain< Mesh::meshDimensions, MeshDomain > 
+ {
+   public:
+
+      typedef Mesh MeshType;
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                  const tnlString& prefix = "" )
+      {
+         return true;
+      }
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         typedef typename MeshEntity::MeshType::VertexType VertexType;
+         VertexType v = entity.getCenter();
+         return 0.0;
+      };
+};
+
+#endif /* eulerRHS_H_ */
diff --git a/examples/inviscid-flow/1d/tnl-run-euler-1d b/examples/inviscid-flow/1d/tnl-run-euler-1d
new file mode 100644
index 0000000000000000000000000000000000000000..a45f664042d2f4dab646319e506dd130b6238cfc
--- /dev/null
+++ b/examples/inviscid-flow/1d/tnl-run-euler-1d
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+tnl-grid-setup --dimensions 1 \
+               --origin-x 0.0 \
+               --proportions-x 1.0 \
+               --size-x 100 
+
+#tnl-init --test-function sin-wave \
+#         --output-file init.tnl
+tnl-euler-1d-dbg --time-discretisation explicit \
+	      --time-step 1.0e-3 \
+              --boundary-conditions-constant 0 \
+              --discrete-solver euler \
+              --snapshot-period 0.1 \
+              --final-time 1.0 \
+              --left-density 1.0 \
+              --left-velocity 0.75 \
+              --left-pressure 1.0 \
+              --right-density 0.125 \
+              --right-velocity 0 \
+              --right-pressure 0.1 \
+              --gamma 1.4 \
+              --riemann-border 0.3 \
+
+tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/inviscid-flow/2d/CMakeLists.txt b/examples/inviscid-flow/2d/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d753d50afcc11a2fccbe04e30410c77e8a5c1f81
--- /dev/null
+++ b/examples/inviscid-flow/2d/CMakeLists.txt
@@ -0,0 +1,21 @@
+set( tnl_heat_equation_SOURCES     
+     euler.cpp
+     euler-cuda.cu )
+               
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE(tnl-euler-2d${debugExt} euler-cuda.cu)
+   target_link_libraries (tnl-euler-2d${debugExt} tnl${debugExt}-${tnlVersion}  ${CUSPARSE_LIBRARY} )
+ELSE(  BUILD_CUDA )               
+   ADD_EXECUTABLE(tnl-euler-2d${debugExt} euler.cpp)     
+   target_link_libraries (tnl-euler-2d${debugExt} tnl${debugExt}-${tnlVersion} )
+ENDIF( BUILD_CUDA )
+
+
+INSTALL( TARGETS tnl-euler-2d${debugExt}
+         RUNTIME DESTINATION bin
+         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+        
+INSTALL( FILES run-euler
+               ${tnl_heat_equation_SOURCES}
+         DESTINATION share/tnl-${tnlVersion}/examples/inviscid-flow-2d )
+
diff --git a/examples/inviscid-flow/2d/EulerPressureGetter.h b/examples/inviscid-flow/2d/EulerPressureGetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..f58813e712cc194c25f867616844bee34557e06d
--- /dev/null
+++ b/examples/inviscid-flow/2d/EulerPressureGetter.h
@@ -0,0 +1,218 @@
+#ifndef EulerPressureGetter_H
+#define EulerPressureGetter_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class EulerPressureGetter
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerPressureGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real gamma;
+      MeshFunctionType velocity;
+      MeshFunctionType rho;
+      MeshFunctionType energy;
+
+      void setGamma(const Real& gamma)
+      {
+          this->gamma = gamma;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+          this->velocity = velocity;
+      };
+
+      void setRho(const MeshFunctionType& rho)
+      {
+          this->rho = rho;
+      };
+
+      void setEnergy(const MeshFunctionType& energy)
+      {
+          this->energy = energy;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerPressureGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real gamma;
+      MeshFunctionType velocity;
+      MeshFunctionType rho;
+      MeshFunctionType energy;
+
+      void setGamma(const Real& gamma)
+      {
+          this->gamma = gamma;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+          this->velocity = velocity;
+      };
+
+      void setRho(const MeshFunctionType& rho)
+      {
+          this->rho = rho;
+      };
+
+      void setEnergy(const MeshFunctionType& energy)
+      {
+          this->energy = energy;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerPressureGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real gamma;
+      MeshFunctionType velocity;
+      MeshFunctionType rho;
+      MeshFunctionType energy;
+
+      void setGamma(const Real& gamma)
+      {
+          this->gamma = gamma;
+      };
+
+      void setVelocity(const MeshFunctionType& velocity)
+      {
+          this->velocity = velocity;
+      };
+
+      void setRho(const MeshFunctionType& rho)
+      {
+          this->rho = rho;
+      };
+
+      void setEnergy(const MeshFunctionType& energy)
+      {
+          this->energy = energy;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "EulerPressureGetter_impl.h"
+
+#endif	/* EulerPressureGetter_H */
diff --git a/examples/inviscid-flow/2d/EulerPressureGetter_impl.h b/examples/inviscid-flow/2d/EulerPressureGetter_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..481fe580f150f57cbeeaf10ac64da1840ce7debd
--- /dev/null
+++ b/examples/inviscid-flow/2d/EulerPressureGetter_impl.h
@@ -0,0 +1,334 @@
+#ifndef EulerPressureGetter_IMPL_H
+#define EulerPressureGetter_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerPressureGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerPressureGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerPressureGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerPressureGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerPressureGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerPressureGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerPressureGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerPressureGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+   //pressure
+   const IndexType& center = entity.getIndex(); 
+
+   return ( this->gamma - 1 ) * ( energy[ center ] - 0.5 * rho[ center ] * pow( velocity[ center ],2 ));
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerPressureGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerPressureGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerPressureGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerPressureGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerPressureGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerPressureGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerPressureGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* EulerPressureGetterIMPL_H */
+
diff --git a/examples/inviscid-flow/2d/EulerVelGetter.h b/examples/inviscid-flow/2d/EulerVelGetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b9ed8201f0a6ecdd146784d26e1335d78107154
--- /dev/null
+++ b/examples/inviscid-flow/2d/EulerVelGetter.h
@@ -0,0 +1,179 @@
+#ifndef EulerVelGetter_H
+#define EulerVelGetter_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class EulerVelGetter
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerVelGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      MeshFunctionType velX;
+      MeshFunctionType velY;
+
+      void setVelX(const MeshFunctionType& velX)
+      {
+          this->velX = velX;
+      };
+
+      void setVelY(const MeshFunctionType& velY)
+      {
+          this->velY = velY;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerVelGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      MeshFunctionType velX;
+      MeshFunctionType velY;
+
+      void setVelX(const MeshFunctionType& velX)
+      {
+          this->velX = velX;
+      };
+
+      void setVelY(const MeshFunctionType& velY)
+      {
+          this->velY = velY;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerVelGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      MeshFunctionType velX;
+      MeshFunctionType velY;
+
+      void setVelX(const MeshFunctionType& velX)
+      {
+          this->velX = velX;
+      };
+
+      void setVelY(const MeshFunctionType& velY)
+      {
+          this->velY = velY;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "EulerVelGetter_impl.h"
+
+#endif	/* EulerVelGetter_H */
diff --git a/examples/inviscid-flow/2d/EulerVelGetter_impl.h b/examples/inviscid-flow/2d/EulerVelGetter_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb0fdbc2baf31b12fd7a5a5a21df444caa643331
--- /dev/null
+++ b/examples/inviscid-flow/2d/EulerVelGetter_impl.h
@@ -0,0 +1,336 @@
+#ifndef EulerVelGetter_IMPL_H
+#define EulerVelGetter_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerVelGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerVelGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerVelGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerVelGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerVelGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerVelGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerVelGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerVelGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   //vel
+   const IndexType& center = entity.getIndex(); 
+   return sqrt(pow( velX[ center ],2)+pow( velY[ center ],2));
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerVelGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerVelGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerVelGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerVelGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerVelGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerVelGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerVelGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* EulerVelGetterIMPL_H */
+
diff --git a/examples/inviscid-flow/2d/EulerVelXGetter.h b/examples/inviscid-flow/2d/EulerVelXGetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d3a17b4601668322c3806657cc90313262c3285
--- /dev/null
+++ b/examples/inviscid-flow/2d/EulerVelXGetter.h
@@ -0,0 +1,180 @@
+#ifndef EulerVelXGetter_H
+#define EulerVelXGetter_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class EulerVelXGetter
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerVelXGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      MeshFunctionType rhoVelX;
+      MeshFunctionType rho;
+
+      void setRhoVelX(const MeshFunctionType& rhoVelX)
+      {
+          this->rhoVelX = rhoVelX;
+      };
+
+      void setRho(const MeshFunctionType& rho)
+      {
+          this->rho = rho;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerVelXGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      MeshFunctionType rhoVelX;
+      MeshFunctionType rho;
+
+      void setRhoVelX(const MeshFunctionType& rhoVelX)
+      {
+          this->rhoVelX = rhoVelX;
+      };
+
+      void setRho(const MeshFunctionType& rho)
+      {
+          this->rho = rho;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerVelXGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      MeshFunctionType rhoVelX;
+      MeshFunctionType rho;
+
+      void setRhoVelX(const MeshFunctionType& rhoVelX)
+      {
+          this->rhoVelX = rhoVelX;
+      };
+
+      void setRho(const MeshFunctionType& rho)
+      {
+          this->rho = rho;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "EulerVelXGetter_impl.h"
+
+#endif	/* EulerVelXGetter_H */
diff --git a/examples/inviscid-flow/2d/EulerVelXGetter_impl.h b/examples/inviscid-flow/2d/EulerVelXGetter_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..bca8de8f557e0e3843dcc9af34e0acc990ac1b12
--- /dev/null
+++ b/examples/inviscid-flow/2d/EulerVelXGetter_impl.h
@@ -0,0 +1,336 @@
+#ifndef EulerVelXGetter_IMPL_H
+#define EulerVelXGetter_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerVelXGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerVelXGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerVelXGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerVelXGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerVelXGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerVelXGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerVelXGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerVelXGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   //velX
+   const IndexType& center = entity.getIndex(); 
+   return ( rhoVelX[ center ] / rho[ center ]);
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerVelXGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerVelXGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerVelXGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerVelXGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerVelXGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerVelXGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerVelXGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* EulerVelXGetterIMPL_H */
+
diff --git a/examples/inviscid-flow/2d/EulerVelYGetter.h b/examples/inviscid-flow/2d/EulerVelYGetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..c4f5689e9c12c1f14a611bf2d6b9bd10af730562
--- /dev/null
+++ b/examples/inviscid-flow/2d/EulerVelYGetter.h
@@ -0,0 +1,179 @@
+#ifndef EulerVelYGetter_H
+#define EulerVelYGetter_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class EulerVelYGetter
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerVelYGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      MeshFunctionType rhoVelY;
+      MeshFunctionType rho;
+
+      void setRhoVelY(const MeshFunctionType& rhoVelY)
+      {
+          this->rhoVelY = rhoVelY;
+      };
+
+      void setRho(const MeshFunctionType& rho)
+      {
+          this->rho = rho;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerVelYGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      MeshFunctionType rhoVelY;
+      MeshFunctionType rho;
+
+      void setRhoVelY(const MeshFunctionType& rhoVelY)
+      {
+          this->rhoVelY = rhoVelY;
+      };
+
+      void setRho(const MeshFunctionType& rho)
+      {
+          this->rho = rho;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class EulerVelYGetter< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      MeshFunctionType rhoVelY;
+      MeshFunctionType rho;
+
+      void setRhoVelY(const MeshFunctionType& rhoVelY)
+      {
+          this->rhoVelY = rhoVelY;
+      };
+
+      void setRho(const MeshFunctionType& rho)
+      {
+          this->rho = rho;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "EulerVelYGetter_impl.h"
+
+#endif	/* EulerVelYGetter_H */
diff --git a/examples/inviscid-flow/2d/EulerVelYGetter_impl.h b/examples/inviscid-flow/2d/EulerVelYGetter_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..3d1ce93bb81f6434592e5b47af7e094aeacc4944
--- /dev/null
+++ b/examples/inviscid-flow/2d/EulerVelYGetter_impl.h
@@ -0,0 +1,328 @@
+#ifndef EulerVelYGetter_IMPL_H
+#define EulerVelYGetter_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerVelYGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerVelYGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerVelYGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerVelYGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerVelYGetter< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerVelYGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerVelYGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerVelYGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   //velY
+   const IndexType& center = entity.getIndex(); 
+   return ( rhoVelY[ center ] / rho[ center ]);
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerVelYGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerVelYGetter< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+EulerVelYGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "EulerVelYGetter< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+EulerVelYGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+EulerVelYGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+EulerVelYGetter< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* EulerVelYGetterIMPL_H */
+
diff --git a/examples/inviscid-flow/2d/LaxFridrichs.h b/examples/inviscid-flow/2d/LaxFridrichs.h
new file mode 100644
index 0000000000000000000000000000000000000000..82ebc703cf344d3c4bdf826dd7b3282f1c03c6d8
--- /dev/null
+++ b/examples/inviscid-flow/2d/LaxFridrichs.h
@@ -0,0 +1,37 @@
+#ifndef LaxFridrichs_H
+#define LaxFridrichs_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+#include "LaxFridrichsContinuity.h"
+#include "LaxFridrichsEnergy.h"
+#include "LaxFridrichsMomentumX.h"
+#include "LaxFridrichsMomentumY.h"
+#include "EulerPressureGetter.h"
+#include "EulerVelXGetter.h"
+#include "EulerVelYGetter.h"
+#include "EulerVelGetter.h"
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichs
+{
+   public:
+      typedef Real RealType;
+      typedef Index IndexType;
+      typedef tnlMeshFunction< Mesh > MeshFunctionType;
+ 
+      typedef LaxFridrichsContinuity< Mesh, Real, Index > Continuity;
+      typedef LaxFridrichsMomentumX< Mesh, Real, Index > MomentumX;
+      typedef LaxFridrichsMomentumY< Mesh, Real, Index > MomentumY;
+      typedef LaxFridrichsEnergy< Mesh, Real, Index > Energy;
+      typedef EulerVelXGetter< Mesh, Real, Index > VelocityX;
+      typedef EulerVelYGetter< Mesh, Real, Index > VelocityY;
+      typedef EulerVelGetter< Mesh, Real, Index > Velocity;
+      typedef EulerPressureGetter< Mesh, Real, Index > Pressure;
+   
+};
+
+#endif	/* LaxFridrichs_H */
diff --git a/examples/inviscid-flow/2d/LaxFridrichsContinuity.h b/examples/inviscid-flow/2d/LaxFridrichsContinuity.h
new file mode 100644
index 0000000000000000000000000000000000000000..49d77403832c25973b2a1cd78540d9ac83f550bf
--- /dev/null
+++ b/examples/inviscid-flow/2d/LaxFridrichsContinuity.h
@@ -0,0 +1,200 @@
+#ifndef LaxFridrichsContinuity_H
+#define LaxFridrichsContinuity_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsContinuity
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsContinuity< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsContinuity< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsContinuity< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "LaxFridrichsContinuity_impl .h"
+
+#endif	/* LaxFridrichsContinuity_H */
diff --git a/examples/inviscid-flow/2d/LaxFridrichsContinuity_impl .h b/examples/inviscid-flow/2d/LaxFridrichsContinuity_impl .h
new file mode 100644
index 0000000000000000000000000000000000000000..91d9301311cd8124a4f6224099661f0b88b3c5e0
--- /dev/null
+++ b/examples/inviscid-flow/2d/LaxFridrichsContinuity_impl .h	
@@ -0,0 +1,345 @@
+#ifndef LaxFridrichsContinuity_IMPL_H
+#define LaxFridrichsContinuity_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsContinuity< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsContinuity< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsContinuity< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+    const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+    const IndexType& center = entity.getIndex(); 
+    const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+    const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsContinuity< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsContinuity< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsContinuity< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsContinuity< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsContinuity< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   //rho
+   const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); 
+   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); 
+   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 >(); 
+   return (0.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
+          - 0.5 * hxInverse * ( u[ west ] * this->velocityX[ west ] - u[ east ] * this->velocityX[ east ] )
+          - 0.5 * hyInverse * ( u[ north ] * this->velocityY[ north ] - u[ south ] * this->velocityY[ east ] );
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsContinuity< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsContinuity< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsContinuity< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsContinuity< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsContinuity< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsContinuity< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsContinuity< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* LaxFridrichsContinuityIMPL_H */
+
diff --git a/examples/inviscid-flow/2d/LaxFridrichsEnergy.h b/examples/inviscid-flow/2d/LaxFridrichsEnergy.h
new file mode 100644
index 0000000000000000000000000000000000000000..f9bc36c52e7a6503924c984ef7aa4e08cb715750
--- /dev/null
+++ b/examples/inviscid-flow/2d/LaxFridrichsEnergy.h
@@ -0,0 +1,215 @@
+#ifndef LaxFridrichsEnergy_H
+#define LaxFridrichsEnergy_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsEnergy
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsEnergy< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsEnergy< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsEnergy< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "LaxFridrichsEnergy_impl.h"
+
+#endif	/* LaxFridrichsEnergy_H */
diff --git a/examples/inviscid-flow/2d/LaxFridrichsEnergy_impl.h b/examples/inviscid-flow/2d/LaxFridrichsEnergy_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..1758be462709573188225a45f824909ce31b2492
--- /dev/null
+++ b/examples/inviscid-flow/2d/LaxFridrichsEnergy_impl.h
@@ -0,0 +1,346 @@
+#ifndef LaxFridrichsEnergy_IMPL_H
+#define LaxFridrichsEnergy_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsEnergy< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsEnergy< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsEnergy< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsEnergy< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsEnergy< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsEnergy< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsEnergy< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsEnergy< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   //energy
+   const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); 
+   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); 
+   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 >(); 
+   return (0.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
+          - 0.5 * hxInverse * ((( u[ west ] + this->pressure[ west ] ) * this->velocityX[ west ] )
+			      -(( u[ east ] + this->pressure[ east ] ) * this->velocityX[ east ] ))
+          - 0.5 * hyInverse * ((( u[ north ] + this->pressure[ north ] ) * this->velocityY[ north ] )
+			      -(( u[ south ] + this->pressure[ south ] ) * this->velocityY[ south ] ));
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsEnergy< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsEnergy< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsEnergy< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsEnergy< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsEnergy< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsEnergy< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsEnergy< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* LaxFridrichsEnergyIMPL_H */
+
diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h
new file mode 100644
index 0000000000000000000000000000000000000000..6c22302031f3096a7f0f8e084889f919cad1749e
--- /dev/null
+++ b/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h
@@ -0,0 +1,216 @@
+#ifndef LaxFridrichsMomentumX_H
+#define LaxFridrichsMomentumX_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsMomentumX
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentumX< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentumX< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentumX< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "LaxFridrichsMomentumX_impl.h"
+
+#endif	/* LaxFridrichsMomentumX_H */
diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumX_impl.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumX_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..14de7f4f6381c5858096dff791589324d9c1e2be
--- /dev/null
+++ b/examples/inviscid-flow/2d/LaxFridrichsMomentumX_impl.h
@@ -0,0 +1,347 @@
+#ifndef LaxFridrichsMomentumX_IMPL_H
+#define LaxFridrichsMomentumX_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsMomentumX< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsMomentumX< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsMomentumX< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsMomentumX< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsMomentumX< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsMomentumX< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsMomentumX< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsMomentumX< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   //rhoVelX
+   const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); 
+   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); 
+   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 >(); 
+   return (0.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
+          - 0.5 * hxInverse * (( u[ west ] * this->velocityX[ west ] + this->pressure[ west ] )
+			      -( u[ east ] * this->velocityX[ east ] + this->pressure[ east ] ))
+          - 0.5 * hyInverse * (( u[ north ] * this->velocityY[ north ] )
+			      -( u[ south ] * this->velocityY[ south ] ));
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsMomentumX< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsMomentumX< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsMomentumX< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsMomentumX< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsMomentumX< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsMomentumX< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsMomentumX< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* LaxFridrichsMomentumXIMPL_H */
+
diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumY.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumY.h
new file mode 100644
index 0000000000000000000000000000000000000000..199f43ca240a788af5c397e352e1efa12502d0fa
--- /dev/null
+++ b/examples/inviscid-flow/2d/LaxFridrichsMomentumY.h
@@ -0,0 +1,215 @@
+#ifndef LaxFridrichsMomentumY_H
+#define LaxFridrichsMomentumY_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class LaxFridrichsMomentumY
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentumY< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentumY< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class LaxFridrichsMomentumY< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+      Real tau;
+      MeshFunctionType velocityX;
+      MeshFunctionType velocityY;
+      MeshFunctionType pressure;
+
+      void setTau(const Real& tau)
+      {
+          this->tau = tau;
+      };
+
+      void setVelocityX(const MeshFunctionType& velocityX)
+      {
+          this->velocityX = velocityX;
+      };
+
+      void setVelocityY(const MeshFunctionType& velocityY)
+      {
+          this->velocityY = velocityY;
+      };
+
+      void setPressure(const MeshFunctionType& pressure)
+      {
+          this->pressure = pressure;
+      };
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void updateLinearSystem( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "LaxFridrichsMomentumY_impl.h"
+
+#endif	/* LaxFridrichsMomentumY_H */
diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumY_impl.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumY_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..478969ff8926198c0edad4ec503c108fb05077ca
--- /dev/null
+++ b/examples/inviscid-flow/2d/LaxFridrichsMomentumY_impl.h
@@ -0,0 +1,347 @@
+#ifndef LaxFridrichsMomentumY_IMPL_H
+#define LaxFridrichsMomentumY_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsMomentumY< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsMomentumY< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsMomentumY< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsMomentumY< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsMomentumY< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsMomentumY< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsMomentumY< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsMomentumY< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   //rhoVelY
+   const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); 
+   const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); 
+   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 >(); 
+   return (0.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) 
+          - 0.5 * hyInverse * (( u[ west ] * this->velocityX[ west ] )
+			      -( u[ east ] * this->velocityX[ east ] ))
+          - 0.5 * hxInverse * (( u[ north ] * this->velocityY[ north ] + this->pressure[ north ] )
+			      -( u[ south ] * this->velocityY[ south ] + this->pressure[ south ]));
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsMomentumY< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsMomentumY< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+LaxFridrichsMomentumY< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "LaxFridrichsMomentumY< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+LaxFridrichsMomentumY< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+LaxFridrichsMomentumY< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+LaxFridrichsMomentumY< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+updateLinearSystem( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* LaxFridrichsMomentumYIMPL_H */
+
diff --git a/examples/inviscid-flow/2d/euler-cuda.cu b/examples/inviscid-flow/2d/euler-cuda.cu
new file mode 100644
index 0000000000000000000000000000000000000000..4d76005cb1f70724be978ff0fa6fec63c4a8a76f
--- /dev/null
+++ b/examples/inviscid-flow/2d/euler-cuda.cu
@@ -0,0 +1 @@
+#include "euler.h"
diff --git a/examples/inviscid-flow/2d/euler.cpp b/examples/inviscid-flow/2d/euler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4d76005cb1f70724be978ff0fa6fec63c4a8a76f
--- /dev/null
+++ b/examples/inviscid-flow/2d/euler.cpp
@@ -0,0 +1 @@
+#include "euler.h"
diff --git a/examples/inviscid-flow/2d/euler.h b/examples/inviscid-flow/2d/euler.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce35381216dbaaa170a3934247cb7e4d49a216d6
--- /dev/null
+++ b/examples/inviscid-flow/2d/euler.h
@@ -0,0 +1,117 @@
+#include <tnlConfig.h>
+#include <solvers/tnlSolver.h>
+#include <solvers/tnlBuildConfigTags.h>
+#include <operators/tnlDirichletBoundaryConditions.h>
+#include <operators/tnlNeumannBoundaryConditions.h>
+#include <functions/tnlConstantFunction.h>
+#include "eulerProblem.h"
+#include "LaxFridrichs.h"
+#include "eulerRhs.h"
+#include "eulerBuildConfigTag.h"
+
+typedef eulerBuildConfigTag BuildConfig;
+
+/****
+ * Uncoment the following (and comment the previous line) for the complete build.
+ * This will include support for all floating point precisions, all indexing types
+ * and more solvers. You may then choose between them from the command line.
+ * The compile time may, however, take tens of minutes or even several hours,
+ * esppecially if CUDA is enabled. Use this, if you want, only for the final build,
+ * not in the development phase.
+ */
+//typedef tnlDefaultConfigTag BuildConfig;
+
+template< typename ConfigTag >class eulerConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription & config )
+      {
+         config.addDelimiter( "euler2D settings:" );
+         config.addEntry< tnlString >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
+            config.addEntryEnum< tnlString >( "dirichlet" );
+            config.addEntryEnum< tnlString >( "neumann" );
+         config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." );
+         config.addEntry< double >( "left-density", "This sets a value of left density." );
+         config.addEntry< double >( "left-velocityX", "This sets a value of left_x velocity." );
+         config.addEntry< double >( "left-velocityY", "This sets a value of left_y velocity." );
+         config.addEntry< double >( "left-pressure", "This sets a value of left pressure." );
+         config.addEntry< double >( "riemann-border", "This sets a position of discontinuity." );
+         config.addEntry< double >( "right-density", "This sets a value of right density." );
+         config.addEntry< double >( "right-velocityX", "This sets a value of right_x velocity." );
+         config.addEntry< double >( "right-velocityY", "This sets a value of right_y velocity." );
+         config.addEntry< double >( "right-pressure", "This sets a value of right pressure." );
+         config.addEntry< double >( "gamma", "This sets a value of gamma constant." );
+
+         /****
+          * Add definition of your solver command line arguments.
+          */
+
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename MeshType,
+          typename ConfigTag,
+          typename SolverStarter >
+class eulerSetter
+{
+   public:
+
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+
+      static bool run( const tnlParameterContainer & parameters )
+      {
+          enum { Dimensions = MeshType::getMeshDimensions() };
+          typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator;
+          typedef eulerRhs< MeshType, Real > RightHandSide;
+          typedef tnlStaticVector < MeshType::getMeshDimensions(), Real > Vertex;
+
+         /****
+          * Resolve the template arguments of your solver here.
+          * The following code is for the Dirichlet and the Neumann boundary conditions.
+          * Both can be constant or defined as descrete values of tnlVector.
+          */
+          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, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+                typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+                SolverStarter solverStarter;
+                return solverStarter.template run< Problem >( parameters );
+             }
+             typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunction, Real, Index > BoundaryConditions;
+             typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+             SolverStarter solverStarter;
+             return solverStarter.template run< Problem >( parameters );
+          }
+          typedef tnlMeshFunction< MeshType > MeshFunction;
+          if( boundaryConditionsType == "dirichlet" )
+          {
+             typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+             typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+             SolverStarter solverStarter;
+             return solverStarter.template run< Problem >( parameters );
+          }
+          typedef tnlNeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
+          typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+          SolverStarter solverStarter;
+          return solverStarter.template run< Problem >( parameters );
+      }
+
+};
+
+int main( int argc, char* argv[] )
+{
+   tnlSolver< eulerSetter, eulerConfig, BuildConfig > solver;
+   if( ! solver. run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
diff --git a/examples/inviscid-flow/2d/eulerBuildConfigTag.h b/examples/inviscid-flow/2d/eulerBuildConfigTag.h
new file mode 100644
index 0000000000000000000000000000000000000000..a03c260be27f0ab5915edde0de252935a31b0f0f
--- /dev/null
+++ b/examples/inviscid-flow/2d/eulerBuildConfigTag.h
@@ -0,0 +1,44 @@
+#ifndef eulerBUILDCONFIGTAG_H_
+#define eulerBUILDCONFIGTAG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class eulerBuildConfigTag{};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< eulerBuildConfigTag, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< eulerBuildConfigTag, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< eulerBuildConfigTag, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< eulerBuildConfigTag, long int >{ enum { enabled = false }; };
+
+template< int Dimensions > struct tnlConfigTagDimensions< eulerBuildConfigTag, Dimensions >{ enum { enabled = ( Dimensions == 2 ) }; };
+
+/****
+ * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types.
+ */
+template< int Dimensions, typename Real, typename Device, typename Index >
+   struct tnlConfigTagMesh< eulerBuildConfigTag, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = tnlConfigTagDimensions< eulerBuildConfigTag, Dimensions >::enabled  &&
+                         tnlConfigTagReal< eulerBuildConfigTag, Real >::enabled &&
+                         tnlConfigTagDevice< eulerBuildConfigTag, Device >::enabled &&
+                         tnlConfigTagIndex< eulerBuildConfigTag, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< eulerBuildConfigTag, tnlExplicitEulerSolverTag >{ enum { enabled = false }; };
+
+#endif /* eulerBUILDCONFIGTAG_H_ */
diff --git a/examples/inviscid-flow/2d/eulerProblem.h b/examples/inviscid-flow/2d/eulerProblem.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9acdf36adbbd24e63ec2ec0d1fd7bc4a7ee03ca
--- /dev/null
+++ b/examples/inviscid-flow/2d/eulerProblem.h
@@ -0,0 +1,120 @@
+#ifndef eulerPROBLEM_H_
+#define eulerPROBLEM_H_
+
+#include <problems/tnlPDEProblem.h>
+#include <functions/tnlMeshFunction.h>
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+           typename DifferentialOperator >
+class eulerProblem:
+   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;
+
+      using typename BaseType::MeshType;
+      using typename BaseType::DofVectorType;
+      using typename BaseType::MeshDependentDataType;
+
+      typedef typename DifferentialOperator::Continuity Continuity;
+      typedef typename DifferentialOperator::MomentumX MomentumX;
+      typedef typename DifferentialOperator::MomentumY MomentumY;
+      typedef typename DifferentialOperator::Energy Energy;
+      typedef typename DifferentialOperator::Velocity Velocity;
+      typedef typename DifferentialOperator::VelocityX VelocityX;
+      typedef typename DifferentialOperator::VelocityY VelocityY;
+      typedef typename DifferentialOperator::Pressure Pressure;
+
+    //definition
+	tnlVector< RealType, DeviceType, IndexType > _uRho;
+	tnlVector< RealType, DeviceType, IndexType > _uRhoVelocityX;
+	tnlVector< RealType, DeviceType, IndexType > _uRhoVelocityY;
+	tnlVector< RealType, DeviceType, IndexType > _uEnergy;
+
+	tnlVector< RealType, DeviceType, IndexType > _fuRho;
+	tnlVector< RealType, DeviceType, IndexType > _fuRhoVelocityX;
+	tnlVector< RealType, DeviceType, IndexType > _fuRhoVelocityY;
+	tnlVector< RealType, DeviceType, IndexType > _fuEnergy;
+
+      tnlVector< RealType, DeviceType, IndexType > rho;
+      tnlVector< RealType, DeviceType, IndexType > rhoVelX;
+      tnlVector< RealType, DeviceType, IndexType > rhoVelY;
+      tnlVector< RealType, DeviceType, IndexType > energy;
+      tnlVector< RealType, DeviceType, IndexType > data;
+      tnlVector< RealType, DeviceType, IndexType > pressure;
+      tnlVector< RealType, DeviceType, IndexType > velocity;
+      tnlVector< RealType, DeviceType, IndexType > velocityX;
+      tnlVector< RealType, DeviceType, IndexType > velocityY;
+      double gamma;
+
+      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 );
+
+      bool postIterate( const RealType& time,
+                        const RealType& tau,
+                        const MeshType& mesh,
+                        DofVectorType& dofs,
+                        MeshDependentDataType& meshDependentData );
+
+   protected:
+
+      DifferentialOperator differentialOperator;
+      BoundaryCondition boundaryCondition;
+      RightHandSide rightHandSide;
+};
+
+#include "eulerProblem_impl.h"
+
+#endif /* eulerPROBLEM_H_ */
diff --git a/examples/inviscid-flow/2d/eulerProblem_impl.h b/examples/inviscid-flow/2d/eulerProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3a543d5807a1b4b03097755a046b4f4e7a9353c
--- /dev/null
+++ b/examples/inviscid-flow/2d/eulerProblem_impl.h
@@ -0,0 +1,434 @@
+#ifndef eulerPROBLEM_IMPL_H_
+#define eulerPROBLEM_IMPL_H_
+
+#include <core/mfilename.h>
+#include <matrices/tnlMatrixSetter.h>
+#include <solvers/pde/tnlExplicitUpdater.h>
+#include <solvers/pde/tnlLinearSystemAssembler.h>
+#include <solvers/pde/tnlBackwardTimeDiscretisation.h>
+
+#include "LaxFridrichsContinuity.h"
+#include "LaxFridrichsEnergy.h"
+#include "LaxFridrichsMomentumX.h"
+#include "LaxFridrichsMomentumY.h"
+#include "EulerPressureGetter.h"
+#include "EulerVelXGetter.h"
+#include "EulerVelYGetter.h"
+#include "EulerVelGetter.h"
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getTypeStatic()
+{
+   return tnlString( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getPrologHeader() const
+{
+   return tnlString( "euler2D" );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const
+{
+   /****
+    * Add data you want to have in the computation report (log) as follows:
+    * logger.writeParameter< double >( "Parameter description", parameter );
+    */
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setup( const tnlParameterContainer& parameters )
+{
+   if( ! this->boundaryCondition.setup( parameters, "boundary-conditions-" ) ||
+       ! this->rightHandSide.setup( parameters, "right-hand-side-" ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+typename eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getDofs( const MeshType& mesh ) const
+{
+   /****
+    * Return number of  DOFs (degrees of freedom) i.e. number
+    * of unknowns to be resolved by the main solver.
+    */
+   return 4*mesh.template getEntitiesCount< typename MeshType::Cell >();
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+bindDofs( const MeshType& mesh,
+          DofVectorType& dofVector )
+{
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setInitialCondition( const tnlParameterContainer& parameters,
+                     const MeshType& mesh,
+                     DofVectorType& dofs,
+                     MeshDependentDataType& meshDependentData )
+{
+   typedef typename MeshType::Cell Cell;
+   double gamma = parameters.getParameter< double >( "gamma" );
+   double rhoL = parameters.getParameter< double >( "left-density" );
+   double velLX = parameters.getParameter< double >( "left-velocityX" );
+   double velLY = parameters.getParameter< double >( "left-velocityY" );
+   double preL = parameters.getParameter< double >( "left-pressure" );
+   double eL = ( preL / (gamma - 1) ) + 0.5 * rhoL * pow(velLX,2)+pow(velLY,2);
+   double rhoR = parameters.getParameter< double >( "right-density" );
+   double velRX = parameters.getParameter< double >( "right-velocityX" );
+   double velRY = parameters.getParameter< double >( "right-velocityY" );
+   double preR = parameters.getParameter< double >( "right-pressure" );
+   double eR = ( preR / (gamma - 1) ) + 0.5 * rhoR * pow(velRX,2)+pow(velRY,2);
+   double x0 = parameters.getParameter< double >( "riemann-border" );
+   int size = mesh.template getEntitiesCount< Cell >();
+   int size2 = pow(size,2);
+   this->rho.bind(dofs,0,size2);
+   this->rhoVelX.bind(dofs,size2,size2);
+   this->rhoVelY.bind(dofs,2*size2,size2);
+   this->energy.bind(dofs,3*size2,size2);
+   this->data.setSize(4*size2);
+   this->pressure.bind(this->data,0,size2);
+   this->velocity.bind(this->data,size2,size2);
+   this->velocityX.bind(this->data,2*size2,size2);
+   this->velocityY.bind(this->data,3*size2,size2);
+   for(long int j = 0; j < size; j++)   
+      for(long int i = 0; i < size; i++)
+         if ((i < x0 * size)&&(j < x0 * size) )
+            {
+               this->rho[j*size+i] = rhoL;
+               this->rhoVelX[j*size+i] = rhoL * velLX;
+               this->rhoVelY[j*size+i] = rhoL * velLY;
+               this->energy[j*size+i] = eL;
+               this->velocity[j*size+i] = sqrt(pow(velLX,2)+pow(velLY,2));
+               this->velocityX[j*size+i] = velLX;
+               this->velocityY[j*size+i] = velLY;
+               this->pressure[j*size+i] = preL;
+            }
+         else
+            {
+               this->rho[j*size+i] = rhoR;
+               this->rhoVelX[j*size+i] = rhoR * velRX;
+               this->rhoVelY[j*size+i] = rhoR * velRY;
+               this->energy[j*size+i] = eR;
+               this->velocity[j*size+i] = sqrt(pow(velRX,2)+pow(velRY,2));
+               this->velocityX[j*size+i] = velRX;
+               this->velocityY[j*size+i] = velRY;
+               this->pressure[j*size+i] = preR;
+            };
+   this->gamma = gamma;
+   return true; 
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+   template< typename Matrix >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setupLinearSystem( const MeshType& mesh,
+                   Matrix& matrix )
+{
+/*   const IndexType dofs = this->getDofs( mesh );
+   typedef typename Matrix::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
+eulerProblem< 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 );
+   tnlString fileName;
+   FileNameBaseNumberEnding( "rho-", step, 5, ".tnl", fileName );
+   if( ! this->rho.save( fileName ) )
+      return false;
+   FileNameBaseNumberEnding( "rhoVelX-", step, 5, ".tnl", fileName );
+   if( ! this->rhoVelX.save( fileName ) )
+      return false;
+   FileNameBaseNumberEnding( "rhoVelY-", step, 5, ".tnl", fileName );
+   if( ! this->rhoVelY.save( fileName ) )
+      return false;
+   FileNameBaseNumberEnding( "energy-", step, 5, ".tnl", fileName );
+   if( ! this->energy.save( fileName ) )
+      return false;
+   FileNameBaseNumberEnding( "velocityX-", step, 5, ".tnl", fileName );
+   if( ! this->velocityX.save( fileName ) )
+      return false;
+   FileNameBaseNumberEnding( "velocityY-", step, 5, ".tnl", fileName );
+   if( ! this->velocityY.save( fileName ) )
+      return false;
+   FileNameBaseNumberEnding( "velocity-", step, 5, ".tnl", fileName );
+   if( ! this->velocity.save( fileName ) )
+      return false;
+   FileNameBaseNumberEnding( "pressure-", step, 5, ".tnl", fileName );
+   if( ! this->pressure.save( fileName ) )
+      return false;
+
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getExplicitRHS( const RealType& time,
+                const RealType& tau,
+                const MeshType& mesh,
+                DofVectorType& _u,
+                DofVectorType& _fu,
+                MeshDependentDataType& meshDependentData )
+{
+    typedef typename MeshType::Cell Cell;
+    int count = mesh.template getEntitiesCount< Cell >()/4;
+	//bind _u
+    this->_uRho.bind(_u,0,count);
+    this->_uRhoVelocityX.bind(_u,count,count);
+    this->_uRhoVelocityY.bind(_u,2 * count,count);
+    this->_uEnergy.bind(_u,3 * count,count);
+		
+	//bind _fu
+    this->_fuRho.bind(_u,0,count);
+    this->_fuRhoVelocityX.bind(_u,count,count);
+    this->_fuRhoVelocityY.bind(_u,2 * count,count);
+    this->_fuEnergy.bind(_u,3 * count,count);
+   //bind MeshFunctionType
+   MeshFunctionType velocity( mesh, this->velocity );
+   MeshFunctionType velocityX( mesh, this->velocityX );
+   MeshFunctionType velocityY( mesh, this->velocityY );
+   MeshFunctionType pressure( mesh, this->pressure );
+   MeshFunctionType uRho( mesh, _uRho ); 
+   MeshFunctionType fuRho( mesh, _fuRho );
+   MeshFunctionType uRhoVelocityX( mesh, _uRhoVelocityX ); 
+   MeshFunctionType fuRhoVelocityX( mesh, _fuRhoVelocityX );
+   MeshFunctionType uRhoVelocityY( mesh, _uRhoVelocityY ); 
+   MeshFunctionType fuRhoVelocityY( mesh, _fuRhoVelocityY );
+   MeshFunctionType uEnergy( mesh, _uEnergy ); 
+   MeshFunctionType fuEnergy( mesh, _fuEnergy );
+   //generate Operators
+   Continuity lF2DContinuity;
+   MomentumX lF2DMomentumX;
+   MomentumY lF2DMomentumY;
+   Energy lF2DEnergy;
+
+   this->bindDofs( mesh, _u );
+   //rho
+   lF2DContinuity.setTau(tau);
+   lF2DContinuity.setVelocityX(velocityX);
+   lF2DContinuity.setVelocityY(velocityY);
+   tnlExplicitUpdater< Mesh, MeshFunctionType, Continuity, BoundaryCondition, RightHandSide > explicitUpdaterContinuity; 
+   explicitUpdaterContinuity.template update< typename Mesh::Cell >( time,
+                                                           mesh,
+                                                           lF2DContinuity,
+                                                           this->boundaryCondition,
+                                                           this->rightHandSide,
+                                                           uRho,
+                                                           fuRho );
+
+   //rhoVelocityX
+   lF2DMomentumX.setTau(tau);
+   lF2DMomentumX.setVelocityX(velocityX);
+   lF2DMomentumX.setVelocityY(velocityY);
+   lF2DMomentumX.setPressure(pressure);
+   tnlExplicitUpdater< Mesh, MeshFunctionType, MomentumX, BoundaryCondition, RightHandSide > explicitUpdaterMomentumX; 
+   explicitUpdaterMomentumX.template update< typename Mesh::Cell >( time,
+                                                           mesh,
+                                                           lF2DMomentumX,
+                                                           this->boundaryCondition,
+                                                           this->rightHandSide,
+                                                           uRhoVelocityX,
+                                                           fuRhoVelocityX );
+
+   //rhoVelocityY
+   lF2DMomentumY.setTau(tau);
+   lF2DMomentumY.setVelocityX(velocityX);
+   lF2DMomentumY.setVelocityY(velocityY);
+   lF2DMomentumY.setPressure(pressure);
+   tnlExplicitUpdater< Mesh, MeshFunctionType, MomentumY, BoundaryCondition, RightHandSide > explicitUpdaterMomentumY;
+   explicitUpdaterMomentumY.template update< typename Mesh::Cell >( time,
+                                                           mesh,
+                                                           lF2DMomentumY,
+                                                           this->boundaryCondition,
+                                                           this->rightHandSide,
+                                                           uRhoVelocityY,
+                                                           fuRhoVelocityY );
+  
+   //energy
+   lF2DEnergy.setTau(tau);
+   lF2DEnergy.setVelocityX(velocityX); 
+   lF2DEnergy.setVelocityY(velocityY); 
+   lF2DEnergy.setPressure(pressure);
+   tnlExplicitUpdater< Mesh, MeshFunctionType, Energy, BoundaryCondition, RightHandSide > explicitUpdaterEnergy;
+   explicitUpdaterEnergy.template update< typename Mesh::Cell >( time,
+                                                           mesh,
+                                                           lF2DEnergy,
+                                                           this->boundaryCondition,
+                                                           this->rightHandSide,
+                                                           uEnergy,
+                                                           fuEnergy );
+
+/*
+   tnlBoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter; 
+   boundaryConditionsSetter.template apply< typename Mesh::Cell >( 
+      this->boundaryCondition, 
+      time + tau, 
+       u );*/
+ }
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+   template< typename Matrix >
+void
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+assemblyLinearSystem( const RealType& time,
+                      const RealType& tau,
+                      const MeshType& mesh,
+                      DofVectorType& _u,
+                      Matrix& matrix,
+                      DofVectorType& b,
+                      MeshDependentDataType& meshDependentData )
+{
+/*   tnlLinearSystemAssembler< Mesh,
+                             MeshFunctionType,
+                             DifferentialOperator,
+                             BoundaryCondition,
+                             RightHandSide,
+                             tnlBackwardTimeDiscretisation,
+                             Matrix,
+                             DofVectorType > systemAssembler;
+
+   tnlMeshFunction< Mesh > u( mesh, _u );
+   systemAssembler.template assembly< typename Mesh::Cell >( time,
+                                                             tau,
+                                                             mesh,
+                                                             this->differentialOperator,
+                                                             this->boundaryCondition,
+                                                             this->rightHandSide,
+                                                             u,
+                                                             matrix,
+                                                             b );*/
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+postIterate( const RealType& time,
+             const RealType& tau,
+             const MeshType& mesh,
+             DofVectorType& dofs,
+             MeshDependentDataType& meshDependentData )
+{
+    typedef typename MeshType::Cell Cell;
+    int count = mesh.template getEntitiesCount< Cell >()/4;
+	//bind _u
+    this->_uRho.bind(dofs, 0, count);
+    this->_uRhoVelocityX.bind(dofs, count, count);
+    this->_uRhoVelocityY.bind(dofs, 2 * count, count);
+    this->_uEnergy.bind(dofs, 3 * count, count);
+
+   MeshFunctionType velocity( mesh, this->velocity );
+   MeshFunctionType velocityX( mesh, this->velocityX );
+   MeshFunctionType velocityY( mesh, this->velocityY );
+   MeshFunctionType pressure( mesh, this->pressure );
+   MeshFunctionType uRho( mesh, _uRho ); 
+   MeshFunctionType uRhoVelocityX( mesh, _uRhoVelocityX ); 
+   MeshFunctionType uRhoVelocityY( mesh, _uRhoVelocityY ); 
+   MeshFunctionType uEnergy( mesh, _uEnergy ); 
+   //Generating differential operators
+   Velocity euler2DVelocity;
+   VelocityX euler2DVelocityX;
+   VelocityY euler2DVelocityY;
+   Pressure euler2DPressure;
+
+   //velocityX
+   euler2DVelocityX.setRhoVelX(uRhoVelocityX);
+   euler2DVelocityX.setRho(uRho);
+//   tnlOperatorFunction< VelocityX, MeshFunction, void, true > OFVelocityX;
+//   velocityX = OFVelocityX;
+
+   //velocityY
+   euler2DVelocityY.setRhoVelY(uRhoVelocityY);
+   euler2DVelocityY.setRho(uRho);
+//   tnlOperatorFunction< VelocityY, MeshFunction, void, time > OFVelocityY;
+//   velocityY = OFVelocityY;
+
+   //velocity
+   euler2DVelocity.setVelX(velocityX);
+   euler2DVelocity.setVelY(velocityY);
+//   tnlOperatorFunction< Velocity, MeshFunction, void, time > OFVelocity;
+//   velocity = OFVelocity;
+
+   //pressure
+   euler2DPressure.setGamma(gamma);
+   euler2DPressure.setVelocity(velocity);
+   euler2DPressure.setEnergy(uEnergy);
+   euler2DPressure.setRho(uRho);
+//   tnlOperatorFunction< euler2DPressure, MeshFunction, void, time > OFPressure;
+//   pressure = OFPressure;
+
+}
+
+#endif /* eulerPROBLEM_IMPL_H_ */
diff --git a/examples/inviscid-flow/2d/eulerRhs.h b/examples/inviscid-flow/2d/eulerRhs.h
new file mode 100644
index 0000000000000000000000000000000000000000..582dc36413ae36d78aa06a03be2ad745325263d6
--- /dev/null
+++ b/examples/inviscid-flow/2d/eulerRhs.h
@@ -0,0 +1,29 @@
+#ifndef eulerRHS_H_
+#define eulerRHS_H_
+#include<functions/tnlDomain.h>
+template< typename Mesh, typename Real >class eulerRhs
+  : public tnlDomain< Mesh::meshDimensions, MeshDomain > 
+ {
+   public:
+
+      typedef Mesh MeshType;
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                  const tnlString& prefix = "" )
+      {
+         return true;
+      }
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         typedef typename MeshEntity::MeshType::VertexType VertexType;
+         VertexType v = entity.getCenter();
+         return 0.0;
+      };
+};
+
+#endif /* eulerRHS_H_ */
diff --git a/examples/inviscid-flow/2d/run-euler b/examples/inviscid-flow/2d/run-euler
new file mode 100644
index 0000000000000000000000000000000000000000..f68b98a8406dea2f2142526283ec60248551c56d
--- /dev/null
+++ b/examples/inviscid-flow/2d/run-euler
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+tnl-grid-setup --dimensions 2 \
+               --origin-x 0.0 \
+               --origin-y 0.0 \
+               --proportions-x 1.0 \
+               --proportions-y 1.0 \
+               --size-x 100 \
+               --size-y 100
+
+tnl-init --test-function sin-wave \
+         --output-file init.tnl
+./euler --time-discretisation explicit \
+              --boundary-conditions-constant 0 \
+              --discrete-solver merson \
+              --snapshot-period 0.01 \
+              --final-time 1.0
+
+tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/examples/inviscid-flow/CMakeLists.txt b/examples/inviscid-flow/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..10af3c9c773bc36bca44191359b4a4e244d1faa4
--- /dev/null
+++ b/examples/inviscid-flow/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory( 1d )
+add_subdirectory( 2d )
diff --git a/examples/mean-curvature-flow/Makefile b/examples/mean-curvature-flow/Makefile
deleted file mode 100644
index 71873be3fbafbf131bd8b092c7078a9dea9b167d..0000000000000000000000000000000000000000
--- a/examples/mean-curvature-flow/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-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/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h b/examples/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h
index 8c0c5da2c5c8b10cb652ee5ed5564fe0f3025a55..2f52be08bf2fa6d0ee33863d65706265d8ed2f05 100644
--- a/examples/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h
+++ b/examples/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h
@@ -20,6 +20,7 @@
 
 #include "tnlNarrowBand.h"
 
+#ifdef HAVE_CUDA
 __device__
 double fabsMin( double x, double y)
 {
@@ -43,7 +44,7 @@ double atomicFabsMin(double* address, double val)
 	} while (assumed != old);
 	return __longlong_as_double(old);
 }
-
+#endif
 
 template< typename MeshReal,
           typename Device,
diff --git a/examples/narrow-band/tnlNarrowBand_CUDA.h b/examples/narrow-band/tnlNarrowBand_CUDA.h
index a0fa59a1ee7343ec951e2b3946ad89c4c7bc57b2..f35ab8e0fcda9176c316b7bacb587b35c6ba7bde 100644
--- a/examples/narrow-band/tnlNarrowBand_CUDA.h
+++ b/examples/narrow-band/tnlNarrowBand_CUDA.h
@@ -59,9 +59,9 @@ public:
 
 	tnlNarrowBand();
 
-	__host__ static tnlString getType();
-	__host__ bool init( const tnlParameterContainer& parameters );
-	__host__ bool run();
+        static tnlString getType();
+	bool init( const tnlParameterContainer& parameters );
+	bool run();
 #ifdef HAVE_CUDA
    __device__ __host__
 #endif
@@ -143,9 +143,9 @@ public:
 
 
 
-	__host__ static tnlString getType();
-	__host__ bool init( const tnlParameterContainer& parameters );
-	__host__ bool run();
+	static tnlString getType();
+	bool init( const tnlParameterContainer& parameters );
+	bool run();
 
 #ifdef HAVE_CUDA
 	__device__ bool initGrid(int i, int j, int k);
diff --git a/examples/navier-stokes/navierStokesBoundaryConditions_impl.h b/examples/navier-stokes/navierStokesBoundaryConditions_impl.h
index 40a22ffa9e7a5cf040b7c84614bf9c9f3ac6c7ad..6bf8585bceb133682478020d352745c937ef84c2 100644
--- a/examples/navier-stokes/navierStokesBoundaryConditions_impl.h
+++ b/examples/navier-stokes/navierStokesBoundaryConditions_impl.h
@@ -31,11 +31,19 @@ navierStokesBoundaryConditions< Mesh >::navierStokesBoundaryConditions()
 template< typename Mesh >
 bool navierStokesBoundaryConditions< Mesh >::setup( const tnlParameterContainer& parameters )
 {
+<<<<<<< HEAD
    this -> maxInflowVelocity = parameters. getParameter< double >( "max-inflow-velocity" );
    //this -> maxOutflowVelocity = parameters. getParameter< double >( "max-outflow-velocity" );
    this -> startUp = parameters. getParameter< double >( "start-up" );
    this -> T = parameters. getParameter< double >( "T" );
    this -> R = parameters. getParameter< double >( "R" );
+=======
+   this->maxInflowVelocity = parameters. getParameter< double >( "max-inflow-velocity" );
+   //this->maxOutflowVelocity = parameters. getParameter< double >( "max-outflow-velocity" );
+   this->startUp = parameters. getParameter< double >( "start-up" );
+   this->T = parameters. getParameter< double >( "T" );
+   this->R = parameters. getParameter< double >( "R" );
+>>>>>>> develop
    this->p0 = parameters. getParameter< double >( "p0" );
    this->gamma = parameters. getParameter< double >( "gamma" );
    return true;
@@ -67,8 +75,8 @@ void navierStokesBoundaryConditions< Mesh >::apply( const RealType& time,
    const RealType hx = this->mesh->getParametricStep().x();
    const RealType hy = this->mesh->getParametricStep().y();
    RealType startUpCoefficient( 1.0 );
-   if( this -> startUp != 0.0 )
-      startUpCoefficient = Min( ( RealType ) 1.0, time / this -> startUp );
+   if( this->startUp != 0.0 )
+      startUpCoefficient = Min( ( RealType ) 1.0, time / this->startUp );
 
    for( IndexType i = 0; i < xSize; i ++ )
    {
@@ -86,14 +94,14 @@ void navierStokesBoundaryConditions< Mesh >::apply( const RealType& time,
       {
          u1[ c1 ] = 0;
          u2[ c1 ] = 0;
-         u1[ c3 ] = sin( M_PI * x ) * startUpCoefficient * this -> maxInflowVelocity;
+         u1[ c3 ] = sin( M_PI * x ) * startUpCoefficient * this->maxInflowVelocity;
          u2[ c3 ] = 0;
 
          rho[ c1 ] = rho[ c2 ];
          rho[ c3 ] = rho[ c4 ];
          energy[ c1 ] = energy[ c2 ];
          energy[ c3 ] = energy[ c4 ];
-          //rho[ c3 ] = this -> p_0 / ( this -> R * this -> T );
+          //rho[ c3 ] = this->p_0 / ( this->R * this->T );
       }
    }
    for( IndexType j = 0; j < ySize; j ++ )
@@ -122,10 +130,10 @@ void navierStokesBoundaryConditions< Mesh >::apply( const RealType& time,
          energy[ c1 ] = this->p0 / ( this->gamma - 1.0 ); //energy[ c2 ];// - tau*( energy[ c2 ] - energy[ c1 ] ) / hx;
          energy[ c3 ] = this->p0 / ( this->gamma - 1.0 ); //energy[ c4 ];// - tau*( energy[ c3 ] - energy[ c4 ] ) / hx;
       }
-      /*rho_u1[ c1 ] = rho[ c1 ] * this -> u1[ c1 ];
-      rho_u2[ c1 ] = rho[ c1 ] * this -> u2[ c1 ];
-      rho_u1[ c3 ] = rho[ c3 ] * this -> u1[ c3 ];
-      rho_u2[ c3 ] = rho[ c3 ] * this -> u2[ c3 ];*/
+      /*rho_u1[ c1 ] = rho[ c1 ] * this->u1[ c1 ];
+      rho_u2[ c1 ] = rho[ c1 ] * this->u2[ c1 ];
+      rho_u1[ c3 ] = rho[ c3 ] * this->u1[ c3 ];
+      rho_u2[ c3 ] = rho[ c3 ] * this->u2[ c3 ];*/
     }
 }
 
diff --git a/examples/navier-stokes/navierStokesSolverMonitor_impl.h b/examples/navier-stokes/navierStokesSolverMonitor_impl.h
index db69fe7b212a453a43b0e7c2cbae5a50060a7dec..4fb5fac89b66d21de947e1a8700d762def7534d2 100644
--- a/examples/navier-stokes/navierStokesSolverMonitor_impl.h
+++ b/examples/navier-stokes/navierStokesSolverMonitor_impl.h
@@ -30,7 +30,11 @@ navierStokesSolverMonitor< Real, Index > :: navierStokesSolverMonitor()
 template< typename Real, typename Index >
 void navierStokesSolverMonitor< Real, Index > :: refresh()
 {
+<<<<<<< HEAD
    if( this -> verbose > 0 && this -> refresRate % this -> refreshRate == 0 )
+=======
+   if( this->verbose > 0 && this->refresRate % this->refreshRate == 0 )
+>>>>>>> develop
    {
       cout << "V=( " << uMax
            << " , " << uAvg
diff --git a/examples/navier-stokes/navierStokesSolver_impl.h b/examples/navier-stokes/navierStokesSolver_impl.h
index f10e8eb64c7f157f8dd2426baa8e65e51e9f55af..af5d256c17650b67d9b589813d611b5df3ff493d 100644
--- a/examples/navier-stokes/navierStokesSolver_impl.h
+++ b/examples/navier-stokes/navierStokesSolver_impl.h
@@ -147,8 +147,8 @@ bool navierStokesSolver< Mesh, EulerScheme >::setup( const tnlParameterContainer
       cerr << "Error: height must be positive real number! It is " << proportions. y() << " now." << endl;
       return false;
    }
-   this -> mesh. setOrigin( tnlStaticVector< 2, RealType >( 0, 0 ) );
-   this -> mesh. setProportions( proportions );
+   this->mesh. setOrigin( tnlStaticVector< 2, RealType >( 0, 0 ) );
+   this->mesh. setProportions( proportions );
 
    if( ! this->initMesh( this->mesh, parameters ) )
       return false;
@@ -187,15 +187,15 @@ bool navierStokesSolver< Mesh, EulerScheme >::setup( const tnlParameterContainer
     */
 
    pressureGradient.setFunction( nsSolver.getPressure() );
-   pressureGradient.bindMesh( this -> mesh );
-   this->eulerScheme. bindMesh( this -> mesh );
-   this->eulerScheme. setPressureGradient( this -> pressureGradient );
-   this->u1Viscosity. bindMesh( this -> mesh );
-   this->u1Viscosity. setFunction( this -> nsSolver.getU1() );
-   this->u2Viscosity. bindMesh( this -> mesh );
-   this->u2Viscosity. setFunction( this -> nsSolver.getU2() );
-   this->eViscosity. bindMesh( this -> mesh );
-   this->eViscosity.setFunction( this -> nsSolver.getEnergy() );
+   pressureGradient.bindMesh( this->mesh );
+   this->eulerScheme. bindMesh( this->mesh );
+   this->eulerScheme. setPressureGradient( this->pressureGradient );
+   this->u1Viscosity. bindMesh( this->mesh );
+   this->u1Viscosity. setFunction( this->nsSolver.getU1() );
+   this->u2Viscosity. bindMesh( this->mesh );
+   this->u2Viscosity. setFunction( this->nsSolver.getU2() );
+   this->eViscosity. bindMesh( this->mesh );
+   this->eViscosity.setFunction( this->nsSolver.getEnergy() );
    nsSolver.setAdvectionScheme( this->eulerScheme );
    nsSolver.setDiffusionScheme( this->u1Viscosity,
                                 this->u2Viscosity,
@@ -244,7 +244,7 @@ bool navierStokesSolver< Mesh, EulerScheme > :: setInitialCondition( const tnlPa
 template< typename Mesh, typename EulerScheme >
 typename navierStokesSolver< Mesh, EulerScheme > :: DofVectorType& navierStokesSolver< Mesh, EulerScheme > :: getDofVector()
 {
-   return this -> dofVector;
+   return this->dofVector;
 }
 
 template< typename Mesh, typename EulerScheme >
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 942dc176e05bcc5dd6db68afba49015699a6f1ba..b51a42b2fe1154fd7783f527086284b6de7c6be9 100755
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -15,17 +15,21 @@ set (headers tnlAssert.h
              tnlDynamicTypeTag.h
              tnlFeature.h
              tnlFile.h 
+             tnlFile_impl.h
              tnlFlopsCounter.h
              tnlHost.h 
              tnlIndexedSet.h
              tnlList.h
-             tnlLogger.h 
+             tnlList_impl.h
+             tnlLogger.h
              tnlObject.h 
              tnlStack.h
              tnlStaticFor.h
              tnlStatistics.h 
              tnlString.h 
+             tnlSystemInfo.h
              tnlReal.h
+             tnlTimer.h
              tnlTimerCPU.h  
              tnlTimerRT.h    
              mfilename.h 
@@ -45,11 +49,14 @@ set( common_SOURCES
      ${CURRENT_DIR}/tnlObject.cpp
      ${CURRENT_DIR}/tnlStatistics.cpp
      ${CURRENT_DIR}/tnlString.cpp 
+     ${CURRENT_DIR}/tnlSystemInfo.cpp 
+     ${CURRENT_DIR}/tnlTimer.cpp 
      ${CURRENT_DIR}/tnlTimerCPU.cpp      
      ${CURRENT_DIR}/mfilename.cpp 
      ${CURRENT_DIR}/mpi-supp.cpp 
      ${CURRENT_DIR}/tnlCuda.cpp
-     ${CURRENT_DIR}/tnlHost.cpp )       
+     ${CURRENT_DIR}/tnlHost.cpp )
+
 
 IF( BUILD_CUDA )
    set( tnl_core_CUDA__SOURCES
diff --git a/src/core/arrays/tnlConstSharedArray_impl.h b/src/core/arrays/tnlConstSharedArray_impl.h
index ce0065859c45fe94f40c8879307f6f5e55e46045..7e7b3d2484f081f778f9d943384f7802afca340b 100644
--- a/src/core/arrays/tnlConstSharedArray_impl.h
+++ b/src/core/arrays/tnlConstSharedArray_impl.h
@@ -25,8 +25,6 @@
 #include <core/mfuncs.h>
 #include <core/param-types.h>
 
-using namespace std;
-
 template< typename Element,
           typename Device,
           typename Index >
@@ -77,13 +75,13 @@ void tnlConstSharedArray< Element, Device, Index > :: bind( const Element* data,
                                                             const Index size )
 {
    tnlAssert( size >= 0,
-              cerr << "You try to set size of tnlConstSharedArray to negative value."
-                   << "New size: " << size << endl );
+              std::cerr << "You try to set size of tnlConstSharedArray to negative value."
+                        << "New size: " << size << std::endl );
    tnlAssert( data != 0,
-              cerr << "You try to use null pointer to data for tnlConstSharedArray." );
+              std::cerr << "You try to use null pointer to data for tnlConstSharedArray." );
 
-   this -> size = size;
-   this -> data = data;
+   this->size = size;
+   this->data = data;
 };
 
 template< typename Element,
@@ -110,8 +108,8 @@ template< typename Element,
           typename Index >
 void tnlConstSharedArray< Element, Device, Index > :: swap( tnlConstSharedArray< Element, Device, Index >& array )
 {
-   :: swap( this -> size, array. size );
-   :: swap( this -> data, array. data );
+   :: swap( this->size, array. size );
+   :: swap( this->data, array. data );
 };
 
 template< typename Element,
@@ -119,8 +117,8 @@ template< typename Element,
           typename Index >
 void tnlConstSharedArray< Element, Device, Index > :: reset()
 {
-   this -> size = 0;
-   this -> data = 0;
+   this->size = 0;
+   this->data = 0;
 };
 
 template< typename Element,
@@ -129,7 +127,7 @@ template< typename Element,
 __cuda_callable__
 Index tnlConstSharedArray< Element, Device, Index > :: getSize() const
 {
-   return this -> size;
+   return this->size;
 }
 
 template< typename Element,
@@ -137,11 +135,11 @@ template< typename Element,
           typename Index >
 Element tnlConstSharedArray< Element, Device, Index > :: getElement( Index i ) const
 {
-   tnlAssert( 0 <= i && i < this -> getSize(),
-              cerr << "Wrong index for getElement method in tnlConstSharedArray with name "
-                   << " index is " << i
-                   << " and array size is " << this -> getSize() );
-   return tnlArrayOperations< Device >::getMemoryElement( &( this -> data[ i ] ) );
+   tnlAssert( 0 <= i && i < this->getSize(),
+              std::cerr << "Wrong index for getElement method in tnlConstSharedArray with name "
+                        << " index is " << i
+                        << " and array size is " << this->getSize() );
+   return tnlArrayOperations< Device >::getMemoryElement( &( this->data[ i ] ) );
 };
 
 template< typename Element,
@@ -150,12 +148,12 @@ template< typename Element,
 __cuda_callable__
 const Element& tnlConstSharedArray< Element, Device, Index > :: operator[] ( Index i ) const
 {
-   tnlAssert( 0 <= i && i < this -> getSize(),
-              cerr << "Wrong index for operator[] in tnlConstSharedArray with name "
-                   << " index is " << i
-                   << " and array size is " << this -> getSize() );
+   tnlAssert( 0 <= i && i < this->getSize(),
+              std::cerr << "Wrong index for operator[] in tnlConstSharedArray with name "
+                        << " index is " << i
+                        << " and array size is " << this->getSize() );
    // TODO: add static assert - this does not make sense for tnlCudaDevice
-   return tnlArrayOperations< Device >::getArrayElementReference( this -> data, i );
+   return tnlArrayOperations< Device >::getArrayElementReference( this->data, i );
 };
 
 template< typename Element,
@@ -184,14 +182,14 @@ template< typename Element,
    template< typename Array >
 bool tnlConstSharedArray< Element, Device, Index > :: operator == ( const Array& array ) const
 {
-   if( array. getSize() != this -> getSize() )
+   if( array. getSize() != this->getSize() )
       return false;
    return tnlArrayOperations< Device,
                               typename Array :: DeviceType > ::
     template compareMemory< typename Array :: ElementType,
                             Element,
                             typename Array :: IndexType >
-                          ( this -> getData(),
+                          ( this->getData(),
                             array. getData(),
                             array. getSize() );
 }
@@ -210,7 +208,7 @@ template< typename Element,
           typename Index >
 const Element* tnlConstSharedArray< Element, Device, Index > :: getData() const
 {
-   return this -> data;
+   return this->data;
 }
 
 template< typename Element,
@@ -236,20 +234,20 @@ template< typename Element,
           typename Index >
 bool tnlConstSharedArray< Element, Device, Index > :: save( tnlFile& file ) const
 {
-   tnlAssert( this -> size != 0,
-              cerr << "You try to save empty array." );
+   tnlAssert( this->size != 0,
+              std::cerr << "You try to save empty array." );
    if( ! tnlObject :: save( file ) )
       return false;
 #ifdef HAVE_NOT_CXX11
-   if( ! file. write< const Index, Device >( &this -> size ) )
+   if( ! file. write< const Index, Device >( &this->size ) )
 #else
-   if( ! file. write( &this -> size ) )
+   if( ! file. write( &this->size ) )
 #endif
       return false;
-   if( ! file. write< Element, Device, Index >( this -> data, this -> size ) )
+   if( ! file. write< Element, Device, Index >( this->data, this->size ) )
    {
-      cerr << "I was not able to WRITE tnlConstSharedArray " 
-           << " with size " << this -> getSize() << endl;
+      std::cerr << "I was not able to WRITE tnlConstSharedArray " 
+                << " with size " << this->getSize() << std::endl;
       return false;
    }
    return true;
diff --git a/src/core/arrays/tnlMultiArray1D_impl.h b/src/core/arrays/tnlMultiArray1D_impl.h
index 17591b814a358a706961d473aafba5026bb4146b..a94a74c8148a514fa872f2ad2203a81605c80714 100644
--- a/src/core/arrays/tnlMultiArray1D_impl.h
+++ b/src/core/arrays/tnlMultiArray1D_impl.h
@@ -75,8 +75,8 @@ bool tnlMultiArray< 1, Element, Device, Index > :: setDimensions( const tnlStati
 {
    tnlAssert( dimensions[ 0 ] > 0,
               cerr << " dimensions[ 0 ] = " << dimensions[ 0 ] );
-   this -> dimensions = dimensions;
-   return tnlArray< Element, Device, Index >::setSize( this -> dimensions[ 0 ] );
+   this->dimensions = dimensions;
+   return tnlArray< Element, Device, Index >::setSize( this->dimensions[ 0 ] );
 }
 
 template< typename Element, typename Device, typename Index >
@@ -97,22 +97,22 @@ template< typename Element, typename Device, typename Index >
 __cuda_callable__
 void tnlMultiArray< 1, Element, Device, Index > :: getDimensions( Index& xSize ) const
 {
-   xSize = this -> dimensions[ 0 ];
+   xSize = this->dimensions[ 0 ];
 }
 
 template< typename Element, typename Device, typename Index >
 __cuda_callable__
 const tnlStaticVector< 1, Index >& tnlMultiArray< 1, Element, Device, Index > :: getDimensions() const
 {
-   return this -> dimensions;
+   return this->dimensions;
 }
 
 template< typename Element, typename Device, typename Index >
 __cuda_callable__
 Index tnlMultiArray< 1, Element, Device, Index > :: getElementIndex( const Index i ) const
 {
-   tnlAssert( i >= 0 && i < this -> dimensions[ 0 ],
-              cerr << "i = " << i << " this -> dimensions[ 0 ] = " <<  this -> dimensions[ 0 ] );
+   tnlAssert( i >= 0 && i < this->dimensions[ 0 ],
+              cerr << "i = " << i << " this->dimensions[ 0 ] = " <<  this->dimensions[ 0 ] );
    return i;
 }
 
@@ -147,9 +147,9 @@ template< typename Element, typename Device, typename Index >
 bool tnlMultiArray< 1, Element, Device, Index > :: operator == ( const MultiArray& array ) const
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to compare two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    return tnlArray< Element, Device, Index > :: operator == ( array );
 }
@@ -166,9 +166,9 @@ tnlMultiArray< 1, Element, Device, Index >&
    tnlMultiArray< 1, Element, Device, Index > :: operator = ( const tnlMultiArray< 1, Element, Device, Index >& array )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to assign two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    tnlArray< Element, Device, Index > :: operator = ( array );
    return ( *this );
@@ -180,7 +180,7 @@ tnlMultiArray< 1, Element, Device, Index >&
    tnlMultiArray< 1, Element, Device, Index > :: operator = ( const MultiArray& array )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to assign two arrays with different dimensions." << endl
                    << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
diff --git a/src/core/arrays/tnlMultiArray2D_impl.h b/src/core/arrays/tnlMultiArray2D_impl.h
index 2b51149244a19719c77cfe01b65f47c5484739de..fb2de4d4e722869c6dcd07aa4eae799d38c9c6cc 100644
--- a/src/core/arrays/tnlMultiArray2D_impl.h
+++ b/src/core/arrays/tnlMultiArray2D_impl.h
@@ -84,9 +84,9 @@ bool tnlMultiArray< 2, Element, Device, Index > :: setDimensions( const tnlStati
    /****
     * Swap the dimensions in the tuple to be compatible with the previous method.
     */
-   this -> dimensions. x() = dimensions. y();
-   this -> dimensions. y() = dimensions. x();
-   return tnlArray< Element, Device, Index > :: setSize( this -> dimensions[ 1 ] * this -> dimensions[ 0 ] );
+   this->dimensions. x() = dimensions. y();
+   this->dimensions. y() = dimensions. x();
+   return tnlArray< Element, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] );
 }
 
 template< typename Element, typename Device, typename Index >
@@ -107,25 +107,25 @@ template< typename Element, typename Device, typename Index >
 __cuda_callable__
 void tnlMultiArray< 2, Element, Device, Index > :: getDimensions( Index& jSize, Index& iSize ) const
 {
-   iSize = this -> dimensions[ 0 ];
-   jSize = this -> dimensions[ 1 ];
+   iSize = this->dimensions[ 0 ];
+   jSize = this->dimensions[ 1 ];
 }
 
 template< typename Element, typename Device, typename Index >
 __cuda_callable__
 const tnlStaticVector< 2, Index >& tnlMultiArray< 2, Element, Device, Index > :: getDimensions() const
 {
-   return this -> dimensions;
+   return this->dimensions;
 }
 
 template< typename Element, typename Device, typename Index >
 __cuda_callable__
 Index tnlMultiArray< 2, Element, Device, Index > :: getElementIndex( const Index j, const Index i ) const
 {
-   tnlAssert( i >= 0 && i < this -> dimensions[ 0 ] && j >= 0 && j < this -> dimensions[ 1 ],
-              cerr << "i = " << i << " j = " << j << " this -> dimensions[ 0 ] = " <<  this -> dimensions[ 0 ]
-                   << " this -> dimensions[ 1 ] = " << this -> dimensions[ 1 ] );
-   return j * this -> dimensions[ 0 ] + i;
+   tnlAssert( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ],
+              cerr << "i = " << i << " j = " << j << " this->dimensions[ 0 ] = " <<  this->dimensions[ 0 ]
+                   << " this->dimensions[ 1 ] = " << this->dimensions[ 1 ] );
+   return j * this->dimensions[ 0 ] + i;
 }
 
 template< typename Element, typename Device, typename Index >
@@ -159,9 +159,9 @@ template< typename Element, typename Device, typename Index >
 bool tnlMultiArray< 2, Element, Device, Index > :: operator == ( const MultiArray& array ) const
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to compare two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    return tnlArray< Element, Device, Index > :: operator == ( array );
 }
@@ -178,9 +178,9 @@ tnlMultiArray< 2, Element, Device, Index >&
    tnlMultiArray< 2, Element, Device, Index > :: operator = ( const tnlMultiArray< 2, Element, Device, Index >& array )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to assign two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    tnlArray< Element, Device, Index > :: operator = ( array );
    return ( *this );
@@ -192,9 +192,9 @@ tnlMultiArray< 2, Element, Device, Index >&
    tnlMultiArray< 2, Element, Device, Index > :: operator = ( const MultiArray& array )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to assign two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    tnlArray< Element, Device, Index > :: operator = ( array );
    return ( *this );
diff --git a/src/core/arrays/tnlMultiArray3D_impl.h b/src/core/arrays/tnlMultiArray3D_impl.h
index 25a91599dfa95d51d2817818315a711ce3adc916..b8b30ad91ebc409c50437000d4a094fd9d3f1d33 100644
--- a/src/core/arrays/tnlMultiArray3D_impl.h
+++ b/src/core/arrays/tnlMultiArray3D_impl.h
@@ -87,12 +87,12 @@ bool tnlMultiArray< 3, Element, Device, Index > :: setDimensions( const tnlStati
    /****
     * Swap the dimensions in the tuple to be compatible with the previous method.
     */
-   this -> dimensions. x() = dimensions. z();
-   this -> dimensions. y() = dimensions. y();
-   this -> dimensions. z() = dimensions. x();
-   return tnlArray< Element, Device, Index > :: setSize( this -> dimensions[ 2 ] *
-                                                          this -> dimensions[ 1 ] *
-                                                          this -> dimensions[ 0 ] );
+   this->dimensions. x() = dimensions. z();
+   this->dimensions. y() = dimensions. y();
+   this->dimensions. z() = dimensions. x();
+   return tnlArray< Element, Device, Index > :: setSize( this->dimensions[ 2 ] *
+                                                          this->dimensions[ 1 ] *
+                                                          this->dimensions[ 0 ] );
 }
 
 template< typename Element, typename Device, typename Index >
@@ -115,16 +115,16 @@ void tnlMultiArray< 3, Element, Device, Index > :: getDimensions( Index& kSize,
                                                                   Index& jSize,
                                                                   Index& iSize ) const
 {
-   iSize = this -> dimensions[ 0 ];
-   jSize = this -> dimensions[ 1 ];
-   kSize = this -> dimensions[ 2 ];
+   iSize = this->dimensions[ 0 ];
+   jSize = this->dimensions[ 1 ];
+   kSize = this->dimensions[ 2 ];
 }
 
 template< typename Element, typename Device, typename Index >
 __cuda_callable__
 const tnlStaticVector< 3, Index >& tnlMultiArray< 3, Element, Device, Index > :: getDimensions() const
 {
-   return this -> dimensions;
+   return this->dimensions;
 }
 
 template< typename Element, typename Device, typename Index >
@@ -133,14 +133,14 @@ Index tnlMultiArray< 3, Element, Device, Index > :: getElementIndex( const Index
                                                                      const Index j,
                                                                      const Index i ) const
 {
-   tnlAssert( i >= 0 && i < this -> dimensions[ 0 ] &&
-              j >= 0 && j < this -> dimensions[ 1 ] &&
-              k >= 0 && k < this -> dimensions[ 2 ],
+   tnlAssert( i >= 0 && i < this->dimensions[ 0 ] &&
+              j >= 0 && j < this->dimensions[ 1 ] &&
+              k >= 0 && k < this->dimensions[ 2 ],
               cerr << " i = " << i
                    << " j = " << j
                    << " k = " << k
-                   << " this -> dimensions = " << this -> dimensions );
-   return ( k * this -> dimensions[ 1 ]  + j ) * this -> dimensions[ 0 ] + i;
+                   << " this->dimensions = " << this->dimensions );
+   return ( k * this->dimensions[ 1 ]  + j ) * this->dimensions[ 0 ] + i;
 }
 
 template< typename Element, typename Device, typename Index >
@@ -183,9 +183,9 @@ template< typename Element, typename Device, typename Index >
 bool tnlMultiArray< 3, Element, Device, Index > :: operator == ( const MultiArray& array ) const
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to compare two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    return tnlArray< Element, Device, Index > :: operator == ( array );
 }
@@ -202,9 +202,9 @@ tnlMultiArray< 3, Element, Device, Index >&
    tnlMultiArray< 3, Element, Device, Index > :: operator = ( const tnlMultiArray< 3, Element, Device, Index >& array )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to assign two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    tnlArray< Element, Device, Index > :: operator = ( array );
    return ( *this );
@@ -216,9 +216,9 @@ tnlMultiArray< 3, Element, Device, Index >&
    tnlMultiArray< 3, Element, Device, Index > :: operator = ( const MultiArray& array )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to assign two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    tnlArray< Element, Device, Index > :: operator = ( array );
    return ( *this );
diff --git a/src/core/arrays/tnlMultiArray4D_impl.h b/src/core/arrays/tnlMultiArray4D_impl.h
index 67d492fa119a6b6b980e5228702b060a694becfc..f03b942ddc5c691c6cf0c2b29b8e42262fba126f 100644
--- a/src/core/arrays/tnlMultiArray4D_impl.h
+++ b/src/core/arrays/tnlMultiArray4D_impl.h
@@ -90,14 +90,14 @@ bool tnlMultiArray< 4, Element, Device, Index > :: setDimensions( const tnlStati
    /****
     * Swap the dimensions in the tuple to be compatible with the previous method.
     */
-   this -> dimensions[ 0 ] = dimensions[ 3 ];
-   this -> dimensions[ 1 ] = dimensions[ 2 ];
-   this -> dimensions[ 2 ] = dimensions[ 1 ];
-   this -> dimensions[ 3 ] = dimensions[ 0 ];
-   return tnlArray< Element, Device, Index > :: setSize( this -> dimensions[ 3 ] *
-                                                         this -> dimensions[ 2 ] *
-                                                         this -> dimensions[ 1 ] *
-                                                         this -> dimensions[ 0 ] );
+   this->dimensions[ 0 ] = dimensions[ 3 ];
+   this->dimensions[ 1 ] = dimensions[ 2 ];
+   this->dimensions[ 2 ] = dimensions[ 1 ];
+   this->dimensions[ 3 ] = dimensions[ 0 ];
+   return tnlArray< Element, Device, Index > :: setSize( this->dimensions[ 3 ] *
+                                                         this->dimensions[ 2 ] *
+                                                         this->dimensions[ 1 ] *
+                                                         this->dimensions[ 0 ] );
 }
 
 template< typename Element, typename Device, typename Index >
@@ -121,17 +121,17 @@ void tnlMultiArray< 4, Element, Device, Index > :: getDimensions( Index& lSize,
                                                                        Index& jSize,
                                                                        Index& iSize ) const
 {
-   iSize = this -> dimensions[ 0 ];
-   jSize = this -> dimensions[ 1 ];
-   kSize = this -> dimensions[ 2 ];
-   lSize = this -> dimensions[ 3 ];
+   iSize = this->dimensions[ 0 ];
+   jSize = this->dimensions[ 1 ];
+   kSize = this->dimensions[ 2 ];
+   lSize = this->dimensions[ 3 ];
 }
 
 template< typename Element, typename Device, typename Index >
 __cuda_callable__
 const tnlStaticVector< 4, Index >& tnlMultiArray< 4, Element, Device, Index > :: getDimensions() const
 {
-   return this -> dimensions;
+   return this->dimensions;
 }
 
 template< typename Element, typename Device, typename Index >
@@ -141,16 +141,16 @@ Index tnlMultiArray< 4, Element, Device, Index > :: getElementIndex( const Index
                                                                      const Index j,
                                                                      const Index i ) const
 {
-   tnlAssert( i >= 0 && i < this -> dimensions[ 0 ] &&
-              j >= 0 && j < this -> dimensions[ 1 ] &&
-              k >= 0 && k < this -> dimensions[ 2 ] &&
-              l >= 0 && l < this -> dimensions[ 3 ],
+   tnlAssert( i >= 0 && i < this->dimensions[ 0 ] &&
+              j >= 0 && j < this->dimensions[ 1 ] &&
+              k >= 0 && k < this->dimensions[ 2 ] &&
+              l >= 0 && l < this->dimensions[ 3 ],
               cerr << " i = " << i
                    << " j = " << j
                    << " k = " << k
                    << " l = " << l
-                   << " this -> dimensions = " << this -> dimensions );
-   return ( ( l * this -> dimensions[ 2 ] + k ) * this -> dimensions[ 1 ]  + j ) * this -> dimensions[ 0 ] + i;
+                   << " this->dimensions = " << this->dimensions );
+   return ( ( l * this->dimensions[ 2 ] + k ) * this->dimensions[ 1 ]  + j ) * this->dimensions[ 0 ] + i;
 }
 
 template< typename Element, typename Device, typename Index >
@@ -197,9 +197,9 @@ template< typename Element, typename Device, typename Index >
 bool tnlMultiArray< 4, Element, Device, Index > :: operator == ( const MultiArray& array ) const
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to compare two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    return tnlArray< Element, Device, Index > :: operator == ( array );
 }
@@ -216,9 +216,9 @@ tnlMultiArray< 4, Element, Device, Index >&
    tnlMultiArray< 4, Element, Device, Index > :: operator = ( const tnlMultiArray< 4, Element, Device, Index >& array )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to assign two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    tnlArray< Element, Device, Index > :: operator = ( array );
    return ( *this );
@@ -230,9 +230,9 @@ tnlMultiArray< 4, Element, Device, Index >&
    tnlMultiArray< 4, Element, Device, Index > :: operator = ( const MultiArray& array )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == array. getDimensions(),
+   tnlAssert( this->getDimensions() == array. getDimensions(),
               cerr << "You are attempting to assign two arrays with different dimensions." << endl
-                   << "First array dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First array dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second array dimensions are ( " << array. getDimensions() << " )" << endl; );
    tnlArray< Element, Device, Index > :: operator = ( array );
    return ( *this );
diff --git a/src/core/arrays/tnlSharedArray_impl.h b/src/core/arrays/tnlSharedArray_impl.h
index 3aad6dd486edc45ff944823be9b9dfe35156a46f..627140d2aa6b736f95eac0de3977998f018394da 100644
--- a/src/core/arrays/tnlSharedArray_impl.h
+++ b/src/core/arrays/tnlSharedArray_impl.h
@@ -26,8 +26,6 @@
 #include <core/mfuncs.h>
 #include <core/param-types.h>
 
-using namespace std;
-
 template< typename Element,
           typename Device,
           typename Index >
@@ -108,13 +106,13 @@ void tnlSharedArray< Element, Device, Index > :: bind( Element* data,
                                                        const Index size )
 {
    tnlAssert( size >= 0,
-              cerr << "You try to set size of tnlSharedArray to negative value."
-                   << "New size: " << size << endl );
+              std::cerr << "You try to set size of tnlSharedArray to negative value."
+                        << "New size: " << size << std::endl );
    tnlAssert( data != 0,
-              cerr << "You try to use null pointer to data for tnlSharedArray." );
+              std::cerr << "You try to use null pointer to data for tnlSharedArray." );
 
-   this -> size = size;
-   this -> data = data;
+   this->size = size;
+   this->data = data;
 };
 
 template< typename Element,
@@ -154,8 +152,8 @@ template< typename Element,
 __cuda_callable__
 void tnlSharedArray< Element, Device, Index > :: bind( tnlSharedArray< Element, Device, Index >& array )
 {
-   this -> size = array. getSize();
-   this -> data = array. getData();
+   this->size = array. getSize();
+   this->data = array. getData();
 };
 
 template< typename Element,
@@ -163,8 +161,8 @@ template< typename Element,
           typename Index >
 void tnlSharedArray< Element, Device, Index > :: swap( tnlSharedArray< Element, Device, Index >& array )
 {
-   :: swap( this -> size, array. size );
-   :: swap( this -> data, array. data );
+   :: swap( this->size, array. size );
+   :: swap( this->data, array. data );
 };
 
 template< typename Element,
@@ -172,8 +170,8 @@ template< typename Element,
           typename Index >
 void tnlSharedArray< Element, Device, Index > :: reset()
 {
-   this -> size = 0;
-   this -> data = 0;
+   this->size = 0;
+   this->data = 0;
 };
 
 template< typename Element,
@@ -182,7 +180,7 @@ template< typename Element,
 __cuda_callable__
 Index tnlSharedArray< Element, Device, Index > :: getSize() const
 {
-   return this -> size;
+   return this->size;
 }
 
 template< typename Element,
@@ -190,11 +188,11 @@ template< typename Element,
           typename Index >
 void tnlSharedArray< Element, Device, Index > :: setElement( const Index& i, const Element& x )
 {
-   tnlAssert( 0 <= i && i < this -> getSize(),
-              cerr << "Wrong index for setElement method in tnlSharedArray "
-                   << " index is " << i
-                   << " and array size is " << this -> getSize() );
-   return tnlArrayOperations< Device >::setMemoryElement( & ( this -> data[ i ] ), x );
+   tnlAssert( 0 <= i && i < this->getSize(),
+              std::cerr << "Wrong index for setElement method in tnlSharedArray "
+                        << " index is " << i
+                        << " and array size is " << this->getSize() );
+   return tnlArrayOperations< Device >::setMemoryElement( & ( this->data[ i ] ), x );
 };
 
 template< typename Element,
@@ -202,11 +200,11 @@ template< typename Element,
           typename Index >
 Element tnlSharedArray< Element, Device, Index > :: getElement( const Index& i ) const
 {
-   tnlAssert( 0 <= i && i < this -> getSize(),
-              cerr << "Wrong index for getElement method in tnlSharedArray "
-                   << " index is " << i
-                   << " and array size is " << this -> getSize() );
-   return tnlArrayOperations< Device >::getMemoryElement( &( this -> data[ i ] ) );
+   tnlAssert( 0 <= i && i < this->getSize(),
+              std::cerr << "Wrong index for getElement method in tnlSharedArray "
+                        << " index is " << i
+                        << " and array size is " << this->getSize() );
+   return tnlArrayOperations< Device >::getMemoryElement( &( this->data[ i ] ) );
 };
 
 template< typename Element,
@@ -215,10 +213,10 @@ template< typename Element,
 __cuda_callable__
 Element& tnlSharedArray< Element, Device, Index > :: operator[] ( const Index& i )
 {
-   tnlAssert( 0 <= i && i < this -> getSize(),
-              cerr << "Wrong index for operator[] in tnlSharedArray "
-                   << " index is " << i
-                   << " and array size is " << this -> getSize() );
+   tnlAssert( 0 <= i && i < this->getSize(),
+              std::cerr << "Wrong index for operator[] in tnlSharedArray "
+                        << " index is " << i
+                        << " and array size is " << this->getSize() );
    return this->data[ i ];
 };
 
@@ -228,10 +226,10 @@ template< typename Element,
 __cuda_callable__
 const Element& tnlSharedArray< Element, Device, Index > :: operator[] ( const Index& i ) const
 {
-   tnlAssert( 0 <= i && i < this -> getSize(),
-              cerr << "Wrong index for operator[] in tnlSharedArray "
-                   << " index is " << i
-                   << " and array size is " << this -> getSize() );
+   tnlAssert( 0 <= i && i < this->getSize(),
+              std::cerr << "Wrong index for operator[] in tnlSharedArray "
+                        << " index is " << i
+                        << " and array size is " << this->getSize() );
    return this->data[ i ];
 };
 
@@ -241,14 +239,14 @@ template< typename Element,
 tnlSharedArray< Element, Device, Index >&
     tnlSharedArray< Element, Device, Index > :: operator = ( const tnlSharedArray< Element, Device, Index >& array )
 {
-   tnlAssert( array. getSize() == this -> getSize(),
-           cerr << "Source size: " << array. getSize() << endl
-                << "Target size: " << this -> getSize() << endl );
+   tnlAssert( array. getSize() == this->getSize(),
+              std::cerr << "Source size: " << array. getSize() << std::endl
+                        << "Target size: " << this->getSize() << std::endl );
    tnlArrayOperations< Device > ::
    template copyMemory< Element,
                         Element,
                         Index >
-                       ( this -> getData(),
+                       ( this->getData(),
                          array. getData(),
                          array. getSize() );
    return ( *this );
@@ -260,15 +258,15 @@ template< typename Element,
    template< typename Array >
 tnlSharedArray< Element, Device, Index >& tnlSharedArray< Element, Device, Index > :: operator = ( const Array& array )
 {
-   tnlAssert( array. getSize() == this -> getSize(),
-           cerr << "Source size: " << array. getSize() << endl
-                << "Target size: " << this -> getSize() << endl );
+   tnlAssert( array. getSize() == this->getSize(),
+              std::cerr << "Source size: " << array. getSize() << std::endl
+                        << "Target size: " << this->getSize() << std::endl );
    tnlArrayOperations< typename Array :: DeviceType,
                        Device > ::
     template copyMemory< Element,
                          typename Array :: ElementType,
                          typename Array :: IndexType >
-                       ( this -> getData(),
+                       ( this->getData(),
                          array. getData(),
                          array. getSize() );
    return ( *this );
@@ -280,14 +278,14 @@ template< typename Element,
    template< typename Array >
 bool tnlSharedArray< Element, Device, Index > :: operator == ( const Array& array ) const
 {
-   if( array. getSize() != this -> getSize() )
+   if( array. getSize() != this->getSize() )
       return false;
    return tnlArrayOperations< Device,
                               typename Array :: DeviceType > ::
     template compareMemory< typename Array :: ElementType,
                             Element,
                             typename Array :: IndexType >
-                          ( this -> getData(),
+                          ( this->getData(),
                             array. getData(),
                             array. getSize() );
 }
@@ -306,9 +304,9 @@ template< typename Element,
           typename Index >
 void tnlSharedArray< Element, Device, Index > :: setValue( const Element& e )
 {
-   tnlAssert( this -> size != 0, );
+   tnlAssert( this->size != 0, );
    tnlArrayOperations< Device >::template setMemory< Element, Index >
-                              ( this -> getData(), e, this -> getSize() );
+                              ( this->getData(), e, this->getSize() );
 
 }
 
@@ -317,7 +315,7 @@ template< typename Element,
           typename Index >
 const Element* tnlSharedArray< Element, Device, Index > :: getData() const
 {
-   return this -> data;
+   return this->data;
 }
 
 template< typename Element,
@@ -325,7 +323,7 @@ template< typename Element,
           typename Index >
 Element* tnlSharedArray< Element, Device, Index > :: getData()
 {
-   return this -> data;
+   return this->data;
 }
 
 template< typename Element,
@@ -351,19 +349,19 @@ template< typename Element,
           typename Index >
 bool tnlSharedArray< Element, Device, Index > :: save( tnlFile& file ) const
 {
-   tnlAssert( this -> size != 0,
-              cerr << "You try to save empty array." << endl );
+   tnlAssert( this->size != 0,
+              std::cerr << "You try to save empty array." << std::endl );
    if( ! tnlObject :: save( file ) )
       return false;
 #ifdef HAVE_NOT_CXX11
-   if( ! file. write< const Index, tnlHost >( &this -> size ) )
+   if( ! file. write< const Index, tnlHost >( &this->size ) )
 #else            
-   if( ! file. write( &this -> size ) )
+   if( ! file. write( &this->size ) )
 #endif      
       return false;
-   if( ! file. write< Element, Device, Index >( this -> data, this -> size ) )
+   if( ! file. write< Element, Device, Index >( this->data, this->size ) )
    {
-      cerr << "I was not able to WRITE tnlSharedArray with size " << this -> getSize() << endl;
+      std::cerr << "I was not able to WRITE tnlSharedArray with size " << this->getSize() << std::endl;
       return false;
    }
    return true;
@@ -394,15 +392,15 @@ bool tnlSharedArray< Element, Device, Index > :: load( tnlFile& file )
 #endif
    if( _size != this->size )
    {
-      cerr << "Error: The size " << _size << " of the data to be load is different from the " <<
-               "allocated array. This is not possible in the shared array." << endl;
+      std::cerr << "Error: The size " << _size << " of the data to be load is different from the " <<
+                   "allocated array. This is not possible in the shared array." << std::endl;
       return false;
    }
    if( _size )
    {
-      if( ! file. read< Element, Device, Index >( this -> data, this -> size ) )
+      if( ! file. read< Element, Device, Index >( this->data, this->size ) )
       {
-         cerr << "I was not able to READ tnlSharedArray with size " << this -> getSize() << endl;
+         std::cerr << "I was not able to READ tnlSharedArray with size " << this->getSize() << std::endl;
          return false;
       }
    }
diff --git a/src/core/cuda/reduction-operations.h b/src/core/cuda/reduction-operations.h
index da18c6c39ca816ad797c2d5bbf453c3be25ad1b9..0cc066e946329302fc4eed5e6e31e7fc81745be4 100644
--- a/src/core/cuda/reduction-operations.h
+++ b/src/core/cuda/reduction-operations.h
@@ -545,7 +545,7 @@ class tnlParallelReductionLpNorm : public tnlParallelReductionSum< Real, Index >
 
    void setPower( const RealType& p )
    {
-      this -> p = p;
+      this->p = p;
    };
 
    ResultType reduceOnHost( const IndexType& idx,
@@ -879,7 +879,7 @@ class tnlParallelReductionDiffLpNorm : public tnlParallelReductionSum< Real, Ind
 
    void setPower( const RealType& p )
    {
-      this -> p = p;
+      this->p = p;
    };
 
    ResultType reduceOnHost( const IndexType& idx,
diff --git a/src/core/images/tnlPGMImage_impl.h b/src/core/images/tnlPGMImage_impl.h
index 2539fa6b67aacf566039f6e2986bbb7c64a3910f..c204ef2d1c0edb975ecee3f20835e850bbeb972e 100644
--- a/src/core/images/tnlPGMImage_impl.h
+++ b/src/core/images/tnlPGMImage_impl.h
@@ -34,8 +34,8 @@ tnlPGMImage< Index >::
 readHeader()
 {
    char magicNumber[ 3 ];
-   this -> file >> magicNumber;
-   if( this -> file.fail() )
+   this->file >> magicNumber;
+   if( this->file.fail() )
    {
       cerr << "Unable to read the magic number." << endl;
       return false;
@@ -49,17 +49,17 @@ readHeader()
       this->binary = true;
 
    char character;
-   this -> file.get(character);
-   while ( ! this -> file.eof() and ( character == ' ' || character == '\t' || character == '\r' || character == '\n') )
+   this->file.get(character);
+   while ( ! this->file.eof() and ( character == ' ' || character == '\t' || character == '\r' || character == '\n') )
    {
-	this -> file.get(character);
+	this->file.get(character);
 	if ( character == '#' )
-		while (! this -> file.eof() && ( character != '\n' ) )
-			this -> file.get( character );
+		while (! this->file.eof() && ( character != '\n' ) )
+			this->file.get( character );
    }
-   this -> file.unget();
+   this->file.unget();
    
-   this -> file >> this -> width >> this -> height >> this -> maxColors;
+   this->file >> this->width >> this->height >> this->maxColors;
    return true;   
 }
 
@@ -69,7 +69,7 @@ tnlPGMImage< Index >::
 openForRead( const tnlString& fileName )
 {
    this->close();
-   if ( this -> binary )
+   if ( this->binary )
    	this->file.open( fileName.getString(), fstream::in | fstream::binary);
    else 
 	this->file.open( fileName.getString(), fstream::in );
@@ -102,13 +102,13 @@ read( const tnlRegionOfInterest< Index > roi,
       for( j = 0; j < this->width; j ++ )
       {
          int col;
-	 unsigned char col_aux;
-         if( this->binary ) 
-	 {
-		this -> file >> col_aux;
-		col = (int)col_aux;
-	 }
-         else this -> file >> col;
+         unsigned char col_aux;
+              if( this->binary ) 
+         {
+           this->file >> col_aux;
+           col = (int)col_aux;
+         }
+         else this->file >> col;
          if( roi.isIn( i, j ) )
          {
             cell.getCoordinates().x() = j - roi.getLeft();
@@ -190,17 +190,16 @@ write( const tnlGrid< 2, Real, Device, Index >& grid,
          //                                     grid.getDimensions().y() - 1 - i ) );
 
          unsigned char color = 255 * vector.getElement( cell.getIndex() );
-         if ( ! this -> binary )
-	 {
-	     int color_aux = (int)color;
-	     this->file << color_aux;
-             this->file << ' ';
-	 }
-	 else this->file << color;
-      }
-      
-      if ( ! this -> binary )
-        this->file << '\n';
+         if ( ! this->binary )
+         {
+             int color_aux = (int)color;
+             this->file << color_aux;
+                  this->file << ' ';
+         }
+         else this->file << color;
+      }      
+      if ( ! this->binary )
+         this->file << '\n';
    }
    return true;
 }
diff --git a/src/core/mpi-supp.h b/src/core/mpi-supp.h
index ad203c653f16593ad6adb341dc1a60205937aa3f..fd099393f244667dba2ee452e4da3855382c79b6 100644
--- a/src/core/mpi-supp.h
+++ b/src/core/mpi-supp.h
@@ -21,8 +21,6 @@
 #include <iostream>
 #include <cstdlib>
 
-using namespace std;
-
 #ifdef HAVE_MPI
    #include <mpi.h>
 #else
@@ -108,7 +106,7 @@ template< class T > void MPIBcast( T& data,
 
 inline void MPIBcast( tnlString& data, int cout, int root, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   cerr << "Call method MPIBcast of mString instead of function MPIBcast( mString&, ... ) " << endl;
+   std::cerr << "Call method MPIBcast of mString instead of function MPIBcast( mString&, ... ) " << std::endl;
    abort();    
 }
 #else
diff --git a/src/core/param-types.h b/src/core/param-types.h
index 5a43683821cf126b941b3a4578b16ad0df6341f5..351c4872806ffc08f31adb0b8b8c680c8d3f843a 100644
--- a/src/core/param-types.h
+++ b/src/core/param-types.h
@@ -28,6 +28,7 @@ template<> inline tnlString getType< bool >() { return tnlString( "bool" ); };
 template<> inline tnlString getType< short int >() { return tnlString( "short int" ); };
 template<> inline tnlString getType< int >() { return tnlString( "int" ); };
 template<> inline tnlString getType< long int >() { return tnlString( "long int" ); };
+template<> inline tnlString getType< unsigned int >() { return tnlString( "unsigned int" ); };
 template<> inline tnlString getType< char >() { return tnlString( "char" ); };
 template<> inline tnlString getType< float >() { return tnlString( "float" ); };
 template<> inline tnlString getType< double >() { return tnlString( "double" ); };
diff --git a/src/core/terminal-colors.h b/src/core/terminal-colors.h
index 2c67d00c51a06e57f0300f8a0b9d7a73cb61eda9..079fa058286b92393c97f3b6f178239b4abbb2e8 100644
--- a/src/core/terminal-colors.h
+++ b/src/core/terminal-colors.h
@@ -15,16 +15,13 @@
  *                                                                         *
  ***************************************************************************/
 
-#ifndef TERMINAL_COLORS_H
-#define	TERMINAL_COLORS_H
+#pragma once
 
-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 */
+const tnlString red( "\033[0;31m" );
+const tnlString green( "\033[1;32m" );
+const tnlString yellow( "\033[1;33m" );
+const tnlString cyan( "\033[0;36m" );
+const tnlString magenta( "\033[0;35m" );
+const tnlString bold(); 
+const tnlString reset( "\033[0m" );
 
diff --git a/src/core/tnlCommunicator.h b/src/core/tnlCommunicator.h
index ea02f1e65bb9cabd379e775ac51da802b662f1f8..770bc79197b9082285c15046f46a98d6dfcece1f 100644
--- a/src/core/tnlCommunicator.h
+++ b/src/core/tnlCommunicator.h
@@ -155,38 +155,38 @@ tnlCommunicator< Dimensions, Device > :: tnlCommunicator()
 template< int Dimensions, typename Device >
 int tnlCommunicator< Dimensions, Device > :: getCommunicationGroupSize() const
 {
-   return this -> communicationGroupSize;
+   return this->communicationGroupSize;
 }
 
 template< int Dimensions, typename Device >
 bool tnlCommunicator< Dimensions, Device > :: setDimensions( const tnlStaticVector< Dimensions, int >& dimensions )
 {
-   this -> dimensions = dimensions;
+   this->dimensions = dimensions;
    // TODO: add automatic dimensions setting from the group size
 }
 
 template< int Dimensions, typename Device >
 const tnlStaticVector< Dimensions, int >& tnlCommunicator< Dimensions, Device > :: getDimensions() const
 {
-   return this -> dimensions;
+   return this->dimensions;
 }
 
 template< int Dimensions, typename Device >
 const tnlStaticVector< Dimensions, int >& tnlCommunicator< Dimensions, Device > :: getNodeCoordinates() const
 {
-   return this -> nodeCoordinates;
+   return this->nodeCoordinates;
 }
 
 template< int Dimensions, typename Device >
 int tnlCommunicator< Dimensions, Device > :: getDeviceId() const
 {
-    return this -> deviceID;
+    return this->deviceID;
 }
 
 template< int Dimensions, typename Device >
 bool tnlCommunicator< Dimensions, Device > :: setCommunicationGroupSize( int communicationGroupSize )
 {
-    this -> communicationGroupSize = communicationGroupSize;
+    this->communicationGroupSize = communicationGroupSize;
     // TODO: add automatic groupsize setting
 }
 
@@ -194,18 +194,18 @@ template< int Dimensions, typename Device >
 bool tnlCommunicator< Dimensions, Device > :: start()
 {
    dbgFunctionName( "tnlCommunicator", "start" );
-   if( this -> getCommunicationGroupSize() < 1 )
-      this -> setCommunicationGroupSize();
-   if( this -> getCommunicationGroupSize() < 1 )
+   if( this->getCommunicationGroupSize() < 1 )
+      this->setCommunicationGroupSize();
+   if( this->getCommunicationGroupSize() < 1 )
    {
-      cerr << "Sorry, but I have wrong size ( " << this -> getCommunicationGroupSize() << " of the communication group. I cannot create a communicator." << endl;
+      cerr << "Sorry, but I have wrong size ( " << this->getCommunicationGroupSize() << " of the communication group. I cannot create a communicator." << endl;
       return false;
    }
-   if( this -> getDimensions() == tnlStaticVector< Dimensions, int >( 0 ) )
-      this -> setDimensions( tnlStaticVector< Dimensions, int >( 0 ) );
-   if( this -> getDimensions() == tnlStaticVector< Dimensions, int >( -1 ) )
+   if( this->getDimensions() == tnlStaticVector< Dimensions, int >( 0 ) )
+      this->setDimensions( tnlStaticVector< Dimensions, int >( 0 ) );
+   if( this->getDimensions() == tnlStaticVector< Dimensions, int >( -1 ) )
    {
-      cerr << "Sorry, but I have wrong dimensions ( " << this -> getDimensions() << " of the communication group. I cannot create a communicator." << endl;
+      cerr << "Sorry, but I have wrong dimensions ( " << this->getDimensions() << " of the communication group. I cannot create a communicator." << endl;
       return false;
    }
    if( Device :: getDeviceType() == "tnlCuda" ||
@@ -213,7 +213,7 @@ bool tnlCommunicator< Dimensions, Device > :: start()
    {
       deviceID = 0;
       int currentDeviceID = 1;
-      for( int i = 0; i < this -> getCommunicationGroupSize() - 1; i ++ )
+      for( int i = 0; i < this->getCommunicationGroupSize() - 1; i ++ )
       {
          pid_t child_pid = fork();
          if( child_pid != 0 )
@@ -230,7 +230,7 @@ bool tnlCommunicator< Dimensions, Device > :: start()
             dbgCout( "The CHILD process is setting ID to " << deviceID );
             return true;
          } // if( child_pid != 0 ) - else
-      } // for( int i = 0; i < this -> getCommunicationGroupSize() - 1; i ++ )
+      } // for( int i = 0; i < this->getCommunicationGroupSize() - 1; i ++ )
    }
 }
 
diff --git a/src/core/tnlCudaDeviceInfo.cpp b/src/core/tnlCudaDeviceInfo.cpp
index cd5a4623900ebc174ee5da705674fe23eccb4ccc..137602f80edefe710823480f56dde6964ea082b7 100644
--- a/src/core/tnlCudaDeviceInfo.cpp
+++ b/src/core/tnlCudaDeviceInfo.cpp
@@ -25,7 +25,14 @@ getNumberOfDevices()
 {
    return -1;
 }
-      
+
+int
+tnlCudaDeviceInfo::
+getActiveDevice()
+{
+   return -1;
+}
+
 tnlString
 tnlCudaDeviceInfo::
 getDeviceName( int deviceNum )
@@ -39,7 +46,7 @@ getArchitectureMajor( int deviceNum )
 {
     return 0;
 }
-      
+
 int
 tnlCudaDeviceInfo::
 getArchitectureMinor( int deviceNum )
@@ -53,7 +60,7 @@ getClockRate( int deviceNum )
 {
    return 0;
 }
-      
+
 size_t
 tnlCudaDeviceInfo::
 getGlobalMemory( int deviceNum )
@@ -96,5 +103,5 @@ getCudaCores( int deviceNum )
    return 0;
 }
 
+#endif
 
-#endif
\ No newline at end of file
diff --git a/src/core/tnlCudaDeviceInfo.cu b/src/core/tnlCudaDeviceInfo.cu
index 5754f38b43a7ac42360f3f2443c0e89e34d965d6..3e4ea3a091b0317f1f7881cde0332c726ff65a25 100644
--- a/src/core/tnlCudaDeviceInfo.cu
+++ b/src/core/tnlCudaDeviceInfo.cu
@@ -28,7 +28,16 @@ getNumberOfDevices()
     cudaGetDeviceCount( &devices );
     return devices;
 }
-      
+
+int
+tnlCudaDeviceInfo::
+getActiveDevice()
+{
+    int device;
+    cudaGetDevice( &device );
+    return device;
+}
+
 tnlString
 tnlCudaDeviceInfo::
 getDeviceName( int deviceNum )
@@ -46,7 +55,7 @@ getArchitectureMajor( int deviceNum )
     cudaGetDeviceProperties( &properties, deviceNum );
     return properties.major;
 }
-      
+
 int
 tnlCudaDeviceInfo::
 getArchitectureMinor( int deviceNum )
@@ -55,7 +64,7 @@ getArchitectureMinor( int deviceNum )
     cudaGetDeviceProperties( &properties, deviceNum );
     return properties.minor;
 }
-      
+
 int
 tnlCudaDeviceInfo::
 getClockRate( int deviceNum )
@@ -64,7 +73,7 @@ getClockRate( int deviceNum )
     cudaGetDeviceProperties( &properties, deviceNum );
     return properties.clockRate;
 }
-      
+
 size_t
 tnlCudaDeviceInfo::
 getGlobalMemory( int deviceNum )
@@ -115,7 +124,7 @@ getCudaCoresPerMultiprocessors( int deviceNum )
         switch( minor )
         {
             case 0:  // GF100 class
-                return 32; 
+                return 32;
             case 1:  // GF10x class
                 return 48;
         }
@@ -136,5 +145,5 @@ getCudaCores( int deviceNum )
            tnlCudaDeviceInfo::getCudaCoresPerMultiprocessors( deviceNum );
 }
 
+#endif
 
-#endif
\ No newline at end of file
diff --git a/src/core/tnlCudaDeviceInfo.h b/src/core/tnlCudaDeviceInfo.h
index 34a560e3303ee17d3077b2613ecf968aec9a9d94..cf6c6cfa73fa32b2ade248ef0f470ef625069dcf 100644
--- a/src/core/tnlCudaDeviceInfo.h
+++ b/src/core/tnlCudaDeviceInfo.h
@@ -15,8 +15,7 @@
  *                                                                         *
  ***************************************************************************/
 
-#ifndef TNLCUDADEVICEINFO_H
-#define	TNLCUDADEVICEINFO_H
+#pragma once 
 
 #include <stdlib.h>
 #include <core/tnlCuda.h>
@@ -24,33 +23,29 @@
 class tnlCudaDeviceInfo
 {
    public:
-      
+
       static int getNumberOfDevices();
-      
+
+      static int getActiveDevice();
+
       static tnlString getDeviceName( int deviceNum );
-      
+
       static int getArchitectureMajor( int deviceNum );
-      
+
       static int getArchitectureMinor( int deviceNum );
-      
+
       static int getClockRate( int deviceNum );
-      
+
       static size_t getGlobalMemory( int deviceNum );
 
       static int getMemoryClockRate( int deviceNum );
 
       static bool getECCEnabled( int deviceNum );
 
-      static int getCudaMultiprocessors( int deviceNum );      
-      
-      static int getCudaCoresPerMultiprocessors( int deviceNum );      
-      
-      static int getCudaCores( int deviceNum );      
-      
-};
-
-
+      static int getCudaMultiprocessors( int deviceNum );
 
+      static int getCudaCoresPerMultiprocessors( int deviceNum );
 
-#endif	/* TNLCUDADEVICEINFO_H */
+      static int getCudaCores( int deviceNum );
 
+};
\ No newline at end of file
diff --git a/src/core/tnlCuda_impl.h b/src/core/tnlCuda_impl.h
index 42ec1165994f66a55f0c0512795e4cf719b62d3d..dd9c8e66ee9e5fe93d4680a83298fe5940cffeff 100644
--- a/src/core/tnlCuda_impl.h
+++ b/src/core/tnlCuda_impl.h
@@ -32,7 +32,7 @@ __host__ __device__
 inline int tnlCuda::getMaxGridSize()
 {
    // TODO: make it preprocessor macro constant defined in tnlConfig
-   return 65536;
+   return 65535;
 };
 
 #ifdef HAVE_CUDA
diff --git a/src/core/tnlFile.cpp b/src/core/tnlFile.cpp
index bd543cce9d2fd0a730942f8e7d4e14a20e11f439..7c02c0db864b68d29b9a53fe101c18745e45928d 100644
--- a/src/core/tnlFile.cpp
+++ b/src/core/tnlFile.cpp
@@ -68,3 +68,15 @@ bool tnlFile :: close()
    readElements = writtenElements = 0;
    return true;
 };
+
+bool fileExists( const tnlString& fileName )
+{
+  fstream file;
+  file.open( fileName. getString(), ios::in );
+  bool result( true );
+  if( ! file )
+     result = false;
+  file.close();
+  return result;
+};
+
diff --git a/src/core/tnlFile.h b/src/core/tnlFile.h
index 5accc399c1afc1e586a497eb5e3b48f94aa0d3a2..8ea18afee6a30f45727eaa311969b9d17383a01f 100644
--- a/src/core/tnlFile.h
+++ b/src/core/tnlFile.h
@@ -32,8 +32,6 @@
 #include <core/tnlHost.h>
 #include <core/tnlCuda.h>
 
-using namespace std;
-
 enum tnlIOMode { tnlUndefinedMode = 0,
                  tnlReadMode = 1,
                  tnlWriteMode = 2 };
@@ -124,212 +122,9 @@ class tnlFile
 
 };
 
-template< typename Type, typename Device >
-bool tnlFile :: read( Type* buffer )
-{
-   return read< Type, Device, int >( buffer, 1 );
-};
+bool fileExists( const tnlString& fileName );
 
-template< typename Type, typename Device >
-bool tnlFile :: write( const Type* buffer )
-{
-   return write< Type, Device, int >( buffer, 1 );
-};
 
-
-template< typename Type, typename Device, typename Index >
-bool tnlFile :: read( Type* buffer,
-                      const Index& elements )
-{
-   tnlAssert( elements >= 0,
-              cerr << " elements = " << elements << endl; );
-   if( ! elements )
-      return true;
-   if( ! fileOK )
-   {
-      cerr << "File " << fileName << " was not properly opened. " << endl;
-      return false;
-   }
-   if( mode != tnlReadMode )
-   {
-      cerr << "File " << fileName << " was not opened for reading. " << endl;
-      return false;
-   }
-   this->readElements = 0;
-   const Index host_buffer_size = :: Min( ( Index ) ( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ) ),
-                                          elements );
-   void* host_buffer( 0 );
-   if( Device :: getDeviceType() == "tnlHost" )
-   {
-      if( fread( buffer,
-             sizeof( Type ),
-             elements,
-             file ) != elements )
-      {
-         cerr << "I am not able to read the data from the file " << fileName << "." << endl;
-         perror( "Fread ended with the error code" );
-         return false;
-      }
-      this->readElements = elements;
-      return true;
-   }
-   if( Device :: getDeviceType() == "tnlCuda" )
-   {
-#ifdef HAVE_CUDA
-      /*!***
-       * Here we cannot use
-       *
-       * host_buffer = new Type[ host_buffer_size ];
-       *
-       * because it does not work for constant types like
-       * T = const bool.
-       */
-      host_buffer = malloc( sizeof( Type ) * host_buffer_size );
-      readElements = 0;
-      if( ! host_buffer )
-      {
-         cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file "
-              << this -> getFileName() << "." << endl;
-         return false;
-
-      }
-
-      while( readElements < elements )
-      {
-         int transfer = :: Min( ( Index ) ( elements - readElements ), host_buffer_size );
-         size_t transfered = fread( host_buffer, sizeof( Type ), transfer, file );
-         if( transfered != transfer )
-         {
-            cerr << "I am not able to read the data from the file " << fileName << "." << endl;
-            cerr << transfered << " bytes were transfered. " << endl;
-            perror( "Fread ended with the error code" );
-            return false;
-         }
-
-         cudaMemcpy( ( void* ) & ( buffer[ readElements ] ),
-                     host_buffer,
-                     transfer * sizeof( Type ),
-                     cudaMemcpyHostToDevice );
-         if( ! checkCudaDevice )
-         {
-            cerr << "Transfer of data from the CUDA device to the file " << this -> fileName
-                 << " failed." << endl;
-            free( host_buffer );
-            return false;
-         }
-         readElements += transfer;
-      }
-      free( host_buffer );
-      return true;
-#else
-      tnlCudaSupportMissingMessage;;
-      return false;
-#endif
-   }
-   return true;
-};
-
-template< class Type, typename Device, typename Index >
-bool tnlFile ::  write( const Type* buffer,
-                        const Index elements )
-{
-   tnlAssert( elements >= 0,
-              cerr << " elements = " << elements << endl; );
-   if( ! elements )
-      return true;
-   if( ! fileOK )
-   {
-      cerr << "File " << fileName << " was not properly opened. " << endl;
-      return false;
-   }
-   if( mode != tnlWriteMode )
-   {
-      cerr << "File " << fileName << " was not opened for writing. " << endl;
-      return false;
-   }
-
-   Type* buf = const_cast< Type* >( buffer );
-   void* host_buffer( 0 );
-   this->writtenElements = 0;
-   const long int host_buffer_size = :: Min( ( Index ) ( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ) ),
-                                          elements );
-   if( Device :: getDeviceType() == "tnlHost" )
-   {
-      if( fwrite( buf,
-                  sizeof( Type ),
-                  elements,
-                  this->file ) != elements )
-      {
-         cerr << "I am not able to write the data to the file " << fileName << "." << endl;
-         perror( "Fwrite ended with the error code" );
-         return false;
-      }
-      this->writtenElements = elements;
-      return true;
-   }
-   if( Device :: getDeviceType() == "tnlCuda" )
-   {
-#ifdef HAVE_CUDA
-         /*!***
-          * Here we cannot use
-          *
-          * host_buffer = new Type[ host_buffer_size ];
-          *
-          * because it does not work for constant types like
-          * T = const bool.
-          */
-         host_buffer = malloc( sizeof( Type ) * host_buffer_size );
-         if( ! host_buffer )
-         {
-            cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file "
-                 << this -> getFileName() << "." << endl;
-            return false;
-         }
-
-         while( this->writtenElements < elements )
-         {
-            Index transfer = Min( elements - this->writtenElements, host_buffer_size );
-            cudaMemcpy( host_buffer,
-                       ( void* ) & ( buffer[ this->writtenElements ] ),
-                       transfer * sizeof( Type ),
-                       cudaMemcpyDeviceToHost );
-            if( ! checkCudaDevice )
-            {
-               cerr << "Transfer of data from the file " << this -> fileName
-                    << " to the CUDA device failed." << endl;
-               free( host_buffer );
-               return false;
-            }
-            if( fwrite( host_buffer,
-                        sizeof( Type ),
-                        transfer,
-                        this->file ) != transfer )
-            {
-               cerr << "I am not able to write the data to the file " << fileName << "." << endl;
-               perror( "Fwrite ended with the error code" );
-               return false;
-            }
-            this->writtenElements += transfer;
-         }
-         free( host_buffer );
-         return true;
-#else
-         tnlCudaSupportMissingMessage;;
-         return false;
-#endif
-   }
-   return true;
-};
-
-inline bool fileExists( const tnlString& fileName )
-{
-  fstream file;
-  file.open( fileName. getString(), ios::in );
-  bool result( true );
-  if( ! file )
-     result = false;
-  file.close();
-  return result;
-};
+#include <core/tnlFile_impl.h>
 
 #endif /* TNLFILE_H_ */
diff --git a/src/core/tnlFile_impl.h b/src/core/tnlFile_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3e6eb32f1ce86688355b11219af6dc4aa28da46
--- /dev/null
+++ b/src/core/tnlFile_impl.h
@@ -0,0 +1,221 @@
+/***************************************************************************
+                          tnlFile_impl.h  -  description
+                             -------------------
+    begin                : Mar 5, Oct 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 TNLFILE_IMPL_H
+#define	TNLFILE_IMPL_H
+
+template< typename Type, typename Device >
+bool tnlFile :: read( Type* buffer )
+{
+   return read< Type, Device, int >( buffer, 1 );
+};
+
+template< typename Type, typename Device >
+bool tnlFile :: write( const Type* buffer )
+{
+   return write< Type, Device, int >( buffer, 1 );
+};
+
+
+template< typename Type, typename Device, typename Index >
+bool tnlFile :: read( Type* buffer,
+                      const Index& elements )
+{
+   tnlAssert( elements >= 0,
+              cerr << " elements = " << elements << endl; );
+   if( ! elements )
+      return true;
+   if( ! fileOK )
+   {
+      cerr << "File " << fileName << " was not properly opened. " << endl;
+      return false;
+   }
+   if( mode != tnlReadMode )
+   {
+      cerr << "File " << fileName << " was not opened for reading. " << endl;
+      return false;
+   }
+   this->readElements = 0;
+   const Index host_buffer_size = :: Min( ( Index ) ( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ) ),
+                                          elements );
+   void* host_buffer( 0 );
+   if( Device :: getDeviceType() == "tnlHost" )
+   {
+      if( fread( buffer,
+             sizeof( Type ),
+             elements,
+             file ) != elements )
+      {
+         cerr << "I am not able to read the data from the file " << fileName << "." << endl;
+         perror( "Fread ended with the error code" );
+         return false;
+      }
+      this->readElements = elements;
+      return true;
+   }
+   if( Device :: getDeviceType() == "tnlCuda" )
+   {
+#ifdef HAVE_CUDA
+      /*!***
+       * Here we cannot use
+       *
+       * host_buffer = new Type[ host_buffer_size ];
+       *
+       * because it does not work for constant types like
+       * T = const bool.
+       */
+      host_buffer = malloc( sizeof( Type ) * host_buffer_size );
+      readElements = 0;
+      if( ! host_buffer )
+      {
+         cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file "
+              << this->getFileName() << "." << endl;
+         return false;
+
+      }
+
+      while( readElements < elements )
+      {
+         int transfer = :: Min( ( Index ) ( elements - readElements ), host_buffer_size );
+         size_t transfered = fread( host_buffer, sizeof( Type ), transfer, file );
+         if( transfered != transfer )
+         {
+            cerr << "I am not able to read the data from the file " << fileName << "." << endl;
+            cerr << transfered << " bytes were transfered. " << endl;
+            perror( "Fread ended with the error code" );
+            return false;
+         }
+
+         cudaMemcpy( ( void* ) & ( buffer[ readElements ] ),
+                     host_buffer,
+                     transfer * sizeof( Type ),
+                     cudaMemcpyHostToDevice );
+         if( ! checkCudaDevice )
+         {
+            cerr << "Transfer of data from the CUDA device to the file " << this->fileName
+                 << " failed." << endl;
+            free( host_buffer );
+            return false;
+         }
+         readElements += transfer;
+      }
+      free( host_buffer );
+      return true;
+#else
+      tnlCudaSupportMissingMessage;;
+      return false;
+#endif
+   }
+   return true;
+};
+
+template< class Type, typename Device, typename Index >
+bool tnlFile ::  write( const Type* buffer,
+                        const Index elements )
+{
+   tnlAssert( elements >= 0,
+              cerr << " elements = " << elements << endl; );
+   if( ! elements )
+      return true;
+   if( ! fileOK )
+   {
+      cerr << "File " << fileName << " was not properly opened. " << endl;
+      return false;
+   }
+   if( mode != tnlWriteMode )
+   {
+      cerr << "File " << fileName << " was not opened for writing. " << endl;
+      return false;
+   }
+
+   Type* buf = const_cast< Type* >( buffer );
+   void* host_buffer( 0 );
+   this->writtenElements = 0;
+   const long int host_buffer_size = :: Min( ( Index ) ( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ) ),
+                                          elements );
+   if( Device :: getDeviceType() == "tnlHost" )
+   {
+      if( fwrite( buf,
+                  sizeof( Type ),
+                  elements,
+                  this->file ) != elements )
+      {
+         cerr << "I am not able to write the data to the file " << fileName << "." << endl;
+         perror( "Fwrite ended with the error code" );
+         return false;
+      }
+      this->writtenElements = elements;
+      return true;
+   }
+   if( Device :: getDeviceType() == "tnlCuda" )
+   {
+#ifdef HAVE_CUDA
+         /*!***
+          * Here we cannot use
+          *
+          * host_buffer = new Type[ host_buffer_size ];
+          *
+          * because it does not work for constant types like
+          * T = const bool.
+          */
+         host_buffer = malloc( sizeof( Type ) * host_buffer_size );
+         if( ! host_buffer )
+         {
+            cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file "
+                 << this->getFileName() << "." << endl;
+            return false;
+         }
+
+         while( this->writtenElements < elements )
+         {
+            Index transfer = Min( elements - this->writtenElements, host_buffer_size );
+            cudaMemcpy( host_buffer,
+                       ( void* ) & ( buffer[ this->writtenElements ] ),
+                       transfer * sizeof( Type ),
+                       cudaMemcpyDeviceToHost );
+            if( ! checkCudaDevice )
+            {
+               cerr << "Transfer of data from the file " << this->fileName
+                    << " to the CUDA device failed." << endl;
+               free( host_buffer );
+               return false;
+            }
+            if( fwrite( host_buffer,
+                        sizeof( Type ),
+                        transfer,
+                        this->file ) != transfer )
+            {
+               cerr << "I am not able to write the data to the file " << fileName << "." << endl;
+               perror( "Fwrite ended with the error code" );
+               return false;
+            }
+            this->writtenElements += transfer;
+         }
+         free( host_buffer );
+         return true;
+#else
+         tnlCudaSupportMissingMessage;;
+         return false;
+#endif
+   }
+   return true;
+};
+
+
+
+#endif	/* TNLFILE_IMPL_H */
+
diff --git a/src/core/tnlHost.cpp b/src/core/tnlHost.cpp
index 7d53f0435cdc88f707af57ad46b0ee45b6b3d8af..639ea76eecbe38758270d950ac8dfdcba5eb9503 100644
--- a/src/core/tnlHost.cpp
+++ b/src/core/tnlHost.cpp
@@ -19,6 +19,15 @@
 #define TNLHOSTL_H_
 
 #include <core/tnlHost.h>
+#ifdef HAVE_OPENMP
+#include <omp.h>
+#endif
+#include <config/tnlConfigDescription.h>
+#include <config/tnlParameterContainer.h>
+
+
+bool tnlHost::ompEnabled( true );
+int tnlHost::maxThreadsCount( -1 );
 
 tnlString tnlHost::getDeviceType()
 {
@@ -32,4 +41,63 @@ size_t tnlHost::getFreeMemory()
    return pages * page_size;
 };
 
+void tnlHost::enableOMP()
+{
+   ompEnabled = true;
+}
+
+void tnlHost::disableOMP()
+{
+   ompEnabled = false;
+}
+
+void tnlHost::setMaxThreadsCount( int maxThreadsCount_ )
+{
+   maxThreadsCount = maxThreadsCount_;
+#ifdef HAVE_OPENMP   
+   omp_set_num_threads( maxThreadsCount );
+#endif   
+}
+
+int tnlHost::getMaxThreadsCount()
+{
+#ifdef HAVE_OPENMP
+   if( maxThreadsCount == -1 )
+      return omp_get_max_threads();
+   return maxThreadsCount;
+#else
+   return 0;
+#endif
+}
+      
+int tnlHost::getThreadIdx()
+{
+#ifdef HAVE_OPENMP
+   return omp_get_thread_num();
+#else
+   return 0;
+#endif  
+}
+
+void tnlHost::configSetup( tnlConfigDescription& config, const tnlString& prefix )
+{
+#ifdef HAVE_OPENMP
+   config.addEntry< bool >( prefix + "omp-enabled", "Enable support of OpenMP.", true );
+   config.addEntry<  int >( prefix + "omp-max-threads", "Set maximum number of OpenMP threads.", omp_get_max_threads() );
+#else
+   config.addEntry< bool >( prefix + "omp-enabled", "Enable support of OpenMP (not supported on this system).", false );
+   config.addEntry<  int >( prefix + "omp-max-threads", "Set maximum number of OpenMP threads (not supported on this system).", 0 );
+#endif
+   
+}
+      
+bool tnlHost::setup( const tnlParameterContainer& parameters,
+                    const tnlString& prefix )
+{
+   ompEnabled = parameters.getParameter< bool >( prefix + "omp-enabled" );
+   maxThreadsCount = parameters.getParameter< int >( prefix + "omp-max-threads" );
+   return true;
+}
+
+
 #endif /* TNLHOST_H_ */
diff --git a/src/core/tnlHost.h b/src/core/tnlHost.h
index 6f921492dfb24f0b5c2f8c5106eacf2ff56252c2..23826c968e7d81b4d4bd0f0b0283ec4546dda886 100644
--- a/src/core/tnlHost.h
+++ b/src/core/tnlHost.h
@@ -22,20 +22,48 @@
 #include <core/tnlDevice.h>
 #include <core/tnlString.h>
 
+class tnlConfigDescription;
+class tnlParameterContainer;
+
 class tnlHost
 {
    public:
 
-   enum { DeviceType = tnlHostDevice };
+      enum { DeviceType = tnlHostDevice };
+
+      static tnlString getDeviceType();
+
+   #ifdef HAVE_CUDA
+      __host__ __device__
+   #endif
+      static inline tnlDeviceEnum getDevice() { return tnlHostDevice; };
+
+      static size_t getFreeMemory();
+   
+      static void disableOMP();
+      
+      static void enableOMP();
+      
+      static inline bool isOMPEnabled() { return ompEnabled; };
+      
+      static void setMaxThreadsCount( int maxThreadsCount );
+      
+      static int getMaxThreadsCount();
+      
+      static int getThreadIdx();
+      
+      static void configSetup( tnlConfigDescription& config, const tnlString& prefix = "" );
+      
+      static bool setup( const tnlParameterContainer& parameters,
+                         const tnlString& prefix = "" );
 
-   static tnlString getDeviceType();
+   protected:
+      
+      static bool ompEnabled;
+      
+      static int maxThreadsCount;
 
-#ifdef HAVE_CUDA
-   __host__ __device__
-#endif
-   static inline tnlDeviceEnum getDevice() { return tnlHostDevice; };
 
-   static size_t getFreeMemory();
 };
 
 #endif /* TNLHOST_H_ */
diff --git a/src/core/tnlList.h b/src/core/tnlList.h
index b6ec489c82bc2986d42ae1c607a6d274f693a5b7..7d3c4579396e66968967f62df65604e33fd87c80 100644
--- a/src/core/tnlList.h
+++ b/src/core/tnlList.h
@@ -23,10 +23,10 @@
 #include <iostream>
 #include <core/tnlDataElement.h>
 #include <core/tnlString.h>
-#include <core/tnlFile.h>
+
 #include <core/param-types.h>
 
-using namespace :: std;
+class tnlFile;
 
 //! Template for double linked lists
 /*! To acces elements in the list one can use method getSize() and
@@ -46,397 +46,102 @@ using namespace :: std;
  */
 template< class T > class tnlList
 {
-   protected:
 
-   //! Pointer to the first element
-   tnlDataElement< T >* first;
+   public:
 
-   //! Pointer to the last element
-   /*! We use pointer to last element while adding new element to keep order of elements
-    */
-   tnlDataElement< T >* last;
-   
-   //! List size
-   int size;
+      typedef T ElementType;
 
-   //! Iterator
-   mutable tnlDataElement< T >* iterator;
+      //! Basic constructor
+      tnlList();
 
-   //! Iterator index
-   mutable int index;
+      //! Copy constructor
+      tnlList( const tnlList& list );
 
-   public:
-   typedef T ElementType;
-
-   //! Basic constructor
-   tnlList() 
-      : first( 0 ),
-        last( 0 ),
-        size( 0 ),
-        iterator( 0 ),
-        index( 0 ){};
-
-   //! Copy constructor
-   tnlList( const tnlList& list )
-      : first( 0 ),
-        last( 0 ),
-        size( 0 ),
-        iterator( 0 ),
-        index( 0 )
-   {
-      AppendList( list );
-   };
-
-   //! Destructor
-   ~tnlList() { reset(); };
-
-   static tnlString getType()
-   {
-      return tnlString( "tnlList< " ) + ::getType< T >() +  tnlString( " >" );
-   };
-
-   //! If the list is empty return 'true'
-   bool isEmpty() const { return ! size; };
-   
-   //! Return size of the list
-   int getSize() const { return size; };
-
-   //! Indexing operator
-   T& operator[] ( int ind )
-   {
-      tnlAssert( ind < size, );
-      //if( ! size ) return NULL;
-      // find fastest way to element with index i
-      // we can use iterator as it is set now or
-      // we can start from the first ro from the last
-      // element
-      //cout << "List operator[]: size = " << size
-      //     << " current index = " << index
-      //     << " index = " << ind << endl;
-      int iter_dist = abs( index - ind );
-      if( ! iterator ||
-          iter_dist > ind || 
-          iter_dist > size - ind )
-      {
-         // it is better to start from the first one or the last one
-         if( ind < size - ind )
-         {
-            // start from the first one
-            //cout << "Setting curent index to 0." << endl;
-            index = 0;
-            iterator = first;
-         }
-         else
-         {
-            //cout << "Setting curent index to size - 1." << endl;
-            index = size - 1;
-            iterator = last;
-         }
-      }
-      while( index != ind )
-      {
-         //cout << " current index = " << index
-         //     << " index = " << ind << endl;
-         if( ind < index ) 
-         {
-            iterator = iterator -> Previous();
-            index --;
-         }
-         else
-         {
-            iterator = iterator -> Next();
-            index ++;
-         }
-         tnlAssert( iterator, );
-      }
-      return iterator -> Data();
-   };
-   
-   //! Indexing operator for constant instances
-   const T& operator[] ( int ind ) const
-   {
-      return const_cast< tnlList< T >* >( this ) -> operator[]( ind );
-   }
-
-   const tnlList& operator = ( const tnlList& lst )
-   {
-      AppendList( lst );
-      return( *this );
-   }
-
-   //! Append new data element
-   bool Append( const T& data )
-   {
-      if( ! first )
-      {
-         tnlAssert( ! last, );
-         first = last = new tnlDataElement< T >( data );
-         if( ! first ) return false;
-      }
-      else 
-      {
-         tnlDataElement< T >* new_element =  new tnlDataElement< T >( data, last, 0 );
-         if( ! new_element ) return false;
-         tnlAssert( last, );
-         last = last -> Next() = new_element;
-      }
-      size ++;
-      return true;
-   };
-
-   //! Prepend new data element
-   bool Prepend( const T& data )
-   {
-      if( ! first )
-      {
-         tnlAssert( ! last, );
-         first = last = new tnlDataElement< T >( data );
-         if( ! first ) return false;
-      }
-      else
-      {
-         tnlDataElement< T >* new_element =  new tnlDataElement< T >( data, 0, first );
-         if( ! new_element ) return false;
-         first = first -> Previous() = new_element; 
-      }
-      size ++;
-      index ++;
-      return true;
-   };
-
-   //! Insert new data element at given position
-   bool Insert( const T& data, int ind )
-   {
-      tnlAssert( ind <= size || ! size, );
-      if( ind == 0 ) return Prepend( data );
-      if( ind == size ) return Append( data );
-      operator[]( ind );
-      tnlDataElement< T >* new_el = 
-         new tnlDataElement< T >( data,
-                                iterator -> Previous(),
-                                iterator );
-      if( ! new_el ) return false;
-      iterator -> Previous() -> Next() = new_el;
-      iterator -> Previous() = new_el;
-      iterator = new_el;
-      size ++;
-      return true;
-   };
-
-   //! Append copy of another list
-   bool AppendList( const tnlList< T >& lst )
-   {
-      int i;
-      for( i = 0; i < lst. getSize(); i ++ )
-      {
-         if( ! Append( lst[ i ] ) ) return false;
-      }
-      return true;
-   };
-   
-   //! Prepend copy of another list
-   bool PrependList( const tnlList< T >& lst )
-   
-   {
-      int i;
-      for( i = lst. getSize(); i > 0; i -- )
-         if( ! Prepend( lst[ i - 1 ] ) ) return false;
-      return true;
-   };
-
-   template< typename Array >
-   void toArray( Array& array )
-   {
-      tnlAssert( this->getSize() <= array.getSize(),
-                 cerr << "this->getSize() = " << this->getSize()
-                      << " array.getSize() = " << array.getSize() << endl; );
-      for( int i = 0; i < this->getSize(); i++ )
-         array[ i ] = ( *this )[ i ];
-   }
-
-   //! Erase data element at given position
-   void Erase( int ind )
-   {
-      operator[]( ind );
-      tnlDataElement< T >* tmp_it = iterator;
-      if( iterator -> Next() )
-         iterator -> Next() -> Previous() = iterator -> Previous();
-      if( iterator -> Previous() )
-        iterator -> Previous() -> Next() = iterator -> Next();
-      if( iterator -> Next() ) iterator = iterator -> Next();
-      else
-      {
-         iterator = iterator -> Previous();
-         index --;
-      }
-      if( first == tmp_it ) first = iterator;
-      if( last == tmp_it ) last = iterator;
-      delete tmp_it;
-      size --;
-   };
-
-   //! Erase data element with contained data at given position
-   void DeepErase( int ind )
-   {
-      operator[]( ind );
-      delete iterator -> Data();
-      Erase( ind );
-   };
-
-   //! Erase all data elements
-   void reset()
-   {
-      iterator = first;
-      tnlDataElement< T >* tmp_it;
-      while( iterator )
-      {
-    	   tnlAssert( iterator, );
-         tmp_it = iterator;
-         iterator = iterator -> Next();
-         delete tmp_it;
-      }
-      first = last = 0;
-      size = 0;
-   };
-
-   //! Erase all data elements with contained data
-   void DeepEraseAll()
-   {
-      iterator = first;
-      tnlDataElement< T >* tmp_it;
-      while( iterator )
-      {
-         tmp_it = iterator;
-         iterator = iterator -> Next();
-         delete tmp_it -> Data();
-         delete tmp_it;
-      }
-      first = last = 0;
-      size = 0;
-   };
-   
-   //! Save the list in binary format
-   bool Save( tnlFile& file ) const
-   {
-#ifdef HAVE_NOT_CXX11
-      file. write< const int, tnlHost >( &size );
-      for( int i = 0; i < size; i ++ )
-         if( ! file. write< int, tnlHost, int >( &operator[]( i ), 1 ) )
-            return false;
-      return true;
-#else
-      file. write( &size );
-      for( int i = 0; i < size; i ++ )
-         if( ! file. write( &operator[]( i ), 1 ) )
-            return false;
-      return true;
-
-#endif            
-   }
-
-   //! Save the list in binary format using method save of type T
-   bool DeepSave( tnlFile& file ) const
-   {
-#ifdef HAVE_NOT_CXX11
-      file. write< const int, tnlHost >( &size );
-      for( int i = 0; i < size; i ++ )
-         if( ! operator[]( i ). save( file ) ) return false;
-      return true;
-#else
-      file. write( &size );
-      for( int i = 0; i < size; i ++ )
-         if( ! operator[]( i ). save( file ) ) return false;
-      return true;
-#endif            
-   }
-
-   //! Load the list
-   bool Load( tnlFile& file )
-   {
-#ifdef HAVE_NOT_CXX11
-      reset();
-      int _size;
-      file. read< int, tnlHost >( &_size );
-      if( _size < 0 )
-      {
-         cerr << "The curve size is negative." << endl;
-         return false;
-      }
-      T t;
-      for( int i = 0; i < _size; i ++ )
-      {
-         if( ! file. read< T, tnlHost >( &t ) )
-            return false;
-         Append( t );
-      }
-      return true;
-#else
-      reset();
-      int _size;
-      file. read( &_size, 1 );
-      if( _size < 0 )
-      {
-         cerr << "The curve size is negative." << endl;
-         return false;
-      }
-      T t;
-      for( int i = 0; i < _size; i ++ )
-      {
-         if( ! file. read( &t, 1 ) )
-            return false;
-         Append( t );
-      }
-      return true;
-#endif            
-   };
-
-   //! Load the list using method Load of the type T
-   bool DeepLoad( tnlFile& file )
-   {
-#ifdef HAVE_NOT_CXX11
-      reset();
-      int _size;
-      file. read< int, tnlHost >( &_size );
-      if( _size < 0 )
-      {
-         cerr << "The list size is negative." << endl;
-         return false;
-      }
-      for( int i = 0; i < _size; i ++ )
-      {
-         T t;
-         if( ! t. load( file ) ) return false;
-         Append( t );
-      }
-      return true;
-#else
-      reset();
-      int _size;
-      file. read( &_size );
-      if( _size < 0 )
-      {
-         cerr << "The list size is negative." << endl;
-         return false;
-      }
-      for( int i = 0; i < _size; i ++ )
-      {
-         T t;
-         if( ! t. load( file ) ) return false;
-         Append( t );
-      }
-      return true;
-#endif            
-   };
+      //! Destructor
+      ~tnlList();
+
+      static tnlString getType();
+
+      //! If the list is empty return 'true'
+      bool isEmpty() const;
+
+      //! Return size of the list
+      int getSize() const;
+
+      //! Indexing operator
+      T& operator[] ( const int& ind );
+
+      //! Indexing operator for constant instances
+      const T& operator[] ( const int& ind ) const;
+
+      const tnlList& operator = ( const tnlList& lst );
+
+      //! Append new data element
+      bool Append( const T& data );
+
+      //! Prepend new data element
+      bool Prepend( const T& data );
+
+      //! Insert new data element at given position
+      bool Insert( const T& data, const int& ind );
+
+      //! Append copy of another list
+      bool AppendList( const tnlList< T >& lst );
+
+      //! Prepend copy of another list
+      bool PrependList( const tnlList< T >& lst );   
+
+      template< typename Array >
+      void toArray( Array& array );
+
+      //! Erase data element at given position
+      void Erase( const int& ind );
+
+      //! Erase data element with contained data at given position
+      void DeepErase( const int& ind );
+
+      //! Erase all data elements
+      void reset();
+
+      //! Erase all data elements with contained data
+      void DeepEraseAll();
+
+      //! Save the list in binary format
+      bool Save( tnlFile& file ) const;
+
+      //! Save the list in binary format using method save of type T
+      bool DeepSave( tnlFile& file ) const;
+
+      //! Load the list
+      bool Load( tnlFile& file );
+
+      //! Load the list using method Load of the type T
+      bool DeepLoad( tnlFile& file );
    
-};
+   protected:
 
+      //! Pointer to the first element
+      tnlDataElement< T >* first;
+
+      //! Pointer to the last element
+      /*! We use pointer to last element while adding new element to keep order of elements
+       */
+      tnlDataElement< T >* last;
+
+      //! List size
+      int size;
+
+      //! Iterator
+      mutable tnlDataElement< T >* iterator;
+
+      //! Iterator index
+      mutable int index;   
+      
 
-template< typename T > ostream& operator << ( ostream& str, const tnlList< T >& list )
-{
-   int i, size( list. getSize() );
-   for( i = 0; i < size; i ++ )
-      str << "Item " << i << ":" << list[ i ] << endl;
-   return str;
 };
 
+template< typename T > ostream& operator << ( ostream& str, const tnlList< T >& list );
+
+#include<core/tnlList_impl.h>
+
 #endif
diff --git a/src/core/tnlList_impl.h b/src/core/tnlList_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..886d5959425e1f96ec911066cf8c53c2fe7411f7
--- /dev/null
+++ b/src/core/tnlList_impl.h
@@ -0,0 +1,391 @@
+/***************************************************************************
+                          tnlList_impl.h  -  description
+                             -------------------
+    begin                : Mar, 5 Apr 2016 12:46 PM
+    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 TNLLIST_IMPL_H
+#define	TNLLIST_IMPL_H
+
+#include <core/tnlFile.h>
+
+template< typename T > 
+tnlList< T >::tnlList() 
+   : first( 0 ),  last( 0 ), size( 0 ), iterator( 0 ), index( 0 )
+{
+}
+
+template< typename T > 
+tnlList< T >::tnlList( const tnlList& list )
+   : first( 0 ), last( 0 ), size( 0 ), iterator( 0 ), index( 0 )
+{
+   AppendList( list );
+}
+
+template< typename T > 
+tnlList< T >::~tnlList()
+{ 
+   reset(); 
+}
+
+template< typename T >    
+tnlString tnlList< T >::getType()
+{
+   return tnlString( "tnlList< " ) + ::getType< T >() +  tnlString( " >" );
+}
+
+template< typename T > 
+bool tnlList< T >::isEmpty() const
+{ 
+   return ! size; 
+}
+   
+template< typename T > 
+int tnlList< T >::getSize() const
+{ 
+   return size; 
+}
+
+template< typename T > 
+T& tnlList< T >::operator[]( const int& ind )
+{
+   tnlAssert( ind < size, );
+   int iter_dist = abs( index - ind );
+   if( ! iterator ||
+       iter_dist > ind || 
+       iter_dist > size - ind )
+   {
+      if( ind < size - ind )
+      {
+         //cout << "Setting curent index to 0." << endl;
+         index = 0;
+         iterator = first;
+      }
+      else
+      {
+         //cout << "Setting curent index to size - 1." << endl;
+         index = size - 1;
+         iterator = last;
+      }
+   }
+   while( index != ind )
+   {
+      //cout << " current index = " << index
+      //     << " index = " << ind << endl;
+      if( ind < index ) 
+      {
+         iterator = iterator -> Previous();
+         index --;
+      }
+      else
+      {
+         iterator = iterator -> Next();
+         index ++;
+      }
+      tnlAssert( iterator, );
+   }
+   return iterator -> Data();
+};
+   
+template< typename T > 
+const T& tnlList< T >::operator[]( const int& ind ) const
+{
+   return const_cast< tnlList< T >* >( this ) -> operator[]( ind );
+}
+
+template< typename T >    
+const tnlList< T >& tnlList< T >::operator = ( const tnlList& lst )
+{
+   AppendList( lst );
+   return( *this );
+}
+
+template< typename T > 
+bool tnlList< T >::Append( const T& data )
+{
+   if( ! first )
+   {
+      tnlAssert( ! last, );
+      first = last = new tnlDataElement< T >( data );
+      if( ! first ) return false;
+   }
+   else 
+   {
+      tnlDataElement< T >* new_element =  new tnlDataElement< T >( data, last, 0 );
+      if( ! new_element ) return false;
+      tnlAssert( last, );
+      last = last -> Next() = new_element;
+   }
+   size ++;
+   return true;
+};
+
+template< typename T > 
+bool tnlList< T >::Prepend( const T& data )
+{
+   if( ! first )
+   {
+      tnlAssert( ! last, );
+      first = last = new tnlDataElement< T >( data );
+      if( ! first ) return false;
+   }
+   else
+   {
+      tnlDataElement< T >* new_element =  new tnlDataElement< T >( data, 0, first );
+      if( ! new_element ) return false;
+      first = first -> Previous() = new_element; 
+   }
+   size ++;
+   index ++;
+   return true;
+};
+
+template< typename T > 
+bool tnlList< T >::Insert( const T& data, const int& ind )
+{
+   tnlAssert( ind <= size || ! size, );
+   if( ind == 0 ) return Prepend( data );
+   if( ind == size ) return Append( data );
+   operator[]( ind );
+   tnlDataElement< T >* new_el = 
+      new tnlDataElement< T >( data,
+                             iterator -> Previous(),
+                             iterator );
+   if( ! new_el ) return false;
+   iterator -> Previous() -> Next() = new_el;
+   iterator -> Previous() = new_el;
+   iterator = new_el;
+   size ++;
+   return true;
+};
+
+template< typename T > 
+bool tnlList< T >::AppendList( const tnlList< T >& lst )
+{
+   int i;
+   for( i = 0; i < lst. getSize(); i ++ )
+   {
+      if( ! Append( lst[ i ] ) ) return false;
+   }
+   return true;
+};
+   
+template< typename T > 
+bool tnlList< T >::PrependList( const tnlList< T >& lst )
+
+{
+   int i;
+   for( i = lst. getSize(); i > 0; i -- )
+      if( ! Prepend( lst[ i - 1 ] ) ) return false;
+   return true;
+};
+
+template< typename T >    
+   template< typename Array >
+void tnlList< T >::toArray( Array& array )
+{
+   tnlAssert( this->getSize() <= array.getSize(),
+              cerr << "this->getSize() = " << this->getSize()
+                   << " array.getSize() = " << array.getSize() << endl; );
+   for( int i = 0; i < this->getSize(); i++ )
+      array[ i ] = ( *this )[ i ];
+}
+
+template< typename T > 
+void tnlList< T >::Erase( const int& ind )
+{
+   operator[]( ind );
+   tnlDataElement< T >* tmp_it = iterator;
+   if( iterator -> Next() )
+      iterator -> Next() -> Previous() = iterator -> Previous();
+   if( iterator -> Previous() )
+     iterator -> Previous() -> Next() = iterator -> Next();
+   if( iterator -> Next() ) iterator = iterator -> Next();
+   else
+   {
+      iterator = iterator -> Previous();
+      index --;
+   }
+   if( first == tmp_it ) first = iterator;
+   if( last == tmp_it ) last = iterator;
+   delete tmp_it;
+   size --;
+};
+
+template< typename T > 
+void tnlList< T >::DeepErase( const int& ind )
+{
+   operator[]( ind );
+   delete iterator -> Data();
+   Erase( ind );
+};
+
+template< typename T > 
+void tnlList< T >::reset()
+{
+   iterator = first;
+   tnlDataElement< T >* tmp_it;
+   while( iterator )
+   {
+      tnlAssert( iterator, );
+      tmp_it = iterator;
+      iterator = iterator -> Next();
+      delete tmp_it;
+   }
+   first = last = 0;
+   size = 0;
+};
+
+template< typename T > 
+void tnlList< T >::DeepEraseAll()
+{
+   iterator = first;
+   tnlDataElement< T >* tmp_it;
+   while( iterator )
+   {
+      tmp_it = iterator;
+      iterator = iterator -> Next();
+      delete tmp_it -> Data();
+      delete tmp_it;
+   }
+   first = last = 0;
+   size = 0;
+};
+   
+template< typename T > 
+bool tnlList< T >::Save( tnlFile& file ) const
+{
+#ifdef HAVE_NOT_CXX11
+   file. write< const int, tnlHost >( &size );
+   for( int i = 0; i < size; i ++ )
+      if( ! file. write< int, tnlHost, int >( &operator[]( i ), 1 ) )
+         return false;
+   return true;
+#else
+   file. write( &size );
+   for( int i = 0; i < size; i ++ )
+      if( ! file. write( &operator[]( i ), 1 ) )
+         return false;
+   return true;
+
+#endif            
+}
+
+template< typename T > 
+bool tnlList< T >::DeepSave( tnlFile& file ) const
+{
+#ifdef HAVE_NOT_CXX11
+   file. write< const int, tnlHost >( &size );
+   for( int i = 0; i < size; i ++ )
+      if( ! operator[]( i ). save( file ) ) return false;
+   return true;
+#else
+   file. write( &size );
+   for( int i = 0; i < size; i ++ )
+      if( ! operator[]( i ). save( file ) ) return false;
+   return true;
+#endif            
+}
+
+template< typename T > 
+bool tnlList< T >::Load( tnlFile& file )
+{
+#ifdef HAVE_NOT_CXX11
+   reset();
+   int _size;
+   file. read< int, tnlHost >( &_size );
+   if( _size < 0 )
+   {
+      cerr << "The curve size is negative." << endl;
+      return false;
+   }
+   T t;
+   for( int i = 0; i < _size; i ++ )
+   {
+      if( ! file. read< T, tnlHost >( &t ) )
+         return false;
+      Append( t );
+   }
+   return true;
+#else
+   reset();
+   int _size;
+   file. read( &_size, 1 );
+   if( _size < 0 )
+   {
+      cerr << "The curve size is negative." << endl;
+      return false;
+   }
+   T t;
+   for( int i = 0; i < _size; i ++ )
+   {
+      if( ! file. read( &t, 1 ) )
+         return false;
+      Append( t );
+   }
+   return true;
+#endif            
+};
+
+template< typename T > 
+bool tnlList< T >::DeepLoad( tnlFile& file )
+{
+#ifdef HAVE_NOT_CXX11
+   reset();
+   int _size;
+   file. read< int, tnlHost >( &_size );
+   if( _size < 0 )
+   {
+      cerr << "The list size is negative." << endl;
+      return false;
+   }
+   for( int i = 0; i < _size; i ++ )
+   {
+      T t;
+      if( ! t. load( file ) ) return false;
+      Append( t );
+   }
+   return true;
+#else
+   reset();
+   int _size;
+   file. read( &_size );
+   if( _size < 0 )
+   {
+      cerr << "The list size is negative." << endl;
+      return false;
+   }
+   for( int i = 0; i < _size; i ++ )
+   {
+      T t;
+      if( ! t. load( file ) ) return false;
+      Append( t );
+   }
+   return true;
+#endif            
+};
+   
+template< typename T >
+ostream& operator << ( ostream& str, const tnlList< T >& list )
+{
+   int i, size( list. getSize() );
+   for( i = 0; i < size; i ++ )
+      str << "Item " << i << ":" << list[ i ] << endl;
+   return str;
+};
+
+
+
+#endif	/* TNLLIST_IMPL_H */
+
diff --git a/src/core/tnlLogger.cpp b/src/core/tnlLogger.cpp
index 492af9eb93ebb6a497e39422dc065e12583d7fd3..82d8383c22613557243fab44bd37711f9dabf34c 100644
--- a/src/core/tnlLogger.cpp
+++ b/src/core/tnlLogger.cpp
@@ -15,13 +15,10 @@
  *                                                                         *
  ***************************************************************************/
 
-#include <sys/utsname.h>
-#include <time.h>
-#include <unistd.h>
-#include <fstream>
 #include <iomanip>
 #include <core/tnlLogger.h>
 #include <tnlConfig.h>
+#include <core/tnlSystemInfo.h>
 #include <core/tnlCudaDeviceInfo.h>
 
 tnlLogger :: tnlLogger( int _width,
@@ -53,106 +50,38 @@ void tnlLogger :: writeSeparator()
 
 bool tnlLogger :: writeSystemInformation( const tnlParameterContainer& parameters )
 {
-   char host_name[ 256 ];
-   struct utsname uts;
-   gethostname( host_name, 255 );
-   uname( &uts );
-   writeParameter< char* >( "Host name:", host_name );
-   writeParameter< char* >( "Architecture:", uts. machine );
-   fstream file;
-   file.open( "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", ios::in );
-   int maxCpuFreq( 0 );
-   if( file )
-   {
-      char line[ 1024 ];
-      file.getline( line, 1024 );
-      maxCpuFreq = atoi( line );
-   }
-   else
-       cerr << "Unable to read information from /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq." << endl;
-   file.close();
-   file. open( "/proc/cpuinfo", ios :: in );
-   if( file )
-   {
-      char line[ 1024 ];
-      char* cpu_id;
-      char* cpu_model_name;
-      char* cpu_mhz;
-      char* cpu_cache;
-      tnlString modelName, Mhz, cache;
-      int cores( 0 ), siblings( 0 );
-      while( ! file. eof() )
-      {
-         int i;
-         file. getline( line, 1024 );
-         /*if( strncmp( line, "processor", strlen( "processor" ) ) == 0 )
-         {
-            i = strlen( "processor" );
-            while( line[ i ] != ':' && line[ i ] ) i ++;
-            cpu_id = &line[ i + 1 ];
-            writeParameter< char * >( "CPU Id.:", cpu_id );
-            continue;
-         }*/
-         if( strncmp( line, "model name", strlen( "model name" ) ) == 0 )
-         {
-            i = strlen( "model name" );
-            while( line[ i ] != ':' && line[ i ] ) i ++;
-            //cpu_model_name = &line[ i + 1 ];
-            modelName.setString( &line[ i + 1 ] );
-            //writeParameter< char * >( "Model name:", cpu_model_name );
-            continue;
-         }
-         if( strncmp( line, "cpu cores", strlen( "cpu cores" ) ) == 0 )
-         {
-            i = strlen( "cpu MHz" );
-            while( line[ i ] != ':' && line[ i ] ) i ++;
-            cores = atoi( &line[ i + 1 ] );
-            continue;
-         }
-         if( strncmp( line, "siblings", strlen( "siblings" ) ) == 0 )
-         {
-            i = strlen( "siblings" );
-            while( line[ i ] != ':' && line[ i ] ) i ++;
-            siblings = atoi( &line[ i + 1 ] );
-         }
-         /*if( strncmp( line, "cpu MHz", strlen( "cpu MHz" ) ) == 0 )
-         {
-            i = strlen( "cpu MHz" );
-            while( line[ i ] != ':' && line[ i ] ) i ++;
-            //cpu_mhz = &line[ i + 1 ];
-            Mhz.setString( &line[ i + 1 ] );
-            //writeParameter< char * >( "CPU MHz:", cpu_mhz );
-            continue;
-         }*/
-         if( strncmp( line, "cache size", strlen( "cache size" ) ) == 0 )
-         {
-            i = strlen( "cache size" );
-            while( line[ i ] != ':' && line[ i ] ) i ++;
-            //cpu_cache = &line[ i + 1 ];
-            cache.setString( &line[ i + 1 ] );
-            //writeParameter< char * >( "CPU cache:", cpu_cache );
-            continue;
-         }
-      }
-      int threadsPerCore = siblings / cores;
-      writeParameter< tnlString >( "CPU info", tnlString("") );
-      writeParameter< tnlString >( "Model name:", modelName, 1 );
-      writeParameter< int >( "Cores:", cores, 1 );
-      writeParameter< int >( "Threads per core:", threadsPerCore, 1 );
-      writeParameter< tnlString >( "Max clock rate (in MHz):", maxCpuFreq / 1000, 1 );
-      writeParameter< tnlString >( "Cache:", cache, 1 );
-    }
-   else
-      cerr << "Unable to read information from /proc/cpuinfo." << endl;
-   file.close();
+   tnlSystemInfo systemInfo;
+
+   writeParameter< tnlString >( "Host name:", systemInfo.getHostname() );
+   writeParameter< tnlString >( "Architecture:", systemInfo.getArchitecture() );
+   // FIXME: generalize for multi-socket systems, here we consider only the first found CPU
+   const int cpu_id = 0;
+   const int threads = systemInfo.getNumberOfThreads( cpu_id );
+   const int cores = systemInfo.getNumberOfCores( cpu_id );
+   int threadsPerCore = threads / cores;
+   writeParameter< tnlString >( "CPU info", tnlString("") );
+   writeParameter< tnlString >( "Model name:", systemInfo.getCPUModelName( cpu_id ), 1 );
+   writeParameter< int >( "Cores:", cores, 1 );
+   writeParameter< int >( "Threads per core:", threadsPerCore, 1 );
+   writeParameter< tnlString >( "Max clock rate (in MHz):", systemInfo.getCPUMaxFrequency( cpu_id ) / 1000, 1 );
+   tnlCacheSizes cacheSizes = systemInfo.getCPUCacheSizes( cpu_id );
+   tnlString cacheInfo = tnlString( cacheSizes.L1data ) + ", "
+                       + tnlString( cacheSizes.L1instruction ) + ", "
+                       + tnlString( cacheSizes.L2 ) + ", "
+                       + tnlString( cacheSizes.L3 );
+   writeParameter< tnlString >( "Cache (L1d, L1i, L2, L3):", cacheInfo, 1 );
    if( parameters.getParameter< tnlString >( "device" ) == "cuda" )
    {      
-      int devices = tnlCudaDeviceInfo::getNumberOfDevices();
       writeParameter< tnlString >( "CUDA GPU info", tnlString("") );   
-      writeParameter< int >( "Number of devices", devices,1 );
-      for( int i = 0; i < devices; i++ )
-      {
-        writeParameter< int >( "Device no.", i, 1 );       
+      // TODO: Printing all devices does not make sense, but in the future TNL
+      //       might use more than one device for computations. Printing only
+      //       the active device for now...
+//      int devices = tnlCudaDeviceInfo::getNumberOfDevices();
+//      writeParameter< int >( "Number of devices", devices, 1 );
+//      for( int i = 0; i < devices; i++ )
+//      {
+//        writeParameter< int >( "Device no.", i, 1 );
+        int i = tnlCudaDeviceInfo::getActiveDevice();
         writeParameter< tnlString >( "Name", tnlCudaDeviceInfo::getDeviceName( i ), 2 );
         tnlString deviceArch = tnlString( tnlCudaDeviceInfo::getArchitectureMajor( i ) ) + "." +
                                 tnlString( tnlCudaDeviceInfo::getArchitectureMinor( i ) );
@@ -165,22 +94,18 @@ bool tnlLogger :: writeSystemInformation( const tnlParameterContainer& parameter
         double memoryClockRate = ( double ) tnlCudaDeviceInfo::getMemoryClockRate( i ) / 1.0e3;
         writeParameter< double >( "Memory clock rate (in Mhz)", memoryClockRate, 2 );
         writeParameter< bool >( "ECC enabled", tnlCudaDeviceInfo::getECCEnabled( i ), 2 );         
-      }
+//      }
    }
-   writeParameter< char* >( "System:", uts. sysname );
-   writeParameter< char* >( "Release:", uts. release );
+   writeParameter< tnlString >( "System:", systemInfo.getSystemName() );
+   writeParameter< tnlString >( "Release:", systemInfo.getSystemRelease() );
    writeParameter< char* >( "TNL Compiler:", ( char* ) TNL_CPP_COMPILER_NAME );
    return true;
 }
 
 void tnlLogger :: writeCurrentTime( const char* label )
 {
-   time_t timeval;
-   time( &timeval );
-   tm *tm_ptr = localtime( &timeval );
-   char buf[ 256 ];
-   strftime( buf, 256, "%a %b %d %H:%M:%S\0", tm_ptr );
-   writeParameter< char* >( label, buf );
+   tnlSystemInfo systemInfo;
+   writeParameter< tnlString >( label, systemInfo.getCurrentTime() );
 }
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
diff --git a/src/core/tnlLogger.h b/src/core/tnlLogger.h
index c657ee4fe3e549bcfb6762533e8df83718110311..f122fd64f4ed54a1532da8ee7c7f2311a143ebff 100644
--- a/src/core/tnlLogger.h
+++ b/src/core/tnlLogger.h
@@ -18,9 +18,7 @@
 #ifndef mLoggerH
 #define mLoggerH
 
-#include <cstring>
 #include <ostream>
-#include <iomanip>
 #include <config/tnlParameterContainer.h>
 
 class tnlLogger
diff --git a/src/core/tnlLogger_impl.h b/src/core/tnlLogger_impl.h
index cd058d37b3e2ab55d33dfd055997b2d5bd103a0f..ba85809fe6d89a222ef7f228431d9f38953c8e07 100644
--- a/src/core/tnlLogger_impl.h
+++ b/src/core/tnlLogger_impl.h
@@ -19,6 +19,7 @@
 #define TNLLOGGER_IMPL_H_
 
 #include <sstream>
+#include <iomanip>
 
 template< typename T >
 void tnlLogger::writeParameter( const tnlString& label,
diff --git a/src/core/tnlObject.cpp b/src/core/tnlObject.cpp
index e8157c1393552b8f298617576e63fe57f39ec7f0..e86cc0e532026e8d21047abe65a99632e840b0a7 100644
--- a/src/core/tnlObject.cpp
+++ b/src/core/tnlObject.cpp
@@ -85,7 +85,7 @@ bool tnlObject :: save( const tnlString& fileName ) const
       cerr << "I am not bale to open the file " << fileName << " for writing." << endl;
       return false;
    }
-   if( ! this -> save( file ) )
+   if( ! this->save( file ) )
       return false;
    if( ! file. close() )
    {
@@ -103,7 +103,7 @@ bool tnlObject :: load( const tnlString& fileName )
       cerr << "I am not bale to open the file " << fileName << " for reading." << endl;
       return false;
    }
-   if( ! this -> load( file ) )
+   if( ! this->load( file ) )
       return false;
    if( ! file. close() )
    {
diff --git a/src/core/tnlReal.h b/src/core/tnlReal.h
index 415f3b6da8b9622d767ea124309488f9f3d5463b..27063f6fb62f6c111559e75b188335af35312110 100644
--- a/src/core/tnlReal.h
+++ b/src/core/tnlReal.h
@@ -24,8 +24,6 @@
 #include <math.h>
 #include <core/tnlFlopsCounter.h>
 
-using namespace std;
-
 template< class T > class tnlReal
 {
    T data;
@@ -425,7 +423,7 @@ template< class T > const tnlReal< T > log10( const tnlReal< T >& x )
 };
 
 template< class T >
-ostream& operator << ( ostream& str, const tnlReal< T >& v )
+std::ostream& operator << ( std::ostream& str, const tnlReal< T >& v )
 {
    str << v. Data();
    return str;
diff --git a/src/core/tnlStaticMultiIndex.h b/src/core/tnlStaticMultiIndex.h
deleted file mode 100644
index 6d856a1da7e60b788ee3cb75c685ba0447b07880..0000000000000000000000000000000000000000
--- a/src/core/tnlStaticMultiIndex.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/***************************************************************************
-                          tnlStaticMultiIndex.h  -  description
-                             -------------------
-    begin                : Nov 13, 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 TNLSTATICMULTIINDEX_H
-#define	TNLSTATICMULTIINDEX_H
-
-template< int i1_ >
-class tnlStaticMultiIndex1D
-{
-   public:
-      
-      static const int i1 = i1_;
-      
-      static const int size = 1;
-};
-
-template< int i1_,
-          int i2_ >
-class tnlStaticMultiIndex2D
-{
-   public:
-      
-      static const int i1 = i1_;
-      
-      static const int i2 = i2_;
-      
-      static const int size = 2;
-};
-
-template< int i1_,
-          int i2_,
-          int i3_ >
-class tnlStaticMultiIndex3D
-{
-   public:
-      
-      static const int i1 = i1_;
-      
-      static const int i2 = i2_;
-      
-      static const int i3 = i3_;
-      
-      static const int size = 3;
-};
-
-
-
-
-#endif	/* TNLSTATICMULTIINDEX_H */
-
diff --git a/src/core/tnlString.cpp b/src/core/tnlString.cpp
index 7ccf68a36a2245d96696798a877d032530533d15..30e679954317d9c5f7aa4e006226820030242cc9 100644
--- a/src/core/tnlString.cpp
+++ b/src/core/tnlString.cpp
@@ -49,6 +49,12 @@ tnlString :: tnlString( const tnlString& str )
    setString( str. getString() );
 }
 
+tnlString :: tnlString( unsigned number )
+: string( 0 ), length( 0 )
+{
+   this->setString( convertToString( number ).getString() );
+}
+
 tnlString :: tnlString( int number )
 : string( 0 ), length( 0 )
 {
@@ -420,7 +426,7 @@ bool tnlString :: getLine( istream& stream )
 {
    std :: string str;
    getline( stream, str );
-   this -> setString( str. data() );
+   this->setString( str. data() );
    if( ! ( *this ) ) return false;
    return true;
 }
diff --git a/src/core/tnlString.h b/src/core/tnlString.h
index 42bfa9cabc197f0083d91aa9ef22493d4ea335f6..8e3e45e6b9ad41dc2e644512f7df87e093ca9b0e 100644
--- a/src/core/tnlString.h
+++ b/src/core/tnlString.h
@@ -56,6 +56,8 @@ class tnlString
    tnlString( const tnlString& str );
 
    //! Convert number to a string
+   tnlString( unsigned number );
+
    tnlString( int number );
    
    tnlString( long int number );
diff --git a/src/core/tnlSystemInfo.cpp b/src/core/tnlSystemInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..db1872d7f78c4579f4867cc53ac0d66345efddf2
--- /dev/null
+++ b/src/core/tnlSystemInfo.cpp
@@ -0,0 +1,174 @@
+#include <set>
+#include <iomanip>
+#include <cstring>
+#include <ctime>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "tnlSystemInfo.h"
+
+tnlSystemInfo::tnlSystemInfo()
+{
+   uname( &uts );
+   parseCPUInfo();
+}
+
+void
+tnlSystemInfo::parseCPUInfo( void )
+{
+   std::ifstream file( "/proc/cpuinfo" );
+   if( ! file ) {
+      std::cerr << "Unable to read information from /proc/cpuinfo." << std::endl;
+      return;
+   }
+
+   char line[ 1024 ];
+   std::set< int > processors;
+   while( ! file. eof() )
+   {
+      int i;
+      file.getline( line, 1024 );
+      if( strncmp( line, "physical id", strlen( "physical id" ) ) == 0 )
+      {
+         i = strlen( "physical id" );
+         while( line[ i ] != ':' && line[ i ] ) i ++;
+         processors.insert( atoi( &line[ i + 1 ] ) );
+         continue;
+      }
+      // FIXME: the rest does not work on heterogeneous multi-socket systems
+      if( strncmp( line, "model name", strlen( "model name" ) ) == 0 )
+      {
+         i = strlen( "model name" );
+         while( line[ i ] != ':' && line[ i ] ) i ++;
+         CPUModelName.setString( &line[ i + 1 ] );
+         continue;
+      }
+      if( strncmp( line, "cpu cores", strlen( "cpu cores" ) ) == 0 )
+      {
+         i = strlen( "cpu MHz" );
+         while( line[ i ] != ':' && line[ i ] ) i ++;
+         CPUCores = atoi( &line[ i + 1 ] );
+         continue;
+      }
+      if( strncmp( line, "siblings", strlen( "siblings" ) ) == 0 )
+      {
+         i = strlen( "siblings" );
+         while( line[ i ] != ':' && line[ i ] ) i ++;
+         CPUThreads = atoi( &line[ i + 1 ] );
+      }
+   }
+   numberOfProcessors = processors.size();
+}
+
+tnlString
+tnlSystemInfo::getHostname( void ) const
+{
+   char host_name[ 256 ];
+   gethostname( host_name, 255 );
+   return tnlString( host_name );
+}
+
+tnlString
+tnlSystemInfo::getArchitecture( void ) const
+{
+   return tnlString( uts.machine );
+}
+
+tnlString
+tnlSystemInfo::getSystemName( void ) const
+{
+   return tnlString( uts.sysname );
+}
+
+tnlString
+tnlSystemInfo::getSystemRelease( void ) const
+{
+   return tnlString( uts.release );
+}
+
+tnlString
+tnlSystemInfo::getCurrentTime( const char* format ) const
+{
+   const std::time_t time_since_epoch = std::time( nullptr );
+   std::tm* localtime = std::localtime( &time_since_epoch );
+   // TODO: use std::put_time in the future (available since GCC 5)
+//   std::stringstream ss;
+//   ss << std::put_time( localtime, format );
+//   return tnlString( ss.str().c_str() );
+   char buffer[1024];
+   std::strftime( buffer, 1024, format, localtime );
+   return tnlString( buffer );
+}
+
+int
+tnlSystemInfo::getNumberOfProcessors( void ) const
+{
+   return numberOfProcessors;
+}
+
+tnlString
+tnlSystemInfo::getOnlineCPUs( void ) const
+{
+   std::string online = readFile< std::string >( "/sys/devices/system/cpu/online" );
+   return tnlString( online.c_str() );
+}
+
+int
+tnlSystemInfo::getNumberOfCores( int cpu_id ) const
+{
+   return CPUCores;
+}
+
+int
+tnlSystemInfo::getNumberOfThreads( int cpu_id ) const
+{
+   return CPUThreads;
+}
+
+tnlString
+tnlSystemInfo::getCPUModelName( int cpu_id ) const
+{
+   cout << "model name = " << CPUModelName << endl;
+   return CPUModelName;
+}
+
+int
+tnlSystemInfo::getCPUMaxFrequency( int cpu_id ) const
+{
+   tnlString fileName( "/sys/devices/system/cpu/cpu" );
+   fileName += tnlString( cpu_id ) + "/cpufreq/cpuinfo_max_freq";
+   return readFile< int >( fileName );
+}
+
+tnlCacheSizes
+tnlSystemInfo::getCPUCacheSizes( int cpu_id ) const
+{
+   tnlString directory( "/sys/devices/system/cpu/cpu" );
+   directory += tnlString( cpu_id ) + "/cache";
+
+   tnlCacheSizes sizes;
+   for( int i = 0; i <= 3; i++ ) {
+      const tnlString cache = directory + "/index" + tnlString( i );
+
+      // check if the directory exists
+      struct stat st;
+      if( stat( cache.getString(), &st ) != 0 || ! S_ISDIR( st.st_mode ) )
+         break;
+
+      const int level = readFile< int >( cache + "/level" );
+      const std::string type = readFile< std::string >( cache + "/type" );
+      const int size = readFile< int >( cache + "/size" );
+
+      if( level == 1 && type == "Instruction" )
+         sizes.L1instruction = size;
+      else if( level == 1 && type == "Data" )
+         sizes.L1data = size;
+      else if( level == 2 )
+         sizes.L2 = size;
+      else if( level == 3 )
+         sizes.L3 = size;
+   }
+   return sizes;
+}
diff --git a/src/core/tnlSystemInfo.h b/src/core/tnlSystemInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..40d5bed2643a65bcc0e5cab0d7576c5bb72249c5
--- /dev/null
+++ b/src/core/tnlSystemInfo.h
@@ -0,0 +1,58 @@
+#pragma once
+
+#include <fstream>
+#include <sstream>
+
+#include <sys/utsname.h>
+
+#include <core/tnlString.h>
+
+struct tnlCacheSizes {
+   int L1instruction = 0;
+   int L1data = 0;
+   int L2 = 0;
+   int L3 = 0;
+};
+
+class tnlSystemInfo
+{
+public:
+   tnlSystemInfo();
+
+   tnlString getHostname( void ) const;
+   tnlString getArchitecture( void ) const;
+   tnlString getSystemName( void ) const;
+   tnlString getSystemRelease( void ) const;
+   tnlString getCurrentTime( const char* format = "%a %b %d %Y, %H:%M:%S" ) const;
+
+   int getNumberOfProcessors( void ) const;
+   tnlString getOnlineCPUs( void ) const;
+   int getNumberOfCores( int cpu_id ) const;
+   int getNumberOfThreads( int cpu_id ) const;
+   tnlString getCPUModelName( int cpu_id ) const;
+   int getCPUMaxFrequency( int cpu_id ) const;
+   tnlCacheSizes getCPUCacheSizes( int cpu_id ) const;
+
+protected:
+   struct utsname uts;
+   int numberOfProcessors = 0;
+   tnlString CPUModelName;
+   int CPUThreads = 0;
+   int CPUCores = 0;
+
+   void parseCPUInfo( void );
+
+   template< typename ResultType >
+   ResultType
+   readFile( const tnlString & fileName ) const
+   {
+      std::ifstream file( fileName.getString() );
+      if( ! file ) {
+         std::cerr << "Unable to read information from " << fileName << "." << std::endl;
+         return 0;
+      }
+      ResultType result;
+      file >> result;
+      return result;
+   }
+};
diff --git a/src/core/tnlTimer.cpp b/src/core/tnlTimer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..30e43f41dfb9faa83ebee6dc6b06714c589ef5f8
--- /dev/null
+++ b/src/core/tnlTimer.cpp
@@ -0,0 +1,152 @@
+/***************************************************************************
+                          tnlTimer.cpp  -  description
+                             -------------------
+    begin                : Mar 14, 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 <core/tnlTimer.h>
+
+#include "tnlConfig.h"
+#ifdef HAVE_SYS_RESOURCE_H
+   #include <sys/resource.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+   #include <stddef.h>
+   #include <sys/time.h>
+   #define HAVE_TIME
+#endif
+
+
+tnlTimer defaultTimer;
+
+tnlTimer::tnlTimer()
+{
+   reset();
+}
+
+void tnlTimer::reset()
+{
+   this->initialCPUTime = 0;
+   this->totalCPUTime = 0.0;
+   this->initialRealTime = 0;
+   this->totalRealTime = 0.0;
+   this->initialCPUCycles = 0;
+   this->totalCPUCycles = 0;
+   this->stopState = true;
+}
+
+void tnlTimer::stop()
+{
+
+   if( ! this->stopState )
+   {
+      /****
+       * Real time
+       */
+#ifdef HAVE_TIME      
+      struct timeval tp;
+      int rtn = gettimeofday( &tp, NULL );
+      this->totalRealTime += ( double ) tp. tv_sec + 1.0e-6 * ( double ) tp. tv_usec - this->initialRealTime;
+#endif
+      
+      /****
+       * CPU time
+       */
+#ifdef HAVE_SYS_RESOURCE_H      
+      rusage initUsage;
+      getrusage(  RUSAGE_SELF, &initUsage );
+      this->totalCPUTime += initUsage. ru_utime. tv_sec + 1.0e-6 * ( double ) initUsage. ru_utime. tv_usec - this->initialCPUTime;
+#endif      
+      
+      /****
+       * CPU cycles
+       */
+      this->totalCPUCycles += this->rdtsc() - this->initialCPUCycles;
+      this->stopState = true;
+   }
+}
+
+void tnlTimer::start()
+{
+   /****
+    * Real time
+    */
+#ifdef HAVE_TIME
+   struct timeval tp;
+   int rtn = gettimeofday( &tp, NULL );
+   this->initialRealTime = ( double ) tp. tv_sec + 1.0e-6 * ( double ) tp. tv_usec;
+#endif
+
+   /****
+    * CPU Time
+    */
+#ifdef HAVE_SYS_RESOURCE_H
+   rusage initUsage;
+   getrusage( RUSAGE_SELF, &initUsage );
+   this->initialCPUTime = initUsage. ru_utime. tv_sec + 1.0e-6 * ( double ) initUsage. ru_utime. tv_usec;
+#endif
+   
+   /****
+    * CPU cycles
+    */
+   this->initialCPUCycles = this->rdtsc();
+   
+   this->stopState = false;
+}
+
+double tnlTimer::getRealTime()
+{
+#ifdef HAVE_TIME
+   if( ! this->stopState )
+   {
+      this->stop();
+      this->start();
+   }
+   return this->totalRealTime;
+#else
+   return -1;
+#endif
+}
+
+double tnlTimer::getCPUTime()
+{
+#ifdef HAVE_SYS_RESOURCE_H
+   if( ! this->stopState )
+   {
+      this->stop();
+      this->start();
+   }
+   return this->totalCPUTime;
+#else
+   return -1;
+#endif
+}
+
+unsigned long long int tnlTimer::getCPUCycles()
+{
+   if( ! this->stopState )
+   {
+      this->stop();
+      this->start();
+   }
+   return this->totalCPUCycles;
+}
+
+bool tnlTimer::writeLog( tnlLogger& logger, int logLevel )
+{
+   logger.writeParameter< double                 >( "Real time:",  this->getRealTime(),  logLevel );
+   logger.writeParameter< double                 >( "CPU time:",   this->getCPUTime(),   logLevel );
+   logger.writeParameter< unsigned long long int >( "CPU Cycles:", this->getCPUCycles(), logLevel );
+
+}
diff --git a/src/core/tnlTimer.h b/src/core/tnlTimer.h
new file mode 100644
index 0000000000000000000000000000000000000000..b72001da772626e35f7371ab9f97ba3db1f7a296
--- /dev/null
+++ b/src/core/tnlTimer.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+                          tnlTimer.h  -  description
+                             -------------------
+    begin                : Mar 14, 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 TNLTIMER_H
+#define	TNLTIMER_H
+
+#include <core/tnlLogger.h>
+
+class tnlTimer
+{
+   public:
+   
+      tnlTimer();
+
+      void reset();
+
+      void stop();
+
+      void start();
+
+      double getRealTime();
+
+      double getCPUTime();
+
+      unsigned long long int getCPUCycles();
+      
+      bool writeLog( tnlLogger& logger, int logLevel = 0 );
+         
+   protected:
+
+   double initialRealTime, totalRealTime,
+          initialCPUTime, totalCPUTime;
+   
+   unsigned long long int initialCPUCycles, totalCPUCycles;
+   
+   bool stopState;
+   
+   inline unsigned long long rdtsc()
+   {
+     unsigned hi, lo;
+     __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
+     return ( ( unsigned long long ) lo ) | ( ( ( unsigned long long ) hi ) << 32 );
+   }
+};
+
+extern tnlTimer defaultTimer;
+
+#endif	/* TNLTIMER_H */
+
diff --git a/src/core/tnlTimerCPU.cpp b/src/core/tnlTimerCPU.cpp
index d618b455e372c9daa16bfdfaa129019adbc395be..a05b34d61eb0379c2e22115dacaca2f6df540d84 100644
--- a/src/core/tnlTimerCPU.cpp
+++ b/src/core/tnlTimerCPU.cpp
@@ -26,15 +26,9 @@ tnlTimerCPU :: tnlTimerCPU()
 
 void tnlTimerCPU::reset()
 {
-#ifdef HAVE_SYS_RESOURCE_H
-   rusage init_usage;
-   getrusage(  RUSAGE_SELF, &init_usage );
-   initial_time = init_usage. ru_utime. tv_sec + 1.0e-6 * ( double ) init_usage. ru_utime. tv_usec;
-#else
    initial_time = 0;
-#endif
    total_time = 0.0;
-   stop_state = false;
+   stop_state = true;
 }
 
 void tnlTimerCPU::stop()
@@ -57,14 +51,17 @@ void tnlTimerCPU::start()
    getrusage(  RUSAGE_SELF, &init_usage );
    initial_time = init_usage. ru_utime. tv_sec + 1.0e-6 * ( double ) init_usage. ru_utime. tv_usec;
 #endif
-  stop_state = false;
+   stop_state = false;
 }
 
 double tnlTimerCPU::getTime( int root, MPI_Comm comm )
 {
 #ifdef HAVE_SYS_RESOURCE_H
-   stop();
-   start();
+   if( ! stop_state )
+   {
+      stop();
+      start();
+   }
    double mpi_total_time;
    MPIReduce( total_time, mpi_total_time, 1, MPI_SUM, root, comm );
    return mpi_total_time;
diff --git a/src/core/tnlTimerRT.cpp b/src/core/tnlTimerRT.cpp
index 7351972dc5cb83697d7d5884170ab74fcd9f392a..50f90e8d66290b4ddea973e78aa941b4e7bc3617 100644
--- a/src/core/tnlTimerRT.cpp
+++ b/src/core/tnlTimerRT.cpp
@@ -34,16 +34,9 @@ tnlTimerRT::tnlTimerRT()
 
 void tnlTimerRT::reset()
 {
-#ifdef HAVE_TIME
-   struct timeval tp;
-   int rtn = gettimeofday( &tp, NULL );
-   initial_time = ( double ) tp. tv_sec + 1.0e-6 * ( double ) tp. tv_usec;
-   total_time = 0.0;
-   stop_state = false;
-#else
    initial_time = 0.0;
-#endif
-
+   total_time = 0.0;
+   stop_state = true;
 }
 
 void tnlTimerRT::stop()
@@ -72,9 +65,12 @@ void tnlTimerRT::start()
 double tnlTimerRT::getTime()
 {
 #ifdef HAVE_TIME
-	stop();
-	start();
-	return total_time;
+   if( ! stop_state )
+   {
+      stop();
+      start();
+   }
+   return total_time;
 #endif
- return -1;
+   return -1;
 }
diff --git a/src/core/vectors/tnlMultiVector1D_impl.h b/src/core/vectors/tnlMultiVector1D_impl.h
index 1fe506de95cbb7890a50f3df9c8485aa3a70650e..b2348daf8a75f69e762ae26e71d229d6e54846d4 100644
--- a/src/core/vectors/tnlMultiVector1D_impl.h
+++ b/src/core/vectors/tnlMultiVector1D_impl.h
@@ -77,8 +77,8 @@ bool tnlMultiVector< 1, Real, Device, Index > :: setDimensions( const tnlStaticV
 {
    tnlAssert( dimensions[ 0 ] > 0,
               cerr << " dimensions[ 0 ] = " << dimensions[ 0 ] );
-   this -> dimensions = dimensions;
-   return tnlVector< Real, Device, Index > :: setSize( this -> dimensions[ 0 ] );
+   this->dimensions = dimensions;
+   return tnlVector< Real, Device, Index > :: setSize( this->dimensions[ 0 ] );
 }
 
 template< typename Real, typename Device, typename Index >
@@ -91,21 +91,21 @@ bool tnlMultiVector< 1, Real, Device, Index > :: setLike( const tnlMultiVector&
 template< typename Real, typename Device, typename Index >
 void tnlMultiVector< 1, Real, Device, Index > :: getDimensions( Index& xSize ) const
 {
-   xSize = this -> dimensions[ 0 ];
+   xSize = this->dimensions[ 0 ];
 }
 
 template< typename Real, typename Device, typename Index >
 const tnlStaticVector< 1, Index >& tnlMultiVector< 1, Real, Device, Index > :: getDimensions() const
 {
-   return this -> dimensions;
+   return this->dimensions;
 }
 
 template< typename Real, typename Device, typename Index >
 Index tnlMultiVector< 1, Real, Device, Index > :: getElementIndex( const Index i ) const
 {
-   tnlAssert( i >= 0 && i < this -> dimensions[ 0 ],
+   tnlAssert( i >= 0 && i < this->dimensions[ 0 ],
               cerr << "i = " << i
-                   << "this -> dimensions[ 0 ] " << this -> dimensions[ 0 ] );
+                   << "this->dimensions[ 0 ] " << this->dimensions[ 0 ] );
    return i;
 }
 
@@ -139,9 +139,9 @@ template< typename Real, typename Device, typename Index >
 bool tnlMultiVector< 1, Real, Device, Index > :: operator == ( const MultiVector& Vector ) const
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == Vector. getDimensions(),
+   tnlAssert( this->getDimensions() == Vector. getDimensions(),
               cerr << "You are attempting to compare two Vectors with different dimensions." << endl
-                   << "First Vector name dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First Vector name dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second Vector dimensions are ( " << Vector. getDimensions() << " )" << endl; );
    return tnlVector< Real, Device, Index > :: operator == ( Vector );
 }
@@ -158,9 +158,9 @@ tnlMultiVector< 1, Real, Device, Index >&
    tnlMultiVector< 1, Real, Device, Index > :: operator = ( const tnlMultiVector< 1, Real, Device, Index >& Vector )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == Vector. getDimensions(),
+   tnlAssert( this->getDimensions() == Vector. getDimensions(),
               cerr << "You are attempting to assign two Vectors with different dimensions." << endl
-                   << "First vector dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First vector dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second vector dimensions are ( " << Vector. getDimensions() << " )" << endl; );
    tnlVector< Real, Device, Index > :: operator = ( Vector );
    return ( *this );
@@ -172,9 +172,9 @@ tnlMultiVector< 1, Real, Device, Index >&
    tnlMultiVector< 1, Real, Device, Index > :: operator = ( const MultiVector& Vector )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == Vector. getDimensions(),
+   tnlAssert( this->getDimensions() == Vector. getDimensions(),
               cerr << "You are attempting to assign two Vectors with different dimensions." << endl
-                   << "First vector dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First vector dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second vector dimensions are ( " << Vector. getDimensions() << " )" << endl; );
    tnlVector< Real, Device, Index > :: operator = ( Vector );
    return ( *this );
diff --git a/src/core/vectors/tnlMultiVector2D_impl.h b/src/core/vectors/tnlMultiVector2D_impl.h
index be3f3874d9f68504a3b9ff4ea09cc39f7c9fe3e8..2373ad127b621015a5009d9d154b41bf473ae21e 100644
--- a/src/core/vectors/tnlMultiVector2D_impl.h
+++ b/src/core/vectors/tnlMultiVector2D_impl.h
@@ -81,8 +81,8 @@ bool tnlMultiVector< 2, Real, Device, Index > :: setDimensions( const tnlStaticV
 {
    tnlAssert( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0,
               cerr << "dimensions = " << dimensions );
-   this -> dimensions = dimensions;
-   return tnlVector< Real, Device, Index > :: setSize( this -> dimensions[ 1 ] * this -> dimensions[ 0 ] );
+   this->dimensions = dimensions;
+   return tnlVector< Real, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] );
 }
 
 template< typename Real, typename Device, typename Index >
@@ -95,25 +95,25 @@ bool tnlMultiVector< 2, Real, Device, Index > :: setLike( const MultiVector& mul
 template< typename Real, typename Device, typename Index >
 void tnlMultiVector< 2, Real, Device, Index > :: getDimensions( Index& jSize, Index& iSize ) const
 {
-   iSize = this -> dimensions[ 0 ];
-   jSize = this -> dimensions[ 1 ];
+   iSize = this->dimensions[ 0 ];
+   jSize = this->dimensions[ 1 ];
 }
 
 template< typename Real, typename Device, typename Index >
 const tnlStaticVector< 2, Index >& tnlMultiVector< 2, Real, Device, Index > :: getDimensions() const
 {
-   return this -> dimensions;
+   return this->dimensions;
 }
 
 template< typename Real, typename Device, typename Index >
 Index tnlMultiVector< 2, Real, Device, Index > :: getElementIndex( const Index j, const Index i ) const
 {
-   tnlAssert( i >= 0 && i < this -> dimensions[ 0 ] && j >= 0 && j < this -> dimensions[ 1 ],
+   tnlAssert( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ],
               cerr << "i = " << i
                    << "j = " << j
-                   << "this -> dimensions[ 0 ] = " << this -> dimensions[ 0 ]
-                   << "this -> dimensions[ 1 ] = " << this -> dimensions[ 1 ] );
-   return j * this -> dimensions[ 0 ] + i;
+                   << "this->dimensions[ 0 ] = " << this->dimensions[ 0 ]
+                   << "this->dimensions[ 1 ] = " << this->dimensions[ 1 ] );
+   return j * this->dimensions[ 0 ] + i;
 }
 
 template< typename Real, typename Device, typename Index >
@@ -146,9 +146,9 @@ template< typename Real, typename Device, typename Index >
 bool tnlMultiVector< 2, Real, Device, Index > :: operator == ( const MultiVector& Vector ) const
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == Vector. getDimensions(),
+   tnlAssert( this->getDimensions() == Vector. getDimensions(),
               cerr << "You are attempting to compare two Vectors with different dimensions." << endl
-                   << "First vector dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First vector dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second vector dimensions are ( " << Vector. getDimensions() << " )" << endl; );
    return tnlVector< Real, Device, Index > :: operator == ( Vector );
 }
@@ -165,9 +165,9 @@ tnlMultiVector< 2, Real, Device, Index >&
    tnlMultiVector< 2, Real, Device, Index > :: operator = ( const tnlMultiVector< 2, Real, Device, Index >& Vector )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == Vector. getDimensions(),
+   tnlAssert( this->getDimensions() == Vector. getDimensions(),
               cerr << "You are attempting to assign two Vectors with different dimensions." << endl
-                   << "First vector dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First vector dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second vector dimensions are ( " << Vector. getDimensions() << " )" << endl; );
    tnlVector< Real, Device, Index > :: operator = ( Vector );
    return ( *this );
@@ -179,9 +179,9 @@ tnlMultiVector< 2, Real, Device, Index >&
    tnlMultiVector< 2, Real, Device, Index > :: operator = ( const MultiVector& Vector )
 {
    // TODO: Static assert on dimensions
-   tnlAssert( this -> getDimensions() == Vector. getDimensions(),
+   tnlAssert( this->getDimensions() == Vector. getDimensions(),
               cerr << "You are attempting to assign two Vectors with different dimensions." << endl
-                   << "First vector dimensions are ( " << this -> getDimensions() << " )" << endl
+                   << "First vector dimensions are ( " << this->getDimensions() << " )" << endl
                    << "Second vector dimensions are ( " << Vector. getDimensions() << " )" << endl; );
    tnlVector< Real, Device, Index > :: operator = ( Vector );
    return ( *this );
diff --git a/src/core/vectors/tnlVector.h b/src/core/vectors/tnlVector.h
index 27eedc04fbd5ed7a3086e9d4809cfd4e6bc64eef..4f95d20a9ec040146834b10a6c69bf342f37d5b1 100644
--- a/src/core/vectors/tnlVector.h
+++ b/src/core/vectors/tnlVector.h
@@ -110,7 +110,7 @@ class tnlVector : public tnlArray< Real, Device, Index >
 
    //! Computes scalar dot product
    template< typename Vector >
-   Real scalarProduct( const Vector& v );
+   Real scalarProduct( const Vector& v ) const;
 
    //! Computes this = thisMultiplicator * this + multiplicator * v.
    template< typename Vector >
diff --git a/src/core/vectors/tnlVectorOperationsHost_impl.h b/src/core/vectors/tnlVectorOperationsHost_impl.h
index 1b5b42ee510701efe9e803f13a06dbb365c7eacc..1ea7fd98a1b17d5a237078bc9079d8da33d2cdd8 100644
--- a/src/core/vectors/tnlVectorOperationsHost_impl.h
+++ b/src/core/vectors/tnlVectorOperationsHost_impl.h
@@ -102,7 +102,7 @@ getVectorL1Norm( const Vector& v )
    Real result( 0.0 );
    const Index n = v. getSize();
 #ifdef HAVE_OPENMP
-#pragma omp parallel for reduction(+:result) if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for reduction(+:result) if( tnlHost::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif           
    for( Index i = 0; i < n; i ++ )
       result += fabs( v[ i ] );
@@ -120,7 +120,7 @@ getVectorL2Norm( const Vector& v )
    Real result( 0.0 );
    const Index n = v. getSize();
 #ifdef HAVE_OPENMP
-#pragma omp parallel for reduction(+:result) if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for reduction(+:result) if( tnlHost::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif           
    for( Index i = 0; i < n; i ++ )
    {
@@ -149,7 +149,7 @@ getVectorLpNorm( const Vector& v,
    Real result( 0.0 );
    const Index n = v. getSize();
 #ifdef HAVE_OPENMP
-#pragma omp parallel for reduction(+:result) if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for reduction(+:result) if( tnlHost::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif           
    for( Index i = 0; i < n; i ++ )
       result += pow( fabs( v[ i ] ), p );
@@ -166,7 +166,7 @@ typename Vector :: RealType tnlVectorOperations< tnlHost > :: getVectorSum( cons
    Real result( 0.0 );
    const Index n = v. getSize();
 #ifdef HAVE_OPENMP
-#pragma omp parallel for reduction(+:result) if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for reduction(+:result) if( tnlHost::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif        
    for( Index i = 0; i < n; i ++ )
       result += v[ i ];
@@ -254,7 +254,7 @@ getVectorDifferenceL1Norm( const Vector1& v1,
    Real result( 0.0 );
    const Index n = v1. getSize();
 #ifdef HAVE_OPENMP
-#pragma omp parallel for reduction(+:result) if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for reduction(+:result) if( tnlHost::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif        
    for( Index i = 0; i < n; i ++ )
       result += fabs( v1[ i ] - v2[ i ] );
@@ -276,7 +276,7 @@ getVectorDifferenceL2Norm( const Vector1& v1,
    Real result( 0.0 );
    const Index n = v1. getSize();
 #ifdef HAVE_OPENMP
-#pragma omp parallel for reduction(+:result) if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for reduction(+:result) if( tnlHost::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif        
    for( Index i = 0; i < n; i ++ )
    {
@@ -310,7 +310,7 @@ getVectorDifferenceLpNorm( const Vector1& v1,
    Real result( 0.0 );
    const Index n = v1. getSize();
 #ifdef HAVE_OPENMP
-#pragma omp parallel for reduction(+:result) if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for reduction(+:result) if( tnlHost::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif        
    for( Index i = 0; i < n; i ++ )
       result += pow( fabs( v1. getElement( i ) - v2. getElement( i ) ), p );
@@ -330,7 +330,7 @@ typename Vector1::RealType tnlVectorOperations< tnlHost > :: getVectorDifference
    Real result( 0.0 );
    const Index n = v1. getSize();
 #ifdef HAVE_OPENMP
-#pragma omp parallel for reduction(+:result) if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for reduction(+:result) if( tnlHost::isOMPEnabled() &&n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif        
    for( Index i = 0; i < n; i ++ )
       result += v1. getElement( i ) - v2. getElement( i );
@@ -369,7 +369,7 @@ typename Vector1 :: RealType tnlVectorOperations< tnlHost > :: getScalarProduct(
    Real result( 0.0 );
    const Index n = v1. getSize();
 #ifdef HAVE_OPENMP
-  #pragma omp parallel for reduction(+:result) if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+  #pragma omp parallel for reduction(+:result) if( tnlHost::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif     
    for( Index i = 0; i < n; i++ )
       result += v1[ i ] * v2[ i ];
@@ -409,13 +409,13 @@ void tnlVectorOperations< tnlHost > :: addVector( Vector1& y,
    const Index n = y. getSize();
    if( thisMultiplicator == 1.0 )
 #ifdef HAVE_OPENMP
-#pragma omp parallel for if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for if( tnlHost::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif           
       for( Index i = 0; i < n; i ++ )
          y[ i ] += alpha * x[ i ];
    else
 #ifdef HAVE_OPENMP
-#pragma omp parallel for if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for if( tnlHost::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif           
       for( Index i = 0; i < n; i ++ )
          y[ i ] = thisMultiplicator * y[ i ] + alpha * x[ i ];
@@ -443,13 +443,13 @@ addVectors( Vector1& v,
    const Index n = v.getSize();
    if( thisMultiplicator == 1.0 )
 #ifdef HAVE_OPENMP
-#pragma omp parallel for if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for if( tnlHost::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif           
       for( Index i = 0; i < n; i ++ )
          v[ i ] += multiplicator1 * v1[ i ] + multiplicator2 * v2[ i ];
    else
 #ifdef HAVE_OPENMP
-#pragma omp parallel for if( n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
+#pragma omp parallel for if( tnlHost::isOMPEnabled() && n > OpenMPVectorOperationsThreshold ) // TODO: check this threshold
 #endif           
       for( Index i = 0; i < n; i ++ )
          v[ i ] = thisMultiplicator * v[ i ] * multiplicator1 * v1[ i ] + multiplicator2 * v2[ i ];
diff --git a/src/core/vectors/tnlVector_impl.h b/src/core/vectors/tnlVector_impl.h
index 180eb7bdad221a2498f7f0b36ce0ca9239a225a7..9615e4ca8ed3e51eeb12a4ef694fe689b251bcdd 100644
--- a/src/core/vectors/tnlVector_impl.h
+++ b/src/core/vectors/tnlVector_impl.h
@@ -33,7 +33,7 @@ template< typename Real,
           typename Index >
 tnlVector< Real, Device, Index >::tnlVector( const Index size )
 {
-   this -> setSize( size );
+   this->setSize( size );
 }
 
 
@@ -291,7 +291,7 @@ 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 ) const
 {
    return tnlVectorOperations< Device >::getScalarProduct( *this, v );
 }
diff --git a/src/debug/tnlDebugStructure.cpp b/src/debug/tnlDebugStructure.cpp
index 067dca0cf5fff766fb86906e7f51282370a48d0c..4e5dfdae3bd1e7a890dc150b5b9e925815babafa 100644
--- a/src/debug/tnlDebugStructure.cpp
+++ b/src/debug/tnlDebugStructure.cpp
@@ -41,7 +41,7 @@ tnlDebugStructure :: ~tnlDebugStructure()
 
 void tnlDebugStructure :: setDebug( bool debug )
 {
-   this -> debug = debug;
+   this->debug = debug;
 }
 
 void tnlDebugStructure :: AppendGroup( tnlDebugGroup* group )
diff --git a/src/functions/tnlMeshFunction.h b/src/functions/tnlMeshFunction.h
index add52cc1c939d2b202206e15a949f1879285d050..e86aca9d3260e1cb33e9827b7b3cafd87a232c73 100644
--- a/src/functions/tnlMeshFunction.h
+++ b/src/functions/tnlMeshFunction.h
@@ -66,6 +66,8 @@ class tnlMeshFunction :
       bool setup( const tnlParameterContainer& parameters,
                   const tnlString& prefix = "" );      
       
+      void bind( ThisType& meshFunction );
+      
       template< typename Vector >
       void bind( const MeshType& mesh,
                  const Vector& data,
diff --git a/src/functions/tnlMeshFunctionVTKWriter.h b/src/functions/tnlMeshFunctionVTKWriter.h
index b06e4ea27ff18f38db6d00fbea097f26194ddd6b..d236a00e6a9168888fc870d17492e56c61007608 100644
--- a/src/functions/tnlMeshFunctionVTKWriter.h
+++ b/src/functions/tnlMeshFunctionVTKWriter.h
@@ -24,13 +24,190 @@ 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;
-      }
+                         ostream& str );
+      static void writeHeader(const MeshFunction& function,
+                         ostream& str ){}
 };
 
+/***
+ * 1D grid, cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionVTKWriter< 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 );
+      static void writeHeader(const MeshFunctionType& function,
+                         ostream& str );
+};
+        
+/***
+ * 1D grid, vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionVTKWriter< 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 );
+      static void writeHeader(const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 2D grid, cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionVTKWriter< 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 );
+      static void writeHeader(const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 2D grid, faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionVTKWriter< 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 );
+      static void writeHeader(const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 2D grid, vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionVTKWriter< 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 );
+      static void writeHeader(const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 3D grid, cells
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 3, Real > >
+{
+   public:
+      typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef tnlMeshFunction< MeshType, 3, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         ostream& str );
+      static void writeHeader(const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 3D grid, faces
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 2, Real > >
+{
+   public:
+      typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef tnlMeshFunction< MeshType, 2, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         ostream& str );
+      static void writeHeader(const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 3D grid, edges
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 1, Real > >
+{
+   public:
+      typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef tnlMeshFunction< MeshType, 1, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         ostream& str );
+      static void writeHeader(const MeshFunctionType& function,
+                         ostream& str );
+};
+
+/***
+ * 3D grid, vertices
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+class tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 0, Real > >
+{
+   public:
+      typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef tnlMeshFunction< MeshType, 0, RealType > MeshFunctionType;
+
+      static bool write( const MeshFunctionType& function,
+                         ostream& str );
+      static void writeHeader(const MeshFunctionType& function,
+                         ostream& str );
+};
 
 #endif	/* TNLMESHFUNCTIONVTKWRITER_H */
 
diff --git a/src/functions/tnlMeshFunctionVTKWriter_impl.h b/src/functions/tnlMeshFunctionVTKWriter_impl.h
index 4173fd0399e50145efd5c76e03715ac824c8284d..c33957ab050e3b0bab2381b8291463e285c572dc 100644
--- a/src/functions/tnlMeshFunctionVTKWriter_impl.h
+++ b/src/functions/tnlMeshFunctionVTKWriter_impl.h
@@ -15,10 +15,1007 @@
  *                                                                         *
  ***************************************************************************/
 
-#ifndef TNLMESHFUNCTIONVTKWRITER_IMPL_H
-#define	TNLMESHFUNCTIONVTKWRITER_IMPL_H
+#pragma once 
 
+template< typename MeshFunction >
+bool
+tnlMeshFunctionVTKWriter< MeshFunction >::
+write( const MeshFunction& function,
+                         ostream& str )
+{
+   std::cerr << "VTK writer for mesh functions defined on mesh type " << MeshFunction::MeshType::getType() << " is not (yet) implemented." << std::endl;
+   return false;   
+}
 
+/****
+ * 1D grid, cells
+ */
 
-#endif	/* TNLMESHFUNCTIONVTKWRITER_IMPL_H */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+void
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 1, MeshReal, Device, MeshIndex >, 1, Real > >::
+writeHeader( const MeshFunctionType& function,
+       ostream& str )
+{ 
+    const MeshType& mesh = function.getMesh();
+    const typename MeshType::VertexType& origin = mesh.getOrigin();
+    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    str << "# vtk DataFile Version 2.0" << endl;
+    str << "TNL DATA" << endl;
+    str << "ASCII" << endl;
+    str << "DATASET UNSTRUCTURED_GRID" << endl;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 1, MeshReal, Device, MeshIndex >, 1, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{ 
+   writeHeader(function, str);
+   
+   const MeshType& mesh = function.getMesh();
+   const RealType origin = mesh.getOrigin().x();
+   const RealType spaceStep = mesh.getSpaceSteps().x();
+   
+   str << "POINTS " << mesh.getDimensions().x() + 1 << " float" << endl;
+   
+   for (int i = 0; i <= mesh.getDimensions().x(); i++)
+   {
+       str << origin + i * spaceStep << " 0 0" << endl;
+   }
+   
+   str << endl << "CELLS " << mesh.getDimensions().x() << " " << mesh.getDimensions().x() * 3 << endl;
+   for (int i = 0; i < mesh.getDimensions().x(); i++)
+   {
+       str << "2 " << i << " " << i+1 << endl;
+   }
+   
+   str << endl << "CELL_TYPES " << mesh.getDimensions().x() << endl;
+   for (int i = 0; i < mesh.getDimensions().x(); i++)
+   {
+       str << "3 " << endl;
+   }   
+   
+   str << endl << "CELL_DATA " << mesh.getDimensions().x() << endl;
+   str << "SCALARS cellFunctionValues float 1" << endl;
+   str << "LOOKUP_TABLE default" << endl;
+
+   typename MeshType::Cell entity( mesh );
+   for( entity.getCoordinates().x() = 0;
+        entity.getCoordinates().x() < mesh.getDimensions().x();
+        entity.getCoordinates().x() ++ )
+   {
+      entity.refresh();
+      str << function.getData().getElement( entity.getIndex() ) << std::endl;
+   }
+   
+   return true;
+}
+
+/****
+ * 1D grid, vertices
+ */
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+void
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 1, MeshReal, Device, MeshIndex >, 0, Real > >::
+writeHeader( const MeshFunctionType& function,
+       ostream& str )
+{ 
+    const MeshType& mesh = function.getMesh();
+    const typename MeshType::VertexType& origin = mesh.getOrigin();
+    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    str << "# vtk DataFile Version 2.0" << endl;
+    str << "TNL DATA" << endl;
+    str << "ASCII" << endl;
+    str << "DATASET UNSTRUCTURED_GRID" << endl;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 1, MeshReal, Device, MeshIndex >, 0, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{ 
+   writeHeader(function, str);
+   
+   const MeshType& mesh = function.getMesh();
+   const RealType origin = mesh.getOrigin().x();
+   const RealType spaceStep = mesh.getSpaceSteps().x();
+   
+   str << "POINTS " << mesh.getDimensions().x() + 1 << " float" << endl;
+   
+   for (int i = 0; i < mesh.getDimensions().x() + 1; i++)
+   {
+       str << origin + i * spaceStep << " 0 0" << endl;
+   }
+   
+   str << endl << "CELLS " << mesh.getDimensions().x() + 1 << " " << ( mesh.getDimensions().x() + 1 ) * 2 << endl;
+   for (int i = 0; i < mesh.getDimensions().x() + 1; i++)
+   {
+       str << "1 " << i << endl;
+   }
+   
+   str << endl << "CELL_TYPES " << mesh.getDimensions().x() + 1 << endl;
+   for (int i = 0; i < mesh.getDimensions().x() + 1; i++)
+   {
+       str << "1 " << endl;
+   }   
+   
+   str << endl << "CELL_DATA " << mesh.getDimensions().x() + 1 << endl;
+   str << "SCALARS VerticesFunctionValues float 1" << endl;
+   str << "LOOKUP_TABLE default" << endl;
+
+   typename MeshType::Vertex entity( mesh );
+   for( entity.getCoordinates().x() = 0;
+        entity.getCoordinates().x() <= mesh.getDimensions().x();
+        entity.getCoordinates().x() ++ )
+   {
+      entity.refresh();
+      str << function.getData().getElement( entity.getIndex() ) << std::endl;
+   }
+   
+   return true;
+}
+
+/****
+ * 2D grid, cells
+ */
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+void
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 2, Real > >::
+writeHeader( const MeshFunctionType& function,
+       ostream& str )
+{ 
+    const MeshType& mesh = function.getMesh();
+    const typename MeshType::VertexType& origin = mesh.getOrigin();
+    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    str << "# vtk DataFile Version 2.0" << endl;
+    str << "TNL DATA" << endl;
+    str << "ASCII" << endl;
+    str << "DATASET UNSTRUCTURED_GRID" << endl;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 2, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{  
+   writeHeader(function, str);
+   
+   const MeshType& mesh = function.getMesh();
+   const RealType originX = mesh.getOrigin().x();
+   const RealType spaceStepX = mesh.getSpaceSteps().x();
+   const RealType originY = mesh.getOrigin().y();
+   const RealType spaceStepY = mesh.getSpaceSteps().y();
+   
+   str << "POINTS " << (mesh.getDimensions().x() + 1) * (mesh.getDimensions().y() + 1) << " float" << endl;
+   
+   for (int j = 0; j < mesh.getDimensions().y() + 1; j++)
+   {
+        for (int i = 0; i < mesh.getDimensions().x() + 1; i++)
+        {
+             str << originX + i * spaceStepX << " " << originY + j * spaceStepY << " 0" << endl;
+        }
+   }
+   
+   str << endl << "CELLS " << mesh.getDimensions().x() * mesh.getDimensions().y() << " " << 
+          mesh.getDimensions().x() * mesh.getDimensions().y() * 5 << endl;
+   for (int j = 0; j < mesh.getDimensions().y(); j++)
+   {
+        for (int i = 0; i < mesh.getDimensions().x(); i++)
+        {
+            str << "4 " << j * ( mesh.getDimensions().x() + 1 ) + i << " " << j * ( mesh.getDimensions().x() + 1 )+ i + 1 << 
+                   " " << (j+1) * ( mesh.getDimensions().x() + 1 ) + i << " " << (j+1) * ( mesh.getDimensions().x() + 1 ) + i + 1 << endl;
+        }
+   }
+   
+   str << endl << "CELL_TYPES " << mesh.getDimensions().x() * mesh.getDimensions().y() << endl;
+   for (int i = 0; i < mesh.getDimensions().x()*mesh.getDimensions().y(); i++)
+   {
+       str << "8 " << endl;
+   }   
+   
+   str << endl << "CELL_DATA " << mesh.getDimensions().x() * mesh.getDimensions().y() << endl;
+   str << "SCALARS cellFunctionValues float 1" << endl;
+   str << "LOOKUP_TABLE default" << endl;
+
+   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();
+         str << function.getData().getElement( entity.getIndex() ) << endl;      
+      }
+   }
+   return true;
+}
+
+/****
+ * 2D grid, faces
+ */
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+void
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 1, Real > >::
+writeHeader( const MeshFunctionType& function,
+       ostream& str )
+{ 
+    const MeshType& mesh = function.getMesh();
+    const typename MeshType::VertexType& origin = mesh.getOrigin();
+    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    str << "# vtk DataFile Version 2.0" << endl;
+    str << "TNL DATA" << endl;
+    str << "ASCII" << endl;
+    str << "DATASET UNSTRUCTURED_GRID" << endl;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 1, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{
+   typedef typename MeshType::template MeshEntity< 0 > Vertex;
+   typedef typename MeshType::template MeshEntity< 1 > Face;
+   writeHeader(function, str);
+   
+   const MeshType& mesh = function.getMesh();
+   const RealType originX = mesh.getOrigin().x();
+   const RealType spaceStepX = mesh.getSpaceSteps().x();
+   const RealType originY = mesh.getOrigin().y();
+   const RealType spaceStepY = mesh.getSpaceSteps().y();
+   
+   str << "POINTS " << mesh.template getEntitiesCount< Vertex >() << " float" << endl;
+   
+   for (int j = 0; j < ( mesh.getDimensions().y() + 1); j++)
+   {
+        for (int i = 0; i < ( mesh.getDimensions().x() + 1 ); i++)
+        {
+             str << originX + i * spaceStepX << " " << originY + j * spaceStepY << " 0" << endl;
+        }
+   }
+   
+   str << endl << "CELLS " << mesh.template getEntitiesCount< Face >() << " " << 
+          mesh.template getEntitiesCount< Face >() * 3 << endl;
+   for (int j = 0; j < mesh.getDimensions().y(); j++)
+   {
+        for (int i = 0; i < ( mesh.getDimensions().x() + 1 ); i++)
+        {
+            str << "2 " << j * ( mesh.getDimensions().x() + 1 ) + i << " " << (j+1) * ( mesh.getDimensions().x() + 1 ) + i << endl;
+        }
+   }
+   
+   for (int j = 0; j < (mesh.getDimensions().y()+1); j++)
+   {
+        for (int i = 0; i < mesh.getDimensions().x(); i++)
+        {
+            str << "2 " << j * ( mesh.getDimensions().x() + 1 ) + i << " " <<j * ( mesh.getDimensions().x() + 1 ) + i + 1<< endl;
+        }
+   }
+   
+   str << endl << "CELL_TYPES " << mesh.template getEntitiesCount< Face >() << endl;
+   for (int i = 0; i < mesh.template getEntitiesCount< Face >(); i++)
+   {
+       str << "3" << endl;
+   }  
+   
+   str << endl << "CELL_DATA " << mesh.template getEntitiesCount< Face >() << endl;
+   str << "SCALARS FaceslFunctionValues float 1" << endl;
+   str << "LOOKUP_TABLE default" << endl;
+
+   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();
+         str << function.getData().getElement( entity.getIndex() ) << std::endl;      
+      }
+   }
+   
+   entity.setOrientation( EntityOrientation( 0.0, 1.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();
+         str << function.getData().getElement( entity.getIndex() ) << std::endl;      
+      }
+   }
+   return true;
+}
+
+/****
+ * 2D grid, vertices
+ */
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+void
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 0, Real > >::
+writeHeader( const MeshFunctionType& function,
+       ostream& str )
+{ 
+    const MeshType& mesh = function.getMesh();
+    const typename MeshType::VertexType& origin = mesh.getOrigin();
+    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    str << "# vtk DataFile Version 2.0" << endl;
+    str << "TNL DATA" << endl;
+    str << "ASCII" << endl;
+    str << "DATASET UNSTRUCTURED_GRID" << endl;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 2, MeshReal, Device, MeshIndex >, 0, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{  
+   typedef typename MeshType::template MeshEntity< 0 > Vertex;
+   writeHeader(function, str);
+   
+   const MeshType& mesh = function.getMesh();
+   const RealType originX = mesh.getOrigin().x();
+   const RealType spaceStepX = mesh.getSpaceSteps().x();
+   const RealType originY = mesh.getOrigin().y();
+   const RealType spaceStepY = mesh.getSpaceSteps().y();
+
+   
+   str << "POINTS " << mesh.template getEntitiesCount< Vertex >() << " float" << endl;
+   
+   for (int j = 0; j < ( mesh.getDimensions().y() + 1); j++)
+   {
+        for (int i = 0; i < ( mesh.getDimensions().x() + 1 ); i++)
+        {
+             str << originX + i * spaceStepX << " " << originY + j * spaceStepY << " 0" << endl;
+        }
+   }
+   
+   str << endl << "CELLS " << mesh.template getEntitiesCount< Vertex >() << " " << 
+          mesh.template getEntitiesCount< Vertex >() * 2 << endl;
+   for (int j = 0; j < ( mesh.getDimensions().y() + 1 ); j++)
+   {
+        for (int i = 0; i < ( mesh.getDimensions().x() + 1 ); i++)
+        {
+            str << "1 " << j * mesh.getDimensions().x() + i  << endl;
+        }
+   }
+   
+   str << endl << "CELL_TYPES " << mesh.template getEntitiesCount< Vertex >() << endl;
+   for (int i = 0; i < mesh.template getEntitiesCount< Vertex >(); i++)
+   {
+       str << "1" << endl;
+   }  
+   
+   str << endl << "CELL_DATA " << mesh.template getEntitiesCount< Vertex >() << endl;
+   str << "SCALARS VerticesFunctionValues float 1" << endl;
+   str << "LOOKUP_TABLE default" << endl;
+
+   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();
+         str << function.getData().getElement( entity.getIndex() ) << endl;      
+      }
+   }
+   
+   return true;
+}
+
+/****
+ * 3D grid, cells
+ */
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+void
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 3, Real > >::
+writeHeader( const MeshFunctionType& function,
+       ostream& str )
+{ 
+    const MeshType& mesh = function.getMesh();
+    const typename MeshType::VertexType& origin = mesh.getOrigin();
+    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    str << "# vtk DataFile Version 2.0" << endl;
+    str << "TNL DATA" << endl;
+    str << "ASCII" << endl;
+    str << "DATASET UNSTRUCTURED_GRID" << endl;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 3, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{  
+   writeHeader(function, str);
+   
+   const MeshType& mesh = function.getMesh();
+   const RealType originX = mesh.getOrigin().x();
+   const RealType spaceStepX = mesh.getSpaceSteps().x();
+   const RealType originY = mesh.getOrigin().y();
+   const RealType spaceStepY = mesh.getSpaceSteps().y();
+   const RealType originZ = mesh.getOrigin().z();
+   const RealType spaceStepZ = mesh.getSpaceSteps().z();
+   const RealType entitiesCount = mesh.getDimensions().x() * mesh.getDimensions().y() * mesh.getDimensions().z();
+   
+   str << "POINTS " << (mesh.getDimensions().x()+1) * (mesh.getDimensions().y()+1) * (mesh.getDimensions().z()+1) << 
+          " float" << endl;
+   
+   for (int k = 0; k <= mesh.getDimensions().y(); k++)
+   {
+       for (int j = 0; j <= mesh.getDimensions().y(); j++)
+       {
+            for (int i = 0; i <= mesh.getDimensions().x(); i++)
+            {
+                 str << originX + i * spaceStepX << " " << originY + j * spaceStepY << " " << 
+                        originZ + k * spaceStepZ << endl;
+            }
+       }
+   }
+   
+   str << endl << "CELLS " << entitiesCount << " " << 
+          entitiesCount * 9 << endl;
+   for (int k = 0; k < mesh.getDimensions().z(); k++)
+   {
+        for (int j = 0; j < mesh.getDimensions().y(); j++)
+        {
+            for (int i = 0; i < mesh.getDimensions().x(); i++)
+            {
+                str << "8 " <<  k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " " 
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i + 1 << " " 
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + (j+1) * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + (j+1) * ( mesh.getDimensions().x() + 1 ) + i + 1 << " "
+                    << (k+1) * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " " 
+                    << (k+1) * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i + 1 << " " 
+                    << (k+1) * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + (j+1) * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << (k+1) * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + (j+1) * ( mesh.getDimensions().x() + 1 ) + i + 1 << endl;
+            }
+        }
+   }
+   
+   str << endl << "CELL_TYPES " << entitiesCount << endl;
+   for (int i = 0; i < entitiesCount; i++)
+   {
+       str << "11" << endl;
+   }   
+   
+   str << endl << "CELL_DATA " << entitiesCount << endl;
+   str << "SCALARS cellFunctionValues float 1" << endl;
+   str << "LOOKUP_TABLE default" << endl;
+
+   typename MeshType::Cell entity( mesh );
+   for( entity.getCoordinates().z() = 0;
+        entity.getCoordinates().z() < mesh.getDimensions().z();
+        entity.getCoordinates().z() ++ ) 
+   {
+        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();
+                str << function.getData().getElement( entity.getIndex() ) << endl;      
+            }
+        }
+   }
+   return true;
+}
+
+/****
+ * 3D grid, faces
+ */
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+void
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 2, Real > >::
+writeHeader( const MeshFunctionType& function,
+       ostream& str )
+{ 
+    const MeshType& mesh = function.getMesh();
+    const typename MeshType::VertexType& origin = mesh.getOrigin();
+    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    str << "# vtk DataFile Version 2.0" << endl;
+    str << "TNL DATA" << endl;
+    str << "ASCII" << endl;
+    str << "DATASET UNSTRUCTURED_GRID" << endl;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 2, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{  
+   typedef typename MeshType::template MeshEntity< 2 > Face;
+   typedef typename MeshType::template MeshEntity< 3 > Cell;
+   writeHeader(function, str);
+   
+   const MeshType& mesh = function.getMesh();
+   const RealType originX = mesh.getOrigin().x();
+   const RealType spaceStepX = mesh.getSpaceSteps().x();
+   const RealType originY = mesh.getOrigin().y();
+   const RealType spaceStepY = mesh.getSpaceSteps().y();
+   const RealType originZ = mesh.getOrigin().z();
+   const RealType spaceStepZ = mesh.getSpaceSteps().z();
+   const RealType entitiesCount = mesh.template getEntitiesCount< Face >();
+   const RealType pointsCount = mesh.template getEntitiesCount< Cell >();
+   
+   str << "POINTS " << pointsCount << 
+          " float" << endl;
+   
+   for (int k = 0; k <= mesh.getDimensions().y(); k++)
+   {
+       for (int j = 0; j <= mesh.getDimensions().y(); j++)
+       {
+            for (int i = 0; i <= mesh.getDimensions().x(); i++)
+            {
+                 str << originX + i * spaceStepX << " " << originY + j * spaceStepY << " " << 
+                        originZ + k * spaceStepZ << endl;
+            }
+       }
+   }
+   
+   str << endl << "CELLS " << entitiesCount << " " << 
+          entitiesCount * 5 << endl;
+   for (int k = 0; k < mesh.getDimensions().z(); k++)
+   {
+        for (int j = 0; j < mesh.getDimensions().y(); j++)
+        {
+            for (int i = 0; i <= mesh.getDimensions().x(); i++)
+            {
+                str << "4 " << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + (j+1) * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << (k+1) * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << (k+1) * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + (j+1) * ( mesh.getDimensions().x() + 1 ) + i << endl;
+            }
+        }
+   }
+   
+   for (int k = 0; k < mesh.getDimensions().z(); k++)
+   {
+        for (int j = 0; j <= mesh.getDimensions().y(); j++)
+        {
+            for (int i = 0; i < mesh.getDimensions().x(); i++)
+            {
+                str << "4 " << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i + 1 << " "
+                    << (k+1) * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << (k+1) * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i + 1 << endl;
+            }
+        }
+   }
+   
+   for (int k = 0; k <= mesh.getDimensions().z(); k++)
+   {
+        for (int j = 0; j < mesh.getDimensions().y(); j++)
+        {
+            for (int i = 0; i < mesh.getDimensions().x(); i++)
+            {
+                str << "4 " << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i + 1 << " "
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + (j+1) * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + (j+1) * ( mesh.getDimensions().x() + 1 ) + i + 1<< endl;
+            }
+        }
+   }
+   
+   str << endl << "CELL_TYPES " << entitiesCount << endl;
+   for (int i = 0; i < entitiesCount; i++)
+   {
+       str << "8" << endl;
+   }   
+   
+   str << endl << "CELL_DATA " << entitiesCount << endl;
+   str << "SCALARS facesFunctionValues float 1" << endl;
+   str << "LOOKUP_TABLE default" << endl;
+
+   typedef typename MeshType::Face EntityType;
+   typedef typename EntityType::EntityOrientationType EntityOrientation;
+   EntityType entity( mesh );
+   
+   entity.setOrientation( EntityOrientation( 1.0, 0.0 , 0.0) );
+   for( entity.getCoordinates().z() = 0;
+        entity.getCoordinates().z() < mesh.getDimensions().z();
+        entity.getCoordinates().z() ++ ) 
+   {
+        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();
+                 str << function.getData().getElement( entity.getIndex() ) << std::endl;      
+            }
+        }
+   }
+   
+   entity.setOrientation( EntityOrientation( 0.0, 1.0 , 0.0) );
+   for( entity.getCoordinates().z() = 0;
+        entity.getCoordinates().z() < mesh.getDimensions().z();
+        entity.getCoordinates().z() ++ ) 
+   {
+        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();
+                 str << function.getData().getElement( entity.getIndex() ) << std::endl;      
+            }
+        }
+   }
+   
+   entity.setOrientation( EntityOrientation( 0.0, 0.0 , 1.0) );
+   for( entity.getCoordinates().z() = 0;
+        entity.getCoordinates().z() <= mesh.getDimensions().z();
+        entity.getCoordinates().z() ++ ) 
+   {
+        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();
+                 str << function.getData().getElement( entity.getIndex() ) << std::endl;      
+            }
+        }
+   }
+   
+   return true;
+}
+
+/****
+ * 3D grid, edges
+ */
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+void
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 1, Real > >::
+writeHeader( const MeshFunctionType& function,
+       ostream& str )
+{ 
+    const MeshType& mesh = function.getMesh();
+    const typename MeshType::VertexType& origin = mesh.getOrigin();
+    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    str << "# vtk DataFile Version 2.0" << endl;
+    str << "TNL DATA" << endl;
+    str << "ASCII" << endl;
+    str << "DATASET UNSTRUCTURED_GRID" << endl;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 1, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{  
+   typedef typename MeshType::template MeshEntity< 1 > Edge;
+   typedef typename MeshType::template MeshEntity< 3 > Cell;
+   writeHeader(function, str);
+   
+   const MeshType& mesh = function.getMesh();
+   const RealType originX = mesh.getOrigin().x();
+   const RealType spaceStepX = mesh.getSpaceSteps().x();
+   const RealType originY = mesh.getOrigin().y();
+   const RealType spaceStepY = mesh.getSpaceSteps().y();
+   const RealType originZ = mesh.getOrigin().z();
+   const RealType spaceStepZ = mesh.getSpaceSteps().z();
+   const RealType entitiesCount = mesh.template getEntitiesCount< Edge >();
+   const RealType pointsCount = mesh.template getEntitiesCount< Cell >();
+   
+   str << "POINTS " << pointsCount << 
+          " float" << endl;
+   
+   for (int k = 0; k <= mesh.getDimensions().y(); k++)
+   {
+       for (int j = 0; j <= mesh.getDimensions().y(); j++)
+       {
+            for (int i = 0; i <= mesh.getDimensions().x(); i++)
+            {
+                 str << originX + i * spaceStepX << " " << originY + j * spaceStepY << " " << 
+                        originZ + k * spaceStepZ << endl;
+            }
+       }
+   }
+   
+   str << endl << "CELLS " << entitiesCount << " " << 
+          entitiesCount * 3 << endl;
+   for (int k = 0; k <= mesh.getDimensions().z(); k++)
+   {
+        for (int j = 0; j <= mesh.getDimensions().y(); j++)
+        {
+            for (int i = 0; i < mesh.getDimensions().x(); i++)
+            {
+                str << "3 " << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i + 1 << endl;
+            }
+        }
+   }
+   
+   for (int k = 0; k <= mesh.getDimensions().z(); k++)
+   {
+        for (int j = 0; j < mesh.getDimensions().y(); j++)
+        {
+            for (int i = 0; i <= mesh.getDimensions().x(); i++)
+            {
+                str << "3 " << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + (j+1) * ( mesh.getDimensions().x() + 1 ) + i << endl;
+            }
+        }
+   }
+   
+   for (int k = 0; k < mesh.getDimensions().z(); k++)
+   {
+        for (int j = 0; j <= mesh.getDimensions().y(); j++)
+        {
+            for (int i = 0; i <= mesh.getDimensions().x(); i++)
+            {
+                str << "3 " << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << " "
+                    << (k+1) * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i << endl;
+            }
+        }
+   }
+   
+   str << endl << "CELL_TYPES " << entitiesCount << endl;
+   for (int i = 0; i < entitiesCount; i++)
+   {
+       str << "3" << endl;
+   }   
+   
+   str << endl << "CELL_DATA " << entitiesCount << endl;
+   str << "SCALARS edgesFunctionValues float 1" << endl;
+   str << "LOOKUP_TABLE default" << endl;
+
+   typedef typename MeshType::Face EntityType;
+   typedef typename EntityType::EntityOrientationType EntityOrientation;
+   EntityType entity( mesh );
+   
+   entity.setOrientation( EntityOrientation( 1.0, 0.0 , 0.0) );
+   for( entity.getCoordinates().z() = 0;
+        entity.getCoordinates().z() <= mesh.getDimensions().z();
+        entity.getCoordinates().z() ++ ) 
+   {
+        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();
+                 str << function.getData().getElement( entity.getIndex() ) << std::endl;      
+            }
+        }
+   }
+   
+   entity.setOrientation( EntityOrientation( 0.0, 1.0 , 0.0) );
+   for( entity.getCoordinates().z() = 0;
+        entity.getCoordinates().z() <= mesh.getDimensions().z();
+        entity.getCoordinates().z() ++ ) 
+   {
+        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();
+                 str << function.getData().getElement( entity.getIndex() ) << std::endl;      
+            }
+        }
+   }
+   
+   entity.setOrientation( EntityOrientation( 0.0, 0.0 , 1.0) );
+   for( entity.getCoordinates().z() = 0;
+        entity.getCoordinates().z() < mesh.getDimensions().z();
+        entity.getCoordinates().z() ++ ) 
+   {
+        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();
+                 str << function.getData().getElement( entity.getIndex() ) << std::endl;      
+            }
+        }
+   }
+   
+   return true;
+}
+
+/****
+ * 3D grid, vertices
+ */
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+void
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 0, Real > >::
+writeHeader( const MeshFunctionType& function,
+       ostream& str )
+{ 
+    const MeshType& mesh = function.getMesh();
+    const typename MeshType::VertexType& origin = mesh.getOrigin();
+    const typename MeshType::VertexType& proportions = mesh.getProportions();
+    str << "# vtk DataFile Version 2.0" << endl;
+    str << "TNL DATA" << endl;
+    str << "ASCII" << endl;
+    str << "DATASET UNSTRUCTURED_GRID" << endl;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real >
+bool
+tnlMeshFunctionVTKWriter< tnlMeshFunction< tnlGrid< 3, MeshReal, Device, MeshIndex >, 0, Real > >::
+write( const MeshFunctionType& function,
+       ostream& str )
+{  
+   typedef typename MeshType::template MeshEntity< 0 > Vertex;
+   writeHeader(function, str);
+   
+   const MeshType& mesh = function.getMesh();
+   const RealType originX = mesh.getOrigin().x();
+   const RealType spaceStepX = mesh.getSpaceSteps().x();
+   const RealType originY = mesh.getOrigin().y();
+   const RealType spaceStepY = mesh.getSpaceSteps().y();
+   const RealType originZ = mesh.getOrigin().z();
+   const RealType spaceStepZ = mesh.getSpaceSteps().z();
+   
+   str << "POINTS " << mesh.template getEntitiesCount< Vertex >() << " float" << endl;
+   
+   for (int k = 0; k <= mesh.getDimensions().y(); k++)
+   {
+       for (int j = 0; j <= mesh.getDimensions().y(); j++)
+       {
+            for (int i = 0; i <= mesh.getDimensions().x(); i++)
+            {
+                 str << originX + i * spaceStepX << " " << originY + j * spaceStepY << " " << 
+                        originZ + k * spaceStepZ << endl;
+            }
+       }
+   }
+   
+   str << endl << "CELLS " << mesh.template getEntitiesCount< Vertex >() << " " << 
+          mesh.template getEntitiesCount< Vertex >() * 2 << endl;
+   for (int k = 0; k < ( mesh.getDimensions().z() + 1 ); k++)
+   {
+        for (int j = 0; j < ( mesh.getDimensions().y() + 1 ); j++)
+        {
+            for (int i = 0; i < ( mesh.getDimensions().x() + 1 ); i++)
+            {
+                str << "1 " << k * ( mesh.getDimensions().y() + 1 ) * ( mesh.getDimensions().x() + 1 ) + j * ( mesh.getDimensions().x() + 1 ) + i  << endl;
+            }
+        }
+   }
+   
+   str << endl << "CELL_TYPES " << mesh.template getEntitiesCount< Vertex >() << endl;
+   for (int i = 0; i < mesh.template getEntitiesCount< Vertex >(); i++)
+   {
+       str << "1" << endl;
+   }  
+   
+   str << endl << "CELL_DATA " << mesh.template getEntitiesCount< Vertex >() << endl;
+   str << "SCALARS verticesFunctionValues float 1" << endl;
+   str << "LOOKUP_TABLE default" << endl;
+
+   typename MeshType::Vertex entity( mesh );
+   for( entity.getCoordinates().z() = 0;
+        entity.getCoordinates().z() <= mesh.getDimensions().z();
+        entity.getCoordinates().z() ++ ) 
+   {
+        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();
+                 str << function.getData().getElement( entity.getIndex() ) << std::endl;      
+            }
+        }
+   }
+   
+   return true;
+}
 
diff --git a/src/functions/tnlMeshFunction_impl.h b/src/functions/tnlMeshFunction_impl.h
index 2b08d2f2927c25def185d48b1084a40299379331..505a3ce816c54b8126b8a35c2c7bfac6c4ac4cdd 100644
--- a/src/functions/tnlMeshFunction_impl.h
+++ b/src/functions/tnlMeshFunction_impl.h
@@ -133,6 +133,17 @@ setup( const tnlParameterContainer& parameters,
    return true;
 }
 
+template< typename Mesh,
+          int MeshEntityDimensions,
+          typename Real >
+void
+tnlMeshFunction< Mesh, MeshEntityDimensions, Real >::
+bind( tnlMeshFunction< Mesh, MeshEntityDimensions, Real >& meshFunction )
+{
+   this->mesh = &meshFunction.getMesh();
+   this->data.bind( meshFunction.getData() );
+}
+
 template< typename Mesh,
           int MeshEntityDimensions,
           typename Real >
diff --git a/src/functions/tnlTestFunction.h b/src/functions/tnlTestFunction.h
index 6a76aa045b70d8f51226c24decacc13cffbf45ef..e5a50dfe57288e00f444e1e4ca1da1e62abe5a96 100644
--- a/src/functions/tnlTestFunction.h
+++ b/src/functions/tnlTestFunction.h
@@ -35,17 +35,17 @@ class tnlTestFunction : public tnlDomain< FunctionDimensions, SpaceDomain >
                        expBump,
                        sinBumps,
                        sinWave,
-		       cylinder,
-		       flowerpot,
-		       twins,
-           pseudoSquare,
-           blob,
-   	   	   sdfParaboloid,
-   	   	   sdfSinWave,
-   	   	   sdfSinBumps,
-   	   	   sdfParaboloidSDF,
-   	   	   sdfSinWaveSDF,
-   	   	   sdfSinBumpsSDF};
+           		        cylinder,
+		                 flowerpot,
+		                 twins,
+                       pseudoSquare,
+                       blob,
+   	   	           sdfParaboloid,
+   	   	           sdfSinWave,
+   	   	           sdfSinBumps,
+   	   	           sdfParaboloidSDF,
+   	   	           sdfSinWaveSDF,
+   	   	           sdfSinBumpsSDF };
 
    enum TimeDependence { none,
                          linear,
diff --git a/src/functions/tnlTestFunction_impl.h b/src/functions/tnlTestFunction_impl.h
index 7dc8f3fac89e032aa6206381797ecdcab36ceae3..612fd06d188b4d72d77dd0f8d28933a44ef8ac4f 100644
--- a/src/functions/tnlTestFunction_impl.h
+++ b/src/functions/tnlTestFunction_impl.h
@@ -24,7 +24,6 @@
 #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>
@@ -35,14 +34,6 @@
 #include <functions/initial_conditions/level_set_functions/tnlBlobFunction.h>
 #include <functions/initial_conditions/level_set_functions/tnlPseudoSquareFunction.h>
 
-// For hmailton-jacobi
-#include <functions/tnlSDFParaboloid.h>
-#include <functions/tnlSDFSinBumpsFunction.h>
-#include <functions/tnlSDFSinWaveFunction.h>
-#include <functions/tnlSDFParaboloidSDF.h>
-#include <functions/tnlSDFSinBumpsFunctionSDF.h>
-#include <functions/tnlSDFSinWaveFunctionSDF.h>
-
 template< int FunctionDimensions,
           typename Real,
           typename Device >
@@ -72,12 +63,6 @@ configSetup( tnlConfigDescription& config,
       config.addEntryEnum( "twins" );
       config.addEntryEnum( "pseudoSquare" );
       config.addEntryEnum( "blob" );
-      config.addEntryEnum( "sdf-sin-wave" );
-      config.addEntryEnum( "sdf-sin-bumps" );
-      config.addEntryEnum( "sdf-sin-wave-sdf" );
-      config.addEntryEnum( "sdf-sin-bumps-sdf" );
-      config.addEntryEnum( "sdf-para" );
-      config.addEntryEnum( "sdf-para-sdf" );
    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 );
@@ -93,13 +78,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 + "offset", "Offset for paraboloids.", 1.0 );
-   config.addEntry     < double >( prefix + "coefficient", "Coefficient for paraboloids.", 1.0 );
-   config.addEntry     < double >( prefix + "x-centre", "x-centre for paraboloids.", 0.0 );
-   config.addEntry     < double >( prefix + "y-centre", "y-centre for paraboloids.", 0.0 );
-   config.addEntry     < double >( prefix + "z-centre", "z-centre for paraboloids.", 0.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     < 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" );
@@ -220,45 +200,6 @@ setup( const tnlParameterContainer& parameters,
       functionType = blob;
       return setupFunction< FunctionType >( parameters );
    }
-
-  if( testFunction == "sdf-para" )
-   {
-      typedef tnlSDFParaboloid< Dimensions, Real > FunctionType;
-      functionType = sdfParaboloid;
-      return setupFunction< FunctionType >( parameters );
-   }
-   if( testFunction == "sdf-sin-bumps" )
-   {
-      typedef tnlSDFSinBumpsFunction< Dimensions, Real > FunctionType;
-      functionType = sdfSinBumps;
-      return setupFunction< FunctionType >( parameters );
-   }
-   if( testFunction == "sdf-sin-wave" )
-   {
-      typedef tnlSDFSinWaveFunction< Dimensions, Real > FunctionType;
-      functionType = sdfSinWave;
-      return setupFunction< FunctionType >( parameters );
-   }
-   if( testFunction == "sdf-para-sdf" )
-   {
-      typedef tnlSDFParaboloidSDF< Dimensions, Real > FunctionType;
-      functionType = sdfParaboloidSDF;
-      return setupFunction< FunctionType >( parameters );
-   }
-   if( testFunction == "sdf-sin-bumps-sdf" )
-   {
-      typedef tnlSDFSinBumpsFunctionSDF< Dimensions, Real > FunctionType;
-      functionType = sdfSinBumpsSDF;
-      return setupFunction< FunctionType >( parameters );
-   }
-   if( testFunction == "sdf-sin-wave-sdf" )
-   {
-      typedef tnlSDFSinWaveFunctionSDF< Dimensions, Real > FunctionType;
-      functionType = sdfSinWaveSDF;
-      return setupFunction< FunctionType >( parameters );
-   }
-
-
    cerr << "Unknown function " << testFunction << endl;
    return false;
 }
@@ -309,25 +250,6 @@ operator = ( const tnlTestFunction& function )
       case blob:
          this->copyFunction< tnlBlobFunction< FunctionDimensions, Real > >( function.function );
          break;
-
-      case sdfParaboloid:
-         this->copyFunction< tnlSDFParaboloid< FunctionDimensions, Real > >( function.function );
-         break;
-      case sdfSinBumps:
-         this->copyFunction< tnlSDFSinBumpsFunction< FunctionDimensions, Real > >( function.function );
-         break;
-      case sdfSinWave:
-         this->copyFunction< tnlSDFSinWaveFunction< FunctionDimensions, Real > >( function.function );
-         break;
-      case sdfParaboloidSDF:
-         this->copyFunction< tnlSDFParaboloidSDF< FunctionDimensions, Real > >( function.function );
-         break;
-      case sdfSinBumpsSDF:
-         this->copyFunction< tnlSDFSinBumpsFunctionSDF< FunctionDimensions, Real > >( function.function );
-         break;
-      case sdfSinWaveSDF:
-         this->copyFunction< tnlSDFSinWaveFunctionSDF< FunctionDimensions, Real > >( function.function );
-         break;
       default:
          tnlAssert( false, );
          break;
@@ -368,50 +290,31 @@ getPartialDerivative( const VertexType& vertex,
    {
       case constant:
          return scale * ( ( tnlConstantFunction< Dimensions, Real >* ) function )->
-                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                   template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case expBump:
          return scale * ( ( tnlExpBumpFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case sinBumps:
          return scale * ( ( tnlSinBumpsFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case sinWave:
          return scale * ( ( tnlSinWaveFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case cylinder:
          return scale * ( ( tnlCylinderFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case flowerpot:
          return scale * ( ( tnlFlowerpotFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case twins:
          return scale * ( ( tnlTwinsFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case pseudoSquare:
          return scale * ( ( tnlPseudoSquareFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       case blob:
          return scale * ( ( tnlBlobFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-
-      case sdfParaboloid:
-         return scale * ( ( tnlSDFParaboloid< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfSinBumps:
-         return scale * ( ( tnlSDFSinBumpsFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfSinWave:
-         return scale * ( ( tnlSDFSinWaveFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfParaboloidSDF:
-         return scale * ( ( tnlSDFParaboloidSDF< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfSinBumpsSDF:
-         return scale * ( ( tnlSDFSinBumpsFunctionSDF< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfSinWaveSDF:
-         return scale * ( ( tnlSDFSinWaveFunctionSDF< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
+                  template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       default:
          return 0.0;
    }
@@ -479,26 +382,6 @@ getTimeDerivative( const VertexType& vertex,
          return scale * ( ( tnlBlobFunction< Dimensions, Real >* ) function )->
                   getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
          break;
-
-
-      case sdfParaboloid:
-         return scale * ( ( tnlSDFParaboloid< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfSinBumps:
-         return scale * ( ( tnlSDFSinBumpsFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfSinWave:
-         return scale * ( ( tnlSDFSinWaveFunction< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfParaboloidSDF:
-         return scale * ( ( tnlSDFParaboloidSDF< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfSinBumpsSDF:
-         return scale * ( ( tnlSDFSinBumpsFunctionSDF< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
-      case sdfSinWaveSDF:
-         return scale * ( ( tnlSDFSinWaveFunctionSDF< Dimensions, Real >* ) function )->
-                  getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time );
       default:
          return 0.0;
    }
@@ -560,22 +443,6 @@ deleteFunctions()
       case blob:
          deleteFunction< tnlBlobFunction< Dimensions, Real> >();
          break;
-
-      case sdfSinBumps:
-         deleteFunction< tnlSDFSinBumpsFunction< Dimensions, Real> >();
-         break;
-      case sdfSinWave:
-         deleteFunction< tnlSDFSinWaveFunction< Dimensions, Real> >();
-         break;
-      case sdfParaboloidSDF:
-         deleteFunction< tnlSDFParaboloidSDF< Dimensions, Real> >();
-         break;
-      case sdfSinBumpsSDF:
-         deleteFunction< tnlSDFSinBumpsFunctionSDF< Dimensions, Real> >();
-         break;
-      case sdfSinWaveSDF:
-         deleteFunction< tnlSDFSinWaveFunctionSDF< Dimensions, Real> >();
-         break;
    }
 }
 
@@ -608,17 +475,17 @@ tnlTestFunction< FunctionDimensions, Real, Device >::
 printFunction( ostream& str ) const
 {
    FunctionType* f = ( FunctionType* ) this->function;
-   switch( Device::DeviceType )
+   if( std::is_same< Device, tnlHost >::value )
    {
-      case tnlHostDevice:
-         str << *f;
-         return str;
-      case tnlCudaDevice:
-         tnlCuda::print( f, str );
-         return str;
-      default:
-         return str;
+      str << *f;
+      return str;
+   }
+   if( std::is_same< Device, tnlCuda >::value )
+   {
+      tnlCuda::print( f, str );
+      return str;
    }
+   return str;
 }
 
 template< int FunctionDimensions,
@@ -651,18 +518,6 @@ print( ostream& str ) const
          return printFunction< tnlPseudoSquareFunction< Dimensions, Real> >( str );
       case blob:
          return printFunction< tnlBlobFunction< Dimensions, Real> >( str );
-
-      case sdfSinBumps:
-         return printFunction< tnlSDFSinBumpsFunction< Dimensions, Real> >( str );
-      case sdfSinWave:
-         return printFunction< tnlSDFSinWaveFunction< Dimensions, Real> >( str );
-      case sdfParaboloidSDF:
-         return printFunction< tnlSDFParaboloidSDF< Dimensions, Real> >( str );
-      case sdfSinBumpsSDF:
-         return printFunction< tnlSDFSinBumpsFunctionSDF< Dimensions, Real> >( str );
-      case sdfSinWaveSDF:
-         return printFunction< tnlSDFSinWaveFunctionSDF< Dimensions, Real> >( str );
-
    }
    return str;
 }
diff --git a/src/legacy/benchmarks/tnlSpmvBenchmarkAdaptiveRgCSRMatrix.h b/src/legacy/benchmarks/tnlSpmvBenchmarkAdaptiveRgCSRMatrix.h
index 5d51a2723101db419640f18f9ccbc0888c26f6cb..794874d89857b3468837bcfd119512b117ce96bd 100644
--- a/src/legacy/benchmarks/tnlSpmvBenchmarkAdaptiveRgCSRMatrix.h
+++ b/src/legacy/benchmarks/tnlSpmvBenchmarkAdaptiveRgCSRMatrix.h
@@ -84,14 +84,14 @@ template< typename Real,
           typename Index>
 bool tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: setup( const tnlCSRMatrix< Real, tnlHost, Index >& matrix )
 {
-   //tnlAssert( this -> groupSize > 0, cerr << "groupSize = " << this -> groupSize );
+   //tnlAssert( this->groupSize > 0, cerr << "groupSize = " << this->groupSize );
    if( Device :: getDevice() == tnlHostDevice )
    {
-      this -> matrix. tuneFormat( desiredChunkSize, cudaBlockSize );
-      if( ! this -> matrix. copyFrom( matrix ) )
+      this->matrix. tuneFormat( desiredChunkSize, cudaBlockSize );
+      if( ! this->matrix. copyFrom( matrix ) )
          return false;
       //matrix. printOut( cout, "text", 30 );
-      //this -> matrix. printOut( cout, "text", 30 );
+      //this->matrix. printOut( cout, "text", 30 );
    }
    if( Device :: getDevice() == tnlCudaDevice )
    {
@@ -99,13 +99,13 @@ bool tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: setup( const
       tnlAdaptiveRgCSRMatrix< Real, tnlHost, Index > hostMatrix( "tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: setup : hostMatrix" );
       hostMatrix. tuneFormat( desiredChunkSize, cudaBlockSize );
       hostMatrix. copyFrom( matrix );
-      if( ! this -> matrix. copyFrom( hostMatrix ) )
+      if( ! this->matrix. copyFrom( hostMatrix ) )
          return false;
 #else
       return false;
 #endif
    }
-   this -> setupOk = true;
+   this->setupOk = true;
    return true;
 }
 
@@ -114,8 +114,8 @@ template< typename Real,
           typename Index>
 void tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: tearDown()
 {
-   //this -> matrix. setSize( 0 );
-   //this -> matrix. setNonzeroElements( 0 );
+   //this->matrix. setSize( 0 );
+   //this->matrix. setNonzeroElements( 0 );
 }
 
 template< typename Real,
@@ -123,19 +123,19 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: writeProgress() const
 {
-   cout << left << setw( this -> formatColumnWidth - 15 ) << "Adap. Row-grouped CSR ";
+   cout << left << setw( this->formatColumnWidth - 15 ) << "Adap. Row-grouped CSR ";
    if( Device :: getDevice() == tnlCudaDevice )
-      cout << setw( 5 ) << this -> desiredChunkSize
-           << setw( 10 ) << this -> cudaBlockSize;
+      cout << setw( 5 ) << this->desiredChunkSize
+           << setw( 10 ) << this->cudaBlockSize;
    else
-      cout << setw( 15 ) << this -> desiredChunkSize;
-   cout << right << setw( this -> timeColumnWidth ) << setprecision( 2 ) << this -> getTime()
-        << right << setw( this -> iterationsColumnWidth ) << this -> getIterations()
-        << right << setw( this -> gflopsColumnWidth ) << setprecision( 2 ) << this -> getGflops();
-   if( this -> getBenchmarkWasSuccesful() )
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << " OK - maxError is " << this -> maxError << ". ";
+      cout << setw( 15 ) << this->desiredChunkSize;
+   cout << right << setw( this->timeColumnWidth ) << setprecision( 2 ) << this->getTime()
+        << right << setw( this->iterationsColumnWidth ) << this->getIterations()
+        << right << setw( this->gflopsColumnWidth ) << setprecision( 2 ) << this->getGflops();
+   if( this->getBenchmarkWasSuccesful() )
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << " OK - maxError is " << this->maxError << ". ";
    else
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << "  FAILED";
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << "  FAILED";
 #ifndef HAVE_CUDA
    if( Device :: getDevice() == tnlCudaDevice )
       tnlCudaSupportMissingMessage;;
@@ -152,13 +152,13 @@ void tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: writeToLogTab
                                                                                     const tnlCSRMatrix< Real, tnlHost, Index >& csrMatrix,
                                                                                     bool writeMatrixInfo  ) const
 {
-   if( this -> getBenchmarkWasSuccesful() )
+   if( this->getBenchmarkWasSuccesful() )
    {
       tnlString bgColor="#FFFFFF";
-      double speedUp = this -> getGflops() / csrGflops;
+      double speedUp = this->getGflops() / csrGflops;
       double rgCsrSpeedUp( 0.0 );
-      if( this -> bestRgCSRGflops )
-         rgCsrSpeedUp = this -> getGflops() / this -> bestRgCSRGflops;
+      if( this->bestRgCSRGflops )
+         rgCsrSpeedUp = this->getGflops() / this->bestRgCSRGflops;
       switch( desiredChunkSize )
       {
          case 1: bgColor = "#666666"; break;
@@ -179,20 +179,20 @@ void tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: writeToLogTab
          tnlString matrixPdfFile = baseFileName + tnlString( ".pdf" );
          tnlString matrixHtmlFile = baseFileName + tnlString( ".html" );
          tnlAdaptiveRgCSRMatrix< Real > argCsrMatrix( inputMtxFile );
-         argCsrMatrix. tuneFormat( this -> desiredChunkSize,
-                                 this -> cudaBlockSize );
+         argCsrMatrix. tuneFormat( this->desiredChunkSize,
+                                 this->cudaBlockSize );
          argCsrMatrix. copyFrom( csrMatrix );
-         this -> printMatrixInHtml( matrixHtmlFile, argCsrMatrix );
+         this->printMatrixInHtml( matrixHtmlFile, argCsrMatrix );
          if( rgCsrSpeedUp > 1.0 )
             bgColor=getBgColorByRgCSRSpeedUp( rgCsrSpeedUp );
          logFile << "             <td bgcolor=" << bgColor << "> <a href=\"" << matrixPdfFile << "\">PDF</a>, <a href=\"" << matrixHtmlFile << "\">HTML</a></td> " << endl;
-         logFile << "             <td bgcolor=" << bgColor << "> " << this -> getArtificialZeroElements() << "</td>" << endl;
+         logFile << "             <td bgcolor=" << bgColor << "> " << this->getArtificialZeroElements() << "</td>" << endl;
       }
 
-      bgColor = this -> getBgColorBySpeedUp( speedUp );
+      bgColor = this->getBgColorBySpeedUp( speedUp );
       tnlString textColor = "#000000"; //getBgColorByRgCSRSpeedUp( rgCsrSpeedUp );
-      logFile << "             <td bgcolor=" << bgColor << "><font size=3 color=\"" << textColor << "\"> " << this -> getTime() << "</font></td>" << endl;
-      logFile << "             <td bgcolor=" << bgColor << "><font size=3 color=\"" << textColor << "\"> " << this -> getGflops() << "</font></td>" << endl;
+      logFile << "             <td bgcolor=" << bgColor << "><font size=3 color=\"" << textColor << "\"> " << this->getTime() << "</font></td>" << endl;
+      logFile << "             <td bgcolor=" << bgColor << "><font size=3 color=\"" << textColor << "\"> " << this->getGflops() << "</font></td>" << endl;
       logFile << "             <td bgcolor=" << bgColor << "><font size=3 color=\"" << textColor << "\"> " << speedUp << "</font></td>" << endl;
 
    }
@@ -214,7 +214,7 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: setDesiredChunkSize( const Index desiredChunkSize )
 {
-   this -> desiredChunkSize = desiredChunkSize;
+   this->desiredChunkSize = desiredChunkSize;
 }
 
 template< typename Real,
@@ -222,7 +222,7 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: setCudaBlockSize( const Index cudaBlockSize )
 {
-   this -> cudaBlockSize = cudaBlockSize;
+   this->cudaBlockSize = cudaBlockSize;
 }
 
 template< typename Real,
@@ -230,7 +230,7 @@ template< typename Real,
           typename Index >
 Index tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: getArtificialZeroElements() const
 {
-   return this -> matrix. getArtificialZeroElements();
+   return this->matrix. getArtificialZeroElements();
 }
 
 template< typename Real,
@@ -238,7 +238,7 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkAdaptiveRgCSRMatrix< Real, Device, Index > :: setBestRgCSRGflops( const double& bestRgCSRGflops )
 {
-   this -> bestRgCSRGflops = bestRgCSRGflops;
+   this->bestRgCSRGflops = bestRgCSRGflops;
 }
 
 template< typename Real,
diff --git a/src/legacy/benchmarks/tnlSpmvBenchmarkBase_impl.h b/src/legacy/benchmarks/tnlSpmvBenchmarkBase_impl.h
index dd51338e56a6ad4251de8c0a9c49060a90897ad4..cbe78d3829ec7930d40735a88dbb24e4f13fb8fa 100644
--- a/src/legacy/benchmarks/tnlSpmvBenchmarkBase_impl.h
+++ b/src/legacy/benchmarks/tnlSpmvBenchmarkBase_impl.h
@@ -41,44 +41,44 @@ tnlSpmvBenchmarkBase< Matrix >::tnlSpmvBenchmarkBase()
 template< typename  Matrix >
 bool tnlSpmvBenchmarkBase< Matrix >::getBenchmarkWasSuccesful() const
 {
-   return this -> benchmarkWasSuccesful;
+   return this->benchmarkWasSuccesful;
 }
 
 template< typename Matrix >
 double tnlSpmvBenchmarkBase< Matrix >::getGflops() const
 {
-   return this -> gflops;
+   return this->gflops;
 }
 
 template< typename Matrix >
 double tnlSpmvBenchmarkBase< Matrix >::getTime() const
 {
-   return this -> time;
+   return this->time;
 }
 
 template< typename Matrix >
 void tnlSpmvBenchmarkBase< Matrix >::setMaxIterations( const int maxIterations )
 {
-   this -> maxIterations = maxIterations;
+   this->maxIterations = maxIterations;
 }
 
 template< typename Matrix >
 int tnlSpmvBenchmarkBase< Matrix >::getIterations() const
 {
-   return this -> iterations;
+   return this->iterations;
 }
 
 
 template< typename Matrix >
 typename Matrix::IndexType tnlSpmvBenchmarkBase< Matrix >::getArtificialZeros() const
 {
-   return this -> artificialZeros;
+   return this->artificialZeros;
 }
 
 template< typename Matrix >
 typename Matrix::RealType tnlSpmvBenchmarkBase< Matrix >::getMaxError() const
 {
-   return this -> maxError;
+   return this->maxError;
 }
 
 template< typename Matrix >
@@ -114,7 +114,7 @@ void tnlSpmvBenchmarkBase< Matrix >::runBenchmark( const tnlVector< RealType, De
       iterations ++;
    }
 
-   this -> time = rt_timer. getTime();
+   this->time = rt_timer. getTime();
 
    firstErrorOccurence = 0;
    tnlVector< RealType, tnlHost, IndexType > resB( "tnlSpmvBenchmark< Real, Device, Index, Matrix > :: runBenchmark : b" );
@@ -135,7 +135,7 @@ void tnlSpmvBenchmarkBase< Matrix >::runBenchmark( const tnlVector< RealType, De
          error = ( RealType ) fabs( refB[ j ] );
       if( error > maxError )
          firstErrorOccurence = j;
-      this -> maxError = Max( this -> maxError, error );
+      this->maxError = Max( this->maxError, error );
 
       /*if( error > tnlSpmvBenchmarkPrecision( error ) )
          benchmarkWasSuccesful = false;*/
@@ -144,7 +144,7 @@ void tnlSpmvBenchmarkBase< Matrix >::runBenchmark( const tnlVector< RealType, De
    //cout << "First error was on " << firstErrorOccurence << endl;
 
    double flops = 2.0 * iterations * matrix.getNumberOfNonzeroMatrixElements();
-   this -> gflops = flops / time * 1.0e-9;
+   this->gflops = flops / time * 1.0e-9;
    artificialZeros = matrix.getNumberOfMatrixElements() - matrix.getNumberOfNonzeroMatrixElements();
 
    if( verbose )
@@ -154,20 +154,20 @@ void tnlSpmvBenchmarkBase< Matrix >::runBenchmark( const tnlVector< RealType, De
 template< typename Matrix >
 void tnlSpmvBenchmarkBase< Matrix >::writeProgressTableHeader()
 {
-   int totalWidth = this -> formatColumnWidth +
-                    this -> timeColumnWidth +
-                    this -> iterationsColumnWidth +
-                    this -> gflopsColumnWidth +
-                    this -> benchmarkStatusColumnWidth +
-                    this -> infoColumnWidth;
-
-   cout << left << setw( this -> formatColumnWidth - 5 ) << "MATRIX FORMAT"
+   int totalWidth = this->formatColumnWidth +
+                    this->timeColumnWidth +
+                    this->iterationsColumnWidth +
+                    this->gflopsColumnWidth +
+                    this->benchmarkStatusColumnWidth +
+                    this->infoColumnWidth;
+
+   cout << left << setw( this->formatColumnWidth - 5 ) << "MATRIX FORMAT"
         << left << setw( 5 ) << "BLOCK"
-        << right << setw( this -> timeColumnWidth ) << "TIME"
-        << right << setw( this -> iterationsColumnWidth ) << "ITERATIONS"
-        << right << setw( this -> gflopsColumnWidth ) << "GFLOPS"
-        << right << setw( this -> benchmarkStatusColumnWidth ) << "CHECK"
-        << left << setw(  this -> infoColumnWidth ) << " INFO" << endl
+        << right << setw( this->timeColumnWidth ) << "TIME"
+        << right << setw( this->iterationsColumnWidth ) << "ITERATIONS"
+        << right << setw( this->gflopsColumnWidth ) << "GFLOPS"
+        << right << setw( this->benchmarkStatusColumnWidth ) << "CHECK"
+        << left << setw(  this->infoColumnWidth ) << " INFO" << endl
         << setfill( '-' ) << setw( totalWidth ) << "--" << endl
         << setfill( ' ');
 }
diff --git a/src/legacy/benchmarks/tnlSpmvBenchmarkCSRMatrix.h b/src/legacy/benchmarks/tnlSpmvBenchmarkCSRMatrix.h
index a0912c1d4a7e8791a3e6d428df31cc2a13a70174..c2328ce2b2f156169402a36886bf2c8075d62f89 100644
--- a/src/legacy/benchmarks/tnlSpmvBenchmarkCSRMatrix.h
+++ b/src/legacy/benchmarks/tnlSpmvBenchmarkCSRMatrix.h
@@ -51,15 +51,15 @@ class tnlSpmvBenchmarkCSRMatrix : public tnlSpmvBenchmark< Real, tnlHost, Index,
 template< typename Real, typename Index>
 bool tnlSpmvBenchmarkCSRMatrix< Real, Index > :: setup( const tnlCSRMatrix< Real, tnlHost, Index >& matrix )
 {
-   this -> matrix = matrix;
+   this->matrix = matrix;
 
    const Index size = matrix. getSize();
    tnlVector< Real, tnlHost > refX( "ref-x", size ), refB( "ref-b", size), backwardRefB( "backwardRef-b", size);
    refX. setValue( 1.0 );
-   this -> matrix. vectorProduct( refX, refB );
-   this -> matrix. setBackwardSpMV( true );
-   this -> matrix. vectorProduct( refX, backwardRefB );
-   this -> matrix. setBackwardSpMV( false );
+   this->matrix. vectorProduct( refX, refB );
+   this->matrix. setBackwardSpMV( true );
+   this->matrix. vectorProduct( refX, backwardRefB );
+   this->matrix. setBackwardSpMV( false );
    Real error( 0.0 ), maxError( 0.0 );
    for( Index j = 0; j < refB. getSize(); j ++ )
    {
@@ -70,29 +70,29 @@ bool tnlSpmvBenchmarkCSRMatrix< Real, Index > :: setup( const tnlCSRMatrix< Real
       maxError = Max( error, maxError );
    }
    forwardBackwardDifference = maxError;
-   this -> setupOk = true;
+   this->setupOk = true;
    return true;
 }
 
 template< typename Real, typename Index>
 void tnlSpmvBenchmarkCSRMatrix< Real, Index > :: tearDown()
 {
-   this -> matrix. setSize( 0 );
+   this->matrix. setSize( 0 );
 }
 
 template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkCSRMatrix< Real, Index > :: writeProgress() const
 {
-   cout << left << setw( this -> formatColumnWidth ) << "CSR";
+   cout << left << setw( this->formatColumnWidth ) << "CSR";
    //   cout << left << setw( 25 ) << matrixFormat << setw( 5 ) << cudaBlockSize;
-   cout << right << setw( this -> timeColumnWidth ) << setprecision( 2 ) << this -> getTime()
-        << right << setw( this -> iterationsColumnWidth ) << this -> getIterations()
-        << right << setw( this -> gflopsColumnWidth ) << setprecision( 2 ) << this -> getGflops();
-   if( this -> getBenchmarkWasSuccesful() )
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << " OK - SpMV diff. " << getForwardBackwardDifference();
+   cout << right << setw( this->timeColumnWidth ) << setprecision( 2 ) << this->getTime()
+        << right << setw( this->iterationsColumnWidth ) << this->getIterations()
+        << right << setw( this->gflopsColumnWidth ) << setprecision( 2 ) << this->getGflops();
+   if( this->getBenchmarkWasSuccesful() )
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << " OK - SpMV diff. " << getForwardBackwardDifference();
    else
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << " FAILED ";
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << " FAILED ";
    cout << endl;
 }
 
@@ -104,10 +104,10 @@ void tnlSpmvBenchmarkCSRMatrix< Real, Index > :: writeToLogTable( ostream& logFi
                                                                   const tnlCSRMatrix< Real, tnlHost, Index >& csrMatrix,
                                                                   bool writeMatrixInfo  ) const
 {
-   if( this -> getBenchmarkWasSuccesful() )
+   if( this->getBenchmarkWasSuccesful() )
    {
-      logFile << "             <td> " << this -> getTime() << "</font></td>" << endl;
-      logFile << "             <td> " << this -> getGflops() << "</td>" << endl;
+      logFile << "             <td> " << this->getTime() << "</font></td>" << endl;
+      logFile << "             <td> " << this->getGflops() << "</td>" << endl;
    }
    else
    {
diff --git a/src/legacy/benchmarks/tnlSpmvBenchmarkCusparseCSRMatrix.h b/src/legacy/benchmarks/tnlSpmvBenchmarkCusparseCSRMatrix.h
index 9b952a6d889d9cbd1b9031ba416e478e52c9f87f..d3907e582877687de233b2172119e5c794f2a7aa 100644
--- a/src/legacy/benchmarks/tnlSpmvBenchmarkCusparseCSRMatrix.h
+++ b/src/legacy/benchmarks/tnlSpmvBenchmarkCusparseCSRMatrix.h
@@ -48,9 +48,9 @@ class tnlSpmvBenchmarkCusparseCSRMatrix : public tnlSpmvBenchmark< Real, tnlCuda
 template< typename Real, typename Index>
 bool tnlSpmvBenchmarkCusparseCSRMatrix< Real, Index > :: setup( const tnlCSRMatrix< Real, tnlHost, Index >& matrix )
 {
-   if( ! this -> matrix. copyFrom( matrix ) )
+   if( ! this->matrix. copyFrom( matrix ) )
       return false;
-   this -> setupOk = true;
+   this->setupOk = true;
    return true;
 }
 
@@ -58,7 +58,7 @@ template< typename Real,
           typename Index>
 void tnlSpmvBenchmarkCusparseCSRMatrix< Real, Index > :: tearDown()
 {
-   this -> matrix. reset();
+   this->matrix. reset();
 }
 
 template< typename Real,
@@ -72,15 +72,15 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkCusparseCSRMatrix< Real, Index > :: writeProgress() const
 {
-   cout << left << setw( this -> formatColumnWidth ) << "Cusparse";
+   cout << left << setw( this->formatColumnWidth ) << "Cusparse";
    //   cout << left << setw( 25 ) << matrixFormat << setw( 5 ) << cudaBlockSize;
-   cout << right << setw( this -> timeColumnWidth ) << setprecision( 2 ) << this -> getTime()
-        << right << setw( this -> iterationsColumnWidth ) << this -> getIterations()
-        << right << setw( this -> gflopsColumnWidth ) << setprecision( 2 ) << this -> getGflops();
-   if( this -> getBenchmarkWasSuccesful() )
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << "OK ";
+   cout << right << setw( this->timeColumnWidth ) << setprecision( 2 ) << this->getTime()
+        << right << setw( this->iterationsColumnWidth ) << this->getIterations()
+        << right << setw( this->gflopsColumnWidth ) << setprecision( 2 ) << this->getGflops();
+   if( this->getBenchmarkWasSuccesful() )
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << "OK ";
    else
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << "  FAILED - maxError is " << this -> maxError << ". ";
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << "  FAILED - maxError is " << this->maxError << ". ";
 #ifndef HAVE_CUSP
    cout << "CUSPARSE library is missing.";
 #endif
@@ -102,12 +102,12 @@ void tnlSpmvBenchmarkCusparseCSRMatrix< Real, Index > :: writeToLogTable( ostrea
                                                                        const tnlCSRMatrix< Real, tnlHost, Index >& csrMatrix,
                                                                        bool writeMatrixInfo  ) const
 {
-   if( this -> getBenchmarkWasSuccesful() )
+   if( this->getBenchmarkWasSuccesful() )
    {
-      double speedUp = this -> getGflops() / csrGflops;
-      tnlString bgColor = this -> getBgColorBySpeedUp( speedUp );
-      logFile << "             <td bgcolor=" << bgColor << ">" << this -> getTime() << "</td>" << endl;
-      logFile << "             <td bgcolor=" << bgColor << ">" << this -> getGflops() << "</td>" << endl;
+      double speedUp = this->getGflops() / csrGflops;
+      tnlString bgColor = this->getBgColorBySpeedUp( speedUp );
+      logFile << "             <td bgcolor=" << bgColor << ">" << this->getTime() << "</td>" << endl;
+      logFile << "             <td bgcolor=" << bgColor << ">" << this->getGflops() << "</td>" << endl;
 
       logFile << "             <td bgcolor=" << bgColor << "> " << speedUp << "</td>" << endl;
    }
diff --git a/src/legacy/benchmarks/tnlSpmvBenchmarkHybridMatrix.h b/src/legacy/benchmarks/tnlSpmvBenchmarkHybridMatrix.h
index 8dffd254eedc72d39c48991e462824127a670047..fc6f36ffbe1321dcc71b30cf171707d8fc08491d 100644
--- a/src/legacy/benchmarks/tnlSpmvBenchmarkHybridMatrix.h
+++ b/src/legacy/benchmarks/tnlSpmvBenchmarkHybridMatrix.h
@@ -63,7 +63,7 @@ class tnlSpmvBenchmarkHybridMatrix : public tnlSpmvBenchmark< Real, tnlHost, Ind
 template< typename Real, typename Index>
 void tnlSpmvBenchmarkHybridMatrix< Real, Index > :: setFileName( const tnlString& fileName )
 {
-   this -> fileName = fileName;
+   this->fileName = fileName;
 }
 
 template< typename Real, typename Index>
@@ -85,7 +85,7 @@ void tnlSpmvBenchmarkHybridMatrix< Real, Index > :: runBenchmark( const tnlVecto
                                                                   const tnlVector< Real, tnlHost, Index >& refB,
                                                                   bool verbose )
 {
-   this -> benchmarkWasSuccesful = false;
+   this->benchmarkWasSuccesful = false;
 #ifdef HAVE_CUSP
    try
    {
@@ -93,7 +93,7 @@ void tnlSpmvBenchmarkHybridMatrix< Real, Index > :: runBenchmark( const tnlVecto
       cusp::hyb_matrix< Index, Real, cusp::device_memory > A;
 
       // load a matrix stored in MatrixMarket format
-      cusp::io::read_matrix_market_file( A, this -> fileName. getString() );
+      cusp::io::read_matrix_market_file( A, this->fileName. getString() );
 
       // allocate storage for solution (x) and right hand side (b)
       cusp::array1d< Real, cusp::host_memory > host_x( A.num_rows, 1 );
@@ -108,17 +108,17 @@ void tnlSpmvBenchmarkHybridMatrix< Real, Index > :: runBenchmark( const tnlVecto
       tnlTimerRT rt_timer;
       rt_timer. Reset();
 
-      this -> iterations = 0;
+      this->iterations = 0;
       //while( rt_timer. getTime() < time )
       {
-         for( int i = 0; i < this -> maxIterations; i ++ )
+         for( int i = 0; i < this->maxIterations; i ++ )
          {
             cusp :: multiply( A, x, b );
             cudaThreadSynchronize();
-            this -> iterations ++;
+            this->iterations ++;
          }
       }
-      this -> time = rt_timer. getTime();
+      this->time = rt_timer. getTime();
 
       cusp::array1d< Real, cusp::host_memory > host_b( b );
       host_b = b;
@@ -127,18 +127,18 @@ void tnlSpmvBenchmarkHybridMatrix< Real, Index > :: runBenchmark( const tnlVecto
       {
          //f << refB[ j ] << " - " << host_b[ j ] << " = "  << refB[ j ] - host_b[ j ] <<  endl;
          if( refB[ j ] != 0.0 )
-            this -> maxError = Max( this -> maxError, ( Real ) fabs( refB[ j ] - host_b[ j ] ) /  ( Real ) fabs( refB[ j ] ) );
+            this->maxError = Max( this->maxError, ( Real ) fabs( refB[ j ] - host_b[ j ] ) /  ( Real ) fabs( refB[ j ] ) );
          else
-            this -> maxError = Max( this -> maxError, ( Real ) fabs( refB[ j ] ) );
+            this->maxError = Max( this->maxError, ( Real ) fabs( refB[ j ] ) );
       }
-      //if( this -> maxError < 1.0 )
-         this -> benchmarkWasSuccesful = true;
+      //if( this->maxError < 1.0 )
+         this->benchmarkWasSuccesful = true;
       //else
-      //   this -> benchmarkWasSuccesful = false;
+      //   this->benchmarkWasSuccesful = false;
 
 
-      double flops = 2.0 * this -> iterations * this -> nonzeroElements;
-      this -> gflops = flops / this -> time * 1.0e-9;
+      double flops = 2.0 * this->iterations * this->nonzeroElements;
+      this->gflops = flops / this->time * 1.0e-9;
 
    }
    catch( std::bad_alloc )
@@ -147,7 +147,7 @@ void tnlSpmvBenchmarkHybridMatrix< Real, Index > :: runBenchmark( const tnlVecto
       return;
    }
 #else
-   this -> benchmarkWasSuccesful = false;
+   this->benchmarkWasSuccesful = false;
 #endif
    writeProgress();
 }
@@ -156,15 +156,15 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkHybridMatrix< Real, Index > :: writeProgress() const
 {
-   cout << left << setw( this -> formatColumnWidth ) << "Hybrid";
+   cout << left << setw( this->formatColumnWidth ) << "Hybrid";
    //   cout << left << setw( 25 ) << matrixFormat << setw( 5 ) << cudaBlockSize;
-   cout << right << setw( this -> timeColumnWidth ) << setprecision( 2 ) << this -> getTime()
-        << right << setw( this -> iterationsColumnWidth ) << this -> getIterations()
-        << right << setw( this -> gflopsColumnWidth ) << setprecision( 2 ) << this -> getGflops();
-   if( this -> getBenchmarkWasSuccesful() )
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << "OK ";
+   cout << right << setw( this->timeColumnWidth ) << setprecision( 2 ) << this->getTime()
+        << right << setw( this->iterationsColumnWidth ) << this->getIterations()
+        << right << setw( this->gflopsColumnWidth ) << setprecision( 2 ) << this->getGflops();
+   if( this->getBenchmarkWasSuccesful() )
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << "OK ";
    else
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << "  FAILED - maxError is " << this -> maxError << ". ";
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << "  FAILED - maxError is " << this->maxError << ". ";
 #ifndef HAVE_CUSP
    cout << "CUSP library is missing.";
 #endif
@@ -179,12 +179,12 @@ void tnlSpmvBenchmarkHybridMatrix< Real, Index > :: writeToLogTable( ostream& lo
                                                                      const tnlCSRMatrix< Real, tnlHost, Index >& csrMatrix,
                                                                      bool writeMatrixInfo  ) const
 {
-   if( this -> getBenchmarkWasSuccesful() )
+   if( this->getBenchmarkWasSuccesful() )
    {
-      double speedUp = this -> getGflops() / csrGflops;
-      tnlString bgColor = this -> getBgColorBySpeedUp( speedUp );
-      logFile << "             <td bgcolor=" << bgColor << ">" << this -> getTime() << "</td>" << endl;
-      logFile << "             <td bgcolor=" << bgColor << ">" << this -> getGflops() << "</td>" << endl;
+      double speedUp = this->getGflops() / csrGflops;
+      tnlString bgColor = this->getBgColorBySpeedUp( speedUp );
+      logFile << "             <td bgcolor=" << bgColor << ">" << this->getTime() << "</td>" << endl;
+      logFile << "             <td bgcolor=" << bgColor << ">" << this->getGflops() << "</td>" << endl;
 
       logFile << "             <td bgcolor=" << bgColor << "> " << speedUp << "</td>" << endl;
    }
@@ -201,7 +201,7 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkHybridMatrix< Real, Index > :: setNonzeroElements( const Index nonzeroElements )
 {
-   this -> nonzeroElements = nonzeroElements;
+   this->nonzeroElements = nonzeroElements;
 }
 
 #endif /* TNLSPMVBENCHMARKHYBRIDMATRIX_H_ */
diff --git a/src/legacy/benchmarks/tnlSpmvBenchmarkRgCSRMatrix.h b/src/legacy/benchmarks/tnlSpmvBenchmarkRgCSRMatrix.h
index 5209fededda3b0bd79bf46a5b30c421318d1e5a1..8dd3d85b83e4e59d37cde56eb4ff46a9f051a614 100644
--- a/src/legacy/benchmarks/tnlSpmvBenchmarkRgCSRMatrix.h
+++ b/src/legacy/benchmarks/tnlSpmvBenchmarkRgCSRMatrix.h
@@ -76,13 +76,13 @@ template< typename Real,
           typename Index>
 bool tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: setup( const tnlCSRMatrix< Real, tnlHost, Index >& csrMatrix )
 {
-   tnlAssert( this -> groupSize > 0, cerr << "groupSize = " << this -> groupSize );
+   tnlAssert( this->groupSize > 0, cerr << "groupSize = " << this->groupSize );
    if( Device :: getDevice() == tnlHostDevice )
    {
-      this -> matrix. tuneFormat( groupSize,
-                                  this -> useAdaptiveGroupSize,
-                                  this -> adaptiveGroupSizeStrategy );
-      if( ! this -> matrix. copyFrom( csrMatrix ) )
+      this->matrix. tuneFormat( groupSize,
+                                  this->useAdaptiveGroupSize,
+                                  this->adaptiveGroupSizeStrategy );
+      if( ! this->matrix. copyFrom( csrMatrix ) )
          return false;
    }
    if( Device :: getDevice() == tnlCudaDevice )
@@ -90,16 +90,16 @@ bool tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: setup( const tnlCSRMa
 #ifdef HAVE_CUDA
       tnlRgCSRMatrix< Real, tnlHost, Index > hostMatrix( "tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: setup : hostMatrix" );
       hostMatrix. tuneFormat( groupSize,
-                              this -> useAdaptiveGroupSize,
-                              this -> adaptiveGroupSizeStrategy );
+                              this->useAdaptiveGroupSize,
+                              this->adaptiveGroupSizeStrategy );
       hostMatrix. copyFrom( csrMatrix );
-      if( ! this -> matrix. copyFrom( hostMatrix ) )
+      if( ! this->matrix. copyFrom( hostMatrix ) )
          return false;
 #else
       return false;
 #endif
    }
-   this -> setupOk = true;
+   this->setupOk = true;
    return true;
 }
 
@@ -108,7 +108,7 @@ template< typename Real,
           typename Index>
 void tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: tearDown()
 {
-   this -> matrix. reset();
+   this->matrix. reset();
 }
 
 template< typename Real,
@@ -116,29 +116,29 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: writeProgress() const
 {
-   cout << left << setw( this -> formatColumnWidth - 15 ) << "Row-grouped CSR ";
+   cout << left << setw( this->formatColumnWidth - 15 ) << "Row-grouped CSR ";
    if( Device :: getDevice() == tnlCudaDevice )
    {
       if( useAdaptiveGroupSize )
          cout << setw( 5 ) << "Var.";
       else
-         cout << setw( 5 ) << this -> groupSize;
-      cout << setw( 10 ) << this -> cudaBlockSize;
+         cout << setw( 5 ) << this->groupSize;
+      cout << setw( 10 ) << this->cudaBlockSize;
    }
    else
    {
       if( useAdaptiveGroupSize )
          cout << setw( 15 ) << "Var.";
       else
-         cout << setw( 15 ) << this -> groupSize;
+         cout << setw( 15 ) << this->groupSize;
    }
-   cout << right << setw( this -> timeColumnWidth ) << setprecision( 2 ) << this -> getTime()
-        << right << setw( this -> iterationsColumnWidth ) << this -> getIterations()
-        << right << setw( this -> gflopsColumnWidth ) << setprecision( 2 ) << this -> getGflops();
-   if( this -> getBenchmarkWasSuccesful() )
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << "  OK  - maxError is " << this -> maxError << ". ";
+   cout << right << setw( this->timeColumnWidth ) << setprecision( 2 ) << this->getTime()
+        << right << setw( this->iterationsColumnWidth ) << this->getIterations()
+        << right << setw( this->gflopsColumnWidth ) << setprecision( 2 ) << this->getGflops();
+   if( this->getBenchmarkWasSuccesful() )
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << "  OK  - maxError is " << this->maxError << ". ";
    else
-        cout << right << setw( this -> benchmarkStatusColumnWidth ) << "  FAILED - maxError is " << this -> maxError << ". ";
+        cout << right << setw( this->benchmarkStatusColumnWidth ) << "  FAILED - maxError is " << this->maxError << ". ";
 #ifndef HAVE_CUDA
    if( Device :: getDevice() == tnlCudaDevice )
       tnlCudaSupportMissingMessage;;
@@ -151,7 +151,7 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: setGroupSize( const Index groupSize )
 {
-   this -> groupSize = groupSize;
+   this->groupSize = groupSize;
 }
 
 template< typename Real,
@@ -159,8 +159,8 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: setCudaBlockSize( const Index cudaBlockSize )
 {
-   this -> matrix. setCUDABlockSize( cudaBlockSize );
-   this -> cudaBlockSize = cudaBlockSize;
+   this->matrix. setCUDABlockSize( cudaBlockSize );
+   this->cudaBlockSize = cudaBlockSize;
 }
 
 template< typename Real,
@@ -168,7 +168,7 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: setUseAdaptiveGroupSize( bool useAdaptiveGroupSize )
 {
-   this -> useAdaptiveGroupSize = useAdaptiveGroupSize;
+   this->useAdaptiveGroupSize = useAdaptiveGroupSize;
 }
 
 template< typename Real,
@@ -176,7 +176,7 @@ template< typename Real,
           typename Index >
 void tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: setAdaptiveGroupSizeStrategy( tnlAdaptiveGroupSizeStrategy adaptiveGroupSizeStrategy )
 {
-   this -> adaptiveGroupSizeStrategy = adaptiveGroupSizeStrategy;
+   this->adaptiveGroupSizeStrategy = adaptiveGroupSizeStrategy;
 }
 
 template< typename Real,
@@ -184,7 +184,7 @@ template< typename Real,
           typename Index >
 Index tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: getArtificialZeroElements() const
 {
-   return this -> matrix. getArtificialZeroElements();
+   return this->matrix. getArtificialZeroElements();
 }
 
 template< typename Real,
@@ -214,20 +214,20 @@ void tnlSpmvBenchmarkRgCSRMatrix< Real, Device, Index > :: writeToLogTable( ostr
       tnlString matrixHtmlFile( baseFileName );
       matrixHtmlFile += tnlString( ".html" );
       tnlRgCSRMatrix< Real > rgCsrMatrix( inputMtxFile );
-      rgCsrMatrix. tuneFormat( this -> groupSize,
-                               this -> useAdaptiveGroupSize,
-                               this -> adaptiveGroupSizeStrategy );
+      rgCsrMatrix. tuneFormat( this->groupSize,
+                               this->useAdaptiveGroupSize,
+                               this->adaptiveGroupSizeStrategy );
       rgCsrMatrix. copyFrom( csrMatrix );
-      this -> printMatrixInHtml( matrixHtmlFile, rgCsrMatrix );
+      this->printMatrixInHtml( matrixHtmlFile, rgCsrMatrix );
       logFile << "             <td bgcolor=" << bgColor << "> <a href=\"" << matrixPdfFile << "\">PDF</a>,<a href=\"" << matrixHtmlFile << "\"> HTML</a></td>" << endl;
-      logFile << "             <td bgcolor=" << bgColor << "> " << this -> getArtificialZeroElements() << "</td>" << endl;
+      logFile << "             <td bgcolor=" << bgColor << "> " << this->getArtificialZeroElements() << "</td>" << endl;
    }
-   if( this -> getBenchmarkWasSuccesful() )
+   if( this->getBenchmarkWasSuccesful() )
    {
-      const double speedUp = this -> getGflops() / csrGflops;
-      bgColor =  this -> getBgColorBySpeedUp( speedUp );
-      logFile << "             <td bgcolor=" << bgColor << ">" << this -> getTime() << "</td>" << endl;
-      logFile << "             <td bgcolor=" << bgColor << "> " << this -> getGflops() << "</td>" << endl;
+      const double speedUp = this->getGflops() / csrGflops;
+      bgColor =  this->getBgColorBySpeedUp( speedUp );
+      logFile << "             <td bgcolor=" << bgColor << ">" << this->getTime() << "</td>" << endl;
+      logFile << "             <td bgcolor=" << bgColor << "> " << this->getGflops() << "</td>" << endl;
       logFile << "             <td bgcolor=" << bgColor << "> " << speedUp << "</td>" << endl;
    }
    else
diff --git a/src/legacy/matrices/tnlAdaptiveRgCSRMatrix.h b/src/legacy/matrices/tnlAdaptiveRgCSRMatrix.h
index 0f9e338bbac4cdd203916165435b7d17a411a98d..ac14fc2576462d6831915b6ac90ea4ff2b13e51c 100644
--- a/src/legacy/matrices/tnlAdaptiveRgCSRMatrix.h
+++ b/src/legacy/matrices/tnlAdaptiveRgCSRMatrix.h
@@ -250,10 +250,10 @@ template< typename Real, typename Device, typename Index >
 bool tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: setSize( Index newSize )
 {
    tnlAssert( newSize > 0, cerr << "newSize = " << newSize );
-   this -> size = newSize;
-   if( ! groupInfo. setSize( this -> getSize() ) ||
-       ! threads. setSize( this -> getSize() ) ||
-       ! rowToGroupMapping. setSize( this -> getSize() ) )
+   this->size = newSize;
+   if( ! groupInfo. setSize( this->getSize() ) ||
+       ! threads. setSize( this->getSize() ) ||
+       ! rowToGroupMapping. setSize( this->getSize() ) )
       return false;
    threads. setValue( 0 );
    rowToGroupMapping. setValue( 0 );
@@ -308,15 +308,15 @@ template< typename Real, typename Device, typename Index >
 void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: tuneFormat( const Index desiredChunkSize,
                                                                   const Index cudaBlockSize )
 {
-   this -> desiredChunkSize = desiredChunkSize;
-   this -> cudaBlockSize = cudaBlockSize;
+   this->desiredChunkSize = desiredChunkSize;
+   this->cudaBlockSize = cudaBlockSize;
 }
 
 template< typename Real, typename Device, typename Index >
 Index tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: getFirstThreadInRow( const Index row, const Index groupId ) const
 {
    dbgFunctionName( "tnlAdaptiveRgCSRMatrix< Real, tnlHost >", "getFirstThreadInRow" );
-   tnlAssert( row >= 0 && row < this -> getSize(), cerr << " row = " << row << " size = " << this -> getSize() );
+   tnlAssert( row >= 0 && row < this->getSize(), cerr << " row = " << row << " size = " << this->getSize() );
    //dbgExpr( row );
    //dbgExpr( groupInfo[ groupId ]. firstRow );
    if( row == groupInfo[ groupId ]. firstRow )
@@ -327,7 +327,7 @@ Index tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: getFirstThreadInRow( cons
 template< typename Real, typename Device, typename Index >
 Index tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: getLastThreadInRow( const Index row, const Index groupId ) const
 {
-   tnlAssert( row >= 0 && row < this -> getSize(), cerr << " row = " << row << " size = " << this -> getSize() );
+   tnlAssert( row >= 0 && row < this->getSize(), cerr << " row = " << row << " size = " << this->getSize() );
    return threads. getElement( row );
 }
 
@@ -335,7 +335,7 @@ template< typename Real, typename Device, typename Index >
 bool tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatrix< Real, tnlHost, Index >& csrMatrix )
 {
   dbgFunctionName( "tnlAdaptiveRgCSRMatrix< Real, tnlHost >", "copyFrom" );
-  if( ! this -> setSize( csrMatrix. getSize() ) )
+  if( ! this->setSize( csrMatrix. getSize() ) )
           return false;
   
   if( Device :: getDevice() == tnlHostDevice )
@@ -360,14 +360,14 @@ bool tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatr
           * First compute the group size such that the number of the non-zero elements in each group is
           * approximately the same.
           */
-         groupEnd += this -> groupSizeStep;
-         groupEnd = Min( groupEnd, this -> getSize() );
+         groupEnd += this->groupSizeStep;
+         groupEnd = Min( groupEnd, this->getSize() );
 
          nonzerosInGroup = csrMatrix. row_offsets[ groupEnd ] - csrMatrix. row_offsets[ groupBegin ];
          rowsInGroup = groupEnd - groupBegin;
 
          if( nonzerosInGroup < cudaBlockSize * desiredChunkSize &&
-             groupEnd < this -> getSize() &&
+             groupEnd < this->getSize() &&
              rowsInGroup < cudaBlockSize )
             continue;
 
@@ -466,7 +466,7 @@ bool tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatr
          numberOfStoredValues += cudaBlockSize * maxChunkSize;
          groupBegin = groupEnd;
 
-         if( groupBegin == this -> getSize() )
+         if( groupBegin == this->getSize() )
          {
             numberOfGroups = groupId;
             break;
@@ -505,13 +505,13 @@ bool tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatr
             const Index matrixRow = groupRow + baseRow;
             dbgCout( "Row = " << matrixRow <<
                      " group row = " << groupRow <<
-                     " firstThreadInRow = " << this -> getFirstThreadInRow( matrixRow, groupId ) <<
-                     " lastThreadInRow = " << this -> getLastThreadInRow( matrixRow, groupId ) <<
+                     " firstThreadInRow = " << this->getFirstThreadInRow( matrixRow, groupId ) <<
+                     " lastThreadInRow = " << this->getLastThreadInRow( matrixRow, groupId ) <<
                      " inserting offset = " << index );
             Index pos = csrMatrix. row_offsets[ matrixRow ];
             Index rowCounter( 0 );
-            for( Index thread = this -> getFirstThreadInRow( matrixRow, groupId );
-                 thread < this -> getLastThreadInRow( matrixRow, groupId );
+            for( Index thread = this->getFirstThreadInRow( matrixRow, groupId );
+                 thread < this->getLastThreadInRow( matrixRow, groupId );
                  thread ++ )
             {
                Index insertPosition = groupInfo[ groupId ]. offset + thread;
@@ -546,11 +546,11 @@ bool tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatr
             {
                const Index matrixRow = groupRow + baseRow;
                dbgCout( "group row = " << row <<
-                        " firstThreadInRow = " << this -> getFirstThreadInRow( matrixRow, groupId ) <<
-                        " lastThreadInRow = " << this -> getLastThreadInRow( matrixRow, groupId ) <<
+                        " firstThreadInRow = " << this->getFirstThreadInRow( matrixRow, groupId ) <<
+                        " lastThreadInRow = " << this->getLastThreadInRow( matrixRow, groupId ) <<
                         " inserting offset = " << index );
-               for( Index thread = this -> getFirstThreadInRow( matrixRow, groupId );
-                    thread < this -> getLastThreadInRow( matrixRow, groupId );
+               for( Index thread = this->getFirstThreadInRow( matrixRow, groupId );
+                    thread < this->getLastThreadInRow( matrixRow, groupId );
                     thread ++ )
                {
                   tnlAssert( index < numberOfStoredValues, cerr << "Index = " << index << " numberOfStoredValues = " << numberOfStoredValues );
@@ -597,7 +597,7 @@ bool tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlAdaptiv
    numberOfGroups = adaptiveRgCSRMatrix. numberOfGroups;
   
 
-   if( ! this -> setSize( adaptiveRgCSRMatrix. getSize() ) )
+   if( ! this->setSize( adaptiveRgCSRMatrix. getSize() ) )
       return false;   
 
    /****
@@ -624,7 +624,7 @@ Real tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: getElement( Index row,
                                                                   Index column ) const
 {
    dbgFunctionName( "tnlAdaptiveRgCSRMatrix< Real, tnlHost >", "getElement" );
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
               cerr << "The row is outside the matrix." );
    if( Device :: getDevice() == tnlHostDevice )
    {
@@ -637,10 +637,10 @@ Real tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: getElement( Index row,
          for( Index currentRow = firstRow; currentRow < lastRow; currentRow ++ )
          {
             if( currentRow != row )
-               pointer += this -> getLastThreadInRow( currentRow, groupId ) - this -> getFirstThreadInRow( currentRow, groupId );
+               pointer += this->getLastThreadInRow( currentRow, groupId ) - this->getFirstThreadInRow( currentRow, groupId );
             else
-               for( Index i = this -> getFirstThreadInRow( currentRow, groupId );
-                    i < this -> getLastThreadInRow( currentRow, groupId );
+               for( Index i = this->getFirstThreadInRow( currentRow, groupId );
+                    i < this->getLastThreadInRow( currentRow, groupId );
                     i ++ )
                {
                   if( columns[ pointer ] == column )
@@ -665,20 +665,20 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVe
                                                                      tnlVector< Real, Device, Index >& result ) const
 {
    dbgFunctionName( "tnlAdaptiveRgCSRMatrix< Real, tnlHost >", "vectorProduct" )
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
-   tnlAssert( result. getSize() == this -> getSize(),
+   tnlAssert( result. getSize() == this->getSize(),
               cerr << "The matrix and result vector of a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
 
    if( Device :: getDevice() == tnlHostDevice )
    {
 
       Real partialSums[ 256 ];
-      const Index blockDim = this -> getCUDABlockSize();
+      const Index blockDim = this->getCUDABlockSize();
       for( Index bId = 0; bId < numberOfGroups; bId ++ )
       //for( Index bId = 0; bId < 1; bId ++ )
       {
@@ -730,9 +730,9 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVe
                   continue;
                Index rowCounter( 0 ), chunkCounter( firstChunk );
                Real partialSum( 0.0 );
-               for( Index j = 0; j < this -> getSize(); j ++)
+               for( Index j = 0; j < this->getSize(); j ++)
                {
-                  const Real val = this -> getElement( row, j );
+                  const Real val = this->getElement( row, j );
                   if( val != 0 )
                   {
                      if( row == 2265 )
@@ -784,8 +784,8 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVe
                 * Check the result with the method getElement
                 */
                Real checkSum( 0.0 );
-               for( Index i = 0; i < this -> getSize(); i ++ )
-                  checkSum += this -> getElement( row, i );// * vec[ i ];
+               for( Index i = 0; i < this->getSize(); i ++ )
+                  checkSum += this->getElement( row, i );// * vec[ i ];
 
                if( checkSum != sum )
                {
@@ -808,8 +808,8 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVe
       /****
        * Go over all groups ...
        */
-      dbgExpr( this -> numberOfGroups );
-      for( Index groupId = 0; groupId < this -> numberOfGroups; groupId ++ )
+      dbgExpr( this->numberOfGroups );
+      for( Index groupId = 0; groupId < this->numberOfGroups; groupId ++ )
       {
          /****
           * In each group compute partial sums of each thread
@@ -817,14 +817,14 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVe
          dbgExpr( groupId );
          for( Index thread = 0; thread < cudaBlockSize; thread ++ )
          {
-            idx[ thread ] = this -> groupInfo[ groupId ]. offset + thread;
+            idx[ thread ] = this->groupInfo[ groupId ]. offset + thread;
             psum[ thread ] = 0;
             for( Index chunkOffset = 0;
-                 chunkOffset < this -> groupInfo[ groupId ]. chunkSize;
+                 chunkOffset < this->groupInfo[ groupId ]. chunkSize;
                  chunkOffset ++ )
             {
-               if( this -> columns[ idx[ thread ] ] != -1  )
-                  psum[ thread ] += this -> nonzeroElements[ idx[ thread ] ] * vec[ this -> columns[ idx[ thread ] ] ];
+               if( this->columns[ idx[ thread ] ] != -1  )
+                  psum[ thread ] += this->nonzeroElements[ idx[ thread ] ] * vec[ this->columns[ idx[ thread ] ] ];
                idx[ thread ] += cudaBlockSize;
             }
             dbgExpr( psum[ thread ] );
@@ -837,10 +837,10 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVe
               row < groupInfo[ groupId ]. firstRow + groupInfo[ groupId ]. size;
               row ++ )
          {
-            dbgCout( "Row: " << row << " firstThreadInRow: " << this -> getFirstThreadInRow( row, groupId ) << " lastThreadInRow: " << this -> getLastThreadInRow( row, groupId ) );
+            dbgCout( "Row: " << row << " firstThreadInRow: " << this->getFirstThreadInRow( row, groupId ) << " lastThreadInRow: " << this->getLastThreadInRow( row, groupId ) );
             result[ row ] = 0.0;
-            for( Index thread = this -> getFirstThreadInRow( row, groupId );
-                 thread < this -> getLastThreadInRow( row, groupId );
+            for( Index thread = this->getFirstThreadInRow( row, groupId );
+                 thread < this->getLastThreadInRow( row, groupId );
                  thread ++ )
             {
                result[ row ] += psum[ thread ];
@@ -853,11 +853,11 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVe
    if( Device :: getDevice() == tnlCudaDevice )
    {
 #ifdef HAVE_CUDA
-   Index blockSize = this -> getCUDABlockSize();
-   const Index size = this -> getSize();
+   Index blockSize = this->getCUDABlockSize();
+   const Index size = this->getSize();
 
    Index desGridSize;
-	desGridSize = this -> numberOfGroups;
+	desGridSize = this->numberOfGroups;
 	//desGridSize = (desGridSize < 4096) ? desGridSize : 4096;
 
    cudaThreadSynchronize();
@@ -907,16 +907,16 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: printOutGroup( ostream& st
    Index groupBaseRow = groupInfo[ groupId ]. firstRow;
    for( Index row = firstRow; row < lastRow; row ++ )
    {
-      Index firstThread = this -> getFirstThreadInRow( row, groupId );
-      Index lastThread = this -> getLastThreadInRow( row, groupId );
+      Index firstThread = this->getFirstThreadInRow( row, groupId );
+      Index lastThread = this->getLastThreadInRow( row, groupId );
       str << " Row number: " << row << " Threads: " << firstThread << " -- " << lastThread << endl;
       for( Index thread = firstThread; thread < lastThread; thread ++ )
       {
-         Index threadOffset = this -> groupInfo[ groupId ]. offset + thread;
+         Index threadOffset = this->groupInfo[ groupId ]. offset + thread;
          str << "  Thread: " << thread << " Thread Offset: " << threadOffset << " Chunk: ";
          for( Index i = 0; i < groupInfo[ groupId ]. chunkSize; i ++ )
-            str << this -> nonzeroElements[ threadOffset + i * cudaBlockSize ] << "["
-                << this -> columns[ threadOffset + i * cudaBlockSize ] << "], ";
+            str << this->nonzeroElements[ threadOffset + i * cudaBlockSize ] << "["
+                << this->columns[ threadOffset + i * cudaBlockSize ] << "], ";
          str << endl;
       }
       str << endl;
@@ -934,13 +934,13 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: printOut( ostream& str,
    {
       str << "Structure of tnlAdaptiveRgCSRMatrix" << endl;
       str << "Matrix name:" << name << endl;
-      str << "Matrix size:" << this -> getSize() << endl;
+      str << "Matrix size:" << this->getSize() << endl;
       str << "Allocated elements:" << nonzeroElements. getSize() << endl;
       str << "Number of groups: " << numberOfGroups << endl;
 
       Index print_lines = lines;
       if( ! print_lines )
-         print_lines = this -> getSize();
+         print_lines = this->getSize();
 
       for( Index groupId = 0; groupId < numberOfGroups; groupId ++ )
       {
@@ -956,26 +956,26 @@ void tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: printOut( ostream& str,
    {
       str << "<h1>Structure of tnlAdaptiveRgCSRMatrix</h1>" << endl;
       str << "<b>Matrix name:</b> " << name << "<p>" << endl;
-      str << "<b>Matrix size:</b> " << this -> getSize() << "<p>" << endl;
+      str << "<b>Matrix size:</b> " << this->getSize() << "<p>" << endl;
       str << "<b>Allocated elements:</b> " << nonzeroElements. getSize() << "<p>" << endl;
-      str << "<b>Number of groups:</b> " << this -> numberOfGroups << "<p>" << endl;
+      str << "<b>Number of groups:</b> " << this->numberOfGroups << "<p>" << endl;
       str << "<table border=1>" << endl;
       str << "<tr> <td> <b> GroupId </b> </td> <td> <b> Size </b> </td> <td> <b> Chunk size </b> </td> <td> <b> % of nonzeros </b> </td> </tr>" << endl;
       Index print_lines = lines;
       if( ! print_lines )
-         print_lines = this -> getSize();
+         print_lines = this->getSize();
 
-      Index minGroupSize( this -> getSize() );
+      Index minGroupSize( this->getSize() );
       Index maxGroupSize( 0 );
-      for( Index i = 0; i < this -> numberOfGroups; i ++ )
+      for( Index i = 0; i < this->numberOfGroups; i ++ )
       {
-         const Index groupSize = this -> groupInfo. getElement( i ). size;
+         const Index groupSize = this->groupInfo. getElement( i ). size;
          minGroupSize = Min( groupSize, minGroupSize );
          maxGroupSize = Max( groupSize, maxGroupSize );
-         const Index chunkSize = this -> groupInfo. getElement( i ). chunkSize;
-         const Index allElements = chunkSize * this -> cudaBlockSize;
+         const Index chunkSize = this->groupInfo. getElement( i ). chunkSize;
+         const Index allElements = chunkSize * this->cudaBlockSize;
          double filling = ( double ) ( allElements ) /
-                          ( double ) this -> nonzeroElements. getSize();
+                          ( double ) this->nonzeroElements. getSize();
          str << "<tr> <td> " << i
             << "</td> <td> " << groupSize
             << "</td> <td> " << chunkSize
@@ -1005,32 +1005,32 @@ bool tnlAdaptiveRgCSRMatrix< Real, Device, Index > :: draw( ostream& str,
    if( format == "eps" )
    {
       const int elementSize = 10;
-      this -> writePostscriptHeader( str, elementSize );
+      this->writePostscriptHeader( str, elementSize );
 
       /****
        * Draw the groups
        */
       for( Index groupId = 0; groupId < numberOfGroups; groupId ++ )
       {
-         const Index groupSize = this -> groupInfo. getElement( groupId ). size;
+         const Index groupSize = this->groupInfo. getElement( groupId ). size;
          if( groupId % 2 == 0 )
             str << "0.9 0.9 0.9 setrgbcolor" << endl;
          else
             str << "0.8 0.8 0.8 setrgbcolor" << endl;
          str << "0 -" << groupSize * elementSize
-             << " translate newpath 0 0 " << this -> getSize() * elementSize
+             << " translate newpath 0 0 " << this->getSize() * elementSize
              << " " << groupSize * elementSize << " rectfill" << endl;
       }
       /****
        * Restore black color and the origin of the coordinates
        */
       str << "0 0 0 setrgbcolor" << endl;
-      str << "0 " << this -> getSize() * elementSize << " translate" << endl;
+      str << "0 " << this->getSize() * elementSize << " translate" << endl;
 
       if( csrMatrix )
          csrMatrix -> writePostscriptBody( str, elementSize, verbose );
       else
-         this -> writePostscriptBody( str, elementSize, verbose );
+         this->writePostscriptBody( str, elementSize, verbose );
 
 
       str << "showpage" << endl;
diff --git a/src/legacy/matrices/tnlCSRMatrix.h b/src/legacy/matrices/tnlCSRMatrix.h
index b59f0e31397a5eda5f261c05575db22f84cf04f2..73e3d9f2e665a56fe0155e05f35246c0ada346f0 100644
--- a/src/legacy/matrices/tnlCSRMatrix.h
+++ b/src/legacy/matrices/tnlCSRMatrix.h
@@ -269,8 +269,8 @@ tnlString tnlCSRMatrix< Real, Device, Index > :: getType() const
 template< typename Real, typename Device, typename Index >
 bool tnlCSRMatrix< Real, Device, Index > :: setSize( Index new_size )
 {
-   this -> size = new_size;
-   if( ! row_offsets. setSize( this -> size + 1 ) )
+   this->size = new_size;
+   if( ! row_offsets. setSize( this->size + 1 ) )
       return false;
    row_offsets. setValue( 0 );
    last_nonzero_element = 0;
@@ -283,7 +283,7 @@ bool tnlCSRMatrix< Real, Device, Index > :: setLike( const tnlCSRMatrix< Real, D
    dbgFunctionName( "tnlCSRMatrix< Real, Device, Index >", "setLike" );
    dbgCout( "Setting size to " << matrix. getSize() << "." );
 
-   this -> size = matrix. getSize();
+   this->size = matrix. getSize();
    if( ! nonzero_elements. setLike( matrix. nonzero_elements ) ||
        ! columns. setLike( matrix. columns ) ||
        ! row_offsets. setLike( matrix. row_offsets ) )
@@ -323,8 +323,8 @@ Index tnlCSRMatrix< Real, Device, Index > :: getNonzeroElements() const
 template< typename Real, typename Device, typename Index >
 Index tnlCSRMatrix< Real, Device, Index > :: getNonzeroElementsInRow( const Index& row ) const
 {
-   tnlAssert( row >= 0 && row < this -> getSize(),
-              cerr << "row = " << row << " this -> getSize() = " << this -> getSize() );
+   tnlAssert( row >= 0 && row < this->getSize(),
+              cerr << "row = " << row << " this->getSize() = " << this->getSize() );
    return row_offsets[ row + 1 ] - row_offsets[ row ];
 }
 
@@ -340,7 +340,7 @@ Index tnlCSRMatrix< Real, Device, Index > :: checkNonzeroElements() const
 template< typename Real, typename Device, typename Index >
 Index tnlCSRMatrix< Real, Device, Index > :: getRowLength( const Index row ) const
 {
-	tnlAssert( row >= 0 && row < this -> getSize(), );
+	tnlAssert( row >= 0 && row < this->getSize(), );
 	return row_offsets[ row + 1 ] - row_offsets[ row ];
 }
 
@@ -390,7 +390,7 @@ bool tnlCSRMatrix< Real, Device, Index > :: shiftElements( Index position,
       }
    }
    last_nonzero_element += shift;
-   for( Index i = row + 1; i <= this -> size; i ++ )
+   for( Index i = row + 1; i <= this->size; i ++ )
       if( row_offsets[ i ] >= position )
       {
          row_offsets[ i ] += shift;
@@ -412,13 +412,13 @@ bool tnlCSRMatrix< Real, Device, Index > :: insertRow( Index row,
                                                        Index* offsets )
 {
    dbgFunctionName( "tnlCSRMatrix< Real, Device, Index >", "insertRow" )
-   tnlAssert( row >=0 && row < this -> getSize(),
+   tnlAssert( row >=0 && row < this->getSize(),
               cerr << "The row " << row << " is out of the matrix." );
    tnlAssert( elements > 0,
               cerr << "The number of elements to insert is negative:" << elements << "." );
    tnlAssert( data != NULL,
               cerr << "Null pointer passed as data for the inserted row." );
-   tnlAssert( first_column >=0 &&  first_column < this -> getSize(),
+   tnlAssert( first_column >=0 &&  first_column < this->getSize(),
               cerr << "first_column is out of the matrix" );
    tnlAssert( offsets != NULL,
               cerr << "Null pointer passed as data for the column offsets." );
@@ -437,7 +437,7 @@ bool tnlCSRMatrix< Real, Device, Index > :: insertRow( Index row,
    /*
     * And now those which have column larger then size - 1
     */
-   while( elements > 0 && first_column + offsets[ elements - 1 ] >= this -> size )
+   while( elements > 0 && first_column + offsets[ elements - 1 ] >= this->size )
    {
 	   elements --;
 	   dbgCout( "Decreasing elements to " << elements << "." );
@@ -474,9 +474,9 @@ template< typename Real, typename Device, typename Index >
 Index tnlCSRMatrix< Real, Device, Index > :: getElementPosition( Index row,
                                                                   Index column ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
               cerr << "The row is outside the matrix." );
-   tnlAssert( 0 <= column && column < this -> getSize(),
+   tnlAssert( 0 <= column && column < this->getSize(),
               cerr << "The column is outside the matrix." );
    Index first_in_row = row_offsets[ row ];
    Index last_in_row = row_offsets[ row + 1 ];
@@ -554,11 +554,11 @@ template< typename Real, typename Device, typename Index >
 Real tnlCSRMatrix< Real, Device, Index > :: rowProduct( Index row,
                                                          const tnlVector< Real, Device, Index >& vec ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
               cerr << "The row is outside the matrix." );
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
    Index i = row_offsets[ row ];
    Index last_in_row = row_offsets[ row + 1 ];
@@ -580,13 +580,13 @@ template< typename Real,
 void tnlCSRMatrix< Real, Device, Index > :: vectorProduct( const Vector1& vec,
                                                            Vector2& result ) const
 {
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
-   tnlAssert( result. getSize() == this -> getSize(),
+   tnlAssert( result. getSize() == this->getSize(),
               cerr << "The matrix and result vector of a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << result. getSize() << endl; );
 
    const Index* cols = columns. getData();
@@ -598,7 +598,7 @@ void tnlCSRMatrix< Real, Device, Index > :: vectorProduct( const Vector1& vec,
 //#ifdef HAVE_OPENMP
 //#pragma omp parallel for
 //#endif
-      for( Index row = 0; row < this -> size; row ++ )
+      for( Index row = 0; row < this->size; row ++ )
       {
          Real product( 0.0 );
          Index i = rw_offsets[ row ];
@@ -616,7 +616,7 @@ void tnlCSRMatrix< Real, Device, Index > :: vectorProduct( const Vector1& vec,
 //#ifdef HAVE_OPENMP
 //#pragma omp parallel for
 //#endif
-      for( Index row = 0; row < this -> size; row ++ )
+      for( Index row = 0; row < this->size; row ++ )
       {
          Real product( 0.0 );
          Index i = rw_offsets[ row + 1 ] - 1;
@@ -638,26 +638,26 @@ bool tnlCSRMatrix< Real, Device, Index > :: performSORIteration( const Real& ome
                                                                  Index firstRow,
                                                                  Index lastRow ) const
 {
-   tnlAssert( firstRow >=0 && firstRow < this -> getSize(),
-              cerr << "Wrong parameter firstRow. Should be in 0..." << this -> getSize()
+   tnlAssert( firstRow >=0 && firstRow < this->getSize(),
+              cerr << "Wrong parameter firstRow. Should be in 0..." << this->getSize()
                    << " but it equals " << firstRow << endl; );
-   tnlAssert( lastRow >=0 && lastRow < this -> getSize(),
-              cerr << "Wrong parameter lastRow. Should be in 0..." << this -> getSize()
+   tnlAssert( lastRow >=0 && lastRow < this->getSize(),
+              cerr << "Wrong parameter lastRow. Should be in 0..." << this->getSize()
                    << " but it equals " << lastRow << endl; );
 
    if( lastRow == 0 )
-      lastRow = this -> getSize();
+      lastRow = this->getSize();
    for( Index i = firstRow; i < lastRow; i ++ )
    {
       Real diagonal( 0.0 );
       Real update = b[ i ];
-      for( Index j = this -> row_offsets[ i ]; j < this -> row_offsets[ i + 1 ]; j ++ )
+      for( Index j = this->row_offsets[ i ]; j < this->row_offsets[ i + 1 ]; j ++ )
       {
-         const Index column = this -> columns[ j ];
+         const Index column = this->columns[ j ];
          if( column == i )
-            diagonal = this -> nonzero_elements[ j ];
+            diagonal = this->nonzero_elements[ j ];
          else
-            update -= this -> nonzero_elements[ j ] * x[ column ];
+            update -= this->nonzero_elements[ j ] * x[ column ];
       }
       if( diagonal == ( Real ) 0.0 )
       {
@@ -673,13 +673,13 @@ bool tnlCSRMatrix< Real, Device, Index > :: performSORIteration( const Real& ome
 template< typename Real, typename Device, typename Index >
 void tnlCSRMatrix< Real, Device, Index > :: setBackwardSpMV( bool backwardSpMV )
 {
-   this -> backwardSpMV = backwardSpMV;
+   this->backwardSpMV = backwardSpMV;
 }
 
 template< typename Real, typename Device, typename Index >
 Real tnlCSRMatrix< Real, Device, Index > :: getRowL1Norm( Index row ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
                  cerr << "The row is outside the matrix." );
    Index i = row_offsets[ row ];
    Index last_in_row = row_offsets[ row + 1 ];
@@ -693,7 +693,7 @@ Real tnlCSRMatrix< Real, Device, Index > :: getRowL1Norm( Index row ) const
 template< typename Real, typename Device, typename Index >
 void tnlCSRMatrix< Real, Device, Index > :: multiplyRow( Index row, const Real& value )
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
                  cerr << "The row is outside the matrix." );
    Index i = row_offsets[ row ];
    Index last_in_row = row_offsets[ row + 1 ];
@@ -708,12 +708,12 @@ bool tnlCSRMatrix< Real, Device, Index > :: reorderRows( const tnlVector< Index,
 {
    dbgFunctionName( "tnlCSRMatrix< Real, Device, Index >", "reorderRows" );
    last_nonzero_element = 0;
-   if( ! this -> setLike( inputCsrMatrix ) )
+   if( ! this->setLike( inputCsrMatrix ) )
    {
       cerr << "I am not able to allocate new memory for matrix reordering." << endl;
       return false;
    }
-   for( Index i = 0; i < this -> getSize(); i ++ )
+   for( Index i = 0; i < this->getSize(); i ++ )
    {
       tnlAssert( last_nonzero_element < nonzero_elements. getSize(), );
       tnlAssert( last_nonzero_element < columns. getSize(), );
@@ -728,9 +728,9 @@ bool tnlCSRMatrix< Real, Device, Index > :: reorderRows( const tnlVector< Index,
    }
    tnlAssert( last_nonzero_element <= nonzero_elements. getSize(), );
    tnlAssert( last_nonzero_element <= columns. getSize(), );
-   row_offsets[ this -> getSize() ] = last_nonzero_element;
-   dbgExpr( row_offsets[ this -> getSize() ] );
-   dbgExpr( this -> getSize() );
+   row_offsets[ this->getSize() ] = last_nonzero_element;
+   dbgExpr( row_offsets[ this->getSize() ] );
+   dbgExpr( this->getSize() );
    return true;
 }
 
@@ -804,12 +804,12 @@ void tnlCSRMatrix< Real, Device, Index > :: printOut( ostream& str,
 {
    str << "Structure of tnlCSRMatrix" << endl;
    str << "Matrix name:" << name << endl;
-   str << "Matrix size:" << this -> getSize() << endl;
+   str << "Matrix size:" << this->getSize() << endl;
    str << "Allocated elements:" << nonzero_elements. getSize() << endl;
    str << "Matrix rows:" << endl;
    Index print_lines = lines;
    if( ! print_lines )
-	   print_lines = this -> getSize();
+	   print_lines = this->getSize();
    for( Index i = 0; i < print_lines; i ++ )
    {
       Index first = row_offsets[ i ];
@@ -834,17 +834,17 @@ void tnlCSRMatrix< Real, Device, Index > :: getRowStatistics( Index& min_row_len
                                                         Index& max_row_length,
                                                         Index& average_row_length ) const
 {
-   min_row_length = this -> getSize();
+   min_row_length = this->getSize();
    max_row_length = 0;
    average_row_length = 0;
-   for( Index i = 0; i < this -> getSize(); i ++ )
+   for( Index i = 0; i < this->getSize(); i ++ )
    {
       Index row_length = row_offsets[ i + 1 ] - row_offsets[ i ];
       min_row_length = Min( min_row_length, row_length );
       max_row_length = Max( max_row_length, row_length );
       average_row_length += row_length;
    }
-   average_row_length /= ( double ) this -> getSize();
+   average_row_length /= ( double ) this->getSize();
 };
 
 template< typename Real, typename Device, typename Index >
@@ -1023,8 +1023,8 @@ bool tnlCSRMatrix< Real, Device, Index > :: read( istream& file,
    if( verbose )
       cout << "Non-zero elements parsed:   " << setw( 9 ) << right << parsed_elements << endl;
 
-   if( ! this -> setSize( size ) ||
-       ! this -> setNonzeroElements( parsed_elements ) )
+   if( ! this->setSize( size ) ||
+       ! this->setNonzeroElements( parsed_elements ) )
    {
       cerr << "Not enough memory to allocate the sparse or the full matrix for testing." << endl;
       return false;
@@ -1099,17 +1099,17 @@ void tnlCSRMatrix< Real, Device, Index > :: writePostscriptBody( ostream& str,
                                                                  const int elementSize,
                                                                  bool verbose ) const
 {
-   const double scale = elementSize * this -> getSize();
-   double hx = scale / ( double ) this -> getSize();
+   const double scale = elementSize * this->getSize();
+   double hx = scale / ( double ) this->getSize();
    Index lastRow( 0 ), lastColumn( 0 );
-   for( Index row = 0; row < this -> getSize(); row ++ )
+   for( Index row = 0; row < this->getSize(); row ++ )
    {
-      for( Index i = this -> row_offsets[ row ]; i < this -> row_offsets[ row + 1 ]; i ++ )
+      for( Index i = this->row_offsets[ row ]; i < this->row_offsets[ row + 1 ]; i ++ )
       {
-         Real elementValue = this -> nonzero_elements[ i ];
+         Real elementValue = this->nonzero_elements[ i ];
          if(  elementValue != ( Real ) 0.0 )
          {
-            Index column = this -> columns[ i ];
+            Index column = this->columns[ i ];
             str << ( column - lastColumn ) * elementSize
                 << " " << -( row - lastRow ) * elementSize
                 << " translate newpath 0 0 " << elementSize << " " << elementSize << " rectstroke" << endl;
diff --git a/src/legacy/matrices/tnlCusparseCSRMatrix.h b/src/legacy/matrices/tnlCusparseCSRMatrix.h
index c05be19bb41890b52477a493342027d4846bb5d7..e993b1727bfc549404e06c5761f7af60f304cc1b 100644
--- a/src/legacy/matrices/tnlCusparseCSRMatrix.h
+++ b/src/legacy/matrices/tnlCusparseCSRMatrix.h
@@ -208,8 +208,8 @@ tnlString tnlCusparseCSRMatrix< Real, Device, Index > :: getType() const
 template< typename Real, typename Device, typename Index >
 bool tnlCusparseCSRMatrix< Real, Device, Index > :: setSize( Index new_size )
 {
-   this -> size = new_size;
-   if( ! row_offsets. setSize( this -> size + 1 ) )
+   this->size = new_size;
+   if( ! row_offsets. setSize( this->size + 1 ) )
       return false;
    row_offsets. setValue( 0 );
    return true;
@@ -221,7 +221,7 @@ bool tnlCusparseCSRMatrix< Real, Device, Index > :: setLike( const tnlCusparseCS
    dbgFunctionName( "tnlCusparseCSRMatrix< Real, Device, Index >", "setLike" );
    dbgCout( "Setting size to " << matrix. getSize() << "." );
 
-   this -> size = matrix. getSize();
+   this->size = matrix. getSize();
    if( ! nonzero_elements. setLike( matrix. nonzero_elements ) ||
        ! columns. setLike( matrix. columns ) ||
        ! row_offsets. setLike( matrix. row_offsets ) )
@@ -283,13 +283,13 @@ bool tnlCusparseCSRMatrix< Real, Device, Index > :: addToElement( Index row, Ind
 template< typename Real, typename Device, typename Index >
 bool tnlCusparseCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatrix< Real, tnlHost, Index >& csr_matrix )
 {
-   if( ! this -> setSize( csr_matrix. getSize() ) ||
-       ! this -> setNonzeroElements( csr_matrix. getNonzeroElements() ) )
+   if( ! this->setSize( csr_matrix. getSize() ) ||
+       ! this->setNonzeroElements( csr_matrix. getNonzeroElements() ) )
          return false;
 
-   this -> nonzero_elements = csr_matrix. nonzero_elements;
-   this -> columns = csr_matrix. columns;
-   this -> row_offsets = csr_matrix. row_offsets;
+   this->nonzero_elements = csr_matrix. nonzero_elements;
+   this->columns = csr_matrix. columns;
+   this->row_offsets = csr_matrix. row_offsets;
    return true;
 }
 
@@ -309,10 +309,10 @@ void tnlCusparseCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVect
 #ifdef HAVE_CUSPARSE
   cusparseSpmv( cusparseHandle,
                 cusparseMatDescr,
-                this -> getSize(),
-                this -> nonzero_elements. getData(),
-                this -> row_offsets. getData(),
-                this -> columns. getData(),
+                this->getSize(),
+                this->nonzero_elements. getData(),
+                this->row_offsets. getData(),
+                this->columns. getData(),
                 x. getData(),
                 b. getData() );
 #endif
diff --git a/src/legacy/matrices/tnlEllpackMatrix.h b/src/legacy/matrices/tnlEllpackMatrix.h
index 33b3c28919b370a704b9b43e772a2580905e504d..118a7b393ed9b4e4d9d8f2996d3ba64b9c86bdd6 100644
--- a/src/legacy/matrices/tnlEllpackMatrix.h
+++ b/src/legacy/matrices/tnlEllpackMatrix.h
@@ -132,7 +132,7 @@ tnlString tnlEllpackMatrix< Real, tnlHost, Index > :: getType() const
 template< typename Real, typename Index >
 bool tnlEllpackMatrix< Real, tnlHost, Index > :: setSize( Index new_size )
 {
-   this -> size = new_size;
+   this->size = new_size;
    if( ! ellpack_nonzero_elements. setSize( new_size * row_length ) )
       return false;
    ellpack_nonzero_elements. setValue( 0 );
@@ -189,7 +189,7 @@ bool tnlEllpackMatrix< Real, tnlHost, Index > :: copyFrom( const tnlCSRMatrix< R
       row_length = average_row_length;
    }*/
 
-   if( ! this -> setSize( csr_matrix. getSize() ) )
+   if( ! this->setSize( csr_matrix. getSize() ) )
    		return false;
 
    /*
@@ -197,7 +197,7 @@ bool tnlEllpackMatrix< Real, tnlHost, Index > :: copyFrom( const tnlCSRMatrix< R
     * They will be stored in the COO data array.
     */
    Index coo_elements = 0;
-   for( Index i = 0; i < this -> getSize(); i ++ )
+   for( Index i = 0; i < this->getSize(); i ++ )
    {
 	   Index csr_row_length = csr_matrix. getRowLength( i );
 	   if( csr_row_length > row_length )
@@ -210,8 +210,8 @@ bool tnlEllpackMatrix< Real, tnlHost, Index > :: copyFrom( const tnlCSRMatrix< R
     */
    dbgCout( "Inserting CSR row ... ");
    artificial_zeros = 0;
-   dbgExpr( this -> getSize() );
-   for( Index i = 0; i < this -> getSize(); i ++ )
+   dbgExpr( this->getSize() );
+   for( Index i = 0; i < this->getSize(); i ++ )
    {
 	   Index csr_row_length = csr_matrix. getRowLength( i );
 	   Index csr_row_offset = csr_matrix. row_offsets[ i ];
@@ -221,7 +221,7 @@ bool tnlEllpackMatrix< Real, tnlHost, Index > :: copyFrom( const tnlCSRMatrix< R
 	    */
 	   while( j < csr_row_length && j < row_length )
 	   {
-		   Index element_pos = j * this -> getSize() + i;
+		   Index element_pos = j * this->getSize() + i;
 		   ellpack_nonzero_elements[ element_pos ] = csr_matrix. nonzero_elements[ csr_row_offset + j ];
 		   ellpack_columns[ element_pos ] = csr_matrix. columns[ csr_row_offset + j ];
 		   dbgExpr( element_pos );
@@ -252,7 +252,7 @@ Real tnlEllpackMatrix< Real, tnlHost, Index > :: getElement( Index row,
    {
       dbgExpr( element_pos );
       i ++;
-      element_pos += this -> getSize();
+      element_pos += this->getSize();
    }
    if( i < row_length && ellpack_columns[ element_pos ] == column )
       return ellpack_nonzero_elements[ element_pos ];
@@ -263,11 +263,11 @@ template< typename Real, typename Index >
 Real tnlEllpackMatrix< Real, tnlHost, Index > :: rowProduct( Index row,
                                                              const tnlVector< Real, tnlHost, Index >& vector ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
               cerr << "The row is outside the matrix." );
-   tnlAssert( vector. getSize() == this -> getSize(),
+   tnlAssert( vector. getSize() == this->getSize(),
               cerr << "The matrix and vector for multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vector. getSize() << endl; );
 
    Real product( 0.0 );
@@ -282,7 +282,7 @@ Real tnlEllpackMatrix< Real, tnlHost, Index > :: rowProduct( Index row,
       product += ellpack_nonzero_elements[ element_pos ] *
                  vector[ ellpack_columns[ element_pos ] ];
       i ++;
-      element_pos += this -> getSize();
+      element_pos += this->getSize();
    }
    if( i < row_length )
       return product;
@@ -294,16 +294,16 @@ template< typename Real, typename Index >
 void tnlEllpackMatrix< Real, tnlHost, Index > :: vectorProduct( const tnlVector< Real, tnlHost, Index >& x,
                                                                 tnlVector< Real, tnlHost, Index >& b ) const
 {
-   tnlAssert( x. getSize() == this -> getSize(),
+   tnlAssert( x. getSize() == this->getSize(),
               cerr << "The matrix and vector for a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << x. getSize() << endl; );
-   tnlAssert( b. getSize() == this -> getSize(),
+   tnlAssert( b. getSize() == this->getSize(),
               cerr << "The matrix and result vector of a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << b. getSize() << endl; );
 
-   for( Index i = 0; i < this -> getSize(); i ++)
+   for( Index i = 0; i < this->getSize(); i ++)
       b[ i ] = rowProduct( i, x );
 };
 
@@ -313,18 +313,18 @@ void tnlEllpackMatrix< Real, tnlHost, Index > :: printOut( ostream& str,
 {
    str << "Structure of tnlEllpackMatrix" << endl;
    str << "Matrix name:" << name << endl;
-   str << "Matrix size:" << this -> getSize() << endl;
+   str << "Matrix size:" << this->getSize() << endl;
    str << "Allocated elements:" << ellpack_nonzero_elements. getSize() << endl;
    str << "Matrix row length:" << row_length << endl;
-   for( Index i = 0; i < this -> size; i ++ )
+   for( Index i = 0; i < this->size; i ++ )
    {
       str << i << "th row data:    ";
       for( Index j = 0; j < row_length; j ++ )
-         str << setprecision( 5 ) << setw( 8 ) << ellpack_nonzero_elements[ i + j * this -> getSize() ] << " ";
+         str << setprecision( 5 ) << setw( 8 ) << ellpack_nonzero_elements[ i + j * this->getSize() ] << " ";
 
       str << endl << i << "th row columns: ";
       for( Index j = 0; j < row_length; j ++ )
-         str << setprecision( 5 ) << setw( 8 ) << ellpack_columns[ i + j * this -> getSize() ] << " ";
+         str << setprecision( 5 ) << setw( 8 ) << ellpack_columns[ i + j * this->getSize() ] << " ";
       str << endl;
    }
 }
diff --git a/src/legacy/matrices/tnlEllpackMatrixCUDA.h b/src/legacy/matrices/tnlEllpackMatrixCUDA.h
index 07e9216076197f614558e1b696ff4a1a537f61ce..95aef4d66a8ec2f6772d169f9d9a0e39cfe4c45d 100644
--- a/src/legacy/matrices/tnlEllpackMatrixCUDA.h
+++ b/src/legacy/matrices/tnlEllpackMatrixCUDA.h
@@ -166,7 +166,7 @@ tnlString tnlEllpackMatrix< Real, tnlCuda, Index > :: getType() const
 template< typename Real, typename Index >
 bool tnlEllpackMatrix< Real, tnlCuda, Index > :: setSize( Index new_size )
 {
-   this -> size = new_size;
+   this->size = new_size;
    if( ! ellpack_nonzero_elements. setSize( new_size * row_length ) )
       return false;
    ellpack_nonzero_elements. setValue( 0.0 );
@@ -233,7 +233,7 @@ bool tnlEllpackMatrix< Real, tnlCuda, Index > :: copyFrom( const tnlEllpackMatri
    dbgFunctionName( "tnlEllpackMatrix< Real, tnlCuda >", "copyFrom" );
 
    row_length = ellpack_matrix. getRowLength();
-   if( ! this -> setSize( ellpack_matrix. getSize() ) )
+   if( ! this->setSize( ellpack_matrix. getSize() ) )
    		return false;
 
    if( ! setNonzeroCOOElements( ellpack_matrix. coo_nonzero_elements. getSize() ) )
@@ -258,16 +258,16 @@ template< typename Real, typename Index >
 void tnlEllpackMatrix< Real, tnlCuda, Index > :: vectorProduct( const tnlVector< Real, tnlCuda, Index >& x,
                                                                 tnlVector< Real, tnlCuda, Index >& b ) const
 {
-   tnlAssert( x. getSize() == this -> getSize(),
+   tnlAssert( x. getSize() == this->getSize(),
               cerr << "The matrix and vector for a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << x. getSize() << endl; );
-   tnlAssert( b. getSize() == this -> getSize(),
+   tnlAssert( b. getSize() == this->getSize(),
               cerr << "The matrix and result vector of a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << b. getSize() << endl; );
 #ifdef HAVE_CUDA
-	sparseEllpackMatrixVectorProductKernelCaller( this -> getSize(),
+	sparseEllpackMatrixVectorProductKernelCaller( this->getSize(),
 	                                       row_length,
 	                                       ellpack_nonzero_elements. getData(),
 	                                       ellpack_columns. getData(),
@@ -282,9 +282,9 @@ template< typename Real, typename Index >
 Real tnlEllpackMatrix< Real, tnlCuda, Index > :: rowProduct( Index row,
                                                              const tnlVector< Real, tnlCuda, Index >& vector ) const
 {
-   tnlAssert( vector. getSize() == this -> getSize(),
+   tnlAssert( vector. getSize() == this->getSize(),
               cerr << "The matrix and vector for a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vector. getSize() << endl; );
 
 	tnlAssert( false, );
diff --git a/src/legacy/matrices/tnlFastCSRMatrix.h b/src/legacy/matrices/tnlFastCSRMatrix.h
index ffd3c7dc179cfb5789b035aa598222ce719aa687..4faf3e7509da8ff43fd37a77c7a3bbb056c8b060 100644
--- a/src/legacy/matrices/tnlFastCSRMatrix.h
+++ b/src/legacy/matrices/tnlFastCSRMatrix.h
@@ -203,10 +203,10 @@ tnlString tnlFastCSRMatrix< Real, tnlHost, Index > :: getType() const
 template< typename Real, typename Index >
 bool tnlFastCSRMatrix< Real, tnlHost, Index > :: setSize( Index new_size )
 {
-   this -> size = new_size;
-   if( ! row_offsets. setSize( this -> size + 1 ) ||
-	   ! columns_sequences_offsets. setSize( this -> size + 1 ) ||
-	   ! column_sequences_lengths. setSize( this -> size ) )
+   this->size = new_size;
+   if( ! row_offsets. setSize( this->size + 1 ) ||
+	   ! columns_sequences_offsets. setSize( this->size + 1 ) ||
+	   ! column_sequences_lengths. setSize( this->size ) )
       return false;
    row_offsets. setValue( 0 );
    columns_sequences_offsets. setValue( 0.0 );
@@ -256,7 +256,7 @@ Index tnlFastCSRMatrix< Real, tnlHost, Index > :: getColumnSequencesLength() con
 template< typename Real, typename Index >
 Index tnlFastCSRMatrix< Real, tnlHost, Index > :: getRowLength( Index row ) const
 {
-	tnlAssert( row >= 0 && row < this -> getSize(), );
+	tnlAssert( row >= 0 && row < this->getSize(), );
 	return row_offsets[ row + 1 ] - row_offsets[ row ];
 }
 
@@ -297,10 +297,10 @@ template< typename Real, typename Index >
 bool tnlFastCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlCSRMatrix< Real, tnlHost, Index >& csr_matrix )
 {
 	dbgFunctionName( "tnlFastCSRMatrix< Real, tnlHost >", "copyFrom" );
-	if( ! this -> setSize( csr_matrix. getSize() ) )
+	if( ! this->setSize( csr_matrix. getSize() ) )
 		return false;
 
-	if( ! this -> setNonzeroElements( csr_matrix. getNonzeroElements() ) )
+	if( ! this->setNonzeroElements( csr_matrix. getNonzeroElements() ) )
 		return false;
 
 	nonzero_elements = csr_matrix. nonzero_elements;
@@ -309,7 +309,7 @@ bool tnlFastCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlCSRMatrix< R
 	last_nonzero_element = csr_matrix. last_nonzero_element;
 
 	const Index compression_depth = 1024;
-	for( Index row = 0; row < this -> size; row ++ )
+	for( Index row = 0; row < this->size; row ++ )
 	{
 		Index column_sequence_offset = csr_matrix. row_offsets[ row ];
 		Index column_sequence_length = csr_matrix. row_offsets[ row + 1 ] - column_sequence_offset;
@@ -357,9 +357,9 @@ template< typename Real, typename Index >
 Real tnlFastCSRMatrix< Real, tnlHost, Index > :: getElement( Index row,
                                                       Index column ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
 			  cerr << "The row is outside the matrix." );
-   tnlAssert( 0 <= column && column < this -> getSize(),
+   tnlAssert( 0 <= column && column < this->getSize(),
 			  cerr << "The column is outside the matrix." );
    Index column_offset = columns_sequences_offsets[ row ];
    Index data_offset = row_offsets[ row ];
@@ -379,11 +379,11 @@ template< typename Real, typename Index >
 Real tnlFastCSRMatrix< Real, tnlHost, Index > :: rowProduct( Index row,
                                                              const tnlVector< Real, tnlHost, Index >& vec ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
 			  cerr << "The row is outside the matrix." );
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
 
    Index data_offset = row_offsets[ row ];
@@ -412,19 +412,19 @@ template< typename Real, typename Index >
 void tnlFastCSRMatrix< Real, tnlHost, Index > :: vectorProduct( const tnlVector< Real, tnlHost, Index >& vec,
                                                                 tnlVector< Real, tnlHost, Index >& result ) const
 {
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
-   tnlAssert( result. getSize() == this -> getSize(),
+   tnlAssert( result. getSize() == this->getSize(),
               cerr << "The matrix and result vector of a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << result. getSize() << endl; );
 
    const Index* cols = column_sequences. getData();
    const Real* els = nonzero_elements. getData();
 
-   for( Index row = 0; row < this -> size; row ++ )
+   for( Index row = 0; row < this->size; row ++ )
    {
       Index data_offset = row_offsets[ row ];
       Index column_offset =  columns_sequences_offsets[ row ];
@@ -479,12 +479,12 @@ void tnlFastCSRMatrix< Real, tnlHost, Index > :: printOut( ostream& str,
 {
    str << "Structure of tnlFastCSRMatrix" << endl;
    str << "Matrix name:" << name << endl;
-   str << "Matrix size:" << this -> getSize() << endl;
+   str << "Matrix size:" << this->getSize() << endl;
    str << "Allocated elements:" << nonzero_elements. getSize() << endl;
    str << "Matrix rows:" << endl;
    Index print_lines = lines;
    if( ! print_lines )
-	   print_lines = this -> getSize();
+	   print_lines = this->getSize();
 
    for( Index i = 0; i < print_lines; i ++ )
    {
diff --git a/src/legacy/matrices/tnlFastRgCSRMatrix.h b/src/legacy/matrices/tnlFastRgCSRMatrix.h
index b11e0b1fb2dc659df73b27f7ae94d52d2a7c33ac..44e4b287b9b2f9a4c741990372f3ad1dd371b96a 100644
--- a/src/legacy/matrices/tnlFastRgCSRMatrix.h
+++ b/src/legacy/matrices/tnlFastRgCSRMatrix.h
@@ -183,13 +183,13 @@ tnlString tnlFastRgCSRMatrix< Real, tnlHost, Index > :: getType() const
 template< typename Real, typename Index >
 bool tnlFastRgCSRMatrix< Real, tnlHost, Index > :: setSize( Index new_size )
 {
-   this -> size = new_size;
-   Index blocks_number = this -> size / block_size + ( this -> size % block_size != 0 );
+   this->size = new_size;
+   Index blocks_number = this->size / block_size + ( this->size % block_size != 0 );
    if( ! block_offsets. setSize( blocks_number + 1 ) ||
 	   ! columns_sequences_blocks_offsets. setSize( blocks_number + 1 ) ||
 	   ! column_sequences_in_block. setSize( blocks_number ) ||
-	   ! columns_sequences_offsets. setSize( this -> size + 1 ) ||
-	   ! column_sequences_lengths. setSize( this -> size ) )
+	   ! columns_sequences_offsets. setSize( this->size + 1 ) ||
+	   ! column_sequences_lengths. setSize( this->size ) )
       return false;
    block_offsets. setValue( 0 );
    columns_sequences_blocks_offsets. setValue( 0 );
@@ -249,10 +249,10 @@ template< typename Real, typename Index >
 bool tnlFastRgCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlFastCSRMatrix< Real, tnlHost >& fast_csr_matrix )
 {
 	dbgFunctionName( "tnlFastRgCSRMatrix< Real, tnlHost >", "copyFrom" );
-	if( ! this -> setSize( fast_csr_matrix. getSize() ) )
+	if( ! this->setSize( fast_csr_matrix. getSize() ) )
 		return false;
 
-	Index blocks_number = this -> size / block_size + ( this -> size % block_size != 0 );
+	Index blocks_number = this->size / block_size + ( this->size % block_size != 0 );
 	tnlVector< Index > col_seq_block_size( "tnlFastRgCSRMatrix< Real, tnlHost, Index > :: col_seq_block_size" );
 	col_seq_block_size. setSize( blocks_number );
 	col_seq_block_size. setValue( 0 );
@@ -269,7 +269,7 @@ bool tnlFastRgCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlFastCSRMat
 	 *	The length of the longest sequence is stored in longest_sequence_length,
 	 *	and the number of sequences in one block is stored in columns_sequences_in_block
 	 */
-	for( Index i = 0; i < this -> getSize(); i ++ )
+	for( Index i = 0; i < this->getSize(); i ++ )
 	{
 		Index block_id = i / block_size;
 		/*
@@ -277,8 +277,8 @@ bool tnlFastRgCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlFastCSRMat
 		 * We store it in the current_block_size
 		 */
 		Index current_block_size = block_size;
-		if( ( block_id + 1 ) * block_size > this -> getSize() )
-		   current_block_size = this -> getSize() % block_size;
+		if( ( block_id + 1 ) * block_size > this->getSize() )
+		   current_block_size = this->getSize() % block_size;
 
 		Index current_column_sequence = fast_csr_matrix. columns_sequences_offsets[ i ];
 
@@ -342,7 +342,7 @@ bool tnlFastRgCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlFastCSRMat
     column_sequences. setValue( -1 );
 	Index column_sequences_end( 0 );
 	Index inserted_column_sequences( 0 );
-	for( Index i = 0; i < this -> getSize(); i ++ )
+	for( Index i = 0; i < this->getSize(); i ++ )
 	{
 	   dbgCout( "Processing column-sequence for the line " << i );
 		Index block_id = i / block_size;
@@ -413,7 +413,7 @@ bool tnlFastRgCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlFastCSRMat
 	Index total_elements( 0 );
 	Index max_row_in_block( 0 );
 	Index blocks_inserted( -1 );
-	for( Index i = 0; i < this -> getSize(); i ++ )
+	for( Index i = 0; i < this->getSize(); i ++ )
 	{
 		if( i % block_size == 0 )
 		{
@@ -427,7 +427,7 @@ bool tnlFastRgCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlFastCSRMat
 		//dbgExpr( nonzeros_in_row[ i ] );
 		max_row_in_block = Max( max_row_in_block, column_sequences_lengths[ i ] );
 	}
-	total_elements += max_row_in_block * ( this -> getSize() - blocks_inserted * block_size );
+	total_elements += max_row_in_block * ( this->getSize() - blocks_inserted * block_size );
 	block_offsets[ block_offsets. getSize() - 1 ] = total_elements;
 
 
@@ -454,8 +454,8 @@ bool tnlFastRgCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlFastCSRMat
 		 * We store it in the current_block_size
 		 */
 		Index current_block_size = block_size;
-		if( ( i + 1 ) * block_size > this -> getSize() )
-			current_block_size = this -> getSize() % block_size;
+		if( ( i + 1 ) * block_size > this->getSize() )
+			current_block_size = this->getSize() % block_size;
 
 		/*
 		 * We insert 'current_block_size' rows in this matrix with the stride
@@ -471,7 +471,7 @@ bool tnlFastRgCSRMatrix< Real, tnlHost, Index > :: copyFrom( const tnlFastCSRMat
 			Index j = block_offsets[ i ] + k;                   // position of the first element of the row
 			Index element_row = i * block_size + k;
 			//dbgExpr( element_row );
-			if( element_row < this -> getSize() )
+			if( element_row < this->getSize() )
 			{
 
 				/*
@@ -500,9 +500,9 @@ template< typename Real, typename Index >
 Real tnlFastRgCSRMatrix< Real, tnlHost, Index > :: getElement( Index row,
                                                                Index column ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
 			  cerr << "The row is outside the matrix." );
-   tnlAssert( 0 <= column && column < this -> getSize(),
+   tnlAssert( 0 <= column && column < this->getSize(),
 			  cerr << "The column is outside the matrix." );
 
 	Index block_id = row / block_size;
@@ -513,8 +513,8 @@ Real tnlFastRgCSRMatrix< Real, tnlHost, Index > :: getElement( Index row,
 	 * We store it in the current_block_size
 	 */
 	Index current_block_size = block_size;
-	if( ( block_id + 1 ) * block_size > this -> getSize() )
-		current_block_size = this -> getSize() % block_size;
+	if( ( block_id + 1 ) * block_size > this->getSize() )
+		current_block_size = this->getSize() % block_size;
 	Index pos = block_offset + block_row;
 
    Index column_offset = columns_sequences_offsets[ row ];
@@ -535,11 +535,11 @@ template< typename Real, typename Index >
 Real tnlFastRgCSRMatrix< Real, tnlHost, Index > :: rowProduct( Index row,
                                                                const tnlVector< Real, tnlHost, Index >& vec ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
            cerr << "The row is outside the matrix." );
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
 
    Index block_id = row / block_size;
@@ -550,8 +550,8 @@ Real tnlFastRgCSRMatrix< Real, tnlHost, Index > :: rowProduct( Index row,
 	* We store it in the current_block_size
 	*/
    Index current_block_size = block_size;
-   if( ( block_id + 1 ) * block_size > this -> getSize() )
-	   current_block_size = this -> getSize() % block_size;
+   if( ( block_id + 1 ) * block_size > this->getSize() )
+	   current_block_size = this->getSize() % block_size;
    Real product( 0.0 );
    Index val_pos = block_offset + block_row;
    Index column_pos = columns_sequences_offsets[ row ];
@@ -570,16 +570,16 @@ template< typename Real, typename Index >
 void tnlFastRgCSRMatrix< Real, tnlHost, Index > :: vectorProduct( const tnlVector< Real, tnlHost, Index >& vec,
                                                                   tnlVector< Real, tnlHost, Index >& result ) const
 {
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
-   tnlAssert( result. getSize() == this -> getSize(),
+   tnlAssert( result. getSize() == this->getSize(),
               cerr << "The matrix and result vector of a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << result. getSize() << endl; );
 
-   for( Index row = 0; row < this -> getSize(); row ++ )
+   for( Index row = 0; row < this->getSize(); row ++ )
    {
 	   Index block_id = row / block_size;
 	   Index block_row = row % block_size;
@@ -589,8 +589,8 @@ void tnlFastRgCSRMatrix< Real, tnlHost, Index > :: vectorProduct( const tnlVecto
 		* We store it in the current_block_size
 		*/
 	   Index current_block_size = block_size;
-	   if( ( block_id + 1 ) * block_size > this -> getSize() )
-		   current_block_size = this -> getSize() % block_size;
+	   if( ( block_id + 1 ) * block_size > this->getSize() )
+		   current_block_size = this->getSize() % block_size;
 	   Real product( 0.0 );
 	   Index val_pos = block_offset + block_row;
 	   Index column_pos = columns_sequences_offsets[ row ];
@@ -615,22 +615,22 @@ void tnlFastRgCSRMatrix< Real, tnlHost, Index > :: printOut( ostream& str,
 {
    str << "Structure of tnlFastRgCSRMatrix" << endl;
    str << "Matrix name:" << name << endl;
-   str << "Matrix size:" << this -> getSize() << endl;
+   str << "Matrix size:" << this->getSize() << endl;
    str << "Allocated elements:" << nonzero_elements. getSize() << endl;
    str << "Matrix blocks: " << block_offsets. getSize() << endl;
 
    Index print_lines = lines;
    if( ! print_lines )
-	   print_lines = this -> getSize();
+	   print_lines = this->getSize();
 
-   for( Index i = 0; i < this -> block_offsets. getSize() - 1; i ++ )
+   for( Index i = 0; i < this->block_offsets. getSize() - 1; i ++ )
    {
 	   if( i * block_size > print_lines )
 		   continue;
 	   str << endl << "Block number: " << i << endl;
 	   str << " Lines: " << i * block_size << " -- " << ( i + 1 ) * block_size << endl;
 	   str << " Column sequences: " << column_sequences_in_block[ i ] << endl;
-	   for( Index k = i * block_size; k < ( i + 1 ) * block_size && k < this -> getSize(); k ++ )
+	   for( Index k = i * block_size; k < ( i + 1 ) * block_size && k < this->getSize(); k ++ )
 	   {
 		   str << " Line: " << k << flush
 			   << " Line length: " << column_sequences_lengths[ k ] << flush
@@ -643,8 +643,8 @@ void tnlFastRgCSRMatrix< Real, tnlHost, Index > :: printOut( ostream& str,
 	   str << endl;
 
 	   Index current_block_size = block_size;
-	   if( ( i + 1 ) * block_size > this -> getSize() )
-	      current_block_size = this -> getSize() % block_size;
+	   if( ( i + 1 ) * block_size > this->getSize() )
+	      current_block_size = this->getSize() % block_size;
 	   Index block_length = block_offsets[ i + 1 ] - block_offsets[ i ];
 	   Index row_length = block_length / block_size;
 	   str << " Block data: " << block_offsets[ i ] << " -- " << block_offsets[ i + 1 ] << endl;
diff --git a/src/legacy/matrices/tnlFastRgCSRMatrixCUDA.h b/src/legacy/matrices/tnlFastRgCSRMatrixCUDA.h
index 96f89a69fd2acdbbe9c6d0b0584ded7637358b16..643531c294a7e3f3c9fb0c0e17042b0f9871bdd4 100644
--- a/src/legacy/matrices/tnlFastRgCSRMatrixCUDA.h
+++ b/src/legacy/matrices/tnlFastRgCSRMatrixCUDA.h
@@ -201,13 +201,13 @@ tnlString tnlFastRgCSRMatrix< Real, tnlCuda, Index > :: getType() const
 template< typename Real, typename Index >
 bool tnlFastRgCSRMatrix< Real, tnlCuda, Index > :: setSize( int new_size )
 {
-   this -> size = new_size;
-   int blocks_number = this -> size / block_size + ( this -> size % block_size != 0 );
+   this->size = new_size;
+   int blocks_number = this->size / block_size + ( this->size % block_size != 0 );
    if( ! block_offsets. setSize( blocks_number + 1 ) ||
-	   ! columns_sequences_offsets. setSize( this -> size + 1 ) ||
+	   ! columns_sequences_offsets. setSize( this->size + 1 ) ||
 	   ! column_sequences_in_block. setSize( blocks_number ) ||
 	   ! columns_sequences_blocks_offsets. setSize( blocks_number + 1 ) ||
-	   ! column_sequences_lengths. setSize( this -> size ) )
+	   ! column_sequences_lengths. setSize( this->size ) )
       return false;
    block_offsets. setValue( 0 );
    columns_sequences_blocks_offsets. setValue( 0 );
@@ -275,7 +275,7 @@ bool tnlFastRgCSRMatrix< Real, tnlCuda, Index > :: copyFrom( const tnlFastRgCSRM
 	}
 	block_size = coa_fast_csr_matrix. block_size;
 
-	if( ! this -> setSize( coa_fast_csr_matrix. getSize() ) ||
+	if( ! this->setSize( coa_fast_csr_matrix. getSize() ) ||
     	! nonzero_elements. setSize( coa_fast_csr_matrix. nonzero_elements. getSize() ) ||
 		! column_sequences. setSize( coa_fast_csr_matrix. column_sequences. getSize() ) )
 		return false;
@@ -304,9 +304,9 @@ template< typename Real, typename Index >
 Real tnlFastRgCSRMatrix< Real, tnlCuda, Index > :: getElement( int row,
                                                         int column ) const
 {
-    tnlAssert( 0 <= row && row < this -> getSize(),
+    tnlAssert( 0 <= row && row < this->getSize(),
 	 		   cerr << "The row is outside the matrix." );
-    tnlAssert( 0 <= column && column < this -> getSize(),
+    tnlAssert( 0 <= column && column < this->getSize(),
 	    	   cerr << "The column is outside the matrix." );
 	 tnlAssert( false, cerr << "Not Implemeted Yet!" );
 	 return 0;
@@ -316,7 +316,7 @@ template< typename Real, typename Index >
 Real tnlFastRgCSRMatrix< Real, tnlCuda, Index > :: rowProduct( int row,
                                                                const tnlVector< Real, tnlCuda, Index >& vec ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
 			  cerr << "The row is outside the matrix." );
    tnlAssert( vec != NULL, );
    tnlAssert( false, cerr << "Not Implemented Yet!" );
@@ -330,7 +330,7 @@ void tnlFastRgCSRMatrix< Real, tnlCuda, Index > :: vectorProduct( const tnlVecto
    tnlAssert( vec != NULL && result != NULL,);
 
 #ifdef HAVE_CUDA
-	/*sparseFastCSRMatrixVectorProductKernel( this -> getSize(),
+	/*sparseFastCSRMatrixVectorProductKernel( this->getSize(),
 	                                              block_size,
 	                                              columns_sequences_blocks_offsets. getData(),
 	                                              columns_sequences_offsets. getData(),
@@ -355,22 +355,22 @@ void tnlFastRgCSRMatrix< Real, tnlCuda, Index > :: printOut( ostream& str,
 {
    str << "Structure of tnlFastRgCSRMatrix" << endl;
    str << "Matrix name:" << name << endl;
-   str << "Matrix size:" << this -> getSize() << endl;
+   str << "Matrix size:" << this->getSize() << endl;
    str << "Allocated elements:" << nonzero_elements. getSize() << endl;
    str << "Matrix blocks: " << block_offsets. getSize() << endl;
 
    int print_lines = lines;
    if( ! print_lines )
-	   print_lines = this -> getSize();
+	   print_lines = this->getSize();
 
-   for( int i = 0; i < this -> block_offsets. getSize() - 1; i ++ )
+   for( int i = 0; i < this->block_offsets. getSize() - 1; i ++ )
    {
 	   if( i * block_size > print_lines )
 		   continue;
 	   str << endl << "Block number: " << i << endl;
 	   str << " Lines: " << i * block_size << " -- " << ( i + 1 ) * block_size << endl;
 	   str << " Column sequences: " << column_sequences_in_block. getElement( i ) << endl;
-	   for( int k = i * block_size; k < ( i + 1 ) * block_size && k < this -> getSize(); k ++ )
+	   for( int k = i * block_size; k < ( i + 1 ) * block_size && k < this->getSize(); k ++ )
 	   {
 		   str << " Line: " << k << flush
 			   << " Line length: " << column_sequences_lengths. getElement( k ) << flush
@@ -383,8 +383,8 @@ void tnlFastRgCSRMatrix< Real, tnlCuda, Index > :: printOut( ostream& str,
 	   str << endl;
 
 	   int current_block_size = block_size;
-	   if( ( i + 1 ) * block_size > this -> getSize() )
-	      current_block_size = this -> getSize() % block_size;
+	   if( ( i + 1 ) * block_size > this->getSize() )
+	      current_block_size = this->getSize() % block_size;
 	   int block_length = block_offsets. getElement( i + 1 ) - block_offsets. getElement( i );
 	   int row_length = block_length / block_size;
 	   str << " Block data: " << block_offsets. getElement( i ) << " -- " << block_offsets. getElement( i + 1 ) << endl;
diff --git a/src/legacy/matrices/tnlFullMatrix.h b/src/legacy/matrices/tnlFullMatrix.h
index a9a230314b4d445c6bf3759a47af79c140561d1e..1c81fd60eb15a216a46504e389e8b871a96b9d2f 100644
--- a/src/legacy/matrices/tnlFullMatrix.h
+++ b/src/legacy/matrices/tnlFullMatrix.h
@@ -184,11 +184,11 @@ template< typename Real, typename Device, typename Index >
 Real tnlFullMatrix< Real, Device, Index > :: rowProduct( const Index row,
                                                          const tnlVector< Real, Device, Index >& vec ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
               cerr << "The row is outside the matrix." );
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
 
    const Index size = getSize();
@@ -215,13 +215,13 @@ template< typename Real, typename Device, typename Index >
 void tnlFullMatrix< Real, Device, Index > :: vectorProduct( const tnlVector< Real, Device, Index >& vec,
                                                             tnlVector< Real, Device, Index >& result ) const
 {
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
-   tnlAssert( result. getSize() == this -> getSize(),
+   tnlAssert( result. getSize() == this->getSize(),
               cerr << "The matrix and result vector of a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << result. getSize() << endl; );
 
    const Index size = getSize();
diff --git a/src/legacy/matrices/tnlMatrix.h b/src/legacy/matrices/tnlMatrix.h
index db31c122a3103ee73942da5040a99e6ad91bbec9..f3c2afdc563f4e792b42caa2483a43fd80c9b5c6 100644
--- a/src/legacy/matrices/tnlMatrix.h
+++ b/src/legacy/matrices/tnlMatrix.h
@@ -214,15 +214,15 @@ bool tnlMatrix< Real, Device, Index > :: operator == ( const tnlMatrix< Real, De
 template< typename Real, typename Device, typename Index >
 bool tnlMatrix< Real, Device, Index > :: compare( const tnlMatrix< Real, Device, Index >& m, bool verbose ) const
 {
-   if( this -> getSize() != m. getSize() )
+   if( this->getSize() != m. getSize() )
       return false;
-   const Index size = this -> getSize();
+   const Index size = this->getSize();
    for( Index i = 0; i < size; i ++ )
       for( Index j = 0; j < size; j ++ )
       {
          if( verbose )
             cout << "Comparing: " << i << " / " << size << "\r";
-         if( this -> getElement( i, j ) != m. getElement( i, j ) )
+         if( this->getElement( i, j ) != m. getElement( i, j ) )
              return false;
       }
    return true;
@@ -276,7 +276,7 @@ template< typename Real, typename Device, typename Index >
    template< typename Real2 >
 tnlMatrix< Real, Device, Index >& tnlMatrix< Real, Device, Index > ::  operator = ( const tnlMatrix< Real2, Device, Index >& matrix )
 {
-   this -> size = matrix. getSize();
+   this->size = matrix. getSize();
    /*if( ! rowsReorderingPermutation. setSize( matrix. rowsReorderingPermutation. getSize() ) )
    {
       cerr << "I am not able to allocat the row permutation vector for the new matrix." << endl;
@@ -383,8 +383,8 @@ bool tnlMatrix< Real, Device, Index > :: read( istream& file,
            cerr << "There is not square matrix in the file." << endl;
            return false;
          }
-         if( ! this -> setSize( M ) ||
-             ! this -> setNonzeroElements( L ) )
+         if( ! this->setSize( M ) ||
+             ! this->setNonzeroElements( L ) )
          {
             cerr << "Not enough memory to allocate the sparse or the full matrix for testing." << endl;
             return false;
@@ -407,9 +407,9 @@ bool tnlMatrix< Real, Device, Index > :: read( istream& file,
       parsed_elements ++;
       if( verbose )
          cout << "Parsed elements:   " << setw( 9 ) << right << parsed_elements << "\r" << flush;
-      this -> setElement( I - 1, J - 1, A );
+      this->setElement( I - 1, J - 1, A );
       if( symmetric && I != J )
-    	  this -> setElement( J - 1, I - 1, A );
+    	  this->setElement( J - 1, I - 1, A );
    }
    return true;
 }
@@ -431,10 +431,10 @@ bool tnlMatrix< Real, Device, Index > :: sortRowsDecreasingly( tnlVector< Index,
     */
    for( Index i = 0; i < matrixSize; i ++ )
    {
-      tnlAssert( this -> getNonzeroElementsInRow( i ) <= matrixSize,
+      tnlAssert( this->getNonzeroElementsInRow( i ) <= matrixSize,
                  cerr << "getNonzeroElementsInRow( " << i << " ) = " << getNonzeroElementsInRow( i ) 
                       << "; matrixSize = " << matrixSize );
-      permutation[ this -> getNonzeroElementsInRow( i ) ] ++;
+      permutation[ this->getNonzeroElementsInRow( i ) ] ++;
    }
 
    tnlVector< Index, tnlHost, Index > buckets( "tnlMatrix::reorderRowsDecreasingly:buckets" );
@@ -450,11 +450,11 @@ bool tnlMatrix< Real, Device, Index > :: sortRowsDecreasingly( tnlVector< Index,
 
    for( Index i = 0; i < matrixSize; i ++ )
    {
-      tnlAssert( buckets[ matrixSize - this -> getNonzeroElementsInRow( i ) ] <= matrixSize,
-               cerr << "buckets[ matrixSize - this -> getNonzeroElementsInRow( i ) - 1 ] = " << buckets[ matrixSize - this -> getNonzeroElementsInRow( i ) - 1 ]
+      tnlAssert( buckets[ matrixSize - this->getNonzeroElementsInRow( i ) ] <= matrixSize,
+               cerr << "buckets[ matrixSize - this->getNonzeroElementsInRow( i ) - 1 ] = " << buckets[ matrixSize - this->getNonzeroElementsInRow( i ) - 1 ]
                     << "; matrixSize = " << matrixSize );
-      dbgExpr( buckets[ matrixSize - this -> getNonzeroElementsInRow( i ) ] );
-      permutation[ buckets[ matrixSize - this -> getNonzeroElementsInRow( i ) ] ++ ] = i;
+      dbgExpr( buckets[ matrixSize - this->getNonzeroElementsInRow( i ) ] );
+      permutation[ buckets[ matrixSize - this->getNonzeroElementsInRow( i ) ] ++ ] = i;
    }
    return true;
 }
@@ -485,11 +485,11 @@ bool tnlMatrix< Real, Device, Index > :: draw( ostream& str,
 	if( format == "eps" )
 	{
 	   const int elementSize = 10;
-	   this -> writePostscriptHeader( str, elementSize );
+	   this->writePostscriptHeader( str, elementSize );
 	   if( csrMatrix )
 	      csrMatrix -> writePostscriptBody( str, elementSize, verbose );
 	   else
-	      this -> writePostscriptBody( str, elementSize, verbose );
+	      this->writePostscriptBody( str, elementSize, verbose );
 
 	   str << "showpage" << endl;
       str << "%%EOF" << endl;
@@ -506,7 +506,7 @@ template< typename Real, typename Device, typename Index >
 void tnlMatrix< Real, Device, Index > :: writePostscriptHeader( ostream& str,
                                                                 const int elementSize ) const
 {
-   const int scale = elementSize * this -> getSize();
+   const int scale = elementSize * this->getSize();
    str << "%!PS-Adobe-2.0 EPSF-2.0" << endl;
    str << "%%BoundingBox: 0 0 " << scale << " " << scale << endl;
    str << "%%Creator: TNL" << endl;
@@ -520,8 +520,8 @@ void tnlMatrix< Real, Device, Index > :: writePostscriptBody( ostream& str,
                                                               const int elementSize,
                                                               bool verbose ) const
 {
-   const double scale = elementSize * this -> getSize();
-   double hx = scale / ( double ) this -> getSize();
+   const double scale = elementSize * this->getSize();
+   double hx = scale / ( double ) this->getSize();
    Index lastRow( 0 ), lastColumn( 0 );
    for( Index row = 0; row < getSize(); row ++ )
    {
diff --git a/src/legacy/matrices/tnlRgCSRMatrix.h b/src/legacy/matrices/tnlRgCSRMatrix.h
index f6d3f98bcdebd7e59908687ec757dff026d19e79..c7d5faeeb8642a7f45013309ad179e482790f0d3 100644
--- a/src/legacy/matrices/tnlRgCSRMatrix.h
+++ b/src/legacy/matrices/tnlRgCSRMatrix.h
@@ -242,7 +242,7 @@ tnlRgCSRMatrix< Real, Device, Index > :: tnlRgCSRMatrix( const tnlString& name )
    cudaGetDevice( &cudaDevice );
    cudaDeviceProp deviceProperties;
    cudaGetDeviceProperties( &deviceProperties, cudaDevice );
-   //this -> maxCudaGridSize = deviceProperties. maxGridSize[ 0 ];
+   //this->maxCudaGridSize = deviceProperties. maxGridSize[ 0 ];
 #endif
 };
 
@@ -274,17 +274,17 @@ Index tnlRgCSRMatrix< Real, Device, Index > :: getCUDABlockSize() const
 template< typename Real, typename Device, typename Index >
 void tnlRgCSRMatrix< Real, Device, Index > :: setCUDABlockSize( Index blockSize )
 {
-   tnlAssert( blockSize % this -> groupSize == 0, )
+   tnlAssert( blockSize % this->groupSize == 0, )
    cudaBlockSize = blockSize;
 }
 
 template< typename Real, typename Device, typename Index >
 bool tnlRgCSRMatrix< Real, Device, Index > :: setSize( Index new_size )
 {
-   this -> size = new_size;
-   if( ! groupOffsets. setSize( this -> getSize() / groupSize + ( this -> getSize() % groupSize != 0 ) + 1 ) ||
-	    ! nonzeroElementsInRow. setSize( this -> getSize() ) ||
-	    ! adaptiveGroupSizes. setSize( this -> getSize() + 1 ) )
+   this->size = new_size;
+   if( ! groupOffsets. setSize( this->getSize() / groupSize + ( this->getSize() % groupSize != 0 ) + 1 ) ||
+	    ! nonzeroElementsInRow. setSize( this->getSize() ) ||
+	    ! adaptiveGroupSizes. setSize( this->getSize() + 1 ) )
       return false;
    groupOffsets. setValue( 0 );
    nonzeroElementsInRow. setValue( 0 );
@@ -307,7 +307,7 @@ bool tnlRgCSRMatrix< Real, Device, Index > :: setNonzeroElements( Index elements
 template< typename Real, typename Device, typename Index >
 void tnlRgCSRMatrix< Real, Device, Index > :: reset()
 {
-   this -> size = 0;
+   this->size = 0;
    nonzeroElements. reset();
    columns. reset();
    groupOffsets. reset();
@@ -336,10 +336,10 @@ void tnlRgCSRMatrix< Real, Device, Index > :: tuneFormat( const Index groupSize,
                                                           const bool useAdaptiveGroupSize,
                                                           const tnlAdaptiveGroupSizeStrategy adaptiveGroupSizeStrategy )
 {
-   tnlAssert( this -> groupSize > 0, );
-   this -> groupSize = groupSize;
-   this -> useAdaptiveGroupSize = useAdaptiveGroupSize;
-   this -> adaptiveGroupSizeStrategy = adaptiveGroupSizeStrategy;
+   tnlAssert( this->groupSize > 0, );
+   this->groupSize = groupSize;
+   this->useAdaptiveGroupSize = useAdaptiveGroupSize;
+   this->adaptiveGroupSizeStrategy = adaptiveGroupSizeStrategy;
 }
 
 
@@ -356,7 +356,7 @@ bool tnlRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatrix< Real
       return false;
    }
 
-	if( ! this -> setSize( csr_matrix. getRows() ) )
+	if( ! this->setSize( csr_matrix. getRows() ) )
 		return false;
 	dbgExpr( csr_matrix. getSize() );
 
@@ -364,14 +364,14 @@ bool tnlRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatrix< Real
 	 * In case of adaptive group sizes compute maximum number of the non-zero elements in group.
 	 */
 	Index maxNonzeroElementsInGroup( 0 );
-	if( this -> useAdaptiveGroupSize )
+	if( this->useAdaptiveGroupSize )
 	{
-	   if( this -> adaptiveGroupSizeStrategy == tnlAdaptiveGroupSizeStrategyByAverageRowSize )
+	   if( this->adaptiveGroupSizeStrategy == tnlAdaptiveGroupSizeStrategyByAverageRowSize )
 	   {
 	      const Index averageRowSize = ceil( ( double ) csr_matrix. getNumberOfAllocatedElements() / ( double ) csr_matrix. getRows() );
 	      maxNonzeroElementsInGroup = averageRowSize * groupSize;
 	   }
-	   //if( this -> adaptiveGroupSizeStrategy == tnlAdaptiveGroupSizeStrategyByFirstGroup )
+	   //if( this->adaptiveGroupSizeStrategy == tnlAdaptiveGroupSizeStrategyByFirstGroup )
 	   //   for( Index row = 0; row < groupSize; row ++ )
 	   //      maxNonzeroElementsInGroup += csr_matrix. getNonzeroElementsInRow( row );
 	}
@@ -387,16 +387,16 @@ bool tnlRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatrix< Real
 	Index processedLines( 0 );
 	numberOfGroups = 0;
 	groupOffsets[ 0 ] = 0;
-	for( Index i = 0; i < this -> getSize(); i ++ )
+	for( Index i = 0; i < this->getSize(); i ++ )
 	{
 		if( i > 0 && i % groupSize == 0 )
 		{
 		   currentGroupSize += groupSize;
-		   if( ! this -> useAdaptiveGroupSize ||
+		   if( ! this->useAdaptiveGroupSize ||
 		       ( nonzeroElementsInGroup > maxNonzeroElementsInGroup && cudaBlockSize % currentGroupSize == 0 )
 		       || currentGroupSize == cudaBlockSize )
 		   {
-		      if( this -> useAdaptiveGroupSize )
+		      if( this->useAdaptiveGroupSize )
 		         adaptiveGroupSizes[ numberOfGroups + 1 ] = currentGroupSize;
 
 		      dbgCout( numberOfGroups << "-th group size is " << currentGroupSize );
@@ -419,7 +419,7 @@ bool tnlRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatrix< Real
 
 	}
 	dbgExpr( processedLines );
-	currentGroupSize = this -> getSize() - processedLines;
+	currentGroupSize = this->getSize() - processedLines;
 	total_elements += max_row_in_block * ( currentGroupSize );
 	groupOffsets[ numberOfGroups + 1 ] = total_elements;
    if( useAdaptiveGroupSize )
@@ -432,7 +432,7 @@ bool tnlRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatrix< Real
        for( Index i = 1; i < adaptiveGroupSizes. getSize(); i ++ )
           adaptiveGroupSizes[ i ] += adaptiveGroupSizes[ i - 1 ];
        dbgExpr( adaptiveGroupSizes );
-       dbgExpr( this -> getSize() );
+       dbgExpr( this->getSize() );
    }
 	dbgCout( numberOfGroups << "-th group size is " << currentGroupSize );
 	numberOfGroups ++;
@@ -477,7 +477,7 @@ bool tnlRgCSRMatrix< Real, Device, Index > :: copyFrom( const tnlCSRMatrix< Real
             /****
              * Get the element position
              */
-            tnlAssert( elementRow < this -> getSize(), cerr << "Element row = " << elementRow );
+            tnlAssert( elementRow < this->getSize(), cerr << "Element row = " << elementRow );
             Index elementPos = csr_matrix. row_offsets[ elementRow ];
             while( elementPos < csr_matrix. row_offsets[ elementRow + 1 ] )
             {
@@ -505,9 +505,9 @@ copyFrom( const tnlRgCSRMatrix< Real, Device2, Index >& rgCSRMatrix )
    dbgFunctionName( "tnlRgCSRMatrix< Real, Device, Index >", "copyFrom" );
    tnlAssert( rgCSRMatrix. getSize() > 0, cerr << "Copying from matrix with non-positiove size." );
 
-   this -> cudaBlockSize = rgCSRMatrix. cudaBlockSize;
-   this -> groupSize = rgCSRMatrix. groupSize;
-   if( ! this -> setSize( rgCSRMatrix. getSize() ) )
+   this->cudaBlockSize = rgCSRMatrix. cudaBlockSize;
+   this->groupSize = rgCSRMatrix. groupSize;
+   if( ! this->setSize( rgCSRMatrix. getSize() ) )
       return false;
 
    /****
@@ -518,19 +518,19 @@ copyFrom( const tnlRgCSRMatrix< Real, Device2, Index >& rgCSRMatrix )
    dbgCout( "Allocating " << total_elements << " elements.");
    if( ! setNonzeroElements( total_elements ) )
       return false;
-   this -> artificial_zeros = total_elements - rgCSRMatrix. getNonzeroElements();
-
-   this -> nonzeroElements = rgCSRMatrix. nonzeroElements;
-   this -> columns = rgCSRMatrix. columns;
-   this -> groupOffsets = rgCSRMatrix. groupOffsets;
-   this -> nonzeroElementsInRow = rgCSRMatrix. nonzeroElementsInRow;
-   this -> last_nonzero_element = rgCSRMatrix. last_nonzero_element;
-
-   this -> numberOfGroups = rgCSRMatrix. numberOfGroups;
-   this -> adaptiveGroupSizes = rgCSRMatrix. adaptiveGroupSizes;
-   this -> useAdaptiveGroupSize = rgCSRMatrix. useAdaptiveGroupSize;
-   this -> adaptiveGroupSizeStrategy = rgCSRMatrix. adaptiveGroupSizeStrategy;
-   //this -> maxCudaGridSize = rgCSRMatrix. maxCudaGridSize;
+   this->artificial_zeros = total_elements - rgCSRMatrix. getNonzeroElements();
+
+   this->nonzeroElements = rgCSRMatrix. nonzeroElements;
+   this->columns = rgCSRMatrix. columns;
+   this->groupOffsets = rgCSRMatrix. groupOffsets;
+   this->nonzeroElementsInRow = rgCSRMatrix. nonzeroElementsInRow;
+   this->last_nonzero_element = rgCSRMatrix. last_nonzero_element;
+
+   this->numberOfGroups = rgCSRMatrix. numberOfGroups;
+   this->adaptiveGroupSizes = rgCSRMatrix. adaptiveGroupSizes;
+   this->useAdaptiveGroupSize = rgCSRMatrix. useAdaptiveGroupSize;
+   this->adaptiveGroupSizeStrategy = rgCSRMatrix. adaptiveGroupSizeStrategy;
+   //this->maxCudaGridSize = rgCSRMatrix. maxCudaGridSize;
    return true;
 };
 
@@ -540,7 +540,7 @@ Real tnlRgCSRMatrix< Real, Device, Index > :: getElement( Index row,
                                                           Index column ) const
 {
    dbgFunctionName( "tnlRgCSRMatrix< Real, Device, Index >", "getElement" );
-	tnlAssert( 0 <= row && row < this -> getSize(),
+	tnlAssert( 0 <= row && row < this->getSize(),
 			   cerr << "The row is outside the matrix." );
    if( Device :: getDevice() == tnlHostDevice )
    {
@@ -577,11 +577,11 @@ template< typename Real, typename Device, typename Index >
 Real tnlRgCSRMatrix< Real, Device, Index > :: rowProduct( Index row,
                                                           const tnlVector< Real, Device, Index >& vec ) const
 {
-   tnlAssert( 0 <= row && row < this -> getSize(),
+   tnlAssert( 0 <= row && row < this->getSize(),
               cerr << "The row is outside the matrix." );
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
 
    if( Device :: getDevice() == tnlHostDevice )
@@ -618,13 +618,13 @@ void tnlRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVector< Re
                                                              tnlVector< Real, Device, Index >& result ) const
 {
    dbgFunctionName( "tnlRgCSRMatrix< Real, tnlHost >", "vectorProduct" )
-   tnlAssert( vec. getSize() == this -> getSize(),
+   tnlAssert( vec. getSize() == this->getSize(),
               cerr << "The matrix and vector for a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
-   tnlAssert( result. getSize() == this -> getSize(),
+   tnlAssert( result. getSize() == this->getSize(),
               cerr << "The matrix and result vector of a multiplication have different sizes. "
-                   << "The matrix size is " << this -> getSize() << "."
+                   << "The matrix size is " << this->getSize() << "."
                    << "The vector size is " << vec. getSize() << endl; );
 
    if( Device :: getDevice() == tnlHostDevice )
@@ -633,8 +633,8 @@ void tnlRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVector< Re
       /****
        * This is exact emulation of the CUDA kernel
        */
-      Index blockSize = 256; //this -> getCUDABlockSize();
-      const Index size = this -> getSize();
+      Index blockSize = 256; //this->getCUDABlockSize();
+      const Index size = this->getSize();
       Index gridSize = size / blockSize + ( size % blockSize != 0 ) + 1;
       for( Index blockIdx = 0; blockIdx < gridSize; blockIdx ++ )
          for( Index threadIdx = 0; threadIdx < blockSize; threadIdx ++ )
@@ -643,10 +643,10 @@ void tnlRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVector< Re
             if( rowIndex >= size )
                continue;
 
-            const Index groupIndex = floor( threadIdx / this -> groupSize );
-            const Index globalGroupIndex = this -> getGroupIndexFromRow( rowIndex );
-            const Index rowOffsetInGroup = this -> getRowIndexInGroup( rowIndex, globalGroupIndex );
-            const Index currentGroupSize = this -> getCurrentGroupSize( globalGroupIndex );
+            const Index groupIndex = floor( threadIdx / this->groupSize );
+            const Index globalGroupIndex = this->getGroupIndexFromRow( rowIndex );
+            const Index rowOffsetInGroup = this->getRowIndexInGroup( rowIndex, globalGroupIndex );
+            const Index currentGroupSize = this->getCurrentGroupSize( globalGroupIndex );
             tnlAssert( rowOffsetInGroup < currentGroupSize, cerr << "rowOffsetInGroup = " << rowOffsetInGroup << ", currentGroupSize = " << currentGroupSize  );
 
             Real product( 0.0 );
@@ -733,12 +733,12 @@ void tnlRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVector< Re
    if( Device :: getDevice() == tnlCudaDevice )
    {
 #ifdef HAVE_CUDA
-      Index blockSize = this -> getCUDABlockSize();
-      const Index size = this -> getSize();
+      Index blockSize = this->getCUDABlockSize();
+      const Index size = this->getSize();
 
-      if( this -> useAdaptiveGroupSize )
+      if( this->useAdaptiveGroupSize )
       {
-         int gridSize = this -> numberOfGroups;
+         int gridSize = this->numberOfGroups;
          int numberOfGrids = gridSize / maxCudaGridSize + ( gridSize % maxCudaGridSize != 0 );
          int gridNumber( 0 );
          while( gridSize > 0 )
@@ -750,7 +750,7 @@ void tnlRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVector< Re
             /*tnlRgCSRMatrixAdpativeGroupSizeVectorProductKernel< Real, Index >
                                                               <<< gridDim, blockDim, sharedBytes >>>
                                                               ( gridNumber,
-                                                                this -> maxCudaGridSize,
+                                                                this->maxCudaGridSize,
                                                                 size,
                                                                 adaptiveGroupSizes. getData(),
                                                                 nonzeroElements. getData(),
@@ -769,14 +769,14 @@ void tnlRgCSRMatrix< Real, Device, Index > :: vectorProduct( const tnlVector< Re
          int gridNumber( 0 );
          while( gridSize > 0 )
          {
-            /*int currentGridSize = Min( gridSize, this -> maxCudaGridSize );
+            /*int currentGridSize = Min( gridSize, this->maxCudaGridSize );
             dim3 gridDim( currentGridSize ), blockDim( blockSize );
             tnlRgCSRMatrixVectorProductKernel< Real, Index >
                                              <<< gridDim, blockDim >>>
                                              ( gridNumber,
-                                               this -> maxCudaGridSize,
+                                               this->maxCudaGridSize,
                                                size,
-                                               this -> groupSize,
+                                               this->groupSize,
                                                nonzeroElements. getData(),
                                                columns. getData(),
                                                groupOffsets. getData(),
@@ -807,22 +807,22 @@ void tnlRgCSRMatrix< Real, Device, Index > :: printOut( ostream& str,
    {
       str << "Structure of tnlRgCSRMatrix" << endl;
       str << "Matrix name:" << name << endl;
-      str << "Matrix size:" << this -> getSize() << endl;
+      str << "Matrix size:" << this->getSize() << endl;
       str << "Allocated elements:" << nonzeroElements. getSize() << endl;
       str << "Number of groups: " << groupOffsets. getSize() << endl;
 
       Index print_lines = lines;
       if( ! print_lines )
-         print_lines = this -> getSize();
+         print_lines = this->getSize();
 
-      for( Index i = 0; i < this -> numberOfGroups; i ++ )
+      for( Index i = 0; i < this->numberOfGroups; i ++ )
       {
          if( i * groupSize > print_lines )
             return;
          str << endl << "Block number: " << i << endl;
-         str << " Group size: " << this -> getCurrentGroupSize( i ) << endl;
+         str << " Group size: " << this->getCurrentGroupSize( i ) << endl;
          str << " Group non-zeros: ";
-         for( Index k = i * groupSize; k < ( i + 1 ) * groupSize && k < this -> getSize(); k ++ )
+         for( Index k = i * groupSize; k < ( i + 1 ) * groupSize && k < this->getSize(); k ++ )
             str << nonzeroElementsInRow. getElement( k ) << "  ";
          str << endl;
          str << " Group data: "
@@ -855,22 +855,22 @@ void tnlRgCSRMatrix< Real, Device, Index > :: printOut( ostream& str,
    {
       str << "<h1>Structure of tnlRgCSRMatrix</h1>" << endl;
       str << "<b>Matrix name:</b> " << name << "<p>" << endl;
-      str << "<b>Matrix size:</b> " << this -> getSize() << "<p>" << endl;
+      str << "<b>Matrix size:</b> " << this->getSize() << "<p>" << endl;
       str << "<b>Allocated elements:</b> " << nonzeroElements. getSize() << "<p>" << endl;
-      str << "<b>Number of groups:</b> " << this -> numberOfGroups << "<p>" << endl;
+      str << "<b>Number of groups:</b> " << this->numberOfGroups << "<p>" << endl;
       str << "<table border=1>" << endl;
       str << "<tr> <td> <b> GroupId </b> </td> <td> <b> Size </b> </td> <td> <b> % of nonzeros </b> </td> </tr>" << endl;
       Index print_lines = lines;
       if( ! print_lines )
-         print_lines = this -> getSize();
+         print_lines = this->getSize();
 
-      for( Index i = 0; i < this -> numberOfGroups; i ++ )
+      for( Index i = 0; i < this->numberOfGroups; i ++ )
       {
          if( i * groupSize > print_lines )
             return;
-         double filling = ( double ) ( this -> groupOffsets. getElement( i + 1 ) - this -> groupOffsets. getElement( i ) ) /
-                          ( double ) this -> nonzeroElements. getSize();
-         str << "<tr> <td> " << i << "</td> <td>" << this -> getCurrentGroupSize( i ) << " </td> <td> " << 100.0 * filling << "% </td></tr>" << endl;
+         double filling = ( double ) ( this->groupOffsets. getElement( i + 1 ) - this->groupOffsets. getElement( i ) ) /
+                          ( double ) this->nonzeroElements. getSize();
+         str << "<tr> <td> " << i << "</td> <td>" << this->getCurrentGroupSize( i ) << " </td> <td> " << 100.0 * filling << "% </td></tr>" << endl;
       }
       str << "</table>" << endl;
       str << endl;
@@ -893,7 +893,7 @@ bool tnlRgCSRMatrix< Real, Device, Index > :: draw( ostream& str,
    if( format == "eps" )
    {
       const int elementSize = 10;
-      this -> writePostscriptHeader( str, elementSize );
+      this->writePostscriptHeader( str, elementSize );
 
       /****
        * Draw the groups
@@ -906,19 +906,19 @@ bool tnlRgCSRMatrix< Real, Device, Index > :: draw( ostream& str,
          else
             str << "0.8 0.8 0.8 setrgbcolor" << endl;
          str << "0 -" << groupSize * elementSize
-             << " translate newpath 0 0 " << this -> getSize() * elementSize
+             << " translate newpath 0 0 " << this->getSize() * elementSize
              << " " << groupSize * elementSize << " rectfill" << endl;
       }
       /****
        * Restore black color and the origin of the coordinates
        */
       str << "0 0 0 setrgbcolor" << endl;
-      str << "0 " << this -> getSize() * elementSize << " translate" << endl;
+      str << "0 " << this->getSize() * elementSize << " translate" << endl;
 
       if( csrMatrix )
          csrMatrix -> writePostscriptBody( str, elementSize, verbose );
       else
-         this -> writePostscriptBody( str, elementSize, verbose );
+         this->writePostscriptBody( str, elementSize, verbose );
 
       str << "showpage" << endl;
       str << "%%EOF" << endl;
@@ -937,28 +937,28 @@ Index tnlRgCSRMatrix< Real, Device, Index > :: getCurrentGroupSize( const Index
    /****
     * If we use adaptive group sizes they are stored explicitly.
     */
-   if( this -> useAdaptiveGroupSize )
-      return this -> adaptiveGroupSizes. getElement( groupId + 1 ) -
-             this -> adaptiveGroupSizes. getElement( groupId );
+   if( this->useAdaptiveGroupSize )
+      return this->adaptiveGroupSizes. getElement( groupId + 1 ) -
+             this->adaptiveGroupSizes. getElement( groupId );
    /****
     * The last group may be smaller even if we have constant group size.
     */
-   if( ( groupId + 1 ) * this -> groupSize > this -> getSize() )
-      return this -> getSize() % this -> groupSize;
+   if( ( groupId + 1 ) * this->groupSize > this->getSize() )
+      return this->getSize() % this->groupSize;
    /***
     * If it is not the last group, return the common group size.
     */
-   return this -> groupSize;
+   return this->groupSize;
 }
 
 template< typename Real, typename Device, typename Index >
 Index tnlRgCSRMatrix< Real, Device, Index > :: getGroupIndexFromRow( const Index row ) const
 {
-   tnlAssert( row < this -> getSize(), cerr << " row = " << row << " matrix size = " << this -> getSize() );
-   if( this -> useAdaptiveGroupSize )
+   tnlAssert( row < this->getSize(), cerr << " row = " << row << " matrix size = " << this->getSize() );
+   if( this->useAdaptiveGroupSize )
    {
       Index groupId = -1;
-      while( this -> adaptiveGroupSizes. getElement( groupId + 1 ) <= row )
+      while( this->adaptiveGroupSizes. getElement( groupId + 1 ) <= row )
          groupId ++;
       return groupId;
    }
@@ -968,9 +968,9 @@ Index tnlRgCSRMatrix< Real, Device, Index > :: getGroupIndexFromRow( const Index
 template< typename Real, typename Device, typename Index >
 Index tnlRgCSRMatrix< Real, Device, Index > :: getRowIndexInGroup( const Index row, const Index groupId ) const
 {
-   tnlAssert( row < this -> getSize(), cerr << " row = " << row << " matrix size = " << this -> getSize() );
+   tnlAssert( row < this->getSize(), cerr << " row = " << row << " matrix size = " << this->getSize() );
    tnlAssert( groupId < numberOfGroups, cerr << " groupId = " << groupId << " numberOfGroups = " << numberOfGroups );
-   if( this -> useAdaptiveGroupSize )
+   if( this->useAdaptiveGroupSize )
       return row - adaptiveGroupSizes. getElement( groupId );
    return row % groupSize;
 
diff --git a/src/legacy/solvers/tnlGMRESSolverOld.h b/src/legacy/solvers/tnlGMRESSolverOld.h
index 41a8ec4bca5b34d798342d6352789fb1e17757a4..98d8dae911497480603596410591a9738d22763e 100644
--- a/src/legacy/solvers/tnlGMRESSolverOld.h
+++ b/src/legacy/solvers/tnlGMRESSolverOld.h
@@ -170,13 +170,13 @@ bool tnlGMRESSolverOld< Real, Device, Index > :: solve( const tnlMatrix< Real, D
 
    if( normb == 0.0 ) normb = 1.0;
 
-   this -> iteration = 0;
-   this -> residue = beta / normb;
+   this->iteration = 0;
+   this->residue = beta / normb;
 
    tnlSharedVector< Real, Device, Index > vi;
    tnlSharedVector< Real, Device, Index > vk;
-   while( this -> iteration < max_iterations &&
-          this -> residue > max_residue )
+   while( this->iteration < max_iterations &&
+          this->residue > max_residue )
    {
       const Index m = restarting;
       for( i = 0; i < m + 1; i ++ )
@@ -199,7 +199,7 @@ bool tnlGMRESSolverOld< Real, Device, Index > :: solve( const tnlMatrix< Real, D
 
 
       //dbgCout( " ----------- Starting m-loop -----------------" );
-      for( i = 0; i < m && this -> iteration <= max_iterations; i++ )
+      for( i = 0; i < m && this->iteration <= max_iterations; i++ )
       {
          vi. bind( &( _v. getData()[ i * size ] ), size );
          /****
@@ -260,20 +260,20 @@ bool tnlGMRESSolverOld< Real, Device, Index > :: solve( const tnlMatrix< Real, D
                              cs[ i ],
                              sn[ i ] );
 
-         this -> residue = fabs( s[ i + 1 ] ) / normb;
+         this->residue = fabs( s[ i + 1 ] ) / normb;
 
-         if( this -> iteration % 10 == 0 &&
-             this -> verbosity > 1 )
-            this -> printOut();
-         if( this -> residue < max_residue )
+         if( this->iteration % 10 == 0 &&
+             this->verbosity > 1 )
+            this->printOut();
+         if( this->residue < max_residue )
          {
             update( i, m, _H, _s, _v, x );
-            if( this -> verbosity > 0 )
-               this -> printOut();
+            if( this->verbosity > 0 )
+               this->printOut();
             return true;
          }
          //DBG_WAIT;
-         this -> iteration ++;
+         this->iteration ++;
       }
       update( m - 1, m, _H, _s, _v, x );
       //dbgCout_ARRAY( x, size );
@@ -299,12 +299,12 @@ bool tnlGMRESSolverOld< Real, Device, Index > :: solve( const tnlMatrix< Real, D
       //dbgCout_ARRAY( r, size );
       //dbgExpr( beta );
       //dbgExpr( beta / normb );
-      this -> residue = beta / normb;
-      this -> iteration ++;
+      this->residue = beta / normb;
+      this->iteration ++;
    }
-   if( this -> verbosity > 0 )
-      this -> printOut();
-   if( this -> iteration == max_iterations ) return false;
+   if( this->verbosity > 0 )
+      this->printOut();
+   if( this->iteration == max_iterations ) return false;
    return true;
 };
 
@@ -342,7 +342,7 @@ void tnlGMRESSolverOld< Real, Device, Index > :: update( Index k,
    tnlSharedVector< Real, Device, Index > vi;
    for( i = 0; i <= k; i++)
    {
-      vi. bind( &( v. getData()[ i * this -> size ] ), x. getSize() );
+      vi. bind( &( v. getData()[ i * this->size ] ), x. getSize() );
       x. alphaXPlusY( y[ i ], vi );
    }
 };
diff --git a/src/legacy/solvers/tnlMatrixSolver.h b/src/legacy/solvers/tnlMatrixSolver.h
index f5351963d3cfdec6be6ef77aa18fe467f324b178..21077d1432951197196451d1e065426e2420e498 100644
--- a/src/legacy/solvers/tnlMatrixSolver.h
+++ b/src/legacy/solvers/tnlMatrixSolver.h
@@ -89,49 +89,49 @@ tnlMatrixSolver< Real, Device, Index > :: tnlMatrixSolver( const tnlString& name
 template< typename Real, typename Device, typename Index >
 Index tnlMatrixSolver< Real, Device, Index > :: getIterationNumber() const
 {
-   return this -> iteration;
+   return this->iteration;
 };
 
 template< typename Real, typename Device, typename Index >
 const Real& tnlMatrixSolver< Real, Device, Index > :: getResidue() const
 {
-   return this -> residue;
+   return this->residue;
 };
 
 template< typename Real, typename Device, typename Index >
 void tnlMatrixSolver< Real, Device, Index > :: setVerbosity( int verbose )
 {
-   this -> verbosity = verbose;
+   this->verbosity = verbose;
 };
 
 template< typename Real, typename Device, typename Index >
 void tnlMatrixSolver< Real, Device, Index > :: setTimerCPU( tnlTimerCPU* timer )
 {
-   this -> cpu_timer = timer;
+   this->cpu_timer = timer;
 };
 
 template< typename Real, typename Device, typename Index >
 void tnlMatrixSolver< Real, Device, Index > :: setTimerRT( tnlTimerRT* timer )
 {
-   this -> rt_timer = timer;
+   this->rt_timer = timer;
 };
 
 template< typename Real, typename Device, typename Index >
 void tnlMatrixSolver< Real, Device, Index > :: printOut()
 {
-   if( this -> verbosity > 0 )
+   if( this->verbosity > 0 )
    {
       int cpu_time = 0;
-      if( this -> cpu_timer ) cpu_time = this -> cpu_timer -> getTime( 0, this -> solver_comm );
+      if( this->cpu_timer ) cpu_time = this->cpu_timer -> getTime( 0, this->solver_comm );
       if( MPIGetRank() != 0 ) return;
       // TODO: add EST
       //cout << " EST: " << estimated;
       cout << " ITER:" << setw( 8 ) << getIterationNumber()
            << " RES:" << setprecision( 5 ) << setw( 12 ) << getResidue();
-      if( this -> cpu_timer )
+      if( this->cpu_timer )
          cout << " CPU: " << setw( 8 ) << cpu_time;
-      if( this -> rt_timer )
-         cout << " ELA: " << setw( 8 ) << this -> rt_timer -> getTime();
+      if( this->rt_timer )
+         cout << " ELA: " << setw( 8 ) << this->rt_timer -> getTime();
       cout << "   \r" << flush;
    }
 };
diff --git a/src/legacy/solvers/tnlSORSolver.h b/src/legacy/solvers/tnlSORSolver.h
index a184311b11ce7e0fdeb1d17683299514ca29c3c2..4cb3e4c97a330dba100faad6664a3fa436a2631c 100644
--- a/src/legacy/solvers/tnlSORSolver.h
+++ b/src/legacy/solvers/tnlSORSolver.h
@@ -69,13 +69,13 @@ tnlString tnlSORSolverOld< Real, Device, Index > :: getType() const
 template< typename Real, typename Device, typename Index >
 void tnlSORSolverOld< Real, Device, Index > :: setSOROmega( const Real& omega )
 {
-   this -> sorOmega = omega;
+   this->sorOmega = omega;
 }
 
 template< typename Real, typename Device, typename Index >
 Real tnlSORSolverOld< Real, Device, Index > :: getSOROmega( ) const
 {
-   return this -> sorOmega;
+   return this->sorOmega;
 }
 
 template< typename Real, typename Device, typename Index >
@@ -88,33 +88,33 @@ bool tnlSORSolverOld< Real, Device, Index > :: solve( const tnlMatrix< Real, Dev
 {
    const Index size = A. getSize();
 
-   this -> iteration = 0;
-   this -> residue = max_residue + 1.0;;
+   this->iteration = 0;
+   this->residue = max_residue + 1.0;;
 
    Real bNorm = b. lpNorm( ( Real ) 2.0 );
 
-   while( this -> iteration < max_iterations &&
-          max_residue < this -> residue )
+   while( this->iteration < max_iterations &&
+          max_residue < this->residue )
    {
-      A. performSORIteration( this -> sorOmega,
+      A. performSORIteration( this->sorOmega,
                               b,
                               x,
                               0,
                               size );
-      if( this -> iteration % 10 == 0 )
+      if( this->iteration % 10 == 0 )
       {
-         this -> residue = this -> getResidue( A, b, x, bNorm );
-         if( this -> verbosity > 1 )
-            this -> printOut();
+         this->residue = this->getResidue( A, b, x, bNorm );
+         if( this->verbosity > 1 )
+            this->printOut();
       }
-      this -> iteration ++;
+      this->iteration ++;
    }
-   if( this -> verbosity > 0 )
+   if( this->verbosity > 0 )
    {
-      this -> residue = this -> getResidue( A, b, x, bNorm );
-      this -> printOut();
+      this->residue = this->getResidue( A, b, x, bNorm );
+      this->printOut();
    }
-   if( this -> iteration <= max_iterations ) return true;
+   if( this->iteration <= max_iterations ) return true;
    return false;
 };
 
diff --git a/src/matrices/tnlCSRMatrix.h b/src/matrices/tnlCSRMatrix.h
index ac272baf2247aaa93622eb8e4ed8888f23e13ec8..343f5ed277548a37f5202a93d4222a9128961cac 100644
--- a/src/matrices/tnlCSRMatrix.h
+++ b/src/matrices/tnlCSRMatrix.h
@@ -21,6 +21,11 @@
 #include <matrices/tnlSparseMatrix.h>
 #include <core/vectors/tnlVector.h>
 
+#ifdef HAVE_UMFPACK
+    template< typename Matrix, typename Preconditioner >
+    class tnlUmfpackWrapper;
+#endif
+
 template< typename Real >
 class tnlCusparseCSRMatrix;
 
@@ -209,6 +214,10 @@ class tnlCSRMatrix : public tnlSparseMatrix< Real, Device, Index >
    typedef tnlCSRMatrixDeviceDependentCode< DeviceType > DeviceDependentCode;
    friend class tnlCSRMatrixDeviceDependentCode< DeviceType >;
    friend class tnlCusparseCSRMatrix< RealType >;
+#ifdef HAVE_UMFPACK
+    template< typename Matrix, typename Preconditioner >
+    friend class tnlUmfpackWrapper;
+#endif
 
 };
 
diff --git a/src/matrices/tnlCSRMatrix_impl.h b/src/matrices/tnlCSRMatrix_impl.h
index c25354311c5c8e0799b4eafdbf4761839435ac69..6622a0e0d55e8a04e38a971fa5834d06221e2f1d 100644
--- a/src/matrices/tnlCSRMatrix_impl.h
+++ b/src/matrices/tnlCSRMatrix_impl.h
@@ -726,7 +726,7 @@ class tnlCSRMatrixDeviceDependentCode< tnlHost >
          const InVector* inVectorPtr = &inVector;
          OutVector* outVectorPtr = &outVector;
 #ifdef HAVE_OPENMP
-#pragma omp parallel for private( matrixPtr, inVectorPtr, outVectorPtr ), schedule(static )
+#pragma omp parallel for firstprivate( matrixPtr, inVectorPtr, outVectorPtr ), schedule(static ), if( tnlHost::isOMPEnabled() )
 #endif         
          for( Index row = 0; row < rows; row ++ )
             ( *outVectorPtr )[ row ] = matrixPtr->rowVectorProduct( row, *inVectorPtr );
diff --git a/src/matrices/tnlDenseMatrix.h b/src/matrices/tnlDenseMatrix.h
index 7e158ff519f6b86a89552ca6d281920224c7d2bc..b9862b0d4adbb5bab80ac825986c74d97a45a969 100644
--- a/src/matrices/tnlDenseMatrix.h
+++ b/src/matrices/tnlDenseMatrix.h
@@ -122,8 +122,8 @@ class tnlDenseMatrix : public tnlMatrix< Real, Device, Index >
                 const RealType& thisRowMultiplicator = 1.0 );
 
    __cuda_callable__
-   Real getElementFast( const IndexType row,
-                        const IndexType column ) const;
+   const Real& getElementFast( const IndexType row,
+                               const IndexType column ) const;
 
    Real getElement( const IndexType row,
                     const IndexType column ) const;
diff --git a/src/matrices/tnlDenseMatrix_impl.h b/src/matrices/tnlDenseMatrix_impl.h
index 557070f17207fb357e1b16094cabab3dbcb498ee..bcaf48a166fdf8ace882699151646b2cd8d23de1 100644
--- a/src/matrices/tnlDenseMatrix_impl.h
+++ b/src/matrices/tnlDenseMatrix_impl.h
@@ -48,7 +48,7 @@ template< typename Real,
           typename Index >
 tnlString tnlDenseMatrix< Real, Device, Index >::getTypeVirtual() const
 {
-   return this -> getType();
+   return this->getType();
 }
 
 template< typename Real,
@@ -281,8 +281,8 @@ template< typename Real,
           typename Device,
           typename Index >
 __cuda_callable__
-Real tnlDenseMatrix< Real, Device, Index >::getElementFast( const IndexType row,
-                                                            const IndexType column ) const
+const Real& tnlDenseMatrix< Real, Device, Index >::getElementFast( const IndexType row,
+                                                                   const IndexType column ) const
 {
    tnlAssert( row >= 0 && row < this->getRows() &&
               column >= 0 && column < this->getColumns(),
@@ -932,7 +932,7 @@ class tnlDenseMatrixDeviceDependentCode< tnlHost >
                                  OutVector& outVector )
       {
 #ifdef HAVE_OPENMP
-#pragma omp parallel for
+#pragma omp parallel for if( tnlHost::isOMPEnabled() )
 #endif           
          for( Index row = 0; row < matrix.getRows(); row ++ )
             outVector[ row ] = matrix.rowVectorProduct( row, inVector );
diff --git a/src/matrices/tnlEllpackMatrix_impl.h b/src/matrices/tnlEllpackMatrix_impl.h
index a4197cb02dcf0fe6344a70843f8410cd03ec2689..6061ac0f22ead22825ae46ea4bc72524779860bd 100644
--- a/src/matrices/tnlEllpackMatrix_impl.h
+++ b/src/matrices/tnlEllpackMatrix_impl.h
@@ -688,7 +688,7 @@ class tnlEllpackMatrixDeviceDependentCode< tnlHost >
                                  OutVector& outVector )
       {
 #ifdef HAVE_OPENMP
-#pragma omp parallel for
+#pragma omp parallel for if( tnlHost::isOMPEnabled() )
 #endif           
          for( Index row = 0; row < matrix.getRows(); row ++ )
             outVector[ row ] = matrix.rowVectorProduct( row, inVector );
diff --git a/src/matrices/tnlMultidiagonalMatrix_impl.h b/src/matrices/tnlMultidiagonalMatrix_impl.h
index f425782cfdd10bcee847d548b5178b1852020278..2c8a92d0a7b1b3f2db246d7817f0a490b1e6f7cd 100644
--- a/src/matrices/tnlMultidiagonalMatrix_impl.h
+++ b/src/matrices/tnlMultidiagonalMatrix_impl.h
@@ -735,7 +735,7 @@ class tnlMultidiagonalMatrixDeviceDependentCode< tnlHost >
                                  OutVector& outVector )
       {
 #ifdef HAVE_OPENMP
-#pragma omp parallel for
+#pragma omp parallel for if( tnlHost::isOMPEnabled() )
 #endif           
          for( Index row = 0; row < matrix.getRows(); row ++ )
             outVector[ row ] = matrix.rowVectorProduct( row, inVector );
diff --git a/src/matrices/tnlSlicedEllpackMatrix_impl.h b/src/matrices/tnlSlicedEllpackMatrix_impl.h
index a185b5ea056148d71451bb961329843e4ab92463..b047ec08b3891c8ed6d6427cec95f8243424efbc 100644
--- a/src/matrices/tnlSlicedEllpackMatrix_impl.h
+++ b/src/matrices/tnlSlicedEllpackMatrix_impl.h
@@ -756,7 +756,7 @@ class tnlSlicedEllpackMatrixDeviceDependentCode< tnlHost >
                                  OutVector& outVector )
       {
 #ifdef HAVE_OPENMP
-#pragma omp parallel for
+#pragma omp parallel for if( tnlHost::isOMPEnabled() )
 #endif           
          for( Index row = 0; row < matrix.getRows(); row ++ )
             outVector[ row ] = matrix.rowVectorProduct( row, inVector );
diff --git a/src/matrices/tnlTridiagonalMatrix_impl.h b/src/matrices/tnlTridiagonalMatrix_impl.h
index 6791f7b48fa5966121e1f0a2e045f1cf95f98506..3cb917dc81849e2ce12fa4e40a3c33945d2a332a 100644
--- a/src/matrices/tnlTridiagonalMatrix_impl.h
+++ b/src/matrices/tnlTridiagonalMatrix_impl.h
@@ -654,7 +654,7 @@ class tnlTridiagonalMatrixDeviceDependentCode< tnlHost >
                                  OutVector& outVector )
       {
 #ifdef HAVE_OPENMP
-#pragma omp parallel for
+#pragma omp parallel for if( tnlHost::isOMPEnabled() )
 #endif           
          for( Index row = 0; row < matrix.getRows(); row ++ )
             outVector[ row ] = matrix.rowVectorProduct( row, inVector );
diff --git a/src/mesh/grids/tnlGrid1D_impl.h b/src/mesh/grids/tnlGrid1D_impl.h
index bd9f30ac8a3d52f1fd2a00156f32763d60fb04bb..c62ce6d88f994146759b73e130036b5312673356 100644
--- a/src/mesh/grids/tnlGrid1D_impl.h
+++ b/src/mesh/grids/tnlGrid1D_impl.h
@@ -56,7 +56,7 @@ template< typename Real,
           typename Index >
 tnlString tnlGrid< 1, Real, Device, Index >::getTypeVirtual() const
 {
-   return this -> getType();
+   return this->getType();
 }
 
 template< typename Real,
@@ -109,7 +109,7 @@ template< typename Real,
           typename Index  >
 void tnlGrid< 1, Real, Device, Index >::setDimensions( const CoordinatesType& dimensions )
 {
-   this -> setDimensions( dimensions. x() );
+   this->setDimensions( dimensions. x() );
 }
 
 template< typename Real,
@@ -278,7 +278,7 @@ tnlGrid< 1, Real, Device, Index >::getDifferenceAbsMax( const GridFunction& f1,
         cell.getCoordinates().x() < getDimensions().x();
         cell.getCoordinates().x()++ )
    {
-      IndexType c = this -> getEntityIndex( cell );
+      IndexType c = this->getEntityIndex( cell );
       maxDiff = Max( maxDiff, tnlAbs( f1[ c ] - f2[ c ] ) );
    }
    return maxDiff;
@@ -340,7 +340,7 @@ bool tnlGrid< 1, Real, Device, Index >::load( tnlFile& file )
       cerr << "I was not able to load the domain description of a tnlGrid." << endl;
       return false;
    }
-   this -> setDimensions( dimensions );
+   this->setDimensions( dimensions );
    return true;
 };
 
@@ -384,7 +384,7 @@ bool tnlGrid< 1, Real, Device, Index >::write( const MeshFunction& function,
    {
       cerr << "The size ( " << function. getSize()
            << " ) of the mesh function does not agree with the DOFs ( " 
-           << this -> template getEntitiesCount< Cell >() << " ) of a mesh." << endl;
+           << this->template getEntitiesCount< Cell >() << " ) of a mesh." << endl;
       return false;
    }
    fstream file;
diff --git a/src/mesh/grids/tnlGrid2D_impl.h b/src/mesh/grids/tnlGrid2D_impl.h
index c0b03f3c07e466ffdc60d8aae6fe206ca1b3ce3b..bfd4364aa2da8f6d43f25750451b9d65e6b70c77 100644
--- a/src/mesh/grids/tnlGrid2D_impl.h
+++ b/src/mesh/grids/tnlGrid2D_impl.h
@@ -57,7 +57,7 @@ template< typename Real,
            typename Index >
 tnlString tnlGrid< 2, Real, Device, Index > :: getTypeVirtual() const
 {
-   return this -> getType();
+   return this->getType();
 }
 
 template< typename Real,
@@ -397,7 +397,7 @@ bool tnlGrid< 2, Real, Device, Index > :: save( tnlFile& file ) const
       return false;
    if( ! this->origin.save( file ) ||
        ! this->proportions.save( file ) ||
-       ! this -> dimensions.save( file ) )
+       ! this->dimensions.save( file ) )
    {
       cerr << "I was not able to save the domain description of a tnlGrid." << endl;
       return false;
@@ -420,7 +420,7 @@ bool tnlGrid< 2, Real, Device, Index > :: load( tnlFile& file )
       cerr << "I was not able to load the domain description of a tnlGrid." << endl;
       return false;
    }
-   this -> setDimensions( dimensions );
+   this->setDimensions( dimensions );
    return true;
 };
 
@@ -456,20 +456,20 @@ bool tnlGrid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
    if( format == "asymptote" )
    {
       file << "size( "
-           << this -> getProportions(). x() << "cm , "
-           << this -> getProportions(). y() << "cm );"
+           << this->getProportions(). x() << "cm , "
+           << this->getProportions(). y() << "cm );"
            << endl << endl;
       MeshEntity< 0 > vertex( *this );
       CoordinatesType& vertexCoordinates = vertex.getCoordinates();
       VertexType v;
-      for( Index j = 0; j < this -> dimensions. y(); j ++ )
+      for( Index j = 0; j < this->dimensions. y(); j ++ )
       {
          file << "draw( ";
          vertexCoordinates.x() = 0;
          vertexCoordinates.y() = j;
          v = vertex.getCenter();
          file << "( " << v. x() << ", " << v. y() << " )";
-         for( Index i = 0; i < this -> dimensions. x(); i ++ )
+         for( Index i = 0; i < this->dimensions. x(); i ++ )
          {
             vertexCoordinates.x() = i + 1;
             vertexCoordinates.y() = j;
@@ -479,14 +479,14 @@ bool tnlGrid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
          file << " );" << endl;
       }
       file << endl;
-      for( Index i = 0; i < this -> dimensions. x(); i ++ )
+      for( Index i = 0; i < this->dimensions. x(); i ++ )
       {
          file << "draw( ";
          vertexCoordinates.x() = i;
          vertexCoordinates.y() = 0;
          v = vertex.getCenter();
          file << "( " << v. x() << ", " << v. y() << " )";
-         for( Index j = 0; j < this -> dimensions. y(); j ++ )
+         for( Index j = 0; j < this->dimensions. y(); j ++ )
          {
             vertexCoordinates.x() = i;
             vertexCoordinates.y() = j + 1;
@@ -500,8 +500,8 @@ bool tnlGrid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
       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 ++ )
-         for( Index j = 0; j < this -> dimensions. y(); j ++ )
+      for( Index i = 0; i < this->dimensions. x(); i ++ )
+         for( Index j = 0; j < this->dimensions. y(); j ++ )
          {
             cellCoordinates.x() = i;
             cellCoordinates.y() = j;
@@ -510,18 +510,18 @@ bool tnlGrid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
                  << "$\" ), ( " << v. x() << ", " << v. y() << " ), S );" << endl;
          }
 
-      for( Index i = 0; i < this -> dimensions. x(); i ++ )
-         for( Index j = 0; j < this -> dimensions. y(); j ++ )
+      for( Index i = 0; i < this->dimensions. x(); i ++ )
+         for( Index j = 0; j < this->dimensions. y(); j ++ )
          {
             VertexType v1, v2, c;
 
             /****
              * East edge normal
              */
-            /*v1 = this -> getVertex( CoordinatesType( i + 1, j ), v1 );
-            v2 = this -> getVertex( CoordinatesType( i + 1, j + 1 ), v2 );
+            /*v1 = this->getVertex( CoordinatesType( i + 1, j ), v1 );
+            v2 = this->getVertex( CoordinatesType( i + 1, j + 1 ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
-            this -> getEdgeNormal< 1, 0 >( CoordinatesType( i, j ), v );
+            this->getEdgeNormal< 1, 0 >( CoordinatesType( i, j ), v );
             v *= 0.5;
             file << "draw( ( " << c. x() << ", " << c. y() << " )--( "
                  << c. x() + v. x() << ", " << c.y() + v. y() << " ), Arrow(size=1mm),p=green);" << endl;
@@ -529,10 +529,10 @@ bool tnlGrid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
             /****
              * West edge normal
              */
-            /*this -> getVertex< -1, -1 >( CoordinatesType( i, j ), v1 );
-            this -> getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
+            /*this->getVertex< -1, -1 >( CoordinatesType( i, j ), v1 );
+            this->getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
-            this -> getEdgeNormal< -1, 0 >( CoordinatesType( i, j ), v );
+            this->getEdgeNormal< -1, 0 >( CoordinatesType( i, j ), v );
             v *= 0.5;
             file << "draw( ( " << c. x() << ", " << c. y() << " )--( "
                  << c. x() + v. x() << ", " << c.y() + v. y() << " ), Arrow(size=1mm),p=blue);" << endl;
@@ -540,10 +540,10 @@ bool tnlGrid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
             /****
              * North edge normal
              */
-            /*this -> getVertex< 1, 1 >( CoordinatesType( i, j ), v1 );
-            this -> getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
+            /*this->getVertex< 1, 1 >( CoordinatesType( i, j ), v1 );
+            this->getVertex< -1, 1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
-            this -> getEdgeNormal< 0, 1 >( CoordinatesType( i, j ), v );
+            this->getEdgeNormal< 0, 1 >( CoordinatesType( i, j ), v );
             v *= 0.5;
             file << "draw( ( " << c. x() << ", " << c. y() << " )--( "
                  << c. x() + v. x() << ", " << c.y() + v. y() << " ), Arrow(size=1mm),p=green);" << endl;
@@ -551,10 +551,10 @@ bool tnlGrid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName,
             /****
              * South edge normal
              */
-            /*this -> getVertex< 1, -1 >( CoordinatesType( i, j ), v1 );
-            this -> getVertex< -1, -1 >( CoordinatesType( i, j ), v2 );
+            /*this->getVertex< 1, -1 >( CoordinatesType( i, j ), v1 );
+            this->getVertex< -1, -1 >( CoordinatesType( i, j ), v2 );
             c = ( ( Real ) 0.5 ) * ( v1 + v2 );
-            this -> getEdgeNormal< 0, -1 >( CoordinatesType( i, j ), v );
+            this->getEdgeNormal< 0, -1 >( CoordinatesType( i, j ), v );
             v *= 0.5;
             file << "draw( ( " << c. x() << ", " << c. y() << " )--( "
                  << c. x() + v. x() << ", " << c.y() + v. y() << " ), Arrow(size=1mm),p=blue);" << endl;
diff --git a/src/mesh/grids/tnlGrid3D_impl.h b/src/mesh/grids/tnlGrid3D_impl.h
index 55974cfd2c0c10338497295da4a8a33ef157f6e4..e1608d67d184caed263a2e6b2e7e22c9e4a83498 100644
--- a/src/mesh/grids/tnlGrid3D_impl.h
+++ b/src/mesh/grids/tnlGrid3D_impl.h
@@ -61,7 +61,7 @@ template< typename Real,
           typename Index >
 tnlString tnlGrid< 3, Real, Device, Index > :: getTypeVirtual() const
 {
-   return this -> getType();
+   return this->getType();
 }
 
 template< typename Real,
@@ -203,7 +203,7 @@ template< typename Real,
           typename Index >
 void tnlGrid< 3, Real, Device, Index > :: setDimensions( const CoordinatesType& dimensions )
 {
-   return this -> setDimensions( dimensions. x(), dimensions. y(), dimensions. z() );
+   return this->setDimensions( dimensions. x(), dimensions. y(), dimensions. z() );
 }
 
 template< typename Real,
@@ -213,7 +213,7 @@ __cuda_callable__ inline
 const typename tnlGrid< 3, Real, Device, Index > :: CoordinatesType&
    tnlGrid< 3, Real, Device, Index > :: getDimensions() const
 {
-   return this -> dimensions;
+   return this->dimensions;
 }
 
 template< typename Real,
@@ -423,7 +423,7 @@ template< typename Real,
               cell.getCoordinates().x() < getDimensions().x();
               cell.getCoordinates().x()++ )
          {
-            IndexType c = this -> getEntityIndex( cell );
+            IndexType c = this->getEntityIndex( cell );
             maxDiff = Max( maxDiff, tnlAbs( f1[ c ] - f2[ c ] ) );
          }
    return maxDiff;
@@ -528,10 +528,10 @@ bool tnlGrid< 3, Real, Device, Index > :: write( const MeshFunction& function,
                                                  const tnlString& fileName,
                                                  const tnlString& format ) const
 {
-   if( this -> template getEntitiesCount< Cell >() != function. getSize() )
+   if( this->template getEntitiesCount< Cell >() != function. getSize() )
    {
       cerr << "The size ( " << function. getSize() 
-           << " ) of a mesh function does not agree with the DOFs ( " << this -> template getEntitiesCount< Cell >() << " ) of a mesh." << endl;
+           << " ) of a mesh function does not agree with the DOFs ( " << this->template getEntitiesCount< Cell >() << " ) of a mesh." << endl;
       return false;
    }
    fstream file;
diff --git a/src/mesh/grids/tnlGridTraverser.h b/src/mesh/grids/tnlGridTraverser.h
index 8b05a88e4eeec5212c3b8a67f33c92f4372a0ca4..8427932dfd340d80ac60187e72522222531baf90 100644
--- a/src/mesh/grids/tnlGridTraverser.h
+++ b/src/mesh/grids/tnlGridTraverser.h
@@ -112,8 +112,8 @@ class tnlGridTraverser< tnlGrid< 2, Real, tnlHost, Index > >
       static void
       processEntities(
          const GridType& grid,
-         const CoordinatesType& begin,
-         const CoordinatesType& end,
+         const CoordinatesType begin,
+         const CoordinatesType end,
          const CoordinatesType& entityOrientation,
          const CoordinatesType& entityBasis,         
          UserData& userData );
diff --git a/src/mesh/grids/tnlGridTraverser_impl.h b/src/mesh/grids/tnlGridTraverser_impl.h
index 93a6fdac22bae92f285b42c94dd559ead740eb25..8fd55207570d47efd120e128a7ef1d1dbea51044 100644
--- a/src/mesh/grids/tnlGridTraverser_impl.h
+++ b/src/mesh/grids/tnlGridTraverser_impl.h
@@ -38,10 +38,11 @@ processEntities(
    const CoordinatesType& entityBasis,   
    UserData& userData )
 {
+
+   
    GridEntity entity( grid );
    entity.setOrientation( entityOrientation );
    entity.setBasis( entityBasis );
-   
    if( processOnlyBoundaryEntities )
    {
       entity.getCoordinates() = begin;
@@ -71,8 +72,7 @@ template< typename Real,
           typename Index,
           typename GridEntity,
           typename UserData,
-          typename EntitiesProcessor,
-          bool processOnlyBoundaryEntities >
+          typename EntitiesProcessor >
 __global__ void 
 tnlGridTraverser1D(
    const tnlGrid< 1, Real, tnlCuda, Index >* grid,
@@ -94,13 +94,49 @@ tnlGridTraverser1D(
    
    if( coordinates.x() <= end->x() )
    {
-      if( ! processOnlyBoundaryEntities || entity.isBoundaryEntity() )
+      //if( ! processOnlyBoundaryEntities || entity.isBoundaryEntity() )
       {
          entity.refresh();
          EntitiesProcessor::processEntity( entity.getMesh(), *userData, entity );
       }
    }
 }
+
+template< typename Real,
+          typename Index,
+          typename GridEntity,
+          typename UserData,
+          typename EntitiesProcessor >
+__global__ void 
+tnlGridBoundaryTraverser1D(
+   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 )
+{
+   typedef Real RealType;
+   typedef Index IndexType;
+   typedef tnlGrid< 1, Real, tnlCuda, Index > GridType;
+   typename GridType::CoordinatesType coordinates;
+   
+   if( threadIdx.x == 0 )
+   {   
+      coordinates.x() = begin->x();
+      GridEntity entity( *grid, coordinates, *entityOrientation, *entityBasis );
+      entity.refresh();
+      EntitiesProcessor::processEntity( entity.getMesh(), *userData, entity );
+   }
+   if( threadIdx.x == 1 )
+   {   
+      coordinates.x() = end->x();
+      GridEntity entity( *grid, coordinates, *entityOrientation, *entityBasis );
+      entity.refresh();
+      EntitiesProcessor::processEntity( entity.getMesh(), *userData, entity );
+   }
+}
+
 #endif
 
 template< typename Real,           
@@ -128,21 +164,37 @@ processEntities(
    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 );
+   if( processOnlyBoundaryEntities )
+   {
+      dim3 cudaBlockSize( 2 );
+      dim3 cudaBlocks( 1 );
+      tnlGridBoundaryTraverser1D< Real, Index, GridEntity, UserData, EntitiesProcessor >
+            <<< cudaBlocks, cudaBlockSize >>>
+            ( kernelGrid,
+              kernelUserData,
+              kernelBegin,
+              kernelEnd,
+              kernelEntityOrientation,
+              kernelEntityBasis );
+   }
+   else
+   {
+      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 );
+      for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ )
+         tnlGridTraverser1D< Real, Index, GridEntity, UserData, EntitiesProcessor >
+            <<< cudaBlocks, cudaBlockSize >>>
+            ( kernelGrid,
+              kernelUserData,
+              kernelBegin,
+              kernelEnd,
+              kernelEntityOrientation,
+              kernelEntityBasis,
+              gridXIdx );
+   }
    cudaThreadSynchronize();
    checkCudaDevice;
    tnlCuda::freeFromDevice( kernelGrid );
@@ -172,8 +224,8 @@ void
 tnlGridTraverser< tnlGrid< 2, Real, tnlHost, Index > >::
 processEntities(
    const GridType& grid,
-   const CoordinatesType& begin,
-   const CoordinatesType& end,
+   const CoordinatesType begin,
+   const CoordinatesType end,
    const CoordinatesType& entityOrientation,
    const CoordinatesType& entityBasis,      
    UserData& userData )
@@ -211,6 +263,7 @@ processEntities(
    }
    else
    {
+//#pragma omp parallel for firstprivate( entity, begin, end ) if( tnlHost::isOMPEnabled() )      
       for( entity.getCoordinates().y() = begin.y();
            entity.getCoordinates().y() <= end.y();
            entity.getCoordinates().y() ++ )
@@ -314,6 +367,7 @@ processEntities(
               kernelEntityBasis,
               gridXIdx,
               gridYIdx );
+      
    cudaThreadSynchronize();
    checkCudaDevice;   
    tnlCuda::freeFromDevice( kernelGrid );
diff --git a/src/mesh/initializer/tnlMeshSuperentityStorageInitializer.h b/src/mesh/initializer/tnlMeshSuperentityStorageInitializer.h
index 89c18bf540a2c9154a71c9e31855b7c1391db369..383ed996a54bda9a873b95a0be90cae609a94b94 100644
--- a/src/mesh/initializer/tnlMeshSuperentityStorageInitializer.h
+++ b/src/mesh/initializer/tnlMeshSuperentityStorageInitializer.h
@@ -20,6 +20,7 @@
 
 #include <mesh/tnlDimensionsTag.h>
 #include <algorithm>
+#include <vector>
 
 template< typename MeshConfig >
 class tnlMeshInitializer;
diff --git a/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator.h b/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator.h
index af39c588118eb976eec6425cd2c9d068d530c5e5..9b16952d403e5b707a52c41983b40c4de4085034 100644
--- a/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator.h
+++ b/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator.h
@@ -52,7 +52,7 @@ class tnlFiniteVolumeNonlinearOperator< tnlGrid< 1,MeshReal, Device, MeshIndex >
              typename Vector,
              typename Matrix >
    __cuda_callable__
-      void updateLinearSystem( const RealType& time,
+      void setMatrixElements( const RealType& time,
                                const RealType& tau,
                                const MeshType& mesh,
                                const IndexType& index,
@@ -106,7 +106,7 @@ class tnlFiniteVolumeNonlinearOperator< tnlGrid< 2, MeshReal, Device, MeshIndex
              typename Vector,
              typename Matrix >
    __cuda_callable__
-      void updateLinearSystem( const RealType& time,
+      void setMatrixElements( const RealType& time,
                                const RealType& tau,
                                const MeshType& mesh,
                                const IndexType& index,
@@ -158,7 +158,7 @@ class tnlFiniteVolumeNonlinearOperator< tnlGrid< 3, MeshReal, Device, MeshIndex
              typename Vector,
              typename Matrix >
    __cuda_callable__
-      void updateLinearSystem( const RealType& time,
+      void setMatrixElements( const RealType& time,
                                const RealType& tau,
                                const MeshType& mesh,
                                const IndexType& index,
diff --git a/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator_impl.h b/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator_impl.h
index 9bd82a6965d7253712ac51446a31577a95f3df22..2ab2cf18c7b373c460b2e9c566e9978c89bf716c 100644
--- a/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator_impl.h
+++ b/src/operators/diffusion/nonlinear-diffusion-operators/tnlFiniteVolumeNonlinearOperator_impl.h
@@ -71,7 +71,7 @@ template< typename MeshEntity,
 __cuda_callable__
 void
 tnlFiniteVolumeNonlinearOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
-updateLinearSystem( const RealType& time,
+setMatrixElements( const RealType& time,
                     const RealType& tau,
                     const MeshType& mesh,
                     const IndexType& index,
@@ -155,7 +155,7 @@ template< typename MeshEntity,
 __cuda_callable__
 void
 tnlFiniteVolumeNonlinearOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
-updateLinearSystem( const RealType& time,
+setMatrixElements( const RealType& time,
                     const RealType& tau,
                     const MeshType& mesh,
                     const IndexType& index,
@@ -268,7 +268,7 @@ __cuda_callable__
 #endif
 void
 tnlFiniteVolumeNonlinearOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >, OperatorQ, Real, Index >::
-updateLinearSystem( const RealType& time,
+setMatrixElements( const RealType& time,
                     const RealType& tau,
                     const MeshType& mesh,
                     const IndexType& index,
diff --git a/src/operators/diffusion/tnlExactMeanCurvature.h b/src/operators/diffusion/tnlExactMeanCurvature.h
index bb4b3d67fb798ad1c8d2a5605cea77c532528d12..19506f8382db826d52fa016399c194431854379d 100644
--- a/src/operators/diffusion/tnlExactMeanCurvature.h
+++ b/src/operators/diffusion/tnlExactMeanCurvature.h
@@ -44,7 +44,7 @@ class tnlExactMeanCurvature
       template< typename Real >
       void setRegularizationEpsilon( const Real& eps)
       {
-         nonlinearDiffusion.getNonlinearity().getInnerOperator().setRegularizationEpislon( eps );
+         nonlinearDiffusion.getNonlinearity().getInnerOperator().setRegularizationEpsilon( eps );
       }
       
       template< typename Function >
diff --git a/src/operators/diffusion/tnlExactNonlinearDiffusion.h b/src/operators/diffusion/tnlExactNonlinearDiffusion.h
index 3dd005bc237d56b8539c8acb9fcba8ebd8179848..87403c37446355e7f0392ebcfe5f67a692f8371b 100644
--- a/src/operators/diffusion/tnlExactNonlinearDiffusion.h
+++ b/src/operators/diffusion/tnlExactNonlinearDiffusion.h
@@ -73,7 +73,7 @@ class tnlExactNonlinearDiffusion< 1, Nonlinearity, InnerOperator >
          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;          
+         return u_xx * g + u_x * g_x;          
       }
    
       protected:
@@ -131,7 +131,7 @@ class tnlExactNonlinearDiffusion< 2, Nonlinearity, InnerOperator >
          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; 
+         return  ( u_xx + u_yy ) * g + g_x * u_x + g_y * u_y; 
       }
 
       protected:
@@ -193,7 +193,7 @@ class tnlExactNonlinearDiffusion< 3, Nonlinearity, InnerOperator >
          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; 
+         return ( u_xx + u_yy + u_zz ) * g + g_x * u_x + g_y * u_y + g_z * u_z; 
       }
       
       protected:
diff --git a/src/operators/diffusion/tnlLinearDiffusion.h b/src/operators/diffusion/tnlLinearDiffusion.h
index b4683676e673a985b0a233f5a3f016b9f8bf7f4e..9c63d19b641e79c4a8c282154e74273e1f1c80bd 100644
--- a/src/operators/diffusion/tnlLinearDiffusion.h
+++ b/src/operators/diffusion/tnlLinearDiffusion.h
@@ -55,12 +55,10 @@ class tnlLinearDiffusion< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index
       
       static constexpr int getMeshDimensions() { return Dimensions; }
       
-      template< int EntityDimensions = Dimensions >
-      using MeshFunction = tnlMeshFunction< MeshType, EntityDimensions >;
-
       static tnlString getType();
 
-      template< typename PreimageFunction, typename MeshEntity >
+      template< typename PreimageFunction,
+                typename MeshEntity >
       __cuda_callable__
       inline Real operator()( const PreimageFunction& u,
                               const MeshEntity& entity,
@@ -72,19 +70,17 @@ class tnlLinearDiffusion< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index
                                              const IndexType& index,
                                              const MeshEntity& entity ) const;
 
-      template< typename MeshEntity,
-                typename Vector,
-                typename MatrixRow >
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
       __cuda_callable__
-      inline void updateLinearSystem( const RealType& time,
-                                      const RealType& tau,
-                                      const MeshType& mesh,
-                                      const IndexType& index,
-                                      const MeshEntity& entity,
-                                      const MeshFunction< 1 >& u,
-                                      Vector& b,
-                                      MatrixRow& matrixRow ) const;
-
+      inline void setMatrixElements( const PreimageFunction& u,
+                                     const MeshEntity& entity,
+                                     const RealType& time,
+                                     const RealType& tau,
+                                     Matrix& matrix,
+                                     Vector& b ) const;
 };
 
 
@@ -110,10 +106,6 @@ class tnlLinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index
       
       static constexpr int getMeshDimensions() { return Dimensions; }
 
-      
-      template< int EntityDimensions = Dimensions >
-      using MeshFunction = tnlMeshFunction< MeshType, EntityDimensions >;      
-
       static tnlString getType();
 
       template< typename PreimageFunction, typename EntityType >
@@ -127,19 +119,18 @@ class tnlLinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index
       inline Index getLinearSystemRowLength( const MeshType& mesh,
                                              const IndexType& index,
                                              const EntityType& entity ) const;
-
-      template< typename Vector,
-                typename MatrixRow,
-                typename EntityType >
+      
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
       __cuda_callable__
-      inline void updateLinearSystem( const RealType& time,
-                                      const RealType& tau,
-                                      const MeshType& mesh,
-                                      const IndexType& index,
-                                      const EntityType& entity,
-                                      const MeshFunction< 2 >& u,
-                                      Vector& b,
-                                      MatrixRow& matrixRow ) const;
+      inline void setMatrixElements( const PreimageFunction& u,
+                                     const MeshEntity& entity,
+                                     const RealType& time,
+                                     const RealType& tau,
+                                     Matrix& matrix,
+                                     Vector& b ) const;
 };
 
 
@@ -165,10 +156,6 @@ class tnlLinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index
       
       static constexpr int getMeshDimensions() { return Dimensions; }      
 
-      template< int EntityDimensions = Dimensions >
-      using MeshFunction = tnlMeshFunction< MeshType, EntityDimensions >;
-
-      
       static tnlString getType();
 
       template< typename PreimageFunction, 
@@ -184,19 +171,17 @@ class tnlLinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index
                                              const IndexType& index,
                                              const EntityType& entity ) const;
 
-      template< typename Vector,
-                typename MatrixRow,
-                typename EntityType >
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
       __cuda_callable__
-      inline void updateLinearSystem( const RealType& time,
-                                      const RealType& tau,
-                                      const MeshType& mesh,
-                                      const IndexType& index,
-                                      const EntityType& entity,
-                                      const MeshFunction< 3 >& u,
-                                      Vector& b,
-                                      MatrixRow& matrixRow ) const;
-
+      inline void setMatrixElements( const PreimageFunction& u,
+                                     const MeshEntity& entity,
+                                     const RealType& time,
+                                     const RealType& tau,
+                                     Matrix& matrix,
+                                     Vector& b ) const;
 };
 
 
diff --git a/src/operators/diffusion/tnlLinearDiffusion_impl.h b/src/operators/diffusion/tnlLinearDiffusion_impl.h
index ef38d2e8b0f65119b6769fb778b9475df777ec4d..04e4177f6a1b3950912d70926fade6d7d17724a1 100644
--- a/src/operators/diffusion/tnlLinearDiffusion_impl.h
+++ b/src/operators/diffusion/tnlLinearDiffusion_impl.h
@@ -82,25 +82,27 @@ template< typename MeshReal,
           typename MeshIndex,
           typename Real,
           typename Index >
-   template< typename MeshEntity,
-             typename Vector, 
-             typename Matrix >
+   template< typename PreimageFunction,
+             typename MeshEntity,
+             typename Matrix,
+             typename Vector >
 __cuda_callable__
 inline
 void
 tnlLinearDiffusion< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
-updateLinearSystem( const RealType& time,
-                    const RealType& tau,
-                    const MeshType& mesh,
-                    const IndexType& index,
-                    const MeshEntity& entity,
-                    const MeshFunction< 1 >& u,
-                    Vector& b,
-                    Matrix& matrix ) const
+setMatrixElements( const PreimageFunction& u,
+                   const MeshEntity& entity,
+                   const RealType& time,
+                   const RealType& tau,
+                   Matrix& matrix,
+                   Vector& b ) const
 {
+   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 IndexType& index = entity.getIndex();
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
-   const RealType lambdaX = tau * mesh.template getSpaceStepsProducts< -2 >();
+   const RealType lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >();
    matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< -1 >(),      - lambdaX );
    matrixRow.setElement( 1, index,                                              2.0 * lambdaX );
    matrixRow.setElement( 2, neighbourEntities.template getEntityIndex< 1 >(),       - lambdaX );   
@@ -171,26 +173,28 @@ template< typename MeshReal,
           typename MeshIndex,
           typename Real,
           typename Index >
-   template< typename Vector,
+   template< typename PreimageFunction,
+             typename MeshEntity,
              typename Matrix,
-             typename EntityType >
+             typename Vector >
 __cuda_callable__
 inline
 void
 tnlLinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
-updateLinearSystem( const RealType& time,
-                    const RealType& tau,
-                    const MeshType& mesh,
-                    const IndexType& index,
-                    const EntityType& entity,
-                    const MeshFunction< 2 >& u,
-                    Vector& b,
-                    Matrix& matrix ) const
+setMatrixElements( const PreimageFunction& u,
+                   const MeshEntity& entity,
+                   const RealType& time,
+                   const RealType& tau,
+                   Matrix& matrix,
+                   Vector& b ) const
 {
+   static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimensions() == 2, "Wrong preimage function" );
+   const IndexType& index = entity.getIndex();
    typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
-   const RealType lambdaX = tau * mesh.template getSpaceStepsProducts< -2, 0 >();
-   const RealType lambdaY = tau * mesh.template getSpaceStepsProducts< 0, -2 >();
-   const typename EntityType::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
+   const RealType lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >();
+   const RealType lambdaY = tau * entity.getMesh().template getSpaceStepsProducts< 0, -2 >();
+   const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
    matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< 0, -1 >(), -lambdaY );
    matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< -1, 0 >(), -lambdaX );
    matrixRow.setElement( 2, index,                                                        2.0 * ( lambdaX + lambdaY ) );
@@ -266,27 +270,29 @@ template< typename MeshReal,
           typename MeshIndex,
           typename Real,
           typename Index >
-   template< typename Vector,
+   template< typename PreimageFunction,
+             typename MeshEntity,
              typename Matrix,
-             typename EntityType >
+             typename Vector >
 __cuda_callable__
 inline
 void
 tnlLinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
-updateLinearSystem( const RealType& time,
-                    const RealType& tau,
-                    const MeshType& mesh,
-                    const IndexType& index,
-                    const EntityType& entity,
-                    const MeshFunction< 3 >& u,
-                    Vector& b,
-                    Matrix& matrix ) const
+setMatrixElements( const PreimageFunction& u,
+                   const MeshEntity& entity,
+                   const RealType& time,
+                   const RealType& tau,
+                   Matrix& matrix,
+                   Vector& b ) const
 {
-   const typename EntityType::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+   static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." );
+   static_assert( PreimageFunction::getEntitiesDimensions() == 3, "Wrong preimage function" );   
+   const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
+   const IndexType& index = entity.getIndex();
    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 lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >();
+   const RealType lambdaY = tau * entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >();
+   const RealType lambdaZ = tau * entity.getMesh().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
index 88f0bae7ea1b840b24c3f37e73f5a2ba4874a69d..be5e87d68c57ce72093beb484aacb0ed729b070d 100644
--- a/src/operators/diffusion/tnlNonlinearDiffusion_impl.h
+++ b/src/operators/diffusion/tnlNonlinearDiffusion_impl.h
@@ -71,7 +71,7 @@ template< typename MeshEntity,
 __cuda_callable__
 void
 tnlNonlinearDiffusion< tnlGrid< 1, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
-updateLinearSystem( const RealType& time,
+setMatrixElements( const RealType& time,
                     const RealType& tau,
                     const MeshType& mesh,
                     const IndexType& index,
@@ -80,7 +80,7 @@ updateLinearSystem( const RealType& time,
                     Vector& b,
                     Matrix& matrix ) const
 {
-    nonlinearDiffusionOperator.updateLinearSystem( time, tau, mesh, index, entity, u, b, matrix );
+    nonlinearDiffusionOperator.setMatrixElements( time, tau, mesh, index, entity, u, b, matrix );
 }
 
 template< typename MeshReal,
@@ -148,7 +148,7 @@ template< typename MeshEntity,
 __cuda_callable__
 void
 tnlNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
-updateLinearSystem( const RealType& time,
+setMatrixElements( const RealType& time,
                     const RealType& tau,
                     const MeshType& mesh,
                     const IndexType& index,
@@ -157,7 +157,7 @@ updateLinearSystem( const RealType& time,
                     Vector& b,
                     Matrix& matrix ) const
 {
-    nonlinearDiffusionOperator.updateLinearSystem( time, tau, mesh, index, entity, u, b, matrix );
+    nonlinearDiffusionOperator.setMatrixElements( time, tau, mesh, index, entity, u, b, matrix );
 }
 
 template< typename MeshReal,
@@ -225,7 +225,7 @@ template< typename MeshEntity,
 __cuda_callable__
 void
 tnlNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >, NonlinearDiffusionOperator, Real, Index >::
-updateLinearSystem( const RealType& time,
+setMatrixElements( const RealType& time,
                     const RealType& tau,
                     const MeshType& mesh,
                     const IndexType& index,
@@ -234,7 +234,7 @@ updateLinearSystem( const RealType& time,
                     Vector& b,
                     Matrix& matrix ) const
 {
-    nonlinearDiffusionOperator.updateLinearSystem( time, tau, mesh, index, entity, u, b, matrix );
+    nonlinearDiffusionOperator.setMatrixElements( 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
index 87386d89d8fe0145235e6b6c9f09b9226f536bbb..a75f0f855257f3bdb8b8665b1c5c46bb53241579 100644
--- a/src/operators/diffusion/tnlOneSidedMeanCurvature.h
+++ b/src/operators/diffusion/tnlOneSidedMeanCurvature.h
@@ -106,7 +106,7 @@ class tnlOneSidedMeanCurvature
                 typename Vector,
                 typename Matrix >
       __cuda_callable__
-      void updateLinearSystem( const RealType& time,
+      void setMatrixElements( const RealType& time,
                                const RealType& tau,
                                const MeshType& mesh,
                                const IndexType& index,
@@ -115,7 +115,7 @@ class tnlOneSidedMeanCurvature
                                Vector& b,
                                Matrix& matrix ) const
       {
-         this->nonlinearDiffusion.updateLinearSystem( time, tau, mesh, index, entity, u, b, matrix );
+         this->nonlinearDiffusion.setMatrixElements( time, tau, mesh, index, entity, u, b, matrix );
       }            
       
    protected:      
diff --git a/src/operators/diffusion/tnlOneSidedNonlinearDiffusion.h b/src/operators/diffusion/tnlOneSidedNonlinearDiffusion.h
index 1eb186f934d4d7b6f705a53ec2518d11700a9715..e6f62e3edfda873916198ce45f8bcec8609361b2 100644
--- a/src/operators/diffusion/tnlOneSidedNonlinearDiffusion.h
+++ b/src/operators/diffusion/tnlOneSidedNonlinearDiffusion.h
@@ -71,7 +71,7 @@ class tnlOneSidedNonlinearDiffusion< tnlGrid< 1,MeshReal, Device, MeshIndex >, N
       {
          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 RealType& hx_div = entity.getMesh().template getSpaceStepsProducts< -2 >();
          const IndexType& center = entity.getIndex();
          const IndexType& east = neighbourEntities.template getEntityIndex<  1 >();
          const IndexType& west = neighbourEntities.template getEntityIndex< -1 >();
@@ -92,26 +92,24 @@ class tnlOneSidedNonlinearDiffusion< tnlGrid< 1,MeshReal, Device, MeshIndex >, N
          return 3;
       }
 
-      template< typename MeshEntity,
-                typename MeshFunction,
-                typename Vector,
-                typename Matrix >
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
       __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
+      inline void setMatrixElements( const PreimageFunction& u,
+                                     const MeshEntity& entity,
+                                     const RealType& time,
+                                     const RealType& tau,
+                                     Matrix& matrix,
+                                     Vector& b ) 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 lambda_x = tau * entity.getMesh().template getSpaceStepsProducts< -2 >();
          const RealType& nonlinearity_center = this->nonlinearity[ center ];
          const RealType& nonlinearity_west = this->nonlinearity[ west ];
          const RealType aCoef = -lambda_x * nonlinearity_west;
@@ -167,8 +165,8 @@ class tnlOneSidedNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >,
       {
          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 RealType& hx_div = entity.getMesh().template getSpaceStepsProducts< -2,  0 >();
+         const RealType& hy_div = entity.getMesh().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 >();
@@ -194,19 +192,17 @@ class tnlOneSidedNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >,
          return 5;
       }
 
-      template< typename MeshEntity,
-                typename MeshFunction,
-                typename Vector,
-                typename Matrix >
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
       __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
+      inline void setMatrixElements( const PreimageFunction& u,
+                                     const MeshEntity& entity,
+                                     const RealType& time,
+                                     const RealType& tau,
+                                     Matrix& matrix,
+                                     Vector& b ) const
       {
          typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
          const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();
@@ -215,8 +211,8 @@ class tnlOneSidedNonlinearDiffusion< tnlGrid< 2, MeshReal, Device, MeshIndex >,
          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 lambda_x = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0 >();
+         const RealType lambda_y = tau * entity.getMesh().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 ];
@@ -278,9 +274,9 @@ class tnlOneSidedNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >,
       {
          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 RealType& hx_div = entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >();
+         const RealType& hy_div = entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >();
+         const RealType& hz_div = entity.getMesh().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 >();
@@ -313,19 +309,17 @@ class tnlOneSidedNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >,
          return 7;
       }
 
-      template< typename MeshEntity,
-                typename MeshFunction,
-                typename Vector,                
-                typename Matrix >
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
       __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
+      inline void setMatrixElements( const PreimageFunction& u,
+                                     const MeshEntity& entity,
+                                     const RealType& time,
+                                     const RealType& tau,
+                                     Matrix& matrix,
+                                     Vector& b ) const
       {
          typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
          const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();
@@ -338,9 +332,9 @@ class tnlOneSidedNonlinearDiffusion< tnlGrid< 3, MeshReal, Device, MeshIndex >,
          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 lambda_x = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >();
+         const RealType lambda_y = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >();
+         const RealType lambda_z = tau * entity.getMesh().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 ];
diff --git a/src/operators/euler/fvm/tnlLaxFridrichs_impl.h b/src/operators/euler/fvm/tnlLaxFridrichs_impl.h
index c5b014ee6fa4d709e6487fca2357eb7f910bfa09..92cb7b70781005ced0dda7f658be5979a6e01214 100644
--- a/src/operators/euler/fvm/tnlLaxFridrichs_impl.h
+++ b/src/operators/euler/fvm/tnlLaxFridrichs_impl.h
@@ -53,7 +53,7 @@ template< typename Real,
           template< int, typename, typename, typename > class GridGeometry >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureGradient  >::bindMesh( const MeshType& mesh )
 {
-   this -> mesh = &mesh;
+   this->mesh = &mesh;
 }
 
 template< typename Real,
@@ -74,7 +74,7 @@ template< typename Real,
           template< int, typename, typename, typename > class GridGeometry >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureGradient  > :: setRegularization( const RealType& epsilon )
 {
-   this -> regularizeEps = epsilon;
+   this->regularizeEps = epsilon;
 }
 
 template< typename Real,
@@ -84,7 +84,7 @@ template< typename Real,
           template< int, typename, typename, typename > class GridGeometry >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureGradient  > :: setViscosityCoefficient( const RealType& v )
 {
-   this -> viscosityCoefficient = v;
+   this->viscosityCoefficient = v;
 }
 
 template< typename Real,
@@ -106,7 +106,7 @@ template< typename Real,
    template< typename Vector >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureGradient  > :: setRhoU1( Vector& rho_u1 )
 {
-   this -> rho_u1. bind( rho_u1 );
+   this->rho_u1. bind( rho_u1 );
 }
 
 template< typename Real,
@@ -117,7 +117,7 @@ template< typename Real,
    template< typename Vector >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureGradient  > :: setRhoU2( Vector& rho_u2 )
 {
-   this -> rho_u2. bind( rho_u2 );
+   this->rho_u2. bind( rho_u2 );
 }
 
 template< typename Real,
@@ -139,7 +139,7 @@ template< typename Real,
    template< typename Vector >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureGradient  > :: setPressureGradient( Vector& grad_p )
 {
-   this -> pressureGradient = &grad_p;
+   this->pressureGradient = &grad_p;
 }
 
 template< typename Real,
@@ -157,10 +157,10 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureG
    tnlAssert( pressureGradient, cerr << "No pressure gradient was set in the the Lax-Fridrichs scheme." )
 
    const IndexType& c = centralVolume;
-   const IndexType e = this -> mesh -> getElementNeighbour( centralVolume,  1,  0 );
-   const IndexType w = this -> mesh -> getElementNeighbour( centralVolume, -1,  0 );
-   const IndexType n = this -> mesh -> getElementNeighbour( centralVolume,  0,  1 );
-   const IndexType s = this -> mesh -> getElementNeighbour( centralVolume,  0, -1 );
+   const IndexType e = this->mesh -> getElementNeighbour( centralVolume,  1,  0 );
+   const IndexType w = this->mesh -> getElementNeighbour( centralVolume, -1,  0 );
+   const IndexType n = this->mesh -> getElementNeighbour( centralVolume,  0,  1 );
+   const IndexType s = this->mesh -> getElementNeighbour( centralVolume,  0, -1 );
 
    const RealType u1_e = rho_u1[ e ] / regularize( rho[ e ] );
    const RealType u1_w = rho_u1[ w ] / regularize( rho[ w ] );
@@ -177,7 +177,7 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureG
     * Get the central volume and its neighbours (east, north, west, south) coordinates
     */
    CoordinatesType c_coordinates, e_coordinates, n_coordinates, w_coordinates, s_coordinates;
-   this -> mesh -> getElementCoordinates( c, c_coordinates );
+   this->mesh -> getElementCoordinates( c, c_coordinates );
    e_coordinates = n_coordinates = w_coordinates = s_coordinates = c_coordinates;
    e_coordinates. x() ++;
    w_coordinates. x() --;
@@ -187,20 +187,20 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureG
    /****
     * Get the volumes measure
     */
-   const RealType mu_D_c = this -> mesh -> getElementMeasure( c_coordinates );
-   const RealType mu_D_e = this -> mesh -> getElementMeasure( e_coordinates );
-   const RealType mu_D_n = this -> mesh -> getElementMeasure( n_coordinates );
-   const RealType mu_D_w = this -> mesh -> getElementMeasure( w_coordinates );
-   const RealType mu_D_s = this -> mesh -> getElementMeasure( s_coordinates );
+   const RealType mu_D_c = this->mesh -> getElementMeasure( c_coordinates );
+   const RealType mu_D_e = this->mesh -> getElementMeasure( e_coordinates );
+   const RealType mu_D_n = this->mesh -> getElementMeasure( n_coordinates );
+   const RealType mu_D_w = this->mesh -> getElementMeasure( w_coordinates );
+   const RealType mu_D_s = this->mesh -> getElementMeasure( s_coordinates );
 
    /****
     * Get the edge normals
     */
    VertexType e_normal, w_normal, n_normal, s_normal;
-   this -> mesh -> template getEdgeNormal<  1,  0 >( c_coordinates, e_normal );
-   this -> mesh -> template getEdgeNormal< -1,  0 >( c_coordinates, w_normal );
-   this -> mesh -> template getEdgeNormal<  0,  1 >( c_coordinates, n_normal );
-   this -> mesh -> template getEdgeNormal<  0, -1 >( c_coordinates, s_normal );
+   this->mesh -> template getEdgeNormal<  1,  0 >( c_coordinates, e_normal );
+   this->mesh -> template getEdgeNormal< -1,  0 >( c_coordinates, w_normal );
+   this->mesh -> template getEdgeNormal<  0,  1 >( c_coordinates, n_normal );
+   this->mesh -> template getEdgeNormal<  0, -1 >( c_coordinates, s_normal );
 
    /****
     * Compute the fluxes
@@ -245,7 +245,7 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureG
                               rho_f_n * n_normal. x() + rho_g_n * n_normal. y() +
                               rho_f_w * w_normal. x() + rho_g_w * w_normal. y() +
                               rho_f_s * s_normal. x() + rho_g_s * s_normal. y() )
-           + this -> viscosityCoefficient * 1.0 / ( 8.0 * tau ) * mu_D_c *
+           + this->viscosityCoefficient * 1.0 / ( 8.0 * tau ) * mu_D_c *
                             ( ( mu_D_c + mu_D_e ) * ( rho[ e ] - rho[ c ] ) +
                               ( mu_D_c + mu_D_n ) * ( rho[ n ] - rho[ c ] ) +
                               ( mu_D_c + mu_D_w ) * ( rho[ w ] - rho[ c ] ) +
@@ -258,7 +258,7 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureG
                                  rho_u1_f_n * n_normal. x() + rho_u1_g_n * n_normal. y() +
                                  rho_u1_f_w * w_normal. x() + rho_u1_g_w * w_normal. y() +
                                  rho_u1_f_s * s_normal. x() + rho_u1_g_s * s_normal. y() )
-              + this -> viscosityCoefficient * 1.0 / ( 8.0 * tau ) * mu_D_c *
+              + this->viscosityCoefficient * 1.0 / ( 8.0 * tau ) * mu_D_c *
                                ( ( mu_D_c + mu_D_e ) * ( rho_u1[ e ] - rho_u1[ c ] ) +
                                  ( mu_D_c + mu_D_n ) * ( rho_u1[ n ] - rho_u1[ c ] ) +
                                  ( mu_D_c + mu_D_w ) * ( rho_u1[ w ] - rho_u1[ c ] ) +
@@ -272,7 +272,7 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureG
                                  rho_u2_f_n * n_normal. x() + rho_u2_g_n * n_normal. y() +
                                  rho_u2_f_w * w_normal. x() + rho_u2_g_w * w_normal. y() +
                                  rho_u2_f_s * s_normal. x() + rho_u2_g_s * s_normal. y() )
-              + this -> viscosityCoefficient * 1.0 / ( 8.0 * tau ) * mu_D_c *
+              + this->viscosityCoefficient * 1.0 / ( 8.0 * tau ) * mu_D_c *
                                ( ( mu_D_c + mu_D_e ) * ( rho_u2[ e ] - rho_u2[ c ] ) +
                                  ( mu_D_c + mu_D_n ) * ( rho_u2[ n ] - rho_u2[ c ] ) +
                                  ( mu_D_c + mu_D_w ) * ( rho_u2[ w ] - rho_u2[ c ] ) +
@@ -287,7 +287,7 @@ template< typename Real,
           template< int, typename, typename, typename > class GridGeometry >
 Real tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, GridGeometry >, PressureGradient  > :: regularize( const Real& r ) const
 {
-   return r + ( ( r >= 0 ) - ( r < 0 ) ) * this -> regularizeEps;
+   return r + ( ( r >= 0 ) - ( r < 0 ) ) * this->regularizeEps;
 }
 
 /****
@@ -313,7 +313,7 @@ template< typename Real,
           typename PressureGradient >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: bindMesh( const MeshType& mesh )
 {
-   this -> mesh = &mesh;
+   this->mesh = &mesh;
 }
 
 template< typename Real,
@@ -322,7 +322,7 @@ template< typename Real,
           typename PressureGradient >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: setRegularization( const RealType& epsilon )
 {
-   this -> regularizeEps = epsilon;
+   this->regularizeEps = epsilon;
 }
 
 template< typename Real,
@@ -331,7 +331,7 @@ template< typename Real,
           typename PressureGradient >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: setViscosityCoefficient( const RealType& v )
 {
-   this -> viscosityCoefficient = v;
+   this->viscosityCoefficient = v;
 }
 
 template< typename Real,
@@ -341,7 +341,7 @@ template< typename Real,
    template< typename Vector >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: setRho( Vector& rho )
 {
-   this -> rho. bind( rho );
+   this->rho. bind( rho );
 }
 
 template< typename Real,
@@ -351,7 +351,7 @@ template< typename Real,
    template< typename Vector >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: setRhoU1( Vector& rho_u1 )
 {
-   this -> rho_u1. bind( rho_u1 );
+   this->rho_u1. bind( rho_u1 );
 }
 
 template< typename Real,
@@ -361,7 +361,7 @@ template< typename Real,
    template< typename Vector >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: setRhoU2( Vector& rho_u2 )
 {
-   this -> rho_u2. bind( rho_u2 );
+   this->rho_u2. bind( rho_u2 );
 }
 
 template< typename Real,
@@ -391,7 +391,7 @@ template< typename Real,
    template< typename Vector >
 void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: setPressureGradient( Vector& grad_p )
 {
-   this -> pressureGradient = &grad_p;
+   this->pressureGradient = &grad_p;
 }
 
 template< typename Real,
@@ -407,16 +407,16 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry
    tnlAssert( mesh, cerr << "No mesh has been binded with the Lax-Fridrichs scheme." );
    tnlAssert( pressureGradient, cerr << "No pressure gradient was set in the the Lax-Fridrichs scheme." )
 
-   const IndexType& xSize = this -> mesh -> getDimensions(). x();
-   const IndexType& ySize = this -> mesh -> getDimensions(). y();
-   const RealType hx = this -> mesh -> getParametricStep(). x();
-   const RealType hy = this -> mesh -> getParametricStep(). y();
+   const IndexType& xSize = this->mesh -> getDimensions(). x();
+   const IndexType& ySize = this->mesh -> getDimensions(). y();
+   const RealType hx = this->mesh -> getParametricStep(). x();
+   const RealType hy = this->mesh -> getParametricStep(). y();
 
    const IndexType& c = centralVolume;
-   const IndexType e = this -> mesh -> getElementNeighbour( centralVolume,  1,  0 );
-   const IndexType w = this -> mesh -> getElementNeighbour( centralVolume, -1,  0 );
-   const IndexType n = this -> mesh -> getElementNeighbour( centralVolume,  0,  1 );
-   const IndexType s = this -> mesh -> getElementNeighbour( centralVolume,  0, -1 );
+   const IndexType e = this->mesh -> getElementNeighbour( centralVolume,  1,  0 );
+   const IndexType w = this->mesh -> getElementNeighbour( centralVolume, -1,  0 );
+   const IndexType n = this->mesh -> getElementNeighbour( centralVolume,  0,  1 );
+   const IndexType s = this->mesh -> getElementNeighbour( centralVolume,  0, -1 );
 
    /****
     * rho_t + ( rho u_1 )_x + ( rho u_2 )_y =  0
@@ -425,7 +425,7 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry
    const RealType u1_w = rho_u1[ w ] / regularize( rho[ w ] );
    const RealType u2_n = rho_u2[ n ] / regularize( rho[ n ] );
    const RealType u2_s = rho_u2[ s ] / regularize( rho[ s ] );
-   rho_t = this -> viscosityCoefficient / tau * 0.25 * ( rho[ e ] + rho[ w ] + rho[ s ] + rho[ n ] - 4.0 * rho[ c ] )
+   rho_t = this->viscosityCoefficient / tau * 0.25 * ( rho[ e ] + rho[ w ] + rho[ s ] + rho[ n ] - 4.0 * rho[ c ] )
                - ( rho[ e ] * u1_e - rho[ w ] * u1_w ) / ( 2.0 * hx )
                - ( rho[ n ] * u2_n - rho[ s ] * u2_s ) / ( 2.0 * hy );
 
@@ -438,14 +438,14 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry
    /****
     * ( rho * u1 )_t + ( rho * u1 * u1 )_x + ( rho * u1 * u2 )_y - p_x =  0
     */
-   rho_u1_t = this -> viscosityCoefficient / tau * 0.25 * ( rho_u1[ e ] + rho_u1[ w ] + rho_u1[ s ] + rho_u1[ n ] - 4.0 * rho_u1[ c ] )
+   rho_u1_t = this->viscosityCoefficient / tau * 0.25 * ( rho_u1[ e ] + rho_u1[ w ] + rho_u1[ s ] + rho_u1[ n ] - 4.0 * rho_u1[ c ] )
                    - ( rho_u1[ e ] * u1_e - rho_u1[ w ] * u1_w ) / ( 2.0 * hx )
                    - ( rho_u1[ n ] * u2_n - rho_u1[ s ] * u2_s ) / ( 2.0 * hy )
                    - grad_p. x();
    /****
     * ( rho * u2 )_t + ( rho * u2 * u1 )_x + ( rho * u2 * u2 )_y - p_y =  0
     */
-   rho_u2_t = this -> viscosityCoefficient / tau * 0.25 * ( rho_u2[ e ] + rho_u2[ w ] + rho_u2[ s ] + rho_u2[ n ] - 4.0 * rho_u2[ c ] )
+   rho_u2_t = this->viscosityCoefficient / tau * 0.25 * ( rho_u2[ e ] + rho_u2[ w ] + rho_u2[ s ] + rho_u2[ n ] - 4.0 * rho_u2[ c ] )
                    - ( rho_u2[ e ] * u1_e - rho_u2[ w ] * u1_w ) / ( 2.0 * hx )
                    - ( rho_u2[ n ] * u2_n - rho_u2[ s ] * u2_s ) / ( 2.0 * hy )
                    - grad_p. y();
@@ -465,16 +465,16 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry
    tnlAssert( mesh, cerr << "No mesh has been binded with the Lax-Fridrichs scheme." );
    tnlAssert( pressureGradient, cerr << "No pressure gradient was set in the the Lax-Fridrichs scheme." )
 
-   const IndexType& xSize = this -> mesh -> getDimensions(). x();
-   const IndexType& ySize = this -> mesh -> getDimensions(). y();
-   const RealType hx = this -> mesh -> getParametricStep(). x();
-   const RealType hy = this -> mesh -> getParametricStep(). y();
+   const IndexType& xSize = this->mesh -> getDimensions(). x();
+   const IndexType& ySize = this->mesh -> getDimensions(). y();
+   const RealType hx = this->mesh -> getParametricStep(). x();
+   const RealType hy = this->mesh -> getParametricStep(). y();
 
    const IndexType& c = centralVolume;
-   const IndexType e = this -> mesh -> getElementNeighbour( centralVolume,  1,  0 );
-   const IndexType w = this -> mesh -> getElementNeighbour( centralVolume, -1,  0 );
-   const IndexType n = this -> mesh -> getElementNeighbour( centralVolume,  0,  1 );
-   const IndexType s = this -> mesh -> getElementNeighbour( centralVolume,  0, -1 );
+   const IndexType e = this->mesh -> getElementNeighbour( centralVolume,  1,  0 );
+   const IndexType w = this->mesh -> getElementNeighbour( centralVolume, -1,  0 );
+   const IndexType n = this->mesh -> getElementNeighbour( centralVolume,  0,  1 );
+   const IndexType s = this->mesh -> getElementNeighbour( centralVolume,  0, -1 );
 
    /****
     * rho_t + ( rho u_1 )_x + ( rho u_2 )_y =  0
@@ -483,7 +483,7 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry
    const RealType u1_w = rho_u1[ w ] / regularize( rho[ w ] );
    const RealType u2_n = rho_u2[ n ] / regularize( rho[ n ] );
    const RealType u2_s = rho_u2[ s ] / regularize( rho[ s ] );
-   rho_t = this -> viscosityCoefficient / tau * 0.25 * ( rho[ e ] + rho[ w ] + rho[ s ] + rho[ n ] - 4.0 * rho[ c ] )
+   rho_t = this->viscosityCoefficient / tau * 0.25 * ( rho[ e ] + rho[ w ] + rho[ s ] + rho[ n ] - 4.0 * rho[ c ] )
                - ( rho[ e ] * u1_e - rho[ w ] * u1_w ) / ( 2.0 * hx )
                - ( rho[ n ] * u2_n - rho[ s ] * u2_s ) / ( 2.0 * hy );
 
@@ -496,14 +496,14 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry
    /****
     * ( rho * u1 )_t + ( rho * u1 * u1 )_x + ( rho * u1 * u2 )_y - p_x =  0
     */
-   rho_u1_t = this -> viscosityCoefficient / tau * 0.25 * ( rho_u1[ e ] + rho_u1[ w ] + rho_u1[ s ] + rho_u1[ n ] - 4.0 * rho_u1[ c ] )
+   rho_u1_t = this->viscosityCoefficient / tau * 0.25 * ( rho_u1[ e ] + rho_u1[ w ] + rho_u1[ s ] + rho_u1[ n ] - 4.0 * rho_u1[ c ] )
                    - ( rho_u1[ e ] * u1_e - rho_u1[ w ] * u1_w ) / ( 2.0 * hx )
                    - ( rho_u1[ n ] * u2_n - rho_u1[ s ] * u2_s ) / ( 2.0 * hy )
                    - grad_p. x();
    /****
     * ( rho * u2 )_t + ( rho * u2 * u1 )_x + ( rho * u2 * u2 )_y - p_y =  0
     */
-   rho_u2_t = this -> viscosityCoefficient / tau * 0.25 * ( rho_u2[ e ] + rho_u2[ w ] + rho_u2[ s ] + rho_u2[ n ] - 4.0 * rho_u2[ c ] )
+   rho_u2_t = this->viscosityCoefficient / tau * 0.25 * ( rho_u2[ e ] + rho_u2[ w ] + rho_u2[ s ] + rho_u2[ n ] - 4.0 * rho_u2[ c ] )
                    - ( rho_u2[ e ] * u1_e - rho_u2[ w ] * u1_w ) / ( 2.0 * hx )
                    - ( rho_u2[ n ] * u2_n - rho_u2[ s ] * u2_s ) / ( 2.0 * hy )
                    - grad_p. y();
@@ -511,7 +511,7 @@ void tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry
    /****
     * e_t + ( ( e + p ) * u )_x + ( ( e + p ) * v )_y = 0
     */
-   e_t = this -> viscosityCoefficient / tau * 0.25 * ( energy[ e ] + energy[ w ] + energy[ s ] + energy[ n ] - 4.0 * energy[ c ] )
+   e_t = this->viscosityCoefficient / tau * 0.25 * ( energy[ e ] + energy[ w ] + energy[ s ] + energy[ n ] - 4.0 * energy[ c ] )
               - ( ( energy[ e ] + p[ e ] ) * u1_e - ( energy[ w ] + p[ w ] ) * u1_w ) / ( 2.0 * hx )
               - ( ( energy[ n ] + p[ n ] ) * u2_n - ( energy[ s ] + p[ s ] ) * u2_s ) / ( 2.0 * hy );
 }
@@ -523,7 +523,7 @@ template< typename Real,
           typename PressureGradient >
 Real tnlLaxFridrichs< tnlGrid< 2, Real, Device, Index, tnlIdenticalGridGeometry >, PressureGradient  > :: regularize( const Real& r ) const
 {
-   return r + ( ( r >= 0 ) - ( r < 0 ) ) * this -> regularizeEps;
+   return r + ( ( r >= 0 ) - ( r < 0 ) ) * this->regularizeEps;
 }
 
 
diff --git a/src/operators/geometric/tnlExactGradientNorm.h b/src/operators/geometric/tnlExactGradientNorm.h
index 42af00e87e9d86fa80d3fdbc5fed18237c5a6df3..1b03c3cf12670d7a3826be7f70adc62908939a31 100644
--- a/src/operators/geometric/tnlExactGradientNorm.h
+++ b/src/operators/geometric/tnlExactGradientNorm.h
@@ -45,7 +45,7 @@ class tnlExactGradientNorm< 1, Real >
       tnlExactGradientNorm()
       : epsilonSquare( 0.0 ){};
 
-      void setRegularization( const Real& epsilon )
+      void setRegularizationEpsilon( const Real& epsilon )
       {
          this->epsilonSquare = epsilon*epsilon;
       }
@@ -113,7 +113,7 @@ class tnlExactGradientNorm< 2, Real >
       tnlExactGradientNorm()
       : epsilonSquare( 0.0 ){};
 
-      void setRegularization( const Real& epsilon )
+      void setRegularizationEpsilon( const Real& epsilon )
       {
          this->epsilonSquare = epsilon*epsilon;
       }
@@ -187,7 +187,7 @@ class tnlExactGradientNorm< 3, Real >
       tnlExactGradientNorm()
       : epsilonSquare( 0.0 ){};
 
-      void setRegularization( const Real& epsilon )
+      void setRegularizationEpsilon( const Real& epsilon )
       {
          this->epsilonSquare = epsilon*epsilon;
       }
diff --git a/src/operators/tnlDirichletBoundaryConditions.h b/src/operators/tnlDirichletBoundaryConditions.h
index 01f55a1e8e6861f2db5d0a8f6458acbd70ee284b..b155bb7d964cd2d1c98bccb24470c79d69c6ecff 100644
--- a/src/operators/tnlDirichletBoundaryConditions.h
+++ b/src/operators/tnlDirichletBoundaryConditions.h
@@ -20,6 +20,7 @@
 
 #include <operators/tnlOperator.h>
 #include <functions/tnlConstantFunction.h>
+#include <functions/tnlFunctionAdapter.h>
 
 template< typename Mesh,
           typename Function = tnlConstantFunction< Mesh::getMeshDimensions(), typename Mesh::RealType >,
@@ -36,57 +37,86 @@ class tnlDirichletBoundaryConditions
 {
    public:
 
-   typedef Mesh MeshType;
-   typedef Function FunctionType;
-   typedef Real RealType;
-   typedef typename MeshType::DeviceType DeviceType;
-   typedef Index IndexType;
-  
-   typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
-   typedef typename MeshType::VertexType VertexType;
-   
-   static constexpr int getMeshDimensions() { return MeshType::meshDimensions; }
+      typedef Mesh MeshType;
+      typedef Function FunctionType;
+      typedef Real RealType;
+      typedef typename MeshType::DeviceType DeviceType;
+      typedef Index IndexType;
 
-   static void configSetup( tnlConfigDescription& config,
-                            const tnlString& prefix = "" );
+      typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef typename MeshType::VertexType VertexType;
 
-   bool setup( const tnlParameterContainer& parameters,
-               const tnlString& prefix = "" );
+      static constexpr int getMeshDimensions() { return MeshType::meshDimensions; }
 
-   void setFunction( const Function& function );
-   
-   Function& getFunction();
+      static void configSetup( tnlConfigDescription& config,
+                               const tnlString& prefix = "" )
+      {
+         Function::configSetup( config, prefix );
+      }
+      
+      bool setup( const tnlParameterContainer& parameters,
+                  const tnlString& prefix = "" )
+      {
+         return this->function.setup( parameters, prefix );
+      }
 
-   const Function& getFunction() const;
-   
-   template< typename EntityType,
-             typename MeshFunction >
-   __cuda_callable__
-   const RealType operator()( const MeshFunction& u,
-                              const EntityType& entity,                            
-                              const RealType& time = 0 ) const;
+      void setFunction( const Function& function )
+      {
+         this->function = function;
+      }
+
+      Function& getFunction()
+      {
+         return this->function;
+      }
+      
+      const Function& getFunction() const
+      {
+         return this->function;
+      }
+
+      template< typename EntityType,
+                typename MeshFunction >
+      __cuda_callable__
+      const RealType operator()( const MeshFunction& u,
+                                 const EntityType& entity,                            
+                                 const RealType& time = 0 ) const
+      {
+         //static_assert( EntityType::getDimensions() == MeshEntitiesDimensions, "Wrong mesh entity dimensions." );
+         return tnlFunctionAdapter< MeshType, Function >::template getValue( this->function, entity, time );
+      }
+
+      template< typename EntityType >
+      __cuda_callable__
+      IndexType getLinearSystemRowLength( const MeshType& mesh,
+                                          const IndexType& index,
+                                          const EntityType& entity ) const
+      {
+         return 1;
+      }
+
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
+      __cuda_callable__
+      void setMatrixElements( const PreimageFunction& u,
+                              const MeshEntity& entity,
+                              const RealType& time,
+                              const RealType& tau,
+                              Matrix& matrix,
+                              Vector& b ) const
+      {
+         typename Matrix::MatrixRow matrixRow = matrix.getRow( entity.getIndex() );
+         const IndexType& index = entity.getIndex();
+         matrixRow.setElement( 0, index, 1.0 );
+         b[ index ] = tnlFunctionAdapter< MeshType, Function >::getValue( this->function, entity, time );
+      }
    
-   template< typename EntityType >
-   __cuda_callable__
-   IndexType getLinearSystemRowLength( const MeshType& mesh,
-                                       const IndexType& index,
-                                       const EntityType& entity ) const;
-
-   template< typename MatrixRow,
-             typename EntityType,
-             typename MeshFunction >
-   __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const EntityType& entity,
-                               const MeshFunction& u,
-                               DofVectorType& b,
-                               MatrixRow& matrixRow ) const;
 
    protected:
 
-   Function function;
+      Function function;
    
    //static_assert( Device::DeviceType == Function::Device::DeviceType );
 };
@@ -99,6 +129,4 @@ ostream& operator << ( ostream& str, const tnlDirichletBoundaryConditions< Mesh,
    return str;
 }
 
-#include <operators/tnlDirichletBoundaryConditions_impl.h>
-
 #endif /* TNLDIRICHLETBOUNDARYCONDITIONS_H_ */
diff --git a/src/operators/tnlNeumannBoundaryConditions.h b/src/operators/tnlNeumannBoundaryConditions.h
index 06e109e36e6082bb8a9a4f452c52adfedaa9f7d6..57f28ee31ea44ff48a25200b292e3735a605a106 100644
--- a/src/operators/tnlNeumannBoundaryConditions.h
+++ b/src/operators/tnlNeumannBoundaryConditions.h
@@ -1,6 +1,9 @@
 #ifndef TNLNEUMANNBOUNDARYCONDITIONS_H
 #define	TNLNEUMANNBOUNDARYCONDITIONS_H
 
+#include <functions/tnlFunctionAdapter.h>
+#include <operators/tnlOperator.h>
+
 template< typename Mesh,
           typename Function,
           typename Real = typename Mesh::RealType,
@@ -49,7 +52,11 @@ template< typename MeshReal,
           typename Index >
 class tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >
    : public tnlNeumannBoundaryConditionsBase< Function >,
-     public tnlDomain< 1, MeshBoundaryDomain >
+     public tnlOperator< tnlGrid< 1, MeshReal, Device, MeshIndex >,
+                         MeshBoundaryDomain,
+                         1, 1,
+                         Real,
+                         Index >
 {
    public:
 
@@ -62,32 +69,68 @@ class tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, F
    typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
    typedef tnlStaticVector< 1, RealType > VertexType;
    typedef typename MeshType::CoordinatesType CoordinatesType;
+   typedef tnlNeumannBoundaryConditions< MeshType, Function, Real, Index > ThisType;
+   typedef tnlNeumannBoundaryConditionsBase< Function > BaseType;
 
    template< typename EntityType,
              typename MeshFunction >
    __cuda_callable__
    const RealType operator()( const MeshFunction& u,
                               const EntityType& entity,   
-                              const RealType& time = 0 ) const;
+                              const RealType& time = 0 ) const
+   {
+      const MeshType& mesh = entity.getMesh();
+      const auto& neighbourEntities = entity.getNeighbourEntities();
+      const IndexType& index = entity.getIndex();
+      if( entity.getCoordinates().x() == 0 )
+         return u[ neighbourEntities.template getEntityIndex< 1 >() ] - entity.getMesh().getSpaceSteps().x() * 
+            tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+      else
+         return u[ neighbourEntities.template getEntityIndex< -1 >() ] + entity.getMesh().getSpaceSteps().x() * 
+            tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );   
+
+   }
 
 
    template< typename EntityType >
    __cuda_callable__
    Index getLinearSystemRowLength( const MeshType& mesh,
                                    const IndexType& index,
-                                   const EntityType& entity ) const;
-
-   template< typename MatrixRow,
-             typename EntityType,
-             typename MeshFunction >
-   __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const EntityType& entity,
-                               const MeshFunction& u,
-                               DofVectorType& b,
-                               MatrixRow& matrixRow ) const;
+                                   const EntityType& entity ) const
+   {
+      return 2;
+   }
+
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
+      __cuda_callable__
+      void setMatrixElements( const PreimageFunction& u,
+                                     const MeshEntity& entity,
+                                     const RealType& time,
+                                     const RealType& tau,
+                                     Matrix& matrix,
+                                     Vector& b ) const
+      {
+         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const IndexType& index = entity.getIndex();
+         typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+         if( entity.getCoordinates().x() == 0 )
+         {
+            matrixRow.setElement( 0, index, 1.0 );
+            matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 1 >(), -1.0 );
+            b[ index ] = - entity.getMesh().getSpaceSteps().x() * 
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         else
+         {
+            matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< -1 >(), -1.0 );
+            matrixRow.setElement( 1, index, 1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().x() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }         
+      }
 };
 
 /****
@@ -101,44 +144,113 @@ template< typename MeshReal,
           typename Index >
 class tnlNeumannBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index >
    : public tnlNeumannBoundaryConditionsBase< Function >,
-     public tnlDomain< 2, MeshBoundaryDomain >
+     public tnlOperator< tnlGrid< 2, MeshReal, Device, MeshIndex >,
+                         MeshBoundaryDomain,
+                         2, 2,
+                         Real,
+                         Index >
+
 {
    public:
 
-   typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
-   typedef Real RealType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-
-   typedef Function FunctionType;
-   typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
-   typedef tnlStaticVector< 2, RealType > VertexType;
-   typedef typename MeshType::CoordinatesType CoordinatesType;
-
-   template< typename EntityType,
-             typename MeshFunction >
-   __cuda_callable__
-   const RealType operator()( const MeshFunction& u,
-                              const EntityType& entity,                            
-                              const RealType& time = 0 ) const;
-      
-   template< typename EntityType >
-   __cuda_callable__
-   Index getLinearSystemRowLength( const MeshType& mesh,
-                                   const IndexType& index,
-                                   const EntityType& entity ) const;
+      typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
 
-   template< typename MatrixRow,
-             typename EntityType,
-             typename MeshFunction >
-   __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const EntityType& entity,
-                               const MeshFunction& u,
-                               DofVectorType& b,
-                               MatrixRow& matrixRow ) const;
+      typedef Function FunctionType;
+      typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef tnlStaticVector< 2, RealType > VertexType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef tnlNeumannBoundaryConditions< MeshType, Function, Real, Index > ThisType;
+      typedef tnlNeumannBoundaryConditionsBase< Function > BaseType;
+
+
+      template< typename EntityType,
+                typename MeshFunction >
+      __cuda_callable__
+      const RealType operator()( const MeshFunction& u,
+                                 const EntityType& entity,                            
+                                 const RealType& time = 0 ) const
+      {
+         const MeshType& mesh = entity.getMesh();
+         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const IndexType& index = entity.getIndex();
+         if( entity.getCoordinates().x() == 0 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - entity.getMesh().getSpaceSteps().x() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] + entity.getMesh().getSpaceSteps().x() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().y() == 0 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - entity.getMesh().getSpaceSteps().y() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] + entity.getMesh().getSpaceSteps().y() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }         
+      }
+
+      template< typename EntityType >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const EntityType& entity ) const
+      {
+         return 2;
+      }
+
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
+      __cuda_callable__
+      void setMatrixElements( const PreimageFunction& u,
+                              const MeshEntity& entity,
+                              const RealType& time,
+                              const RealType& tau,
+                              Matrix& matrix,
+                              Vector& b ) const
+      {
+         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const IndexType& index = entity.getIndex();
+         typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+         if( entity.getCoordinates().x() == 0 )
+         {
+            matrixRow.setElement( 0, index,                                                1.0 );
+            matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 1, 0 >(), -1.0 );
+            b[ index ] = - entity.getMesh().getSpaceSteps().x() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 )
+         {
+            matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< -1, 0 >(), -1.0 );
+            matrixRow.setElement( 1, index,                                                 1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().x() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().y() == 0 )
+         {
+            matrixRow.setElement( 0, index,                                                1.0 );
+            matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, 1 >(), -1.0 );
+            b[ index ] = - entity.getMesh().getSpaceSteps().y() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 )
+         {
+            matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< 0, -1 >(), -1.0 );
+            matrixRow.setElement( 1, index,                                                 1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().y() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }         
+      }
 };
 
 /****
@@ -152,45 +264,136 @@ template< typename MeshReal,
           typename Index >
 class tnlNeumannBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index >
    : public tnlNeumannBoundaryConditionsBase< Function >,
-     public tnlDomain< 3, MeshBoundaryDomain >
+     public tnlOperator< tnlGrid< 3, MeshReal, Device, MeshIndex >,
+                         MeshBoundaryDomain,
+                         3, 3,
+                         Real,
+                         Index >
 {
    public:
 
-   typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
-   typedef Real RealType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-
-   typedef Function FunctionType;
-   typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
-   typedef tnlStaticVector< 3, RealType > VertexType;
-   typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType;
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
 
-   template< typename EntityType,
-             typename MeshFunction >
-   __cuda_callable__
-   const RealType operator()( const MeshFunction& u,
-                              const EntityType& entity,
-                              const RealType& time = 0 ) const;
-   
-
-   template< typename EntityType >
-   __cuda_callable__
-   Index getLinearSystemRowLength( const MeshType& mesh,
-                                   const IndexType& index,
-                                   const EntityType& entity ) const;
-
-   template< typename MatrixRow,
-             typename EntityType,
-             typename MeshFunction >
-   __cuda_callable__
-      void updateLinearSystem( const RealType& time,
-                               const MeshType& mesh,
-                               const IndexType& index,
-                               const EntityType& entity,
-                               const MeshFunction& u,
-                               DofVectorType& b,
-                               MatrixRow& matrixRow ) const;
+      typedef Function FunctionType;
+      typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType;
+      typedef tnlStaticVector< 3, RealType > VertexType;
+      typedef typename MeshType::CoordinatesType CoordinatesType;
+      typedef tnlNeumannBoundaryConditions< MeshType, Function, Real, Index > ThisType;
+      typedef tnlNeumannBoundaryConditionsBase< Function > BaseType;   
+
+      template< typename EntityType,
+                typename MeshFunction >
+      __cuda_callable__
+      const RealType operator()( const MeshFunction& u,
+                                 const EntityType& entity,
+                                 const RealType& time = 0 ) const
+      {
+         const MeshType& mesh = entity.getMesh();
+         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const IndexType& index = entity.getIndex();
+         if( entity.getCoordinates().x() == 0 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - entity.getMesh().getSpaceSteps().x() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ] + entity.getMesh().getSpaceSteps().x() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().y() == 0 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - entity.getMesh().getSpaceSteps().y() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ] + entity.getMesh().getSpaceSteps().y() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().z() == 0 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - entity.getMesh().getSpaceSteps().z() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 )
+         {
+            return u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ] + entity.getMesh().getSpaceSteps().z() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }   
+      }
+
+
+      template< typename EntityType >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const EntityType& entity ) const
+      {
+         return 2;
+      }
+
+      template< typename PreimageFunction,
+                typename MeshEntity,
+                typename Matrix,
+                typename Vector >
+      __cuda_callable__
+      void setMatrixElements( const PreimageFunction& u,
+                                     const MeshEntity& entity,
+                                     const RealType& time,
+                                     const RealType& tau,
+                                     Matrix& matrix,
+                                     Vector& b ) const
+      {
+         const auto& neighbourEntities = entity.getNeighbourEntities();
+         const IndexType& index = entity.getIndex();
+         typename Matrix::MatrixRow matrixRow = matrix.getRow( index );
+         if( entity.getCoordinates().x() == 0 )
+         {
+            matrixRow.setElement( 0, index,                                                   1.0 );
+            matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 );
+            b[ index ] = - entity.getMesh().getSpaceSteps().x() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 )
+         {
+            matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 );
+            matrixRow.setElement( 1, index,                                                    1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().x() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().y() == 0 )
+         {
+            matrixRow.setElement( 0, index,                                                   1.0 );
+            matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 );
+            b[ index ] = - entity.getMesh().getSpaceSteps().y() * 
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 )
+         {
+            matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 );
+            matrixRow.setElement( 1, index,                                                    1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().y() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().z() == 0 )
+         {
+            matrixRow.setElement( 0, index,                                                   1.0 );
+            matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 );
+            b[ index ] = - entity.getMesh().getSpaceSteps().z() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+         if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 )
+         {
+            matrixRow.setElement( 0, neighbourEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 );
+            matrixRow.setElement( 1, index,                                                    1.0 );
+            b[ index ] = entity.getMesh().getSpaceSteps().z() *
+               tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
+         }
+      }
 };
 
 template< typename Mesh,
diff --git a/src/operators/tnlNeumannBoundaryConditions_impl.h b/src/operators/tnlNeumannBoundaryConditions_impl.h
index a29c5cac1322356cb11d27a7d03195b166f4d9f5..a9c39d0722183b4d0262e584bf35b8afd2611af4 100644
--- a/src/operators/tnlNeumannBoundaryConditions_impl.h
+++ b/src/operators/tnlNeumannBoundaryConditions_impl.h
@@ -9,7 +9,7 @@ tnlNeumannBoundaryConditionsBase< Function >::
 configSetup( tnlConfigDescription& config,
              const tnlString& prefix )
 {
-   Function::configSetup( config );
+   Function::configSetup( config, prefix );
 }
 
 template< typename Function >
@@ -18,7 +18,7 @@ tnlNeumannBoundaryConditionsBase< Function >::
 setup( const tnlParameterContainer& parameters,
        const tnlString& prefix )
 {
-   return this->function.setup( parameters );
+   return this->function.setup( parameters, prefix );
 }
 
 template< typename Function >
@@ -49,7 +49,7 @@ getFunction() const
 /****
  * 1D grid
  */
-
+/*
 template< typename MeshReal,
           typename Device,
           typename MeshIndex,
@@ -106,7 +106,7 @@ template< typename MeshReal,
 __cuda_callable__
 void
 tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >::
-updateLinearSystem( const RealType& time,
+setMatrixElements( const RealType& time,
                     const MeshType& mesh,
                     const IndexType& index,
                     const EntityType& entity,
@@ -130,11 +130,12 @@ updateLinearSystem( const RealType& time,
       b[ index ] = mesh.getSpaceSteps().x() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
    }
-}
+}*/
 
 /****
  * 2D grid
  */
+/*
 template< typename MeshReal,
           typename Device,
           typename MeshIndex,
@@ -204,7 +205,7 @@ template< typename MeshReal,
 __cuda_callable__
 void
 tnlNeumannBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index >::
-updateLinearSystem( const RealType& time,
+setMatrixElements( const RealType& time,
                     const MeshType& mesh,
                     const IndexType& index,
                     const EntityType& entity,
@@ -242,11 +243,12 @@ updateLinearSystem( const RealType& time,
       b[ index ] = mesh.getSpaceSteps().y() *
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
    }
-}
+}*/
 
 /****
  * 3D grid
  */
+/*
 template< typename MeshReal,
           typename Device,
           typename MeshIndex,
@@ -326,7 +328,7 @@ template< typename MeshReal,
 __cuda_callable__
 void
 tnlNeumannBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index >::
-updateLinearSystem( const RealType& time,
+setMatrixElements( const RealType& time,
                     const MeshType& mesh,
                     const IndexType& index,
                     const EntityType& entity,                    
@@ -379,6 +381,7 @@ updateLinearSystem( const RealType& time,
          tnlFunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time );
    }
 }
+*/
 
 #endif	/* TNLNEUMANNBOUNDARYCONDITIONS_IMPL_H */
 
diff --git a/src/problems/tnlHeatEquationProblem.h b/src/problems/tnlHeatEquationProblem.h
index 2dff242534d4ca8512302172fc4025114c41160d..c47cf4072376d4ae668670994f0c4e851ccc7341 100644
--- a/src/problems/tnlHeatEquationProblem.h
+++ b/src/problems/tnlHeatEquationProblem.h
@@ -29,6 +29,7 @@
 #include <operators/diffusion/tnlLinearDiffusion.h>
 #include <matrices/tnlEllpackMatrix.h>
 #include <functions/tnlMeshFunction.h>
+#include <core/tnlTimer.h>
 
 template< typename Mesh,
           typename BoundaryCondition,
@@ -59,6 +60,9 @@ class tnlHeatEquationProblem : public tnlPDEProblem< Mesh,
 
       void writeProlog( tnlLogger& logger,
                         const tnlParameterContainer& parameters ) const;
+      
+      bool writeEpilog( tnlLogger& logger );
+
 
       bool setup( const tnlParameterContainer& parameters );
 
@@ -86,7 +90,7 @@ class tnlHeatEquationProblem : public tnlPDEProblem< Mesh,
                            const RealType& tau,
                            const MeshType& mesh,
                            DofVectorType& _u,
-		                	   DofVectorType& _fu,
+			   DofVectorType& _fu,
                            MeshDependentDataType& meshDependentData );
 
       template< typename Matrix >
@@ -108,6 +112,8 @@ class tnlHeatEquationProblem : public tnlPDEProblem< Mesh,
          BoundaryCondition boundaryCondition;
 
          RightHandSide rightHandSide;
+         
+         tnlTimer gpuTransferTimer;
 };
 
 #include <problems/tnlHeatEquationProblem_impl.h>
diff --git a/src/problems/tnlHeatEquationProblem_impl.h b/src/problems/tnlHeatEquationProblem_impl.h
index 62294b39558186494a2bcfa35a94768616114784..11f1f8569ed90539d3d5c2f8378c37d92470b97c 100644
--- a/src/problems/tnlHeatEquationProblem_impl.h
+++ b/src/problems/tnlHeatEquationProblem_impl.h
@@ -68,6 +68,19 @@ writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const
 {
 }
 
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+tnlHeatEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+writeEpilog( tnlLogger& logger )
+{
+   logger.writeParameter< const char* >( "GPU transfer time:", "" );
+   this->gpuTransferTimer.writeLog( logger, 1 );
+   return true;
+}
+
 template< typename Mesh,
           typename BoundaryCondition,
           typename RightHandSide,
@@ -76,6 +89,7 @@ bool
 tnlHeatEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
 setup( const tnlParameterContainer& parameters )
 {
+   this->gpuTransferTimer.reset();
    if( ! this->boundaryCondition.setup( parameters, "boundary-conditions-" ) ||
        ! this->rightHandSide.setup( parameters, "right-hand-side-" ) )
       return false;
@@ -207,6 +221,7 @@ getExplicitRHS( const RealType& time,
    this->bindDofs( mesh, uDofs );
    MeshFunctionType fu( mesh, fuDofs );
    tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
+   explicitUpdater.setGPUTransferTimer( this->gpuTransferTimer ); 
    explicitUpdater.template update< typename Mesh::Cell >( 
       time,
       mesh,
@@ -220,6 +235,10 @@ getExplicitRHS( const RealType& time,
       this->boundaryCondition,
       time + tau,
       this->u );
+   
+   //fu.write( "fu.txt", "gnuplot" );
+   //this->u.write( "u.txt", "gnuplot");
+   //getchar();
    /*cout << "u = " << u << endl;
    cout << "fu = " << fu << endl;
    u.save( "u.tnl" );
diff --git a/src/problems/tnlPDEProblem.h b/src/problems/tnlPDEProblem.h
index c741abe2987de8538249d57c35354467bb845b58..f18fd41e1f788a2126066e3500b93c04a6816857 100644
--- a/src/problems/tnlPDEProblem.h
+++ b/src/problems/tnlPDEProblem.h
@@ -52,6 +52,9 @@ class tnlPDEProblem : public tnlProblem< Real, Device, Index >
 
       void writeProlog( tnlLogger& logger,
                         const tnlParameterContainer& parameters ) const;
+      
+      bool writeEpilog( tnlLogger& logger ) const;
+
 
       bool setMeshDependentData( const MeshType& mesh,
                                  MeshDependentDataType& meshDependentData );
@@ -64,6 +67,11 @@ class tnlPDEProblem : public tnlProblem< Real, Device, Index >
                        const MeshType& mesh,
                        DofVectorType& dofs,
                        MeshDependentDataType& meshDependentData );
+      
+      void setExplicitBoundaryConditions( const RealType& time,
+                                          const MeshType& mesh,
+                                          DofVectorType& dofs,
+                                          MeshDependentDataType& meshDependentData );
 
       bool postIterate( const RealType& time,
                         const RealType& tau,
diff --git a/src/problems/tnlPDEProblem_impl.h b/src/problems/tnlPDEProblem_impl.h
index 9954e2b1f4294c348fd4f197f7e3dfb6e08f273d..0955ff0c3db72725098413c15b57c4ec88d29da8 100644
--- a/src/problems/tnlPDEProblem_impl.h
+++ b/src/problems/tnlPDEProblem_impl.h
@@ -54,6 +54,18 @@ writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const
 {
 }
 
+template< typename Mesh,
+          typename Real,
+          typename Device,
+          typename Index >
+bool
+tnlPDEProblem< Mesh, Real, Device, Index >::
+writeEpilog( tnlLogger& logger ) const
+{
+   return true;
+}
+
+
 template< typename Mesh,
           typename Real,
           typename Device,
@@ -95,6 +107,20 @@ preIterate( const RealType& time,
    return true;
 }
 
+template< typename Mesh,
+          typename Real,
+          typename Device,
+          typename Index >
+void
+tnlPDEProblem< Mesh, Real, Device, Index >::
+setExplicitBoundaryConditions( const RealType& time,
+                               const MeshType& mesh,
+                               DofVectorType& dofs,
+                               MeshDependentDataType& meshDependentData )
+{   
+}
+
+
 template< typename Mesh,
           typename Real,
           typename Device,
diff --git a/src/solvers/cfd/navier-stokes/tnlNavierStokesSolver_impl.h b/src/solvers/cfd/navier-stokes/tnlNavierStokesSolver_impl.h
index 085eadf14febf6d65334361dbd2d5b16693c51f9..09021f4d2beccdb396464c41525623d3ea135576 100644
--- a/src/solvers/cfd/navier-stokes/tnlNavierStokesSolver_impl.h
+++ b/src/solvers/cfd/navier-stokes/tnlNavierStokesSolver_impl.h
@@ -323,7 +323,7 @@ void tnlNavierStokesSolver< AdvectionScheme,
       const IndexType size = dofs_rho.getSize();
 
       #ifdef HAVE_OPENMP
-      #pragma omp parallel for
+      #pragma omp parallel for, if( tnlHost::isOMPEnabled() )
       #endif
       for( IndexType c = 0; c < size; c++ )
          {
@@ -331,7 +331,7 @@ void tnlNavierStokesSolver< AdvectionScheme,
             const RealType u1 = this->u1[ c ] = dofs_rho_u1[ c ] / dofs_rho[ c ];
             const RealType u2 = this->u2[ c ] = dofs_rho_u2[ c ] / dofs_rho[ c ];
             this->u[ c ] = sqrt( u1*u1 + u2*u2 );
-            //this->p[ c ] = dofs_rho[ c ] * this -> R * this -> T;
+            //this->p[ c ] = dofs_rho[ c ] * this->R * this->T;
             this->p[ c ] = ( this->gamma - 1.0 ) *
                            ( dofs_e[ c ] - 0.5 * this->rho[ c ] * ( this->u1[ c ] * this->u1[ c ] + this->u2[ c ] * this->u2[ c ] ) );
             this->energy[ c ] = dofs_e[ c ];
@@ -447,7 +447,7 @@ void tnlNavierStokesSolver< AdvectionScheme,
    writePhysicalVariables( time, -4 );
 
 #ifdef HAVE_OPENMP
-  #pragma omp parallel for
+  #pragma omp parallel for, if( tnlHost::isOMPEnabled() )
   #endif
   for( IndexType j = 0; j < ySize; j ++ )
      for( IndexType i = 0; i < xSize; i ++ )
@@ -468,7 +468,7 @@ void tnlNavierStokesSolver< AdvectionScheme,
                                          tau );
 
         //rho_u1_t[ c ] += ;
-        //rho_u2_t[ c ] -= startUpCoefficient * this -> gravity * this -> rho[ c ];
+        //rho_u2_t[ c ] -= startUpCoefficient * this->gravity * this->rho[ c ];
 
         /***
          * Add the viscosity term
diff --git a/src/solvers/linear/CMakeLists.txt b/src/solvers/linear/CMakeLists.txt
index 181dc98f872a1de919ba95d851d268199ca2e4aa..2b8ed6ad23884c6b881aa82594e3912e2da6dd59 100755
--- a/src/solvers/linear/CMakeLists.txt
+++ b/src/solvers/linear/CMakeLists.txt
@@ -3,6 +3,8 @@ ADD_SUBDIRECTORY( stationary )
 
 SET( headers tnlLinearResidueGetter.h
              tnlLinearResidueGetter_impl.h 
+             tnlUmfpackWrapper.h
+             tnlUmfpackWrapper_impl.h
    )
 
 SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/solvers/linear )
@@ -20,4 +22,4 @@ if( BUILD_CUDA)
 endif()
 
    
-INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/solvers/linear )
\ No newline at end of file
+INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/solvers/linear )
diff --git a/src/solvers/linear/krylov/tnlBICGStabSolver_impl.h b/src/solvers/linear/krylov/tnlBICGStabSolver_impl.h
index 8532424ef49bdc2633f91e3aa36cd39cdc8f9177..d38b0519c35549c379a645091cc2396dedea0ebd 100644
--- a/src/solvers/linear/krylov/tnlBICGStabSolver_impl.h
+++ b/src/solvers/linear/krylov/tnlBICGStabSolver_impl.h
@@ -39,8 +39,8 @@ template< typename Matrix,
 tnlString tnlBICGStabSolver< Matrix, Preconditioner > :: getType() const
 {
    return tnlString( "tnlBICGStabSolver< " ) +
-          this -> matrix -> getType() + ", " +
-          this -> preconditioner -> getType() + " >";
+          this->matrix -> getType() + ", " +
+          this->preconditioner -> getType() + " >";
 }
 
 template< typename Matrix,
@@ -67,14 +67,14 @@ template< typename Matrix,
           typename Preconditioner >
 void tnlBICGStabSolver< Matrix, Preconditioner > :: setMatrix( const MatrixType& matrix )
 {
-   this -> matrix = &matrix;
+   this->matrix = &matrix;
 }
 
 template< typename Matrix,
            typename Preconditioner >
 void tnlBICGStabSolver< Matrix, Preconditioner > :: setPreconditioner( const Preconditioner& preconditioner )
 {
-   this -> preconditioner = &preconditioner;
+   this->preconditioner = &preconditioner;
 }
 
 template< typename Matrix,
@@ -85,15 +85,15 @@ bool tnlBICGStabSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vect
    dbgFunctionName( "tnlBICGStabSolver", "Solve" );
    if( ! this->setSize( matrix->getRows() ) ) return false;
 
-   this -> resetIterations();
-   this -> setResidue( this -> getConvergenceResidue() + 1.0 );
+   this->resetIterations();
+   this->setResidue( this->getConvergenceResidue() + 1.0 );
 
    RealType alpha, beta, omega, s1, s2, rho( 0.0 ), bNorm( 0.0 );
    // r_0 = b - A x_0, p_0 = r_0
    // r^ast_0 = r_0
 
    dbgCout( "Computing Ax" );
-   this -> matrix -> vectorProduct( x, r );
+   this->matrix -> vectorProduct( x, r );
 
    //if( bNorm == 0.0 ) bNorm = 1.0;
 
@@ -132,7 +132,7 @@ bool tnlBICGStabSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vect
          M -> Solve( M_tmp, Ap );
       }
       else*/
-          this -> matrix -> vectorProduct( p, Ap );
+          this->matrix -> vectorProduct( p, Ap );
 
       //dbgCout( "Computing alpha" );
       s2 = Ap. scalarProduct( r_ast );
@@ -154,7 +154,7 @@ bool tnlBICGStabSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vect
          M -> Solve( M_tmp, As );
       }
       else*/
-          this -> matrix -> vectorProduct( s, As );
+          this->matrix -> vectorProduct( s, As );
 
       s1 = As. scalarProduct( s );
       s2 = As. scalarProduct( As );
diff --git a/src/solvers/linear/krylov/tnlCGSolver_impl.h b/src/solvers/linear/krylov/tnlCGSolver_impl.h
index 86bea9efd293ee7a9db34950d983bfbf70343f42..e6ad7b74312d3246347fb10a01f59b4e78c6d9e4 100644
--- a/src/solvers/linear/krylov/tnlCGSolver_impl.h
+++ b/src/solvers/linear/krylov/tnlCGSolver_impl.h
@@ -29,8 +29,8 @@ template< typename Matrix,
 tnlString tnlCGSolver< Matrix, Preconditioner > :: getType() const
 {
    return tnlString( "tnlCGSolver< " ) +
-          this -> matrix -> getType() + ", " +
-          this -> preconditioner -> getType() + " >";
+          this->matrix -> getType() + ", " +
+          this->preconditioner -> getType() + " >";
 }
 
 template< typename Matrix,
@@ -57,14 +57,14 @@ template< typename Matrix,
           typename Preconditioner >
 void tnlCGSolver< Matrix, Preconditioner > :: setMatrix( const MatrixType& matrix )
 {
-   this -> matrix = &matrix;
+   this->matrix = &matrix;
 }
 
 template< typename Matrix,
            typename Preconditioner >
 void tnlCGSolver< Matrix, Preconditioner > :: setPreconditioner( const Preconditioner& preconditioner )
 {
-   this -> preconditioner = &preconditioner;
+   this->preconditioner = &preconditioner;
 }
 
 template< typename Matrix,
@@ -138,11 +138,11 @@ solve( const Vector& b, Vector& x )
        */
       new_r.swap( r );
       
-      if( this -> getIterations() % 10 == 0 )
-         this -> setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
+      if( this->getIterations() % 10 == 0 )
+         this->setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
    }
-   this -> setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
-   this -> refreshSolverMonitor( true );
+   this->setResidue( ResidueGetter :: getResidue( *matrix, b, x, bNorm ) );
+   this->refreshSolverMonitor( true );
    return this->checkConvergence();
 };
 
diff --git a/src/solvers/linear/krylov/tnlGMRESSolver_impl.h b/src/solvers/linear/krylov/tnlGMRESSolver_impl.h
index 87cc0a8a63b34fbbf3d2ad6fad051f78b044229c..2542a38b3976c13765ac3d9dbddcf35b72bf7a63 100644
--- a/src/solvers/linear/krylov/tnlGMRESSolver_impl.h
+++ b/src/solvers/linear/krylov/tnlGMRESSolver_impl.h
@@ -150,7 +150,7 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
    this->setResidue( beta / normb );
 
    tnlSharedVector< RealType, DeviceType, IndexType > vi, vk;
-   while( this->nextIteration() )
+   while( this->checkNextIteration() )
    {
       const IndexType m = restarting;
       for( IndexType i = 0; i < m + 1; i ++ )
@@ -250,11 +250,7 @@ bool tnlGMRESSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
                              sn[ i ] );
 
          this->setResidue( fabs( s[ i + 1 ] ) / normb );
-         // 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() )
-         {
+         if( ! this->checkNextIteration() ) {
             update( i, m, _H, _s, _v, x );
             this->refreshSolverMonitor( true );
             return this->checkConvergence();
diff --git a/src/solvers/linear/krylov/tnlTFQMRSolver.h b/src/solvers/linear/krylov/tnlTFQMRSolver.h
index ab25f3e349e752bdac403a2323fada4fe34aa30e..32d250f52a18ecf23f961dabc04b1c5a0b89e1e4 100644
--- a/src/solvers/linear/krylov/tnlTFQMRSolver.h
+++ b/src/solvers/linear/krylov/tnlTFQMRSolver.h
@@ -75,7 +75,9 @@ class tnlTFQMRSolver : public tnlObject,
 
    bool setSize( IndexType size );
 
-   tnlVector< RealType, Device, IndexType >  d, r, w, u, v, r_ast, Au;
+   tnlVector< RealType, Device, IndexType >  d, r, w, u, v, r_ast, Au, M_tmp;
+
+   IndexType size;
 
    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 b5e72e6456d4fdb968d3d611d4b97985f87a51df..72dd40e313478ca3e6dcb53a8bd76fa93fb9f2ed 100644
--- a/src/solvers/linear/krylov/tnlTFQMRSolver_impl.h
+++ b/src/solvers/linear/krylov/tnlTFQMRSolver_impl.h
@@ -18,17 +18,12 @@
 #ifndef tnlTFQMRSolver_implH
 #define tnlTFQMRSolver_implH
 
-template< typename RealType,
-          typename Vector >
-RealType computeTFQMRNewP( Vector& p,
-                           const Vector&r,
-                           const RealType& beta,
-                           const RealType& omega,
-                           const Vector& Ap );
-
 template< typename Matrix,
           typename Preconditioner >
 tnlTFQMRSolver< Matrix, Preconditioner > :: tnlTFQMRSolver()
+: size( 0 ),
+  matrix( 0 ),
+  preconditioner( 0 )
 {
 }
 
@@ -65,14 +60,14 @@ template< typename Matrix,
           typename Preconditioner >
 void tnlTFQMRSolver< Matrix, Preconditioner > :: setMatrix( const MatrixType& matrix )
 {
-   this -> matrix = &matrix;
+   this->matrix = &matrix;
 }
 
 template< typename Matrix,
            typename Preconditioner >
 void tnlTFQMRSolver< Matrix, Preconditioner > :: setPreconditioner( const Preconditioner& preconditioner )
 {
-   this -> preconditioner = &preconditioner;
+   this->preconditioner = &preconditioner;
 }
 
 template< typename Matrix,
@@ -81,17 +76,31 @@ template< typename Matrix,
 bool tnlTFQMRSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector& x )
 {
    dbgFunctionName( "tnlTFQMRSolver", "Solve" );
-   if( ! this -> setSize( matrix -> getRows() ) ) return false;
+   if( ! this->setSize( matrix -> getRows() ) ) return false;
 
-   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, b_norm, w_norm;
 
-   this -> matrix -> vectorProduct( x, r );
-   r. addVector( b, 1.0, -1.0 );
+   if( preconditioner ) {
+      preconditioner -> solve( b, M_tmp );
+      b_norm = M_tmp. lpNorm( ( RealType ) 2.0 );
+
+      matrix -> vectorProduct( x, M_tmp );
+      M_tmp.addVector( b, 1.0, -1.0 );
+      preconditioner -> solve( M_tmp, r );
+   }
+   else {
+      b_norm = b. lpNorm( 2.0 );
+      matrix -> vectorProduct( x, r );
+      r.addVector( b, 1.0, -1.0 );
+   }
    w = u = r;
-   matrix -> vectorProduct( u, Au );
+   if( preconditioner ) {
+      matrix -> vectorProduct( u, M_tmp );
+      preconditioner -> solve( M_tmp, Au );
+   }
+   else {
+      matrix -> vectorProduct( u, Au );
+   }
    v = Au;
    d. setValue( 0.0 );
    tau = r. lpNorm( 2.0 );
@@ -101,6 +110,9 @@ bool tnlTFQMRSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
    // only to avoid compiler warning; alpha is initialized inside the loop
    alpha = 0.0;
 
+   if( b_norm == 0.0 )
+       b_norm = 1.0;
+
    this->resetIterations();
    this->setResidue( tau / b_norm );
 
@@ -109,12 +121,18 @@ bool tnlTFQMRSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
       const IndexType iter = this->getIterations();
 
       if( iter % 2 == 1 ) {
-         alpha = rho / v. scalarProduct( this -> r_ast );
+         alpha = rho / v. scalarProduct( this->r_ast );
       }
       else {
          // not necessary in odd iter since the previous iteration
          // already computed v_{m+1} = A*u_{m+1}
-         matrix -> vectorProduct( u, Au );
+         if( preconditioner ) {
+            matrix -> vectorProduct( u, M_tmp );
+            preconditioner -> solve( M_tmp, Au );
+         }
+         else {
+            matrix -> vectorProduct( u, Au );
+         }
       }
       w.addVector( Au, -alpha );
       d.addVector( u, 1.0, theta * theta * eta / alpha );
@@ -131,20 +149,26 @@ bool tnlTFQMRSolver< Matrix, Preconditioner > :: solve( const Vector& b, Vector&
       }
 
       if( iter % 2 == 0 ) {
-         const RealType rho_new  = w. scalarProduct( this -> r_ast );
+         const RealType rho_new  = w. scalarProduct( this->r_ast );
          const RealType beta = rho_new / rho;
          rho = rho_new;
 
          u.addVector( w, 1.0, beta );
          v.addVector( Au, beta, beta * beta );
-         matrix -> vectorProduct( u, Au );
+         if( preconditioner ) {
+            matrix -> vectorProduct( u, M_tmp );
+            preconditioner -> solve( M_tmp, Au );
+         }
+         else {
+            matrix -> vectorProduct( u, Au );
+         }
          v.addVector( Au, 1.0 );
       }
       else {
          u.addVector( v, -alpha );
       }
       
-      this -> refreshSolverMonitor();
+      this->refreshSolverMonitor();
    }
 
 //   this->matrix->vectorProduct( x, r );
@@ -165,13 +189,17 @@ template< typename Matrix,
           typename Preconditioner >
 bool tnlTFQMRSolver< Matrix, Preconditioner > :: setSize( IndexType size )
 {
+   if( this->size == size )
+      return true;
+   this->size = size;
    if( ! d. setSize( size ) ||
        ! r. setSize( size ) ||
        ! w. setSize( size ) ||
        ! u. setSize( size ) ||
        ! v. setSize( size ) ||
        ! r_ast. setSize( size ) ||
-       ! Au. setSize( size ) )
+       ! Au. setSize( size ) ||
+       ! M_tmp. 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/tnlUmfpackWrapper.h b/src/solvers/linear/tnlUmfpackWrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..f5b739f39cf47871a00af1b042f905b277052731
--- /dev/null
+++ b/src/solvers/linear/tnlUmfpackWrapper.h
@@ -0,0 +1,122 @@
+#pragma once
+
+#ifdef HAVE_UMFPACK
+
+#include <umfpack.h>
+
+#include <core/tnlObject.h>
+#include <config/tnlConfigDescription.h>
+#include <matrices/tnlCSRMatrix.h>
+#include <solvers/preconditioners/tnlDummyPreconditioner.h>
+#include <solvers/tnlIterativeSolver.h>
+#include <solvers/linear/tnlLinearResidueGetter.h>
+
+
+template< typename Matrix >
+struct is_csr_matrix
+{
+    static const bool value = false;
+};
+
+template< typename Real, typename Device, typename Index >
+struct is_csr_matrix< tnlCSRMatrix< Real, Device, Index > >
+{
+    static const bool value = true;
+};
+
+
+template< typename Matrix,
+          typename Preconditioner = tnlDummyPreconditioner< typename Matrix :: RealType,
+                                                            typename Matrix :: DeviceType,
+                                                            typename Matrix :: IndexType> >
+class tnlUmfpackWrapper
+    : public tnlObject,
+      // just to ensure the same interface as other linear solvers
+      public tnlIterativeSolver< typename Matrix::RealType,
+                                 typename Matrix::IndexType >
+{
+public:
+    typedef typename Matrix :: RealType RealType;
+    typedef typename Matrix :: IndexType IndexType;
+    typedef typename Matrix :: DeviceType DeviceType;
+    typedef Matrix MatrixType;
+    typedef Preconditioner PreconditionerType;
+
+    tnlUmfpackWrapper()
+    {
+        if( ! is_csr_matrix< Matrix >::value )
+            cerr << "The tnlUmfpackWrapper solver is available only for CSR matrices." << endl;
+        if( std::is_same< typename Matrix::DeviceType, tnlCuda >::value )
+            cerr << "The tnlUmfpackWrapper solver is not available on CUDA." << endl;
+        if( ! std::is_same< RealType, double >::value )
+            cerr << "The tnlUmfpackWrapper solver is available only for double precision." << endl;
+        if( ! std::is_same< IndexType, int >::value )
+            cerr << "The tnlUmfpackWrapper solver is available only for 'int' index type." << endl;
+    }
+
+    static void configSetup( tnlConfigDescription& config,
+                             const tnlString& prefix = "" )
+    {};
+
+    bool setup( const tnlParameterContainer& parameters,
+               const tnlString& prefix = "" )
+    {
+        return false;
+    };
+
+    void setMatrix( const MatrixType& matrix )
+    {};
+
+    void setPreconditioner( const Preconditioner& preconditioner )
+    {};
+
+    template< typename Vector,
+              typename ResidueGetter = tnlLinearResidueGetter< MatrixType, Vector > >
+    bool solve( const Vector& b, Vector& x )
+    {
+        return false;
+    };
+
+};
+
+
+template< typename Preconditioner >
+class tnlUmfpackWrapper< tnlCSRMatrix< double, tnlHost, int >, Preconditioner >
+    : public tnlObject,
+      // just to ensure the same interface as other linear solvers
+      public tnlIterativeSolver< double, int >
+{
+public:
+    typedef double RealType;
+    typedef int IndexType;
+    typedef tnlHost DeviceType;
+    typedef tnlCSRMatrix< double, tnlHost, int > MatrixType;
+    typedef Preconditioner PreconditionerType;
+
+    tnlUmfpackWrapper();
+
+    tnlString getType() const;
+
+    static void configSetup( tnlConfigDescription& config,
+                             const tnlString& prefix = "" );
+
+    bool setup( const tnlParameterContainer& parameters,
+               const tnlString& prefix = "" );
+
+    void setMatrix( const MatrixType& matrix );
+
+    void setPreconditioner( const Preconditioner& preconditioner );
+
+    template< typename Vector,
+              typename ResidueGetter = tnlLinearResidueGetter< MatrixType, Vector > >
+    bool solve( const Vector& b, Vector& x );
+
+protected:
+   const MatrixType* matrix;
+
+   const PreconditionerType* preconditioner;
+};
+
+#include "tnlUmfpackWrapper_impl.h"
+
+#endif
diff --git a/src/solvers/linear/tnlUmfpackWrapper_impl.h b/src/solvers/linear/tnlUmfpackWrapper_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2c60037b869d7deeb39739f0d5614acaeaceaa0
--- /dev/null
+++ b/src/solvers/linear/tnlUmfpackWrapper_impl.h
@@ -0,0 +1,125 @@
+#pragma once
+
+#ifdef HAVE_UMFPACK
+
+#include "tnlUmfpackWrapper.h"
+
+template< typename Preconditioner >
+tnlUmfpackWrapper< tnlCSRMatrix< double, tnlHost, int >, Preconditioner >::
+tnlUmfpackWrapper()
+{}
+
+template< typename Preconditioner >
+void
+tnlUmfpackWrapper< tnlCSRMatrix< double, tnlHost, int >, Preconditioner >::
+configSetup( tnlConfigDescription& config,
+             const tnlString& prefix )
+{
+}
+
+template< typename Preconditioner >
+bool
+tnlUmfpackWrapper< tnlCSRMatrix< double, tnlHost, int >, Preconditioner >::
+setup( const tnlParameterContainer& parameters,
+       const tnlString& prefix )
+{
+    return true;    
+}
+
+template< typename Preconditioner >
+void tnlUmfpackWrapper< tnlCSRMatrix< double, tnlHost, int >, Preconditioner >::
+setMatrix( const MatrixType& matrix )
+{
+    this -> matrix = &matrix;
+}
+
+template< typename Preconditioner >
+void tnlUmfpackWrapper< tnlCSRMatrix< double, tnlHost, int >, Preconditioner >::
+setPreconditioner( const Preconditioner& preconditioner )
+{
+    this -> preconditioner = &preconditioner;
+}
+
+
+template< typename Preconditioner >
+    template< typename Vector, typename ResidueGetter >
+bool tnlUmfpackWrapper< tnlCSRMatrix< double, tnlHost, int >, Preconditioner >::
+solve( const Vector& b,
+       Vector& x )
+{
+    tnlAssert( matrix->getRows() == matrix->getColumns(), );
+    tnlAssert( matrix->getColumns() == x.getSize() && matrix->getColumns() == b.getSize(), );
+
+    const IndexType size = matrix -> getRows();
+
+    this->resetIterations();
+    this->setResidue( this -> getConvergenceResidue() + 1.0 );
+
+    RealType bNorm = b. lpNorm( ( RealType ) 2.0 );
+
+    // UMFPACK objects
+    void* Symbolic = nullptr;
+    void* Numeric = nullptr;
+
+    int status = UMFPACK_OK;
+    double Control[ UMFPACK_CONTROL ];
+    double Info[ UMFPACK_INFO ];
+
+    // umfpack expects Compressed Sparse Column format, we have Compressed Sparse Row
+    // so we need to solve  A^T * x = rhs
+    int system_type = UMFPACK_Aat;
+
+    // symbolic reordering of the sparse matrix
+    status = umfpack_di_symbolic( size, size,
+                                  matrix->rowPointers.getData(),
+                                  matrix->columnIndexes.getData(),
+                                  matrix->values.getData(),
+                                  &Symbolic, Control, Info );
+    if( status != UMFPACK_OK ) {
+        cerr << "error: symbolic reordering failed" << endl;
+        goto finished;
+    }
+
+    // numeric factorization
+    status = umfpack_di_numeric( matrix->rowPointers.getData(),
+                                 matrix->columnIndexes.getData(),
+                                 matrix->values.getData(),
+                                 Symbolic, &Numeric, Control, Info );
+    if( status != UMFPACK_OK ) {
+        cerr << "error: numeric factorization failed" << endl;
+        goto finished;
+    }
+
+    // solve with specified right-hand-side
+    status = umfpack_di_solve( system_type,
+                               matrix->rowPointers.getData(),
+                               matrix->columnIndexes.getData(),
+                               matrix->values.getData(),
+                               x.getData(),
+                               b.getData(),
+                               Numeric, Control, Info );
+    if( status != UMFPACK_OK ) {
+        cerr << "error: umfpack_di_solve failed" << endl;
+        goto finished;
+    }
+
+finished:
+    if( status != UMFPACK_OK ) {
+        // increase print level for reports
+        Control[ UMFPACK_PRL ] = 2;
+        umfpack_di_report_status( Control, status );
+//        umfpack_di_report_control( Control );
+//        umfpack_di_report_info( Control, Info );
+    }
+
+    if( Symbolic )
+        umfpack_di_free_symbolic( &Symbolic );
+    if( Numeric )
+        umfpack_di_free_numeric( &Numeric );
+
+    this->setResidue( ResidueGetter::getResidue( *matrix, x, b, bNorm ) );
+    this->refreshSolverMonitor( true );
+    return status == UMFPACK_OK;
+};
+
+#endif
diff --git a/src/solvers/ode/tnlEulerSolver.h b/src/solvers/ode/tnlEulerSolver.h
index b7c92c7259209a7d2339ba72d371001f2c097846..13df781c2632042d34750083c4ce99e4958e30de 100644
--- a/src/solvers/ode/tnlEulerSolver.h
+++ b/src/solvers/ode/tnlEulerSolver.h
@@ -22,6 +22,7 @@
 #include <config/tnlConfigDescription.h>
 #include <solvers/ode/tnlExplicitSolver.h>
 #include <config/tnlParameterContainer.h>
+#include <core/tnlTimer.h>
 
 template< typename Problem >
 class tnlEulerSolver : public tnlExplicitSolver< Problem >
@@ -60,6 +61,8 @@ class tnlEulerSolver : public tnlExplicitSolver< Problem >
    DofVectorType k1;
 
    RealType cflCondition;
+   
+   //tnlTimer timer, updateTimer;
 };
 
 #include <solvers/ode/tnlEulerSolver_impl.h>
diff --git a/src/solvers/ode/tnlMersonSolver_impl.h b/src/solvers/ode/tnlMersonSolver_impl.h
index bc512effd6a874b3458860ad78de26ebc8893bd2..fee7015670cd1cfcc78f1862fe38e3e305059b59 100644
--- a/src/solvers/ode/tnlMersonSolver_impl.h
+++ b/src/solvers/ode/tnlMersonSolver_impl.h
@@ -122,13 +122,13 @@ bool tnlMersonSolver< Problem > :: setup( const tnlParameterContainer& parameter
 template< typename Problem >
 void tnlMersonSolver< Problem > :: setAdaptivity( const RealType& a )
 {
-   this -> adaptivity = a;
+   this->adaptivity = a;
 };
 
 template< typename Problem >
 bool tnlMersonSolver< Problem > :: solve( DofVectorType& u )
 {
-   if( ! this -> problem )
+   if( ! this->problem )
    {
       cerr << "No problem was set for the Merson ODE solver." << endl;
       return false;
@@ -165,7 +165,7 @@ bool tnlMersonSolver< Problem > :: solve( DofVectorType& u )
    this->resetIterations();
    this->setResidue( this->getConvergenceResidue() + 1.0 );
 
-   this -> refreshSolverMonitor();
+   this->refreshSolverMonitor();
 
    /****
     * Start the main loop
@@ -176,7 +176,7 @@ bool tnlMersonSolver< Problem > :: solve( DofVectorType& u )
        * Compute Runge-Kutta coefficients
        */
       computeKFunctions( u, time, currentTau );
-      if( this -> testingMode )
+      if( this->testingMode )
          writeGrids( u );
 
       /****
@@ -197,13 +197,13 @@ bool tnlMersonSolver< Problem > :: solve( DofVectorType& u )
           * When time is close to stopTime the new residue
           * may be inaccurate significantly.
           */
-         if( currentTau + time == this -> stopTime ) this->setResidue( lastResidue );
+         if( currentTau + time == this->stopTime ) this->setResidue( lastResidue );
          time += currentTau;
 
          if( ! this->nextIteration() )
             return false;
       }
-      this -> refreshSolverMonitor();
+      this->refreshSolverMonitor();
 
       /****
        * Compute the new time step.
@@ -212,22 +212,22 @@ bool tnlMersonSolver< Problem > :: solve( DofVectorType& u )
       {
          currentTau *= 0.8 * pow( adaptivity / eps, 0.2 );
          currentTau = Min( currentTau, this->getMaxTau() );
-         :: MPIBcast( currentTau, 1, 0, this -> solver_comm );
+         :: MPIBcast( currentTau, 1, 0, this->solver_comm );
       }
-      if( time + currentTau > this -> getStopTime() )
-         currentTau = this -> getStopTime() - time; //we don't want to keep such tau
-      else this -> tau = currentTau;
+      if( time + currentTau > this->getStopTime() )
+         currentTau = this->getStopTime() - time; //we don't want to keep such tau
+      else this->tau = currentTau;
 
 
       /****
        * Check stop conditions.
        */
       //cerr << "residue = " << residue << endl;
-      //cerr << "this -> getConvergenceResidue() = " << this -> getConvergenceResidue() << endl;
+      //cerr << "this->getConvergenceResidue() = " << this->getConvergenceResidue() << endl;
       if( time >= this->getStopTime() ||
-          ( this -> getConvergenceResidue() != 0.0 && this->getResidue() < this -> getConvergenceResidue() ) )
+          ( this->getConvergenceResidue() != 0.0 && this->getResidue() < this->getConvergenceResidue() ) )
       {
-         this -> refreshSolverMonitor();
+         this->refreshSolverMonitor();
          return true;
       }
    }
@@ -274,28 +274,28 @@ void tnlMersonSolver< Problem > :: computeKFunctions( DofVectorType& u,
       this->problem->getExplicitRHS( time, tau, u, k1 );
 
    #ifdef HAVE_OPENMP
-   #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, tau, tau_3 )
+   #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, tau, tau_3 ) if( tnlHost::isOMPEnabled() )
    #endif
       for( IndexType i = 0; i < size; i ++ )
          _kAux[ i ] = _u[ i ] + tau * ( 1.0 / 3.0 * _k1[ i ] );
       this->problem->getExplicitRHS( time + tau_3, tau, kAux, k2 );
 
    #ifdef HAVE_OPENMP
-   #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, _k2, tau, tau_3 )
+   #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, _k2, tau, tau_3 ) if( tnlHost::isOMPEnabled() )
    #endif
       for( IndexType i = 0; i < size; i ++ )
          _kAux[ i ] = _u[ i ] + tau * 1.0 / 6.0 * ( _k1[ i ] + _k2[ i ] );
       this->problem->getExplicitRHS( time + tau_3, tau, kAux, k3 );
 
    #ifdef HAVE_OPENMP
-   #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, _k3, tau, tau_3 )
+   #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, _k3, tau, tau_3 ) if( tnlHost::isOMPEnabled() )
    #endif
       for( IndexType i = 0; i < size; i ++ )
          _kAux[ i ] = _u[ i ] + tau * ( 0.125 * _k1[ i ] + 0.375 * _k3[ i ] );
       this->problem->getExplicitRHS( time + 0.5 * tau, tau, kAux, k4 );
 
    #ifdef HAVE_OPENMP
-   #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, _k3, _k4, tau, tau_3 )
+   #pragma omp parallel for firstprivate( size, _kAux, _u, _k1, _k3, _k4, tau, tau_3 ) if( tnlHost::isOMPEnabled() )
    #endif
       for( IndexType i = 0; i < size; i ++ )
          _kAux[ i ] = _u[ i ] + tau * ( 0.5 * _k1[ i ] - 1.5 * _k3[ i ] + 2.0 * _k4[ i ] );
@@ -420,7 +420,7 @@ typename Problem :: RealType tnlMersonSolver< Problem > :: computeError( const R
       }
 #endif
    }
-   :: MPIAllreduce( eps, maxEps, 1, MPI_MAX, this -> solver_comm );
+   :: MPIAllreduce( eps, maxEps, 1, MPI_MAX, this->solver_comm );
    return maxEps;
 }
 
@@ -454,7 +454,7 @@ void tnlMersonSolver< Problem > :: computeNewTimeLevel( DofVectorType& u,
    if( DeviceType :: getDevice() == tnlHostDevice )
    {
 #ifdef HAVE_OPENMP
-#pragma omp parallel for reduction(+:localResidue) firstprivate( size, _u, _k1, _k4, _k5, tau )
+#pragma omp parallel for reduction(+:localResidue) firstprivate( size, _u, _k1, _k4, _k5, tau ) if( tnlHost::isOMPEnabled() )
 #endif
       for( IndexType i = 0; i < size; i ++ )
       {
@@ -493,7 +493,7 @@ void tnlMersonSolver< Problem > :: computeNewTimeLevel( DofVectorType& u,
 #endif
    }
    localResidue /= tau * ( RealType ) size;
-   :: MPIAllreduce( localResidue, currentResidue, 1, MPI_SUM, this -> solver_comm );
+   :: MPIAllreduce( localResidue, currentResidue, 1, MPI_SUM, this->solver_comm );
 
 }
 
diff --git a/src/solvers/ode/tnlODESolverMonitor_impl.h b/src/solvers/ode/tnlODESolverMonitor_impl.h
index 4eed193d24e5ff432b24563418dca31fa4167f98..44ff3d69d2b5a76a5bef95abc13720f66ffd7911 100644
--- a/src/solvers/ode/tnlODESolverMonitor_impl.h
+++ b/src/solvers/ode/tnlODESolverMonitor_impl.h
@@ -28,16 +28,16 @@ tnlODESolverMonitor< RealType, IndexType> :: tnlODESolverMonitor()
 template< typename RealType, typename IndexType >
 void tnlODESolverMonitor< RealType, IndexType> :: refresh()
 {
-   if( this -> verbose > 0 && this -> getIterations() % this -> refreshRate == 0 )
+   if( this->verbose > 0 && this->getIterations() % this->refreshRate == 0 )
    {
       // TODO: add EST
       //cout << " EST: " << estimated;
-      cout << " ITER:" << setw( 8 ) << this -> getIterations()
-           << " TAU:" << setprecision( 5 ) << setw( 12 ) << this -> getTimeStep()
-           << " T:" << setprecision( 5 ) << setw( 12 ) << this -> getTime()
-           << " RES:" << setprecision( 5 ) << setw( 12 ) << this -> getResidue()
-           << " CPU: " << setw( 8 ) << this -> getCPUTime()
-           << " ELA: " << setw( 8 ) << this -> getRealTime();
+      cout << " ITER:" << setw( 8 ) << this->getIterations()
+           << " TAU:" << setprecision( 5 ) << setw( 12 ) << this->getTimeStep()
+           << " T:" << setprecision( 5 ) << setw( 12 ) << this->getTime()
+           << " RES:" << setprecision( 5 ) << setw( 12 ) << this->getResidue()
+           << " CPU: " << setw( 8 ) << this->getCPUTime()
+           << " ELA: " << setw( 8 ) << this->getRealTime();
        /*double flops = ( double ) tnl_flops_counter. getFlops();
        if( flops )
        {
@@ -45,31 +45,31 @@ void tnlODESolverMonitor< RealType, IndexType> :: refresh()
        }*/
        cout << "   \r" << flush;
     }
-   this -> refreshing ++;
+   this->refreshing ++;
 }
 
 template< typename RealType, typename IndexType >
 void tnlODESolverMonitor< RealType, IndexType> :: setTimeStep( const RealType& timeStep )
 {
-   this -> timeStep = timeStep;
+   this->timeStep = timeStep;
 }
 
 template< typename RealType, typename IndexType >
 const RealType& tnlODESolverMonitor< RealType, IndexType> :: getTimeStep() const
 {
-   return this -> timeStep;
+   return this->timeStep;
 }
 
 template< typename RealType, typename IndexType >
 void tnlODESolverMonitor< RealType, IndexType> :: setTime( const RealType& time )
 {
-   this -> time = time;
+   this->time = time;
 }
 
 template< typename RealType, typename IndexType >
 const RealType& tnlODESolverMonitor< RealType, IndexType> :: getTime() const
 {
-   return this -> time;
+   return this->time;
 }
 
 #endif /* TNLODESOLVERMONITOR_IMPL_H_ */
diff --git a/src/solvers/pde/tnlExplicitTimeStepper.h b/src/solvers/pde/tnlExplicitTimeStepper.h
index 9d3dc11a2754673c08fc008b6ebeabb0caa354fd..9c251443789c79ad7c453a75640df1d16a36ddab 100644
--- a/src/solvers/pde/tnlExplicitTimeStepper.h
+++ b/src/solvers/pde/tnlExplicitTimeStepper.h
@@ -21,7 +21,7 @@
 #include <solvers/ode/tnlODESolverMonitor.h>
 #include <config/tnlConfigDescription.h>
 #include <config/tnlParameterContainer.h>
-#include <core/tnlTimerRT.h>
+#include <core/tnlTimer.h>
 #include <core/tnlLogger.h>
 
 
@@ -85,7 +85,9 @@ class tnlExplicitTimeStepper
 
    MeshDependentDataType* meshDependentData;
    
-   tnlTimerRT explicitUpdaterTimer;
+   tnlTimer preIterateTimer, explicitUpdaterTimer, mainTimer, postIterateTimer;
+   
+   long long int allIterations;
 };
 
 #include <solvers/pde/tnlExplicitTimeStepper_impl.h>
diff --git a/src/solvers/pde/tnlExplicitTimeStepper_impl.h b/src/solvers/pde/tnlExplicitTimeStepper_impl.h
index e47e0c562eeaa1f0040abc80e4763897330dc04c..ea1fb5a436a2e6f506892e2c63ad4c38ce5afc61 100644
--- a/src/solvers/pde/tnlExplicitTimeStepper_impl.h
+++ b/src/solvers/pde/tnlExplicitTimeStepper_impl.h
@@ -27,7 +27,8 @@ tnlExplicitTimeStepper< Problem, OdeSolver >::
 tnlExplicitTimeStepper()
 : odeSolver( 0 ),
   problem( 0 ),
-  timeStep( 0 )
+  timeStep( 0 ),
+  allIterations( 0 )
 {
 };
 
@@ -57,6 +58,9 @@ tnlExplicitTimeStepper< Problem, OdeSolver >::
 init( const MeshType& mesh )
 {
    this->explicitUpdaterTimer.reset();
+   this->mainTimer.reset();
+   this->preIterateTimer.reset();
+   this->postIterateTimer.reset();
    return true;
 }
 
@@ -113,7 +117,8 @@ solve( const RealType& time,
        MeshDependentDataType& meshDependentData )
 {
    tnlAssert( this->odeSolver, );
-   this->odeSolver->setTau( this -> timeStep );
+   mainTimer.start();
+   this->odeSolver->setTau( this->timeStep );
    this->odeSolver->setProblem( * this );
    this->odeSolver->setTime( time );
    this->odeSolver->setStopTime( stopTime );
@@ -121,7 +126,12 @@ solve( const RealType& time,
       this->odeSolver->setMaxTau( ( stopTime - time ) / ( typename OdeSolver< Problem >::RealType ) this->odeSolver->getMinIterations() );
    this->mesh = &mesh;
    this->meshDependentData = &meshDependentData;
-   return this->odeSolver->solve( dofVector );
+   if( ! this->odeSolver->solve( dofVector ) )
+      return false;
+   this->problem->setExplicitBoundaryConditions( stopTime, *( this->mesh ), dofVector, *( this->meshDependentData ) );
+   mainTimer.stop();
+   this->allIterations += this->odeSolver->getIterations();
+   return true;
 }
 
 template< typename Problem,
@@ -133,6 +143,7 @@ getExplicitRHS( const RealType& time,
                 DofVectorType& u,
                 DofVectorType& fu )
 {
+   this->preIterateTimer.start();
    if( ! this->problem->preIterate( time,
                                     tau,
                                     *( this->mesh),
@@ -143,9 +154,12 @@ getExplicitRHS( const RealType& time,
       return;
       //return false; // TODO: throw exception
    }
-   this->explicitUpdaterTimer.start();   
+   this->preIterateTimer.stop();
+   this->explicitUpdaterTimer.start();
+   this->problem->setExplicitBoundaryConditions( time, *( this->mesh ), u, *( this->meshDependentData ) );
    this->problem->getExplicitRHS( time, tau, *( this->mesh ), u, fu, *( this->meshDependentData ) );
    this->explicitUpdaterTimer.stop();
+   this->postIterateTimer.start();
    if( ! this->problem->postIterate( time,
                                      tau,
                                      *( this->mesh ),
@@ -156,6 +170,7 @@ getExplicitRHS( const RealType& time,
       return;
       //return false; // TODO: throw exception
    }
+   this->postIterateTimer.stop();
 }
 
 template< typename Problem,
@@ -164,7 +179,15 @@ bool
 tnlExplicitTimeStepper< Problem, OdeSolver >::
 writeEpilog( tnlLogger& logger )
 {
-   logger.writeParameter< double >( "Explicit update computation time:", this->explicitUpdaterTimer.getTime() );
+   logger.writeParameter< long long int >( "Iterations count:", this->allIterations );
+   logger.writeParameter< const char* >( "Pre-iterate time:", "" );
+   this->preIterateTimer.writeLog( logger, 1 );   
+   logger.writeParameter< const char* >( "Explicit update computation:", "" );
+   this->explicitUpdaterTimer.writeLog( logger, 1 );
+   logger.writeParameter< const char* >( "Explicit time stepper time:", "" );
+   this->mainTimer.writeLog( logger, 1 );
+   logger.writeParameter< const char* >( "Post-iterate time:", "" );
+   this->postIterateTimer.writeLog( logger, 1 );   
    return true;
 }
 
diff --git a/src/solvers/pde/tnlExplicitUpdater.h b/src/solvers/pde/tnlExplicitUpdater.h
index c1869086686eccf733362f37faa468136c367d72..597222b741bcd0c8aad030559af109d17a4d563c 100644
--- a/src/solvers/pde/tnlExplicitUpdater.h
+++ b/src/solvers/pde/tnlExplicitUpdater.h
@@ -19,6 +19,7 @@
 #define TNLEXPLICITUPDATER_H_
 
 #include <functions/tnlFunctionAdapter.h>
+#include <core/tnlTimer.h>
 
 template< typename Real,
           typename MeshFunction,
@@ -51,7 +52,8 @@ class tnlExplicitUpdaterTraverserUserData
         rightHandSide( &rightHandSide ),
         u( &u ),
         fu( &fu )
-      {};
+      {
+      };
 };
 
 
@@ -72,6 +74,14 @@ class tnlExplicitUpdater
                                                    DifferentialOperator,
                                                    BoundaryConditions,
                                                    RightHandSide > TraverserUserData;
+      
+      tnlExplicitUpdater()
+      : gpuTransferTimer( 0 ){}
+      
+      void setGPUTransferTimer( tnlTimer& timer )
+      {
+         this->gpuTransferTimer = &timer;
+      }
 
       template< typename EntityType >
       void update( const RealType& time,
@@ -82,7 +92,7 @@ class tnlExplicitUpdater
                    MeshFunction& u,
                    MeshFunction& fu ) const;      
       
-            class TraverserBoundaryEntitiesProcessor
+      class TraverserBoundaryEntitiesProcessor
       {
          public:
             
@@ -126,6 +136,10 @@ class tnlExplicitUpdater
                      *userData.time );
             }
       };
+      
+   protected:
+      
+      tnlTimer* gpuTransferTimer;
 };
 
 #include <solvers/pde/tnlExplicitUpdater_impl.h>
diff --git a/src/solvers/pde/tnlExplicitUpdater_impl.h b/src/solvers/pde/tnlExplicitUpdater_impl.h
index 16a2c0346402907c21701d280609deddd27a3cad..a2c3ff1ce79b1547716f08b5ca1c69d5f011f5ab 100644
--- a/src/solvers/pde/tnlExplicitUpdater_impl.h
+++ b/src/solvers/pde/tnlExplicitUpdater_impl.h
@@ -23,6 +23,8 @@
 #include <mesh/grids/tnlTraverser_Grid2D.h>
 #include <mesh/grids/tnlTraverser_Grid3D.h>
 
+#include "tnlExplicitUpdater.h"
+
 template< typename Mesh,
           typename MeshFunction,
           typename DifferentialOperator,
@@ -60,12 +62,17 @@ update( const RealType& time,
    }
    if( std::is_same< DeviceType, tnlCuda >::value )
    {
+      if( this->gpuTransferTimer ) 
+         this->gpuTransferTimer->start();
       RealType* kernelTime = tnlCuda::passToDevice( time );
       DifferentialOperator* kernelDifferentialOperator = tnlCuda::passToDevice( differentialOperator );
       BoundaryConditions* kernelBoundaryConditions = tnlCuda::passToDevice( boundaryConditions );
       RightHandSide* kernelRightHandSide = tnlCuda::passToDevice( rightHandSide );
       MeshFunction* kernelU = tnlCuda::passToDevice( u );
       MeshFunction* kernelFu = tnlCuda::passToDevice( fu );
+     if( this->gpuTransferTimer ) 
+         this->gpuTransferTimer->stop();
+
       TraverserUserData userData( *kernelTime, *kernelDifferentialOperator, *kernelBoundaryConditions, *kernelRightHandSide, *kernelU, *kernelFu );
       checkCudaDevice;
       tnlTraverser< MeshType, EntityType > meshTraverser;
@@ -78,7 +85,10 @@ update( const RealType& time,
                                                     ( mesh,
                                                       userData );
 
-      checkCudaDevice;
+      if( this->gpuTransferTimer ) 
+         this->gpuTransferTimer->start();
+      
+      checkCudaDevice;      
       tnlCuda::freeFromDevice( kernelTime );
       tnlCuda::freeFromDevice( kernelDifferentialOperator );
       tnlCuda::freeFromDevice( kernelBoundaryConditions );
@@ -86,6 +96,10 @@ update( const RealType& time,
       tnlCuda::freeFromDevice( kernelU );
       tnlCuda::freeFromDevice( kernelFu );
       checkCudaDevice;
+      
+      if( this->gpuTransferTimer ) 
+         this->gpuTransferTimer->stop();
+
    }
 }
 
diff --git a/src/solvers/pde/tnlLinearSystemAssembler.h b/src/solvers/pde/tnlLinearSystemAssembler.h
index 14753fb7877ae1f1126b541345099a1da28a916f..74b7b6e44056915b0b9fbee59f1cd56d132b74f6 100644
--- a/src/solvers/pde/tnlLinearSystemAssembler.h
+++ b/src/solvers/pde/tnlLinearSystemAssembler.h
@@ -121,14 +121,13 @@ class tnlLinearSystemAssembler
                                     const EntityType& entity )
          {
              ( *userData.b )[ entity.getIndex() ] = 0.0;           
-             userData.boundaryConditions->updateLinearSystem
-               ( *userData.time + *userData.tau,
-                 mesh,
-                 entity.getIndex(),
+             userData.boundaryConditions->setMatrixElements
+               ( *userData.u,
                  entity,
-                 *userData.u,
-                 *userData.b,
-                 *userData.matrix );
+                 *userData.time + *userData.tau,
+                 *userData.tau,
+                 *userData.matrix,
+                 *userData.b );
          }
    };
 
@@ -143,15 +142,13 @@ class tnlLinearSystemAssembler
                                     const EntityType& entity )
          {
             ( *userData.b )[ entity.getIndex() ] = 0.0;            
-            userData.differentialOperator->updateLinearSystem
-               ( *userData.time,
-                 *userData.tau,
-                 mesh,
-                 entity.getIndex(),
+            userData.differentialOperator->setMatrixElements
+               ( *userData.u,
                  entity,
-                 *userData.u,
-                 *userData.b,
-                 *userData.matrix );
+                 *userData.time + *userData.tau,
+                 *userData.tau,
+                 *userData.matrix, 
+                 *userData.b );
             
             typedef tnlFunctionAdapter< MeshType, RightHandSide > RhsFunctionAdapter;
             typedef tnlFunctionAdapter< MeshType, MeshFunction > MeshFunctionAdapter;
diff --git a/src/solvers/pde/tnlPDESolver.h b/src/solvers/pde/tnlPDESolver.h
index 87c1f18e5b36a0814455703c9d689a54004f043b..f6065eb478d865c49d90c0e50517cf3f9d4442cd 100644
--- a/src/solvers/pde/tnlPDESolver.h
+++ b/src/solvers/pde/tnlPDESolver.h
@@ -73,13 +73,9 @@ class tnlPDESolver : public tnlObject
 
       const RealType& getSnapshotPeriod() const;
 
-      void setIoRtTimer( tnlTimerRT& ioRtTimer);
+      void setIoTimer( tnlTimer& ioTimer);
 
-      void setComputeRtTimer( tnlTimerRT& computeRtTimer );
-
-      void setIoCpuTimer( tnlTimerCPU& ioCpuTimer );
-
-      void setComputeCpuTimer( tnlTimerCPU& computeCpuTimer );
+      void setComputeTimer( tnlTimer& computeTimer );
 
       bool solve();
 
@@ -99,10 +95,7 @@ class tnlPDESolver : public tnlObject
 
       ProblemType* problem;
 
-      tnlTimerRT *ioRtTimer, *computeRtTimer;
-
-      tnlTimerCPU *ioCpuTimer, *computeCpuTimer;
-
+      tnlTimer *ioTimer, *computeTimer;
 };
 
 #include <solvers/pde/tnlPDESolver_impl.h>
diff --git a/src/solvers/pde/tnlPDESolver_impl.h b/src/solvers/pde/tnlPDESolver_impl.h
index cb820815a14d99c2184ae9d56bbafa1c16dfa1a2..b0356073984a277c1af4930c41dff14927e3ed27 100644
--- a/src/solvers/pde/tnlPDESolver_impl.h
+++ b/src/solvers/pde/tnlPDESolver_impl.h
@@ -18,6 +18,9 @@
 #ifndef TNLPDESOLVER_IMPL_H_
 #define TNLPDESOLVER_IMPL_H_
 
+#include "tnlPDESolver.h"
+
+
 template< typename Problem,
           typename TimeStepper >
 tnlPDESolver< Problem, TimeStepper >::
@@ -29,10 +32,8 @@ tnlPDESolver()
   timeStep( 1.0 ),
   timeStepOrder( 0.0 ),
   problem( 0 ),
-  ioRtTimer( 0 ),
-  computeRtTimer( 0 ),
-  ioCpuTimer( 0 ),
-  computeCpuTimer( 0 )
+  ioTimer( 0 ),
+  computeTimer( 0 )
 {
 }
 
@@ -150,6 +151,7 @@ writeProlog( tnlLogger& logger,
    logger.writeSystemInformation( parameters );
    logger.writeSeparator();
    logger.writeCurrentTime( "Started at:" );
+   logger.writeSeparator();
    return true;
 }
 
@@ -287,27 +289,15 @@ getTimeStepOrder() const
 }
 
 template< typename Problem, typename TimeStepper >
-void tnlPDESolver< Problem, TimeStepper > :: setIoRtTimer( tnlTimerRT& ioRtTimer )
+void tnlPDESolver< Problem, TimeStepper > :: setIoTimer( tnlTimer& ioTimer )
 {
-   this->ioRtTimer = &ioRtTimer;
+   this->ioTimer = &ioTimer;
 }
 
 template< typename Problem, typename TimeStepper >
-void tnlPDESolver< Problem, TimeStepper > :: setComputeRtTimer( tnlTimerRT& computeRtTimer )
+void tnlPDESolver< Problem, TimeStepper > :: setComputeTimer( tnlTimer& computeTimer )
 {
-   this -> computeRtTimer = &computeRtTimer;
-}
-
-template< typename Problem, typename TimeStepper >
-void tnlPDESolver< Problem, TimeStepper > :: setIoCpuTimer( tnlTimerCPU& ioCpuTimer )
-{
-   this -> ioCpuTimer = &ioCpuTimer;
-}
-
-template< typename Problem, typename TimeStepper >
-void tnlPDESolver< Problem, TimeStepper > :: setComputeCpuTimer( tnlTimerCPU& computeCpuTimer )
-{
-   this -> computeCpuTimer = & computeCpuTimer;
+   this->computeTimer = &computeTimer;
 }
 
 template< typename Problem, typename TimeStepper >
@@ -329,21 +319,17 @@ 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();
-
+   this->ioTimer->reset();
+   this->computeTimer->reset();
+   
+   this->ioTimer->start();
    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();
+   }   
+   this->ioTimer->stop();
+   this->computeTimer->start();
 
    /****
     * Initialize the time stepper
@@ -353,29 +339,24 @@ solve()
    this->timeStepper->setTimeStep( this->timeStep * pow( mesh.getSmallestSpaceStep(), this->timeStepOrder ) );
    while( step < allSteps )
    {
-      RealType tau = Min( this -> snapshotPeriod,
-                          this -> finalTime - t );
+      RealType tau = Min( this->snapshotPeriod,
+                          this->finalTime - t );
       if( ! this->timeStepper->solve( t, t + tau, mesh, this->dofs, this->meshDependentData ) )
          return false;
       step ++;
       t += tau;
 
-      this->ioRtTimer->start();
-      this->ioCpuTimer->start();
-      this->computeRtTimer->stop();
-      this->computeCpuTimer->stop();
-
+      this->ioTimer->start();
+      this->computeTimer->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();
+      this->ioTimer->stop();
+      this->computeTimer->start();
    }
+   this->computeTimer->stop();
    return true;
 }
 
@@ -384,7 +365,8 @@ bool
 tnlPDESolver< Problem, TimeStepper >::
 writeEpilog( tnlLogger& logger ) const
 {
-   return this->timeStepper->writeEpilog( logger );
+   return ( this->timeStepper->writeEpilog( logger ) &&
+      this->problem->writeEpilog( logger ) );
 }
 
 #endif /* TNLPDESOLVER_IMPL_H_ */
diff --git a/src/solvers/pde/tnlSemiImplicitTimeStepper.h b/src/solvers/pde/tnlSemiImplicitTimeStepper.h
index 05f16704e760f44ab54d433211a56ddaa5a29623..4ce812079a9a21800fa131fc11cca97eb403fb60 100644
--- a/src/solvers/pde/tnlSemiImplicitTimeStepper.h
+++ b/src/solvers/pde/tnlSemiImplicitTimeStepper.h
@@ -80,9 +80,11 @@ class tnlSemiImplicitTimeStepper
 
    RealType timeStep;
 
-   tnlTimerRT preIterateTimer, linearSystemAssemblerTimer, linearSystemSolverTimer, postIterateTimer;
+   tnlTimer preIterateTimer, linearSystemAssemblerTimer, preconditionerUpdateTimer, linearSystemSolverTimer, postIterateTimer;
    
    bool verbose;
+   
+   long long int allIterations;
 };
 
 #include <solvers/pde/tnlSemiImplicitTimeStepper_impl.h>
diff --git a/src/solvers/pde/tnlSemiImplicitTimeStepper_impl.h b/src/solvers/pde/tnlSemiImplicitTimeStepper_impl.h
index d13ef8050448da323e657cab41935696c8c9b4a4..8c1024baf5b987c740efb1c557b5f212d74c7f30 100644
--- a/src/solvers/pde/tnlSemiImplicitTimeStepper_impl.h
+++ b/src/solvers/pde/tnlSemiImplicitTimeStepper_impl.h
@@ -20,13 +20,16 @@
 
 #include <core/mfuncs.h>
 
+#include "tnlSemiImplicitTimeStepper.h"
+
 template< typename Problem,
           typename LinearSystemSolver >
 tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >::
 tnlSemiImplicitTimeStepper()
 : problem( 0 ),
   linearSystemSolver( 0 ),
-  timeStep( 0 )
+  timeStep( 0 ),
+  allIterations( 0 )
 {
 };
 
@@ -73,8 +76,14 @@ init( const MeshType& mesh )
    }
    if( ! this->rightHandSide.setSize( this->matrix.getRows() ) )
       return false;
+
+   this->preIterateTimer.reset();
    this->linearSystemAssemblerTimer.reset();
+   this->preconditionerUpdateTimer.reset();
    this->linearSystemSolverTimer.reset();
+   this->postIterateTimer.reset();
+
+   this->allIterations = 0;
    return true;
 }
 
@@ -84,7 +93,7 @@ void
 tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >::
 setProblem( ProblemType& problem )
 {
-   this -> problem = &problem;
+   this->problem = &problem;
 };
 
 template< typename Problem,
@@ -93,7 +102,7 @@ Problem*
 tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >::
 getProblem() const
 {
-    return this -> problem;
+    return this->problem;
 };
 
 template< typename Problem,
@@ -177,8 +186,9 @@ solve( const RealType& time,
       if( verbose )
          cout << "                                                                  Solving the linear system for time " << t + currentTau << "             \r" << flush;
 
-      // TODO: add timer
+      this->preconditionerUpdateTimer.start();
       preconditioner.update( this->matrix );
+      this->preconditionerUpdateTimer.stop();
 
       this->linearSystemSolverTimer.start();
       if( ! this->linearSystemSolver->template solve< DofVectorType, tnlLinearResidueGetter< MatrixType, DofVectorType > >( this->rightHandSide, dofVector ) )
@@ -187,6 +197,7 @@ solve( const RealType& time,
          return false;
       }
       this->linearSystemSolverTimer.stop();
+      this->allIterations += this->linearSystemSolver->getIterations();
 
       //if( verbose )
       //   cout << endl;
@@ -214,10 +225,17 @@ 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() );
+   logger.writeParameter< long long int >( "Iterations count:", this->allIterations );
+   logger.writeParameter< const char* >( "Pre-iterate time:", "" );
+   this->preIterateTimer.writeLog( logger, 1 );
+   logger.writeParameter< const char* >( "Linear system assembler time:", "" );
+   this->linearSystemAssemblerTimer.writeLog( logger, 1 );
+   logger.writeParameter< const char* >( "Preconditioner update time:", "" );
+   this->preconditionerUpdateTimer.writeLog( logger, 1 );
+   logger.writeParameter< const char* >( "Linear system solver time:", "" );
+   this->linearSystemSolverTimer.writeLog( logger, 1 );
+   logger.writeParameter< const char* >( "Post-iterate time:", "" );
+   this->postIterateTimer.writeLog( logger, 1 );
    return true;
 }
 
diff --git a/src/solvers/tnlBuildConfigTags.h b/src/solvers/tnlBuildConfigTags.h
index ced6a47fc7913918dd89cb9fa0cbe27345a5406d..4ee030b658a6b43a71bf8e7bd17e3b6562aa1218 100644
--- a/src/solvers/tnlBuildConfigTags.h
+++ b/src/solvers/tnlBuildConfigTags.h
@@ -57,10 +57,7 @@ template< typename ConfigTag > struct tnlConfigTagMeshResolve{ enum { enabled =
 /****
  * 1, 2, and 3 dimensions are enabled by default
  */
-template< typename ConfigTag, int Dimensions > struct tnlConfigTagDimensions{ enum { enabled = false }; };
-   template< typename ConfigTag > struct tnlConfigTagDimensions< ConfigTag, 1 >{ enum { enabled = true }; };
-   template< typename ConfigTag > struct tnlConfigTagDimensions< ConfigTag, 2 >{ enum { enabled = true }; };
-   template< typename ConfigTag > struct tnlConfigTagDimensions< ConfigTag, 3 >{ enum { enabled = true }; };
+template< typename ConfigTag, int Dimensions > struct tnlConfigTagDimensions{ enum { enabled = ( Dimensions > 0 && Dimensions <= 3 ) }; };
 
 /****
  * Up to the exceptions enlisted below, all mesh types are disabled by default.
diff --git a/src/solvers/tnlIterativeSolver.h b/src/solvers/tnlIterativeSolver.h
index 8c05287d8d31cbbfffcfd186d550484da9618466..6b3c017920612416a69c69c791ec425cadb98bbe 100644
--- a/src/solvers/tnlIterativeSolver.h
+++ b/src/solvers/tnlIterativeSolver.h
@@ -65,6 +65,8 @@ class tnlIterativeSolver
 
    bool nextIteration();
 
+   bool checkNextIteration();
+
    bool checkConvergence();
 
    void refreshSolverMonitor( bool force = false );
diff --git a/src/solvers/tnlIterativeSolverMonitor_impl.h b/src/solvers/tnlIterativeSolverMonitor_impl.h
index 7f65f9e596b3cbdc1d8101c3f35c33f6d011c5e7..998706a7e86fefb0d384beb074b7e92322f797c7 100644
--- a/src/solvers/tnlIterativeSolverMonitor_impl.h
+++ b/src/solvers/tnlIterativeSolverMonitor_impl.h
@@ -35,37 +35,37 @@ tnlIterativeSolverMonitor< Real, Index > :: tnlIterativeSolverMonitor()
 template< typename Real, typename Index>
 void tnlIterativeSolverMonitor< Real, Index > :: setIterations( const Index& iterations )
 {
-   this -> iterations = iterations;
+   this->iterations = iterations;
 }
 
 template< typename Real, typename Index>
 const Index& tnlIterativeSolverMonitor< Real, Index > :: getIterations() const
 {
-   return this -> iterations;
+   return this->iterations;
 }
 
 template< typename Real, typename Index>
 void tnlIterativeSolverMonitor< Real, Index > :: setResidue( const Real& residue )
 {
-   this -> residue = residue;
+   this->residue = residue;
 }
 
 template< typename Real, typename Index>
 const Real& tnlIterativeSolverMonitor< Real, Index > :: getResidue() const
 {
-   return this -> residue;
+   return this->residue;
 }
 
 template< typename Real, typename Index>
 void tnlIterativeSolverMonitor< Real, Index > :: setVerbose( const Index& verbose )
 {
-   this -> verbose = verbose;
+   this->verbose = verbose;
 }
 
 template< typename Real, typename Index>
 void tnlIterativeSolverMonitor< Real, Index > :: setRefreshRate( const Index& refreshRate )
 {
-   this -> refreshRate = refreshRate;
+   this->refreshRate = refreshRate;
 }
 
 template< typename Real, typename Index>
@@ -74,9 +74,9 @@ void tnlIterativeSolverMonitor< Real, Index > :: refresh( bool force )
    if( this->verbose > 0 && ( force || this->getIterations() % this->refreshRate == 0 ) )
    {
       cout << " ITER:" << setw( 8 ) << this->getIterations()
-           << " RES:" << setprecision( 5 ) << setw( 12 ) << this -> getResidue()
-           << " CPU: " << setw( 8 ) << this -> getCPUTime()
-           << " ELA: " << setw( 8 ) << this -> getRealTime()
+           << " RES:" << setprecision( 5 ) << setw( 12 ) << this->getResidue()
+           << " CPU: " << setw( 8 ) << this->getCPUTime()
+           << " ELA: " << setw( 8 ) << this->getRealTime()
            << "   \r" << flush;
    }
    this->refreshing ++;
diff --git a/src/solvers/tnlIterativeSolver_impl.h b/src/solvers/tnlIterativeSolver_impl.h
index dc86d6179280a4fe66e0a83aee48b4562df89d4a..2a6f3a0ba34c7a5cfc842200e98f435775a393d7 100644
--- a/src/solvers/tnlIterativeSolver_impl.h
+++ b/src/solvers/tnlIterativeSolver_impl.h
@@ -38,7 +38,7 @@ template< typename Real, typename Index >
 void tnlIterativeSolver< Real, Index> :: configSetup( tnlConfigDescription& config,
                                                       const tnlString& prefix )
 {
-   config.addEntry< int >   ( prefix + "max-iterations", "Maximal number of iterations the solver may perform.", 100000 );
+   config.addEntry< int >   ( prefix + "max-iterations", "Maximal number of iterations the solver may perform.", 100000000000 );
    config.addEntry< int >   ( prefix + "min-iterations", "Minimal number of iterations the solver must perform.", 0 );
    config.addEntry< double >( prefix + "convergence-residue", "Convergence occurs when the residue drops bellow this limit.", 1.0e-6 );
    config.addEntry< double >( prefix + "divergence-residue", "Divergence occurs when the residue exceeds given limit.", DBL_MAX );
@@ -60,39 +60,47 @@ bool tnlIterativeSolver< Real, Index> :: setup( const tnlParameterContainer& par
 template< typename Real, typename Index >
 void tnlIterativeSolver< Real, Index> :: setMaxIterations( const Index& maxIterations )
 {
-   this -> maxIterations = maxIterations;
+   this->maxIterations = maxIterations;
 }
 
 template< typename Real, typename Index >
 const Index& tnlIterativeSolver< Real, Index> :: getMaxIterations() const
 {
-   return this -> maxIterations;
+   return this->maxIterations;
 }
 
 template< typename Real, typename Index >
 void tnlIterativeSolver< Real, Index> :: setMinIterations( const Index& minIterations )
 {
-   this -> minIterations = minIterations;
+   this->minIterations = minIterations;
 }
 
 template< typename Real, typename Index >
 const Index& tnlIterativeSolver< Real, Index> :: getMinIterations() const
 {
-   return this -> minIterations;
+   return this->minIterations;
 }
 
 template< typename Real, typename Index >
 void tnlIterativeSolver< Real, Index> :: resetIterations()
 {
-   this -> currentIteration = 0;
+   this->currentIteration = 0;
 }
 
 template< typename Real, typename Index >
 bool tnlIterativeSolver< Real, Index> :: nextIteration()
+{
+   // this->checkNextIteration() must be called before the iteration counter is incremented
+   bool result = this->checkNextIteration();
+   this->currentIteration++;
+   return result;
+}
+
+template< typename Real, typename Index >
+bool tnlIterativeSolver< Real, Index> :: checkNextIteration()
 {
    // TODO: fix
    //tnlAssert( solverMonitor, );
-   this->currentIteration++;
    if( this->solverMonitor )
    {
       solverMonitor->setIterations( this->currentIteration );
@@ -103,9 +111,26 @@ bool tnlIterativeSolver< Real, Index> :: nextIteration()
 
    if( std::isnan( this->getResidue() ) || 
        this->getIterations() > this->getMaxIterations()  ||
-       ( this->getResidue() > this->getDivergenceResidue() && this->getIterations() > this->getMinIterations() ) ||
-       ( this->getResidue() < this->getConvergenceResidue() && this->getIterations() > this->minIterations ) ) 
+       ( this->getResidue() > this->getDivergenceResidue() && this->getIterations() >= this->getMinIterations() ) ||
+       ( this->getResidue() < this->getConvergenceResidue() && this->getIterations() >= this->getMinIterations() ) )
       return false;
+   
+   if( this->getResidue() > this->getDivergenceResidue() &&
+         this->getIterations() > this->minIterations )
+   {
+      cerr << endl  << "The residue has exceeded allowed tolerance " << this->getDivergenceResidue() << "." << endl;
+      return false;
+   }
+   if( this->getIterations() >= this->getMaxIterations() )
+   {
+      cerr << endl  << "The solver has exceeded maximal allowed number of iterations " << this->getMaxIterations() << "." << endl;
+      return false;
+   }
+   if( this->getResidue() > this->getConvergenceResidue() )
+   {
+      cerr << endl  << "The residue ( = " << this->getResidue() << " ) is too large( > " << this->getConvergenceResidue() << " )." << endl;
+      return false;
+   }
    return true;
 }
 
@@ -143,7 +168,7 @@ const Index&
 tnlIterativeSolver< Real, Index>::
 getIterations() const
 {
-   return this -> currentIteration;
+   return this->currentIteration;
 }
 
 template< typename Real, typename Index >
@@ -174,36 +199,36 @@ const Real& tnlIterativeSolver< Real, Index> :: getDivergenceResidue() const
 template< typename Real, typename Index >
 void tnlIterativeSolver< Real, Index> :: setResidue( const Real& residue )
 {
-   this -> currentResidue = residue;
+   this->currentResidue = residue;
 }
 
 template< typename Real, typename Index >
 const Real& tnlIterativeSolver< Real, Index> :: getResidue() const
 {
-   return this -> currentResidue;
+   return this->currentResidue;
 }
 
 template< typename Real, typename Index >
 void tnlIterativeSolver< Real, Index> :: setRefreshRate( const Index& refreshRate )
 {
-   this -> refreshRate = refreshRate;
+   this->refreshRate = refreshRate;
 }
 
 template< typename Real, typename Index >
 void tnlIterativeSolver< Real, Index> :: setSolverMonitor( tnlIterativeSolverMonitor< Real, Index >& solverMonitor )
 {
-   this -> solverMonitor = &solverMonitor;
+   this->solverMonitor = &solverMonitor;
 }
 
 template< typename Real, typename Index >
 void tnlIterativeSolver< Real, Index> :: refreshSolverMonitor( bool force )
 {
-   if( this -> solverMonitor )
+   if( this->solverMonitor )
    {
-      this -> solverMonitor -> setIterations( this -> getIterations() );
-      this -> solverMonitor -> setResidue( this -> getResidue() );
-      this -> solverMonitor -> setRefreshRate( this-> refreshRate );
-      this -> solverMonitor -> refresh( force );
+      this->solverMonitor -> setIterations( this->getIterations() );
+      this->solverMonitor -> setResidue( this->getResidue() );
+      this->solverMonitor -> setRefreshRate( this-> refreshRate );
+      this->solverMonitor -> refresh( force );
    }
 }
 
diff --git a/src/solvers/tnlSolverConfig_impl.h b/src/solvers/tnlSolverConfig_impl.h
index 01d005335aac5b531af61f05bb0768317688d382..c19010667529791c900a6009afe6af7f86bcec82 100644
--- a/src/solvers/tnlSolverConfig_impl.h
+++ b/src/solvers/tnlSolverConfig_impl.h
@@ -118,6 +118,19 @@ bool tnlSolverConfig< ConfigTag, ProblemConfig >::configSetup( tnlConfigDescript
          config.addEntryEnum( "tfqmr" );
       if( tnlConfigTagSemiImplicitSolver< ConfigTag, tnlSemiImplicitSORSolverTag >::enabled )
          config.addEntryEnum( "sor" );
+#ifdef HAVE_UMFPACK
+      if( tnlMeshConfigSemiImplicitSolver< MeshConfig, tnlSemiImplicitUmfpackSolverTag >::enabled )
+         config.addEntryEnum( "umfpack" );
+#endif
+   }
+   config.addEntry< tnlString >( "preconditioner", "The preconditioner for the discrete solver:", "none" );
+   config.addEntryEnum( "none" );
+   config.addEntryEnum( "diagonal" );
+   if( tnlConfigTagTimeDiscretisation< ConfigTag, tnlExplicitTimeDiscretisationTag >::enabled ||
+       tnlConfigTagTimeDiscretisation< ConfigTag, tnlSemiImplicitTimeDiscretisationTag >::enabled )
+   {
+      config.addDelimiter( " === Iterative solvers parameters === " );
+      tnlIterativeSolver< double, int >::configSetup( config );
    }
    config.addEntry< tnlString >( "preconditioner", "The preconditioner for the discrete solver:", "none" );
    config.addEntryEnum( "none" );
@@ -156,7 +169,7 @@ bool tnlSolverConfig< ConfigTag, ProblemConfig >::configSetup( tnlConfigDescript
 
    config.addDelimiter( " === Logs and messages ===" );
    config.addEntry< int >( "verbose", "Set the verbose mode. The higher number the more messages are generated.", 1 );
-   config.addEntry< tnlString >( "log-file", "Log file for the computation." );
+   config.addEntry< tnlString >( "log-file", "Log file for the computation.", "log.txt" );
    config.addEntry< int >( "log-width", "Number of columns of the log table.", 80 );
    return true;
 
diff --git a/src/solvers/tnlSolverStarter.h b/src/solvers/tnlSolverStarter.h
index 7b9bc2d8f3757487ac9f479ac274ab18ddef4ddd..87c67ac8d72ea3c6fd7575b4c0e63375558001be 100644
--- a/src/solvers/tnlSolverStarter.h
+++ b/src/solvers/tnlSolverStarter.h
@@ -19,8 +19,7 @@
 #define TNLSOLVERSTARTER_H_
 
 #include <config/tnlParameterContainer.h>
-#include <core/tnlTimerRT.h>
-#include <core/tnlTimerCPU.h>
+#include <core/tnlTimer.h>
 #include <ostream>
 
 template< typename MeshConfig >
@@ -45,9 +44,7 @@ class tnlSolverStarter
 
    int logWidth;
 
-   tnlTimerRT ioRtTimer, computeRtTimer, totalRtTimer;
-
-   tnlTimerCPU ioCpuTimer, computeCpuTimer, totalCpuTimer;
+   tnlTimer ioTimer, computeTimer, totalTimer;
 };
 
 #include <solvers/tnlSolverStarter_impl.h>
diff --git a/src/solvers/tnlSolverStarter_impl.h b/src/solvers/tnlSolverStarter_impl.h
index e9bce4d8cc08a540ded118b9c48800dc3b3aef12..64ac34cd6af4142e07e6faf8d41486ab65a3b4c7 100644
--- a/src/solvers/tnlSolverStarter_impl.h
+++ b/src/solvers/tnlSolverStarter_impl.h
@@ -21,6 +21,7 @@
 #include <tnlConfig.h>
 #include <core/tnlLogger.h>
 #include <core/tnlString.h>
+#include <core/tnlCuda.h>
 #include <solvers/ode/tnlMersonSolver.h>
 #include <solvers/ode/tnlEulerSolver.h>
 #include <solvers/linear/stationary/tnlSORSolver.h>
@@ -28,6 +29,7 @@
 #include <solvers/linear/krylov/tnlBICGStabSolver.h>
 #include <solvers/linear/krylov/tnlGMRESSolver.h>
 #include <solvers/linear/krylov/tnlTFQMRSolver.h>
+#include <solvers/linear/tnlUmfpackWrapper.h>
 #include <solvers/preconditioners/tnlDummyPreconditioner.h>
 #include <solvers/preconditioners/tnlDiagonalPreconditioner.h>
 #include <solvers/pde/tnlExplicitTimeStepper.h>
@@ -90,6 +92,9 @@ bool tnlSolverStarter< ConfigTag > :: run( const tnlParameterContainer& paramete
    /****
     * Create and set-up the problem
     */
+   if( ! tnlHost::setup( parameters ) ||
+       ! tnlCuda::setup( parameters ) )
+      return false;
    Problem problem;
    if( ! problem.setup( parameters ) )
    {
@@ -193,6 +198,7 @@ class tnlSolverStarterTimeDiscretisationSetter< Problem, tnlSemiImplicitTimeDisc
                        const tnlParameterContainer& parameters )
       {
          const tnlString& discreteSolver = parameters. getParameter< tnlString>( "discrete-solver" );
+#ifndef HAVE_UMFPACK
          if( discreteSolver != "sor" &&
              discreteSolver != "cg" &&
              discreteSolver != "bicgstab" &&
@@ -202,6 +208,18 @@ class tnlSolverStarterTimeDiscretisationSetter< Problem, tnlSemiImplicitTimeDisc
             cerr << "Unknown semi-implicit discrete solver " << discreteSolver << ". It can be only: sor, cg, bicgstab, gmres or tfqmr." << endl;
             return false;
          }
+#else
+         if( discreteSolver != "sor" &&
+             discreteSolver != "cg" &&
+             discreteSolver != "bicgstab" &&
+             discreteSolver != "gmres" &&
+             discreteSolver != "tfqmr" &&
+             discreteSolver != "umfpack" )
+         {
+            cerr << "Unknown semi-implicit discrete solver " << discreteSolver << ". It can be only: sor, cg, bicgstab, gmres, tfqmr or umfpack." << endl;
+            return false;
+         }
+#endif
 
          if( discreteSolver == "sor" )
             return tnlSolverStarterPreconditionerSetter< Problem, tnlSemiImplicitSORSolverTag, ConfigTag >::run( problem, parameters );
@@ -213,6 +231,10 @@ class tnlSolverStarterTimeDiscretisationSetter< Problem, tnlSemiImplicitTimeDisc
             return tnlSolverStarterPreconditionerSetter< Problem, tnlSemiImplicitGMRESSolverTag, ConfigTag >::run( problem, parameters );
          if( discreteSolver == "tfqmr" )
             return tnlSolverStarterPreconditionerSetter< Problem, tnlSemiImplicitTFQMRSolverTag, ConfigTag >::run( problem, parameters );
+#ifdef HAVE_UMFPACK
+         if( discreteSolver == "umfpack" )
+            return tnlSolverStarterPreconditionerSetter< Problem, tnlSemiImplicitUmfpackSolverTag, ConfigTag >::run( problem, parameters );
+#endif
          return false;
       }
 };
@@ -347,11 +369,14 @@ class tnlSolverStarterExplicitTimeStepperSetter
          typedef typename Problem::IndexType IndexType;
          typedef tnlODESolverMonitor< RealType, IndexType > SolverMonitorType;
 
+         const int verbose = parameters.getParameter< int >( "verbose" );
+
          ExplicitSolver explicitSolver;
          explicitSolver.setup( parameters );
-         int verbose = parameters.getParameter< int >( "verbose" );
          explicitSolver.setVerbose( verbose );
+
          SolverMonitorType odeSolverMonitor;
+         odeSolverMonitor.setVerbose( verbose );
          if( ! problem.getSolverMonitor() )
             explicitSolver.setSolverMonitor( odeSolverMonitor );
          else
@@ -390,10 +415,13 @@ class tnlSolverStarterSemiImplicitTimeStepperSetter
          typedef typename Problem::IndexType IndexType;
          typedef tnlIterativeSolverMonitor< RealType, IndexType > SolverMonitorType;
 
+         const int verbose = parameters.getParameter< int >( "verbose" );
+
          LinearSystemSolverType linearSystemSolver;
          linearSystemSolver.setup( parameters );
 
          SolverMonitorType solverMonitor;
+         solverMonitor.setVerbose( verbose );
          if( ! problem.getSolverMonitor() )
             linearSystemSolver.setSolverMonitor( solverMonitor );
          else
@@ -441,7 +469,7 @@ bool tnlSolverStarter< ConfigTag > :: setDiscreteSolver( Problem& problem,
       DiscreteSolver solver;
       double omega = parameters. getParameter< double >( "sor-omega" );
       solver. setOmega( omega );
-      //solver. setVerbose( this -> verbose );
+      //solver. setVerbose( this->verbose );
       return setSemiImplicitTimeDiscretisation< Problem >( problem, parameters, solver );
    }
 
@@ -450,7 +478,7 @@ bool tnlSolverStarter< ConfigTag > :: setDiscreteSolver( Problem& problem,
       typedef tnlCGSolver< typename Problem :: DiscreteSolverMatrixType,
                            typename Problem :: DiscreteSolverPreconditioner > DiscreteSolver;
       DiscreteSolver solver;
-      //solver. setVerbose( this -> verbose );
+      //solver. setVerbose( this->verbose );
       return setSemiImplicitTimeDiscretisation< Problem >( problem, parameters, solver );
    }
 
@@ -459,7 +487,7 @@ bool tnlSolverStarter< ConfigTag > :: setDiscreteSolver( Problem& problem,
       typedef tnlBICGStabSolver< typename Problem :: DiscreteSolverMatrixType,
                                  typename Problem :: DiscreteSolverPreconditioner > DiscreteSolver;
       DiscreteSolver solver;
-      //solver. setVerbose( this -> verbose );
+      //solver. setVerbose( this->verbose );
       return setSemiImplicitTimeDiscretisation< Problem >( problem, parameters, solver );
    }
 
@@ -470,7 +498,7 @@ bool tnlSolverStarter< ConfigTag > :: setDiscreteSolver( Problem& problem,
       DiscreteSolver solver;
       int restarting = parameters. getParameter< int >( "gmres-restarting" );
       solver. setRestarting( restarting );
-      //solver. setVerbose( this -> verbose );
+      //solver. setVerbose( this->verbose );
       return setSemiImplicitTimeDiscretisation< Problem >( problem, parameters, solver );
    }
    cerr << "Unknown discrete solver " << discreteSolver << "." << endl;
@@ -485,8 +513,9 @@ bool tnlSolverStarter< ConfigTag > :: runPDESolver( Problem& problem,
                                                     const tnlParameterContainer& parameters,
                                                     TimeStepper& timeStepper )
 {
-   this->totalCpuTimer.reset();
-   this->totalRtTimer.reset();
+   this->totalTimer.reset();
+   this->totalTimer.start();
+   
 
    /****
     * Set-up the PDE solver
@@ -529,16 +558,10 @@ bool tnlSolverStarter< ConfigTag > :: runPDESolver( Problem& problem,
    /****
     * Set-up timers
     */
-   this->computeRtTimer.reset();
-   this->computeCpuTimer.reset();
-   this->ioRtTimer.reset();
-   this->ioRtTimer.stop();
-   this->ioCpuTimer.reset();
-   this->ioCpuTimer.stop();
-   solver.setComputeRtTimer( this->computeRtTimer );
-   solver.setComputeCpuTimer( this->computeCpuTimer );
-   solver.setIoRtTimer( this->ioRtTimer );
-   solver.setIoCpuTimer( this->ioCpuTimer );
+   this->computeTimer.reset();
+   this->ioTimer.reset();
+   solver.setComputeTimer( this->computeTimer );
+   solver.setIoTimer( this->ioTimer );
 
    /****
     * Start the solver
@@ -566,10 +589,8 @@ bool tnlSolverStarter< ConfigTag > :: runPDESolver( Problem& problem,
    /****
     * Stop timers
     */
-   this->computeRtTimer.stop();
-   this->computeCpuTimer.stop();
-   this->totalCpuTimer.stop();
-   this->totalRtTimer.stop();
+   this->computeTimer.stop();   
+   this->totalTimer.stop();
 
    /****
     * Write an epilog
@@ -599,17 +620,18 @@ template< typename ConfigTag >
 bool tnlSolverStarter< ConfigTag > :: writeEpilog( ostream& str, const Solver& solver  )
 {
    tnlLogger logger( logWidth, str );
+   logger.writeSeparator();
    logger.writeCurrentTime( "Finished at:" );
    if( ! solver.writeEpilog( logger ) )
-      return false;
-   logger.writeParameter< double >( "IO Real Time:", this -> ioRtTimer. getTime() );
-   logger.writeParameter< double >( "IO CPU Time:", this -> ioCpuTimer. getTime() );
-   logger.writeParameter< double >( "Compute Real Time:", this -> computeRtTimer. getTime() );
-   logger.writeParameter< double >( "Compute CPU Time:", this -> computeCpuTimer. getTime() );
-   logger.writeParameter< double >( "Total Real Time:", this -> totalRtTimer. getTime() );
-   logger.writeParameter< double >( "Total CPU Time:", this -> totalCpuTimer. getTime() );
+      return false;   
+   logger.writeParameter< const char* >( "Compute time:", "" );
+   this->computeTimer.writeLog( logger, 1 );   
+   logger.writeParameter< const char* >( "I/O time:", "" );
+   this->ioTimer.writeLog( logger, 1 );
+   logger.writeParameter< const char* >( "Total time:", "" );
+   this->totalTimer.writeLog( logger, 1 );   
    char buf[ 256 ];
-   sprintf( buf, "%f %%", 100 * ( ( double ) this -> totalCpuTimer. getTime() ) / this -> totalRtTimer. getTime() );
+   sprintf( buf, "%f %%", 100 * ( ( double ) this->totalTimer.getCPUTime() ) / this->totalTimer.getRealTime() );
    logger.writeParameter< char* >( "CPU usage:", buf );
    logger.writeSeparator();
    return true;
diff --git a/src/solvers/tnlSolver_impl.h b/src/solvers/tnlSolver_impl.h
index 33d9b2fe8b794321db5ec0089f459959ed0bfd1e..58c1bce84ffbe1d8b7dc9dec946741c0221453af 100644
--- a/src/solvers/tnlSolver_impl.h
+++ b/src/solvers/tnlSolver_impl.h
@@ -21,6 +21,7 @@
 #include <solvers/tnlSolverInitiator.h>
 #include <solvers/tnlSolverStarter.h>
 #include <solvers/tnlSolverConfig.h>
+#include <core/tnlCuda.h>
 
 template< template< typename Real, typename Device, typename Index, typename MeshType, typename MeshConfig, typename SolverStarter > class ProblemSetter,
           template< typename MeshConfig > class ProblemConfig,
@@ -33,6 +34,10 @@ run( int argc, char* argv[] )
    tnlConfigDescription configDescription;
    ProblemConfig< MeshConfig >::configSetup( configDescription );
    tnlSolverConfig< MeshConfig, ProblemConfig< MeshConfig> >::configSetup( configDescription );
+   configDescription.addDelimiter( "Parallelization setup:" );
+   tnlHost::configSetup( configDescription );
+   tnlCuda::configSetup( configDescription );
+
    if( ! parseCommandLine( argc, argv, configDescription, parameters ) )
       return false;
 
diff --git a/tests/benchmarks/CMakeLists.txt b/tests/benchmarks/CMakeLists.txt
index 8a3c35a8ae7d0dbfb61b091d13586e82e8dc9dfb..a44d068a33c2d2a1503f0580d7ac63627c973e1a 100755
--- a/tests/benchmarks/CMakeLists.txt
+++ b/tests/benchmarks/CMakeLists.txt
@@ -1,37 +1,30 @@
 ADD_SUBDIRECTORY( share )
+ADD_SUBDIRECTORY( heat-equation-benchmark )
 
 IF( BUILD_CUDA )
-    CUDA_ADD_EXECUTABLE( tnl-cuda-benchmarks${debugExt} tnl-cuda-benchmarks.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
-    SET_TARGET_PROPERTIES( tnl-cuda-benchmarks${debugExt} PROPERTIES CUDA_COMPILE_FLAGS "${CXX_OPTIMIZE_FLAGS}" )
+    CUDA_ADD_EXECUTABLE( tnl-cuda-benchmarks${debugExt} tnl-cuda-benchmarks.cu )
+    if( HAVE_CUBLAS STREQUAL "yes" )
+        CUDA_ADD_CUBLAS_TO_TARGET( tnl-cuda-benchmarks${debugExt} )
+    endif()
     TARGET_LINK_LIBRARIES( tnl-cuda-benchmarks${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} )                        
     
-    CUDA_ADD_EXECUTABLE( tnl-benchmark-spmv${debugExt} tnl-benchmark-spmv.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
-    SET_TARGET_PROPERTIES( tnl-benchmark-spmv${debugExt} PROPERTIES CUDA_COMPILE_FLAGS "${CXX_OPTIMIZE_FLAGS}" )
+    CUDA_ADD_EXECUTABLE( tnl-benchmark-spmv${debugExt} tnl-benchmark-spmv.cu )
     TARGET_LINK_LIBRARIES( tnl-benchmark-spmv${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} )                        
     
-    CUDA_ADD_EXECUTABLE( tnl-benchmark-linear-solvers${debugExt} tnl-benchmark-linear-solvers.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
-    SET_TARGET_PROPERTIES( tnl-benchmark-linear-solvers${debugExt} PROPERTIES CUDA_COMPILE_FLAGS "${CXX_OPTIMIZE_FLAGS}" )
+    CUDA_ADD_EXECUTABLE( tnl-benchmark-linear-solvers${debugExt} tnl-benchmark-linear-solvers.cu )
     TARGET_LINK_LIBRARIES( tnl-benchmark-linear-solvers${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} )                        
 
-    CUDA_ADD_EXECUTABLE( tnl-benchmark-simple-heat-equation${debugExt} tnl-benchmark-simple-heat-equation.cu 
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
-    SET_TARGET_PROPERTIES( tnl-benchmark-simple-heat-equation${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_OPTIMIZE_FLAGS}" )    
+    CUDA_ADD_EXECUTABLE( tnl-benchmark-simple-heat-equation${debugExt} tnl-benchmark-simple-heat-equation.cu )
     TARGET_LINK_LIBRARIES( tnl-benchmark-simple-heat-equation${debugExt} tnl${debugExt}-${tnlVersion} )
 
 ELSE()
     ADD_EXECUTABLE( tnl-benchmark-spmv${debugExt} tnl-benchmark-spmv.cpp )
-    SET_TARGET_PROPERTIES( tnl-benchmark-spmv${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_OPTIMIZE_FLAGS}" )
     TARGET_LINK_LIBRARIES( tnl-benchmark-spmv${debugExt} tnl${debugExt}-${tnlVersion} )
 
     ADD_EXECUTABLE( tnl-benchmark-linear-solvers${debugExt} tnl-benchmark-linear-solvers.cpp )    
-    SET_TARGET_PROPERTIES( tnl-benchmark-linear-solvers${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_OPTIMIZE_FLAGS}" )    
     TARGET_LINK_LIBRARIES( tnl-benchmark-linear-solvers${debugExt} tnl${debugExt}-${tnlVersion} )
 
     ADD_EXECUTABLE( tnl-benchmark-simple-heat-equation${debugExt} tnl-benchmark-simple-heat-equation.cpp )    
-    SET_TARGET_PROPERTIES( tnl-benchmark-simple-heat-equation${debugExt} PROPERTIES COMPILE_FLAGS "${CXX_OPTIMIZE_FLAGS}" )    
     TARGET_LINK_LIBRARIES( tnl-benchmark-simple-heat-equation${debugExt} tnl${debugExt}-${tnlVersion} )
 ENDIF()
 
@@ -48,4 +41,4 @@ INSTALL( TARGETS tnl-benchmark-spmv${debugExt}
          RUNTIME DESTINATION bin )
 
 
-                                            
\ No newline at end of file
+                                            
diff --git a/tests/benchmarks/array-operations.h b/tests/benchmarks/array-operations.h
new file mode 100644
index 0000000000000000000000000000000000000000..11f5bd9ff4c56a63dd1b13d3cbe962137f13096b
--- /dev/null
+++ b/tests/benchmarks/array-operations.h
@@ -0,0 +1,142 @@
+#pragma once
+
+#include "benchmarks.h"
+
+#include <core/arrays/tnlArray.h>
+
+namespace tnl
+{
+namespace benchmarks
+{
+
+template< typename Real = double,
+          typename Index = int >
+bool
+benchmarkArrayOperations( Benchmark & benchmark,
+                          const int & loops,
+                          const int & size )
+{
+    typedef tnlArray< Real, tnlHost, Index > HostArray;
+    typedef tnlArray< Real, tnlCuda, Index > CudaArray;
+    using namespace std;
+
+    double datasetSize = ( double ) ( loops * size ) * sizeof( Real ) / oneGB;
+
+    HostArray hostArray, hostArray2;
+    CudaArray deviceArray, deviceArray2;
+    if( ! hostArray.setSize( size ) ||
+        ! hostArray2.setSize( size ) ||
+        ! deviceArray.setSize( size ) ||
+        ! deviceArray2.setSize( size ) )
+    {
+        const char* msg = "error: allocation of arrays failed";
+        cerr << msg << endl;
+        benchmark.addErrorMessage( msg );
+        return false;
+    }
+
+    Real resultHost, resultDevice;
+
+
+    // reset functions
+    auto reset1 = [&]() {
+        hostArray.setValue( 1.0 );
+        deviceArray.setValue( 1.0 );
+    };
+    auto reset2 = [&]() {
+        hostArray2.setValue( 1.0 );
+        deviceArray2.setValue( 1.0 );
+    };
+    auto reset12 = [&]() {
+        reset1();
+        reset2();
+    };
+
+
+    reset12();
+
+
+    auto compareHost = [&]() {
+        resultHost = (int) hostArray == hostArray2;
+    };
+    auto compareCuda = [&]() {
+        resultDevice = (int) deviceArray == deviceArray2;
+    };
+    benchmark.setOperation( "comparison (operator==)", 2 * datasetSize );
+    benchmark.time( reset1,
+                    "CPU", compareHost,
+                    "GPU", compareCuda );
+
+
+    auto copyAssignHostHost = [&]() {
+        hostArray = hostArray2;
+    };
+    auto copyAssignCudaCuda = [&]() {
+        deviceArray = deviceArray2;
+    };
+    benchmark.setOperation( "copy (operator=)", 2 * datasetSize );
+    double basetime = benchmark.time( reset1,
+                    "CPU", copyAssignHostHost,
+                    "GPU", copyAssignCudaCuda );
+
+
+    auto copyAssignHostCuda = [&]() {
+        deviceArray = hostArray;
+    };
+    auto copyAssignCudaHost = [&]() {
+        hostArray = deviceArray;
+    };
+    benchmark.setOperation( "copy (operator=)", datasetSize, basetime );
+    benchmark.time( reset1,
+                    "CPU->GPU", copyAssignHostCuda,
+                    "GPU->CPU", copyAssignCudaHost );
+
+
+    auto setValueHost = [&]() {
+        hostArray.setValue( 3.0 );
+    };
+    auto setValueCuda = [&]() {
+        deviceArray.setValue( 3.0 );
+    };
+    benchmark.setOperation( "setValue", datasetSize );
+    benchmark.time( reset1,
+                    "CPU", setValueHost,
+                    "GPU", setValueCuda );
+
+
+    auto setSizeHost = [&]() {
+        hostArray.setSize( size );
+    };
+    auto setSizeCuda = [&]() {
+        deviceArray.setSize( size );
+    };
+    auto resetSize1 = [&]() {
+        hostArray.reset();
+        deviceArray.reset();
+    };
+    benchmark.setOperation( "allocation (setSize)", datasetSize );
+    benchmark.time( resetSize1,
+                    "CPU", setSizeHost,
+                    "GPU", setSizeCuda );
+
+
+    auto resetSizeHost = [&]() {
+        hostArray.reset();
+    };
+    auto resetSizeCuda = [&]() {
+        deviceArray.reset();
+    };
+    auto setSize1 = [&]() {
+        hostArray.setSize( size );
+        deviceArray.setSize( size );
+    };
+    benchmark.setOperation( "deallocation (reset)", datasetSize );
+    benchmark.time( setSize1,
+                    "CPU", resetSizeHost,
+                    "GPU", resetSizeCuda );
+
+    return true;
+}
+
+} // namespace benchmarks
+} // namespace tnl
diff --git a/tests/benchmarks/benchmarks.h b/tests/benchmarks/benchmarks.h
new file mode 100644
index 0000000000000000000000000000000000000000..97fa5a4f1c44e09d5f1bbbdc1265aeddf11ebf7a
--- /dev/null
+++ b/tests/benchmarks/benchmarks.h
@@ -0,0 +1,425 @@
+#pragma once
+
+#include <iostream>
+#include <iomanip>
+#include <map>
+#include <vector>
+
+#include <core/tnlTimerRT.h>
+#include <core/tnlString.h>
+
+namespace tnl
+{
+namespace benchmarks
+{
+
+const double oneGB = 1024.0 * 1024.0 * 1024.0;
+
+template< typename ComputeFunction,
+          typename ResetFunction >
+double
+timeFunction( ComputeFunction compute,
+              ResetFunction reset,
+              const int & loops )
+{
+    // the timer is constructed zero-initialized and stopped
+    tnlTimerRT timer;
+
+    reset();
+    for(int i = 0; i < loops; ++i) {
+        // Explicit synchronization of the CUDA device
+        // TODO: not necessary for host computations
+#ifdef HAVE_CUDA
+        cudaDeviceSynchronize();
+#endif
+        timer.start();
+        compute();
+#ifdef HAVE_CUDA
+        cudaDeviceSynchronize();
+#endif
+        timer.stop();
+
+        reset();
+    }
+
+    return timer.getTime();
+}
+
+
+struct InternalError {};
+
+
+class Logging
+{
+public:
+    using MetadataElement = std::pair< const char*, tnlString >;
+    using MetadataMap = std::map< const char*, tnlString >;
+    using MetadataColumns = std::vector<MetadataElement>;
+
+    using HeaderElements = std::initializer_list< tnlString >;
+    using RowElements = std::initializer_list< double >;
+
+    Logging( bool verbose = true )
+        : verbose(verbose)
+    { }
+
+    void
+    writeTitle( const tnlString & title )
+    {
+        if( verbose )
+            std::cout << std::endl << "== " << title << " ==" << std::endl << std::endl;
+        log << ": title = " << title << std::endl;
+    }
+
+    void
+    writeMetadata( const MetadataMap & metadata )
+    {
+        if( verbose )
+            std::cout << "properties:" << std::endl;
+
+        for( auto & it : metadata ) {
+            if( verbose )
+                std::cout << "   " << it.first << " = " << it.second << std::endl;
+            log << ": " << it.first << " = " << it.second << std::endl;
+        }
+        if( verbose )
+            std::cout << std::endl;
+    }
+
+    void
+    writeTableHeader( const tnlString & spanningElement,
+                      const HeaderElements & subElements )
+    {
+        using namespace std;
+
+        if( verbose && header_changed ) {
+            for( auto & it : metadataColumns ) {
+                cout << setw( 20 ) << it.first;
+            }
+
+            // spanning element is printed as usual column to stdout,
+            // but is excluded from header
+            cout << setw( 15 ) << "";
+
+            for( auto & it : subElements ) {
+                cout << setw( 15 ) << it;
+            }
+            cout << endl;
+
+            header_changed = false;
+        }
+
+        // initial indent string
+        header_indent = "!";
+        log << endl;
+        for( auto & it : metadataColumns ) {
+            log << header_indent << " " << it.first << endl;
+        }
+
+        // dump stacked spanning columns
+        if( horizontalGroups.size() > 0 )
+            while( horizontalGroups.back().second <= 0 ) {
+                horizontalGroups.pop_back();
+                header_indent.pop_back();
+            }
+        for( int i = 0; i < horizontalGroups.size(); i++ ) {
+            if( horizontalGroups[ i ].second > 0 ) {
+                log << header_indent << " " << horizontalGroups[ i ].first << endl;
+                header_indent += "!";
+            }
+        }
+
+        log << header_indent << " " << spanningElement << endl;
+        for( auto & it : subElements ) {
+            log << header_indent << "! " << it << endl;
+        }
+
+        if( horizontalGroups.size() > 0 ) {
+            horizontalGroups.back().second--;
+            header_indent.pop_back();
+        }
+    }
+
+    void
+    writeTableRow( const tnlString & spanningElement,
+                   const RowElements & subElements )
+    {
+        using namespace std;
+
+        if( verbose ) {
+            for( auto & it : metadataColumns ) {
+                cout << setw( 20 ) << it.second;
+            }
+            // spanning element is printed as usual column to stdout
+            cout << setw( 15 ) << spanningElement;
+            for( auto & it : subElements ) {
+                cout << setw( 15 );
+                if( it != 0.0 ) cout << it;
+                else cout << "N/A";
+            }
+            cout << endl;
+        }
+
+        // only when changed (the header has been already adjusted)
+        // print each element on separate line
+        for( auto & it : metadataColumns ) {
+            log << it.second << endl;
+        }
+
+        // benchmark data are indented
+        const tnlString indent = "    ";
+        for( auto & it : subElements ) {
+            if( it != 0.0 ) log << indent << it << endl;
+            else log << indent << "N/A" << endl;
+        }
+    }
+
+    void
+    writeErrorMessage( const char* msg,
+                       const int & colspan = 1 )
+    {
+        // initial indent string
+        header_indent = "!";
+        log << endl;
+        for( auto & it : metadataColumns ) {
+            log << header_indent << " " << it.first << endl;
+        }
+
+        // make sure there is a header column for the message
+        if( horizontalGroups.size() == 0 )
+            horizontalGroups.push_back( {"", 1} );
+
+        // dump stacked spanning columns
+        while( horizontalGroups.back().second <= 0 ) {
+            horizontalGroups.pop_back();
+            header_indent.pop_back();
+        }
+        for( int i = 0; i < horizontalGroups.size(); i++ ) {
+            if( horizontalGroups[ i ].second > 0 ) {
+                log << header_indent << " " << horizontalGroups[ i ].first << endl;
+                header_indent += "!";
+            }
+        }
+        if( horizontalGroups.size() > 0 ) {
+            horizontalGroups.back().second -= colspan;
+            header_indent.pop_back();
+        }
+
+        // only when changed (the header has been already adjusted)
+        // print each element on separate line
+        for( auto & it : metadataColumns ) {
+            log << it.second << endl;
+        }
+        log << msg << endl;
+    }
+
+    void
+    closeTable()
+    {
+        log << endl;
+        header_indent = body_indent = "";
+        header_changed = true;
+        horizontalGroups.clear();
+    }
+
+    bool save( std::ostream & logFile )
+    {
+        closeTable();
+        logFile << log.str();
+        if( logFile.good() ) {
+            log.str() = "";
+            return true;
+        }
+        return false;
+    }
+
+protected:
+
+    // manual double -> tnlString conversion with fixed precision
+    static tnlString
+    _to_string( const double & num, const int & precision = 0, bool fixed = false )
+    {
+        std::stringstream str;
+        if( fixed )
+            str << std::fixed;
+        if( precision )
+            str << std::setprecision( precision );
+        str << num;
+        return tnlString( str.str().data() );
+    }
+
+    std::stringstream log;
+    std::string header_indent;
+    std::string body_indent;
+
+    bool verbose;
+    MetadataColumns metadataColumns;
+    bool header_changed = true;
+    std::vector< std::pair< tnlString, int > > horizontalGroups;
+};
+
+
+class Benchmark
+    : protected Logging
+{
+public:
+    using Logging::MetadataElement;
+    using Logging::MetadataMap;
+    using Logging::MetadataColumns;
+
+    Benchmark( const int & loops = 10,
+               bool verbose = true )
+        : Logging(verbose), loops(loops)
+    { }
+
+    // TODO: ensure that this is not called in the middle of the benchmark
+    // (or just remove it completely?)
+    void
+    setLoops( const int & loops )
+    {
+        this->loops = loops;
+    }
+
+    // Marks the start of a new benchmark
+    void
+    newBenchmark( const tnlString & title )
+    {
+        closeTable();
+        writeTitle( title );
+    }
+
+    // Marks the start of a new benchmark (with custom metadata)
+    void
+    newBenchmark( const tnlString & title,
+                  MetadataMap metadata )
+    {
+        closeTable();
+        writeTitle( title );
+        // add loops to metadata
+        metadata["loops"] = tnlString(loops);
+        writeMetadata( metadata );
+    }
+
+    // Sets metadata columns -- values used for all subsequent rows until
+    // the next call to this function.
+    void
+    setMetadataColumns( const MetadataColumns & metadata )
+    {
+        if( metadataColumns != metadata )
+            header_changed = true;
+        metadataColumns = metadata;
+    }
+
+    // TODO: maybe should be renamed to createVerticalGroup and ensured that vertical and horizontal groups are not used within the same "Benchmark"
+    // Sets current operation -- operations expand the table vertically
+    //  - baseTime should be reset to 0.0 for most operations, but sometimes
+    //    it is useful to override it
+    //  - Order of operations inside a "Benchmark" does not matter, rows can be
+    //    easily sorted while converting to HTML.)
+    void
+    setOperation( const tnlString & operation,
+                  const double & datasetSize = 0.0, // in GB
+                  const double & baseTime = 0.0 )
+    {
+        if( metadataColumns.size() > 0 && tnlString(metadataColumns[ 0 ].first) == "operation" ) {
+            metadataColumns[ 0 ].second = operation;
+        }
+        else {
+            metadataColumns.insert( metadataColumns.begin(), {"operation", operation} );
+        }
+        setOperation( datasetSize, baseTime );
+        header_changed = true;
+    }
+
+    void
+    setOperation( const double & datasetSize = 0.0,
+                  const double & baseTime = 0.0 )
+    {
+        this->datasetSize = datasetSize;
+        this->baseTime = baseTime;
+    }
+
+    // Creates new horizontal groups inside a benchmark -- increases the number
+    // of columns in the "Benchmark", implies column spanning.
+    // (Useful e.g. for SpMV formats, different configurations etc.)
+    void
+    createHorizontalGroup( const tnlString & name,
+                           const int & subcolumns )
+    {
+        if( horizontalGroups.size() == 0 ) {
+            horizontalGroups.push_back( {name, subcolumns} );
+        }
+        else {
+            auto & last = horizontalGroups.back();
+            if( last.first != name && last.second > 0 ) {
+                horizontalGroups.push_back( {name, subcolumns} );
+            }
+            else {
+                last.first = name;
+                last.second = subcolumns;
+            }
+        }
+    }
+
+    // Times a single ComputeFunction. Subsequent calls implicitly split
+    // the current "horizontal group" into sub-columns identified by
+    // "performer", which are further split into "bandwidth", "time" and
+    // "speedup" columns.
+    // TODO: allow custom columns bound to lambda functions (e.g. for Gflops calculation)
+    // Also terminates the recursion of the following variadic template.
+    template< typename ResetFunction,
+              typename ComputeFunction >
+    double
+    time( ResetFunction reset,
+          const tnlString & performer,
+          ComputeFunction & compute )
+    {
+        const double time = timeFunction( compute, reset, loops );
+        const double bandwidth = datasetSize / time;
+        const double speedup = this->baseTime / time;
+        if( this->baseTime == 0.0 )
+            this->baseTime = time;
+
+        writeTableHeader( performer, HeaderElements({"bandwidth", "time", "speedup"}) );
+        writeTableRow( performer, RowElements({ bandwidth, time, speedup }) );
+
+        return this->baseTime;
+    }
+
+    // Recursive template function to deal with multiple computations with the
+    // same reset function.
+    template< typename ResetFunction,
+              typename ComputeFunction,
+              typename... NextComputations >
+    inline double
+    time( ResetFunction reset,
+          const tnlString & performer,
+          ComputeFunction & compute,
+          NextComputations & ... nextComputations )
+    {
+        time( reset, performer, compute );
+        time( reset, nextComputations... );
+        return this->baseTime;
+    }
+
+    // Adds an error message to the log. Should be called in places where the
+    // "time" method could not be called (e.g. due to failed allocation).
+    void
+    addErrorMessage( const char* msg,
+                     const int & numberOfComputations = 1 )
+    {
+        // each computation has 3 subcolumns
+        const int colspan = 3 * numberOfComputations;
+        writeErrorMessage( msg, colspan );
+    }
+
+    using Logging::save;
+
+protected:
+    int loops;
+    double datasetSize = 0.0;
+    double baseTime = 0.0;
+};
+
+} // namespace benchmarks
+} // namespace tnl
diff --git a/tests/benchmarks/cublasWrappers.h b/tests/benchmarks/cublasWrappers.h
new file mode 100644
index 0000000000000000000000000000000000000000..a7520a34d5d13ced796d8b2366b0382887f09a49
--- /dev/null
+++ b/tests/benchmarks/cublasWrappers.h
@@ -0,0 +1,123 @@
+#pragma once
+
+#ifdef HAVE_CUDA
+#ifdef HAVE_CUBLAS
+
+#include <cublas_v2.h>
+
+inline cublasStatus_t
+cublasIgamax( cublasHandle_t handle, int n,
+              const float           *x, int incx, int *result )
+{
+    return cublasIsamax( handle, n, x, incx, result );
+}
+
+inline cublasStatus_t
+cublasIgamax( cublasHandle_t handle, int n,
+              const double          *x, int incx, int *result )
+{
+    return cublasIdamax( handle, n, x, incx, result );
+}
+
+
+inline cublasStatus_t
+cublasIgamin( cublasHandle_t handle, int n,
+              const float           *x, int incx, int *result )
+{
+    return cublasIsamin( handle, n, x, incx, result );
+}
+
+inline cublasStatus_t
+cublasIgamin( cublasHandle_t handle, int n,
+              const double          *x, int incx, int *result )
+{
+    return cublasIdamin( handle, n, x, incx, result );
+}
+
+
+inline cublasStatus_t
+cublasGasum( cublasHandle_t handle, int n,
+             const float           *x, int incx, float  *result )
+{
+    return cublasSasum( handle, n, x, incx, result );
+}
+
+inline cublasStatus_t
+cublasGasum( cublasHandle_t handle, int n,
+             const double          *x, int incx, double *result )
+{
+    return cublasDasum( handle, n, x, incx, result );
+}
+
+
+inline cublasStatus_t
+cublasGaxpy( cublasHandle_t handle, int n,
+             const float           *alpha,
+             const float           *x, int incx,
+             float                 *y, int incy )
+{
+    return cublasSaxpy( handle, n, alpha, x, incx, y, incy );
+}
+
+inline cublasStatus_t
+cublasGaxpy( cublasHandle_t handle, int n,
+             const double          *alpha,
+             const double          *x, int incx,
+             double                *y, int incy )
+{
+    return cublasDaxpy( handle, n, alpha, x, incx, y, incy );
+}
+
+
+inline cublasStatus_t
+cublasGdot( cublasHandle_t handle, int n,
+            const float        *x, int incx,
+            const float        *y, int incy,
+            float         *result )
+{
+    return cublasSdot( handle, n, x, incx, y, incy, result );
+}
+
+inline cublasStatus_t
+cublasGdot( cublasHandle_t handle, int n,
+            const double       *x, int incx,
+            const double       *y, int incy,
+            double        *result )
+{
+    return cublasDdot( handle, n, x, incx, y, incy, result );
+}
+
+
+inline cublasStatus_t
+cublasGnrm2( cublasHandle_t handle, int n,
+             const float           *x, int incx, float  *result )
+{
+    return cublasSnrm2( handle, n, x, incx, result );
+}
+
+inline cublasStatus_t
+cublasGnrm2( cublasHandle_t handle, int n,
+             const double          *x, int incx, double *result )
+{
+    return cublasDnrm2( handle, n, x, incx, result );
+}
+
+
+inline cublasStatus_t
+cublasGscal( cublasHandle_t handle, int n,
+             const float           *alpha,
+             float           *x, int incx )
+{
+    return cublasSscal( handle, n, alpha, x, incx );
+}
+
+inline cublasStatus_t
+cublasGscal( cublasHandle_t handle, int n,
+             const double          *alpha,
+             double          *x, int incx )
+{
+    return cublasDscal( handle, n, alpha, x, incx );
+}
+
+#endif
+#endif
diff --git a/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace.h b/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace.h
new file mode 100644
index 0000000000000000000000000000000000000000..76269b7139f3c58d82721652f911297803a3ba26
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace.h
@@ -0,0 +1,143 @@
+#ifndef BenchmarkLaplace_H
+#define BenchmarkLaplace_H
+
+#include <core/vectors/tnlVector.h>
+#include <mesh/tnlGrid.h>
+
+template< typename Mesh,
+          typename Real = typename Mesh::RealType,
+          typename Index = typename Mesh::IndexType >
+class BenchmarkLaplace
+{
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class BenchmarkLaplace< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void setMatrixElements( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class BenchmarkLaplace< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void setMatrixElements( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+class BenchmarkLaplace< 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;
+      typedef tnlMeshFunction< MeshType > MeshFunctionType;
+      enum { Dimensions = MeshType::getMeshDimensions() };
+
+      static tnlString getType();
+
+      template< typename MeshFunction, typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshFunction& u,
+                       const MeshEntity& entity,
+                       const RealType& time = 0.0 ) const;
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Index getLinearSystemRowLength( const MeshType& mesh,
+                                      const IndexType& index,
+                                      const MeshEntity& entity ) const;
+
+      template< typename MeshEntity, typename Vector, typename MatrixRow >
+      __cuda_callable__
+      void setMatrixElements( const RealType& time,
+                               const RealType& tau,
+                               const MeshType& mesh,
+                               const IndexType& index,
+                               const MeshEntity& entity,
+                               const MeshFunctionType& u,
+                               Vector& b,
+                               MatrixRow& matrixRow ) const;
+};
+
+
+#include "BenchmarkLaplace_impl.h"
+
+#endif	/* BenchmarkLaplace_H */
diff --git a/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace_impl.h b/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..6cec357de6f5a0a5cd5c6ae93668be721d48c559
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/BenchmarkLaplace_impl.h
@@ -0,0 +1,344 @@
+#ifndef BenchmarkLaplace_IMPL_H
+#define BenchmarkLaplace_IMPL_H
+
+/****
+ * 1D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+BenchmarkLaplace< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "BenchmarkLaplace< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+BenchmarkLaplace< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   return ( u[ west ] - 2.0 * u[ center ]  + u[ east ] ) * hxSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+BenchmarkLaplace< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+BenchmarkLaplace< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >::
+setMatrixElements( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); 
+   const IndexType& center = entity.getIndex(); 
+   const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); 
+   const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); 
+   matrixRow.setElement( 0, west,   - lambdaX );
+   matrixRow.setElement( 1, center, 2.0 * lambdaX );
+   matrixRow.setElement( 2, east,   - lambdaX );
+}
+
+/****
+ * 2D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+BenchmarkLaplace< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "BenchmarkLaplace< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+BenchmarkLaplace< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& hySquareInverse = entity.getMesh().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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+BenchmarkLaplace< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+BenchmarkLaplace< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >::
+setMatrixElements( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, south,  -lambdaY );
+   matrixRow.setElement( 1, west,   -lambdaX );
+   matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) );
+   matrixRow.setElement( 3, east,   -lambdaX );
+   matrixRow.setElement( 4, north,  -lambdaY );
+}
+
+/****
+ * 3D problem
+ */
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+tnlString
+BenchmarkLaplace< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getType()
+{
+   return tnlString( "BenchmarkLaplace< " ) +
+          MeshType::getType() + ", " +
+          ::getType< Real >() + ", " +
+          ::getType< Index >() + " >";
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshFunction, typename MeshEntity >
+__cuda_callable__
+Real
+BenchmarkLaplace< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+operator()( const MeshFunction& u,
+            const MeshEntity& entity,
+            const Real& time ) const
+{
+   /****
+    * Implement your explicit form of the differential operator here.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+    static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); 
+    static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); 
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+
+   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 >(); 
+   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 >(); 
+   return ( u[ west ] - 2.0 * u[ center ] + u[ east ]  ) * hxSquareInverse +
+          ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse +
+          ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+template< typename MeshEntity >
+__cuda_callable__
+Index
+BenchmarkLaplace< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+getLinearSystemRowLength( const MeshType& mesh,
+                          const IndexType& index,
+                          const MeshEntity& entity ) const
+{
+   /****
+    * Return a number of non-zero elements in a line (associated with given grid element) of
+    * the linear system.
+    * The following example is the Laplace operator approximated 
+    * by the Finite difference method.
+    */
+
+   return 2*Dimensions + 1;
+}
+
+template< typename MeshReal,
+          typename Device,
+          typename MeshIndex,
+          typename Real,
+          typename Index >
+   template< typename MeshEntity, typename Vector, typename MatrixRow >
+__cuda_callable__
+void
+BenchmarkLaplace< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >::
+setMatrixElements( const RealType& time,
+                    const RealType& tau,
+                    const MeshType& mesh,
+                    const IndexType& index,
+                    const MeshEntity& entity,
+                    const MeshFunctionType& u,
+                    Vector& b,
+                    MatrixRow& matrixRow ) const
+{
+   /****
+    * Setup the non-zero elements of the linear system here.
+    * The following example is the Laplace operator appriximated 
+    * by the Finite difference method.
+    */
+
+    const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); 
+   const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2,  0,  0 >(); 
+   const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts<  0, -2,  0 >(); 
+   const RealType& lambdaZ = tau * entity.getMesh().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 >(); 
+   matrixRow.setElement( 0, down,   -lambdaZ );
+   matrixRow.setElement( 1, south,  -lambdaY );
+   matrixRow.setElement( 2, west,   -lambdaX );
+   matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) );
+   matrixRow.setElement( 4, east,   -lambdaX );
+   matrixRow.setElement( 5, north,  -lambdaY );
+   matrixRow.setElement( 6, up,     -lambdaZ );
+}
+
+#endif	/* BenchmarkLaplaceIMPL_H */
+
diff --git a/tests/benchmarks/heat-equation-benchmark/CMakeLists.txt b/tests/benchmarks/heat-equation-benchmark/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..22f55d3f1bc27401f9843cf990807b8f6a028df3
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/CMakeLists.txt
@@ -0,0 +1,15 @@
+IF( BUILD_CUDA )
+    CUDA_ADD_EXECUTABLE( tnl-benchmark-heat-equation${debugExt} tnl-benchmark-heat-equation.cu )
+    TARGET_LINK_LIBRARIES( tnl-benchmark-heat-equation${debugExt} tnl${debugExt}-${tnlVersion} )
+
+ELSE()
+    ADD_EXECUTABLE( tnl-benchmark-heat-equation${debugExt} tnl-benchmark-heat-equation.cpp )    
+    TARGET_LINK_LIBRARIES( tnl-benchmark-heat-equation${debugExt} tnl${debugExt}-${tnlVersion} )
+ENDIF()
+
+
+INSTALL( TARGETS tnl-benchmark-heat-equation${debugExt}
+         RUNTIME DESTINATION bin )
+
+
+                                            
diff --git a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkBuildConfigTag.h b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkBuildConfigTag.h
new file mode 100644
index 0000000000000000000000000000000000000000..83640544ff9fcc854a3f41b52d1f8740d6024d43
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkBuildConfigTag.h
@@ -0,0 +1,43 @@
+#ifndef HeatEquationBenchmarkBUILDCONFIGTAG_H_
+#define HeatEquationBenchmarkBUILDCONFIGTAG_H_
+
+#include <solvers/tnlBuildConfigTags.h>
+
+class HeatEquationBenchmarkBuildConfigTag{};
+
+/****
+ * Turn off support for float and long double.
+ */
+template<> struct tnlConfigTagReal< HeatEquationBenchmarkBuildConfigTag, float > { enum { enabled = false }; };
+template<> struct tnlConfigTagReal< HeatEquationBenchmarkBuildConfigTag, long double > { enum { enabled = false }; };
+
+/****
+ * Turn off support for short int and long int indexing.
+ */
+template<> struct tnlConfigTagIndex< HeatEquationBenchmarkBuildConfigTag, short int >{ enum { enabled = false }; };
+template<> struct tnlConfigTagIndex< HeatEquationBenchmarkBuildConfigTag, long int >{ enum { enabled = false }; };
+
+/****
+ * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types.
+ */
+template< int Dimensions, typename Real, typename Device, typename Index >
+   struct tnlConfigTagMesh< HeatEquationBenchmarkBuildConfigTag, tnlGrid< Dimensions, Real, Device, Index > >
+      { enum { enabled = ( Dimensions == 2 )  &&
+                         tnlConfigTagReal< HeatEquationBenchmarkBuildConfigTag, Real >::enabled &&
+                         tnlConfigTagDevice< HeatEquationBenchmarkBuildConfigTag, Device >::enabled &&
+                         tnlConfigTagIndex< HeatEquationBenchmarkBuildConfigTag, Index >::enabled }; };
+
+/****
+ * Please, chose your preferred time discretisation  here.
+ */
+template<> struct tnlConfigTagTimeDiscretisation< HeatEquationBenchmarkBuildConfigTag, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagTimeDiscretisation< HeatEquationBenchmarkBuildConfigTag, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+template<> struct tnlConfigTagTimeDiscretisation< HeatEquationBenchmarkBuildConfigTag, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; };
+
+/****
+ * Only the Runge-Kutta-Merson solver is enabled by default.
+ */
+template<> struct tnlConfigTagExplicitSolver< HeatEquationBenchmarkBuildConfigTag, tnlExplicitEulerSolverTag >{ enum { enabled = true }; };
+template<> struct tnlConfigTagExplicitSolver< HeatEquationBenchmarkBuildConfigTag, tnlExplicitMersonSolverTag >{ enum { enabled = false }; };
+
+#endif /* HeatEquationBenchmarkBUILDCONFIGTAG_H_ */
diff --git a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem.h b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca3b0d7cafae7499c059bef2c9eb2e6ff66e5ec9
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem.h
@@ -0,0 +1,83 @@
+#ifndef HeatEquationBenchmarkPROBLEM_H_
+#define HeatEquationBenchmarkPROBLEM_H_
+
+#include <problems/tnlPDEProblem.h>
+#include <functions/tnlMeshFunction.h>
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+           typename DifferentialOperator >
+class HeatEquationBenchmarkProblem:
+   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;
+
+      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:
+
+      DifferentialOperator differentialOperator;
+      BoundaryCondition boundaryCondition;
+      RightHandSide rightHandSide;
+};
+
+#include "HeatEquationBenchmarkProblem_impl.h"
+
+#endif /* HeatEquationBenchmarkPROBLEM_H_ */
diff --git a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem_impl.h b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..42842c4ab88ac701ad4f50b94d6292bce720fa0b
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkProblem_impl.h
@@ -0,0 +1,254 @@
+#ifndef HeatEquationBenchmarkPROBLEM_IMPL_H_
+#define HeatEquationBenchmarkPROBLEM_IMPL_H_
+
+#include <core/mfilename.h>
+#include <matrices/tnlMatrixSetter.h>
+#include <solvers/pde/tnlExplicitUpdater.h>
+#include <solvers/pde/tnlLinearSystemAssembler.h>
+#include <solvers/pde/tnlBackwardTimeDiscretisation.h>
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getTypeStatic()
+{
+   return tnlString( "HeatEquationBenchmarkProblem< " ) + Mesh :: getTypeStatic() + " >";
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+tnlString
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getPrologHeader() const
+{
+   return tnlString( "Heat Equation Benchmark" );
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const
+{
+   /****
+    * Add data you want to have in the computation report (log) as follows:
+    * logger.writeParameter< double >( "Parameter description", parameter );
+    */
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setup( const tnlParameterContainer& parameters )
+{
+   if( ! this->boundaryCondition.setup( parameters, "boundary-conditions-" ) ||
+       ! this->rightHandSide.setup( parameters, "right-hand-side-" ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+typename HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getDofs( const MeshType& mesh ) const
+{
+   /****
+    * Return number of  DOFs (degrees of freedom) i.e. number
+    * of unknowns to be resolved by the main solver.
+    */
+   return mesh.template getEntitiesCount< typename MeshType::Cell >();
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+bindDofs( const MeshType& mesh,
+          DofVectorType& dofVector )
+{
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+bool
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setInitialCondition( const tnlParameterContainer& parameters,
+                     const MeshType& mesh,
+                     DofVectorType& dofs,
+                     MeshDependentDataType& meshDependentData )
+{
+   const tnlString& initialConditionFile = parameters.getParameter< tnlString >( "initial-condition" );
+   tnlMeshFunction< Mesh > u( mesh, dofs );
+   if( ! u.boundLoad( 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
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+setupLinearSystem( const MeshType& mesh,
+                   Matrix& matrix )
+{
+   const IndexType dofs = this->getDofs( mesh );
+   typedef typename Matrix::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
+HeatEquationBenchmarkProblem< 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 );
+   tnlString fileName;
+   FileNameBaseNumberEnding( "u-", step, 5, ".tnl", fileName );
+   if( ! dofs.save( fileName ) )
+      return false;
+   return true;
+}
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+void
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+getExplicitRHS( const RealType& time,
+                const RealType& tau,
+                const MeshType& mesh,
+                DofVectorType& u,
+                DofVectorType& fu,
+                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 mesh dependent data if you need.
+    */
+
+   const IndexType gridXSize = mesh.getDimensions().x();
+   const IndexType gridYSize = mesh.getDimensions().y();
+   const RealType& hx_inv = mesh.template getSpaceStepsProducts< -2,  0 >();
+   const RealType& hy_inv = mesh.template getSpaceStepsProducts<  0, -2 >();
+   for( IndexType j = 0; j < gridYSize; j++ )
+   {
+      fu[ j * gridXSize ] = 0.0; //u[ j * gridXSize + 1 ];
+      fu[ j * gridXSize + gridXSize - 2 ] = 0.0; //u[ j * gridXSize + gridXSize - 1 ];
+   }
+   for( IndexType i = 0; i < gridXSize; i++ )
+   {
+      fu[ i ] = 0.0; //u[ gridXSize + i ];
+      fu[ ( gridYSize - 1 ) * gridXSize + i ] = 0.0; //u[ ( gridYSize - 2 ) * gridXSize + i ];
+   }
+
+   for( IndexType j = 1; j < gridYSize - 1; j++ )
+      for( IndexType i = 1; i < gridXSize - 1; i++ )
+      {
+         const IndexType c = j * gridXSize + i;
+         fu[ c ] = tau * ( ( u[ c - 1 ] - 2.0 * u[ c ] + u[ c + 1 ] ) * hx_inv +
+                           ( u[ c - gridXSize ] - 2.0 * u[ c ] + u[ c + gridXSize ] ) * hy_inv );
+      }
+
+      
+   /*this->bindDofs( mesh, _u );
+   tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater;
+   MeshFunctionType u( mesh, _u ); 
+   MeshFunctionType fu( mesh, _fu ); 
+   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 + tau, 
+       u ); */
+ }
+
+template< typename Mesh,
+          typename BoundaryCondition,
+          typename RightHandSide,
+          typename DifferentialOperator >
+   template< typename Matrix >
+void
+HeatEquationBenchmarkProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::
+assemblyLinearSystem( const RealType& time,
+                      const RealType& tau,
+                      const MeshType& mesh,
+                      DofVectorType& _u,
+                      Matrix& matrix,
+                      DofVectorType& b,
+                      MeshDependentDataType& meshDependentData )
+{
+   tnlLinearSystemAssembler< Mesh,
+                             MeshFunctionType,
+                             DifferentialOperator,
+                             BoundaryCondition,
+                             RightHandSide,
+                             tnlBackwardTimeDiscretisation,
+                             Matrix,
+                             DofVectorType > systemAssembler;
+
+   tnlMeshFunction< Mesh > u( mesh, _u );
+   systemAssembler.template assembly< typename Mesh::Cell >( time,
+                                                             tau,
+                                                             mesh,
+                                                             this->differentialOperator,
+                                                             this->boundaryCondition,
+                                                             this->rightHandSide,
+                                                             u,
+                                                             matrix,
+                                                             b );
+}
+
+#endif /* HeatEquationBenchmarkPROBLEM_IMPL_H_ */
diff --git a/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkRhs.h b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkRhs.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba9ce459a1855d616f91fe4937a6d230662d7374
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/HeatEquationBenchmarkRhs.h
@@ -0,0 +1,29 @@
+#ifndef HeatEquationBenchmarkRHS_H_
+#define HeatEquationBenchmarkRHS_H_
+#include<functions/tnlDomain.h>
+template< typename Mesh, typename Real >class HeatEquationBenchmarkRhs
+  : public tnlDomain< Mesh::meshDimensions, MeshDomain > 
+ {
+   public:
+
+      typedef Mesh MeshType;
+      typedef Real RealType;
+
+      bool setup( const tnlParameterContainer& parameters,
+                  const tnlString& prefix = "" )
+      {
+         return true;
+      }
+
+      template< typename MeshEntity >
+      __cuda_callable__
+      Real operator()( const MeshEntity& entity,
+                       const Real& time = 0.0 ) const
+      {
+         typedef typename MeshEntity::MeshType::VertexType VertexType;
+         VertexType v = entity.getCenter();
+         return 0.0;
+      }
+};
+
+#endif /* HeatEquationBenchmarkRHS_H_ */
diff --git a/tests/benchmarks/heat-equation-benchmark/run-HeatEquationBenchmark b/tests/benchmarks/heat-equation-benchmark/run-HeatEquationBenchmark
new file mode 100644
index 0000000000000000000000000000000000000000..7a8707fb84905147e482e054865071799d57fcb0
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/run-HeatEquationBenchmark
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+tnl-grid-setup --dimensions 2 \
+               --origin-x 0.0 \
+               --origin-y 0.0 \
+               --proportions-x 1.0 \
+               --proportions-y 1.0 \
+               --size-x 100 \
+               --size-y 100
+
+tnl-init --test-function sin-wave \
+         --output-file init.tnl
+./HeatEquationBenchmark --time-discretisation explicit \
+              --boundary-conditions-constant 0 \
+              --discrete-solver merson \
+              --snapshot-period 0.01 \
+              --final-time 1.0
+
+tnl-view --mesh mesh.tnl --input-files *tnl     
diff --git a/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.cpp b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..282de22e332976a9612e0c972eec3636978d4f2d
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.cpp
@@ -0,0 +1 @@
+#include "tnl-benchmark-heat-equation.h"
diff --git a/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.cu b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.cu
new file mode 100644
index 0000000000000000000000000000000000000000..282de22e332976a9612e0c972eec3636978d4f2d
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.cu
@@ -0,0 +1 @@
+#include "tnl-benchmark-heat-equation.h"
diff --git a/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.h b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.h
new file mode 100644
index 0000000000000000000000000000000000000000..d15404f9c5607d71311b6964d788ec9638850231
--- /dev/null
+++ b/tests/benchmarks/heat-equation-benchmark/tnl-benchmark-heat-equation.h
@@ -0,0 +1,107 @@
+#include <tnlConfig.h>
+#include <solvers/tnlSolver.h>
+#include <solvers/tnlBuildConfigTags.h>
+#include <operators/tnlDirichletBoundaryConditions.h>
+#include <operators/tnlNeumannBoundaryConditions.h>
+#include <functions/tnlConstantFunction.h>
+#include "HeatEquationBenchmarkProblem.h"
+#include "BenchmarkLaplace.h"
+#include "HeatEquationBenchmarkRhs.h"
+#include "HeatEquationBenchmarkBuildConfigTag.h"
+
+typedef HeatEquationBenchmarkBuildConfigTag BuildConfig;
+
+/****
+ * Uncoment the following (and comment the previous line) for the complete build.
+ * This will include support for all floating point precisions, all indexing types
+ * and more solvers. You may then choose between them from the command line.
+ * The compile time may, however, take tens of minutes or even several hours,
+ * esppecially if CUDA is enabled. Use this, if you want, only for the final build,
+ * not in the development phase.
+ */
+//typedef tnlDefaultConfigTag BuildConfig;
+
+template< typename ConfigTag >class HeatEquationBenchmarkConfig
+{
+   public:
+      static void configSetup( tnlConfigDescription & config )
+      {
+         config.addDelimiter( "Heat Equation Benchmark settings:" );
+         config.addEntry< tnlString >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet");
+            config.addEntryEnum< tnlString >( "dirichlet" );
+            config.addEntryEnum< tnlString >( "neumann" );
+         config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." );
+
+         /****
+          * Add definition of your solver command line arguments.
+          */
+
+      }
+};
+
+template< typename Real,
+          typename Device,
+          typename Index,
+          typename MeshType,
+          typename ConfigTag,
+          typename SolverStarter >
+class HeatEquationBenchmarkSetter
+{
+   public:
+
+      typedef Real RealType;
+      typedef Device DeviceType;
+      typedef Index IndexType;
+
+      static bool run( const tnlParameterContainer & parameters )
+      {
+          enum { Dimensions = MeshType::getMeshDimensions() };
+          typedef BenchmarkLaplace< MeshType, Real, Index > ApproximateOperator;
+          typedef HeatEquationBenchmarkRhs< MeshType, Real > RightHandSide;
+          typedef tnlStaticVector < MeshType::getMeshDimensions(), Real > Vertex;
+
+         /****
+          * Resolve the template arguments of your solver here.
+          * The following code is for the Dirichlet and the Neumann boundary conditions.
+          * Both can be constant or defined as descrete values of tnlVector.
+          */
+          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, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+                typedef HeatEquationBenchmarkProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+                SolverStarter solverStarter;
+                return solverStarter.template run< Problem >( parameters );
+             }
+             typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunction, Real, Index > BoundaryConditions;
+             typedef HeatEquationBenchmarkProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+             SolverStarter solverStarter;
+             return solverStarter.template run< Problem >( parameters );
+          }
+          typedef tnlMeshFunction< MeshType > MeshFunction;
+          if( boundaryConditionsType == "dirichlet" )
+          {
+             typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions;
+             typedef HeatEquationBenchmarkProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+             SolverStarter solverStarter;
+             return solverStarter.template run< Problem >( parameters );
+          }
+          typedef tnlNeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
+          typedef HeatEquationBenchmarkProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem;
+          SolverStarter solverStarter;
+          return solverStarter.template run< Problem >( parameters );
+      }
+
+};
+
+int main( int argc, char* argv[] )
+{
+   tnlSolver< HeatEquationBenchmarkSetter, HeatEquationBenchmarkConfig, BuildConfig > solver;
+   if( ! solver. run( argc, argv ) )
+      return EXIT_FAILURE;
+   return EXIT_SUCCESS;
+}
+
diff --git a/tests/benchmarks/share/CMakeLists.txt b/tests/benchmarks/share/CMakeLists.txt
index f494e852aa44238881840f2bdf9e21d40a0e1289..aeb6ace5ef89228e5ca9433b7327bada84cb5f6e 100755
--- a/tests/benchmarks/share/CMakeLists.txt
+++ b/tests/benchmarks/share/CMakeLists.txt
@@ -13,6 +13,7 @@ INSTALL( FILES matrix-market
                DESTINATION share/tnl-${tnlVersion}/benchmark-scripts )
 
 INSTALL( FILES tnl-run-spmv-benchmark
+               tnl-log-to-html.py
          DESTINATION bin
          PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
                                                                    
\ No newline at end of file
diff --git a/tests/benchmarks/share/tnl-log-to-html.py b/tests/benchmarks/share/tnl-log-to-html.py
index 4c7a394b863bec72d58d9e3620fc997fa99f34b5..38adaad4002dc50f7039e006058cb692c6523ade 100644
--- a/tests/benchmarks/share/tnl-log-to-html.py
+++ b/tests/benchmarks/share/tnl-log-to-html.py
@@ -1,264 +1,411 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
-import sys;
+import sys
+import collections
+
+def getSortKey(value):
+    # try to convert to number if possible
+    try:
+        return int(value)
+    except ValueError:
+        try:
+            return float(value)
+        except ValueError:
+            if value:
+                return value
+            # None or empty string
+            return 0
 
 class columnFormating:
 
-   def __init__( self, data ):
-      self.coloring = []
-      self.sorting = "none"
-      self.sortingFile = ""
-      self.sortingData = []
-      self.sortingNaNs = 0
-      dataSplit = data.split( ' ' )
-      currentFormating = ""
-      for word in dataSplit:
-         if word == "COLORING" or word == "SORT":
-            currentFormating = word
-            continue
-         if currentFormating == "COLORING":
-            self.coloring.append( word )
-         if currentFormating == "SORT":
-            if word == "+" or word == "-":
-               self.sorting = word
-            else:
-               self.sortingFile = word
+    def __init__( self, data ):
+        self.coloring = []
+        self.sorting = "none"
+        self.sortingFile = ""
+        self.sortingData = []
+        self.sortingNaNs = 0
+        dataSplit = data.split( ' ' )
+        currentFormating = ""
+        for word in dataSplit:
+            if word == "COLORING" or word == "SORT":
+                currentFormating = word
+                continue
+            if currentFormating == "COLORING":
+                self.coloring.append( word )
+            if currentFormating == "SORT":
+                if word == "+" or word == "-":
+                    self.sorting = word
+                else:
+                    self.sortingFile = word
 
 
-   def write( self, htmlFile, line ):
-      color = ""
-      if len( self.coloring ) > 0:
-         for token in self.coloring:
-            if token.find( "#" ) == 0:
-               color = token
-            else:
-               try:
-                  if float( token ) > float( line ):
-                     break
-               except ValueError:
-                  color = ""
-                  break
-      if color != "":
-         htmlFile.write( " bgcolor=\"" )
-         htmlFile.write( color )
-         htmlFile.write( "\"" )
-
-      if self.sorting == "+" or self.sorting == "-":
-         try:
-            number = float( line )
-            self.sortingData.append( number )
-         except ValueError:
-            self.sortingNaNs += 1
-
-   def processSorting( self ):
-      if self.sorting == "none":
-         return
-      if self.sorting == "+":
-         self.sortingData.sort()
-      if self.sorting == "-":
-         self.sortingData.sort( reverse = True )
-      sortFile = open( self.sortingFile, "w" )
-      sortFile.write( "# Number of NaNs is ")
-      sortFile.write( str( self.sortingNaNs ) )
-      sortFile.write( "\n\n" )
-      idx = 0
-      for n in self.sortingData:
-         sortFile.write( str( idx ) )
-         sortFile.write( "\t" )
-         sortFile.write( str( n ) )
-         sortFile.write( "\n" )
-         idx += 1
-      sortFile.close()
+    def get( self, value ):
+        color = ""
+        if len( self.coloring ) > 0:
+            for token in self.coloring:
+                if token.find( "#" ) == 0:
+                    color = token
+                else:
+                    try:
+                        if float( token ) > float( value ):
+                            break
+                    except ValueError:
+                        color = ""
+                        break
+
+        html = ""
+        if color != "":
+            html += "bgcolor=\"{}\"".format(color)
+
+        if self.sorting == "+" or self.sorting == "-":
+            try:
+                number = float( value )
+                self.sortingData.append( number )
+            except ValueError:
+                self.sortingNaNs += 1
+
+        return html
+
+    def processSorting( self ):
+        if self.sorting == "none":
+            return
+        if self.sorting == "+":
+            self.sortingData.sort()
+        if self.sorting == "-":
+            self.sortingData.sort( reverse = True )
+        sortFile = open( self.sortingFile, "w" )
+        sortFile.write( "# Number of NaNs is ")
+        sortFile.write( str( self.sortingNaNs ) )
+        sortFile.write( "\n\n" )
+        idx = 0
+        for n in self.sortingData:
+            sortFile.write( str( idx ) )
+            sortFile.write( "\t" )
+            sortFile.write( str( n ) )
+            sortFile.write( "\n" )
+            idx += 1
+        sortFile.close()
 
 
 class tableColumn:
 
-   def __init__( self, level, data ):
-      self.level = level
-      self.maxLevel = 0
-      self.height = 0
-      self.subcolumns = []
-      self.numberOfSubcolumns = 0
-      self.rowspan = 0
-      dataSplit = data.split( ':', 1 );
-      label = dataSplit[ 0 ];   
-      self.label = label.rstrip( ' ' );
-      #print self.label
-      if len( dataSplit ) == 2:
-         self.formating = columnFormating( dataSplit[ 1 ] )
-      else:
-         self.formating = columnFormating( "" )
-
-   def insertSubcolumn( self, level, label ):
-      if level > self.maxLevel:
-         self.maxLevel = level
-      if level == self.level + 1:
-         self.subcolumns.append( tableColumn( level, label ) )
-      if level > self.level + 1:
-         self.subcolumns[ len( self.subcolumns ) - 1 ].insertSubcolumn( level, label )
-
-   def countSubcolumns( self ):
-      if( len( self.subcolumns ) == 0 ):
-         self.numberOfSubcolumns = 1
-      else:
-         self.numberOfSubcolumns = 0;
-         for subcolumn in self.subcolumns:
-            self.numberOfSubcolumns = self.numberOfSubcolumns + subcolumn.countSubcolumns()
-      return self.numberOfSubcolumns
-
-   def countHeight( self ):
-      self.height = 1;
-      if len( self.subcolumns ) == 0:
-         return 1
-      for subcolumn in self.subcolumns:
-         self.height = max( self.height, subcolumn.countHeight() + 1 )
-      return self.height
-
-   def countRowspan( self, height ):
-      self.rowspan = height - self.height + 1
-      #print "Setting rowspan of ", self.label, " to ", self.rowspan
-      for subcolumn in self.subcolumns:
-         subcolumn.countRowspan( self.height - 1 )
-
-   def recomputeLevel( self, level ):
-      self.level = level
-      for subcolumn in self.subcolumns:
-         subcolumn.recomputeLevel( self.level + self.rowspan )
-
-   def writeToColumnsHeader( self, htmlFile, height, currentLevel ):
-      if currentLevel > self.level:
-         for subcolumn in self.subcolumns:
-            subcolumn.writeToColumnsHeader( htmlFile, self.height , currentLevel )
-      if currentLevel == self.level:
-         #print "Label  = ", self.label, " self.height = ", self.height, " height = ", height
-         htmlFile.write( "            <td rowspan=" + str( self.rowspan ) + " colspan=" + str( self.numberOfSubcolumns) + ">" + self.label + "</td>\n" )
-
-   def pickLeafColumns( self, leafColumns ):
-      if len( self.subcolumns ) == 0:
-         #print "Appending leaf column ", self.label
-         leafColumns.append( self )
-      else:
-         for subcolumn in self.subcolumns:
-            subcolumn.pickLeafColumns( leafColumns )
-
-   def writeFormating( self, htmlFile, line ):
-      self.formating.write( htmlFile, line )
-
-   def processSorting( self ):
-      self.formating.processSorting()
-      
-      
-      
-      
+    def __init__( self, level, data, parentPath=None ):
+        self.subcolumns = []
+        self.height = 0
+        self.numberOfSubcolumns = 0
+        self.rowspan = 0
+
+        self.level = level
+        dataSplit = data.split( ':', 1 )
+        self.label = dataSplit[ 0 ].strip()
+        if len(dataSplit) == 2:
+            self.attributes = dataSplit[1]
+        else:
+            self.attributes = ""
+
+        if parentPath is None:
+            self.path = []
+        else:
+            # make a copy!
+            self.path = parentPath[:]
+        self.path.append(self.label)
+
+    def insertSubcolumn( self, level, label ):
+        if level == self.level + 1:
+            self.subcolumns.append( tableColumn( level, label, self.path ) )
+        if level > self.level + 1:
+            self.subcolumns[ -1 ].insertSubcolumn( level, label )
+
+    def countSubcolumns( self ):
+        if( len( self.subcolumns ) == 0 ):
+            self.numberOfSubcolumns = 1
+        else:
+            self.numberOfSubcolumns = 0;
+            for subcolumn in self.subcolumns:
+                self.numberOfSubcolumns = self.numberOfSubcolumns + subcolumn.countSubcolumns()
+        return self.numberOfSubcolumns
+
+    def countHeight( self ):
+        self.height = 1;
+        if len( self.subcolumns ) == 0:
+            return 1
+        for subcolumn in self.subcolumns:
+            self.height = max( self.height, subcolumn.countHeight() + 1 )
+        return self.height
+
+    def countRowspan( self, height ):
+        self.rowspan = height - self.height + 1
+        #print "Setting rowspan of ", self.label, " to ", self.rowspan
+        for subcolumn in self.subcolumns:
+            subcolumn.countRowspan( self.height - 1 )
+
+    def recomputeLevel( self, level ):
+        self.level = level
+        for subcolumn in self.subcolumns:
+            subcolumn.recomputeLevel( self.level + self.rowspan )
+
+    def getColumnHeader( self, currentLevel ):
+        if currentLevel == self.level:
+            return "        <td rowspan=" + str( self.rowspan ) + " colspan=" + str( self.numberOfSubcolumns) + ">" + self.label + "</td>\n"
+        return ""
+
+    def pickLeafColumns( self, leafColumns ):
+        if len( self.subcolumns ) == 0:
+            leafColumns.append( self )
+        else:
+            for subcolumn in self.subcolumns:
+                subcolumn.pickLeafColumns( leafColumns )
+
+    def getFormating( self, value ):
+        formating = columnFormating(self.attributes)
+        return formating.get( value )
+
+    def processSorting( self ):
+        self.formating.processSorting()
+
+    def __repr__(self):
+        return "<tableColumn(label={}, subcolumns={})>".format(self.label, [col.label for col in self.subcolumns])
+
+
+
 class logToHtmlConvertor:
 
-   def __init__( self ):
-      self.tableColumns = []
-      self.maxLevel = 0
-      self.leafColumns = []
-
-   def processFile( self, logFileName, htmlFileName ):
-      print "Processing file", logFileName 
-      print "Writing output to", htmlFileName 
-      logFile = open( logFileName, 'r' )
-      htmlFile = open( htmlFileName, 'w' )
-      self.writeHtmlHeader( htmlFile, logFile )
-      htmlFile.close()
-      logFile.close()
-
-   def initColumnsStructure( self, logFile ):
-      for line in logFile:
-         if line[ 0 ] != '#':
-            return
-         data = line[1:]
-         level = len( data ) - len( data.lstrip(' ') )
-         level = level + 1
-         label = data.lstrip( ' ')
-         label = label.rstrip( '\n' )
-         #print " Inserting column on level ", level, " and label ", label
-         if level > self.maxLevel:
-            self.maxLevel = level;
-         if level == 1:
-            self.tableColumns.append( tableColumn( 1, label ) )
-         if level > 1:
-            self.tableColumns[ len( self.tableColumns ) - 1 ].insertSubcolumn( level, label )
-
-   def countSubcolumns( self ):
-      for subcolumn in self.tableColumns:
-         subcolumn.countSubcolumns();
-   
-   def countHeight( self ):
-      for subcolumn in self.tableColumns:
-         subcolumn.countHeight();
-   
-   def countRowspan( self ):
-      for subcolumn in self.tableColumns:
-         subcolumn.countRowspan( self.maxLevel )
-
-   def recomputeLevel( self ):
-      for subcolumn in self.tableColumns:
-         subcolumn.recomputeLevel( 1 )
-
-   def writeColumnsHeader( self, htmlFile ):
-      level = 1
-      while level <= self.maxLevel:
-         #print "Writing columns on level ", level 
-         htmlFile.write( "         <tr>\n")
-         for column in self.tableColumns:
-            column.writeToColumnsHeader( htmlFile, self.maxLevel, level )
-         htmlFile.write( "         </tr>\n")
-         level = level + 1
-
-   def pickLeafColumns( self ):
-      for subcolumn in self.tableColumns:
-         subcolumn.pickLeafColumns( self.leafColumns )
-
-   def writeTable( self, logFile, htmlFile ):
-      firstLine = "true"
-      for line in logFile:
-         if len( line ) == 1 or firstLine == "true":
-            if firstLine == "true":
-               htmlFile.write( "         <tr>\n" )
-               leafColumnsPointer = 0
-               firstLine = "false"
+    def __init__(self):
+        self.html = ""
+        self.reset()
+
+    def reset(self):
+        self.metadata = {}
+        self.maxLevel = 0
+        self.leafColumns = []
+        self.tableColumns = collections.OrderedDict()
+        self.tableRows = []
+
+    def processFile( self, logFileName, htmlFileName ):
+        # init HTML text
+        self.writeHtmlHeader()
+
+        print("Processing file", logFileName)
+        logFile = open( logFileName, 'r' )
+        self.readFile(logFile)
+        logFile.close()
+
+        self.writeHtmlFooter()
+        print("Writing output to", htmlFileName)
+        htmlFile = open( htmlFileName, 'w' )
+        htmlFile.write(self.html)
+        htmlFile.close()
+
+        self.reset()
+        self.html = ""
+
+    def readFile( self, logFile ):
+        # read file by lines
+        lines = logFile.readlines()
+
+        # drop comments and blank lines
+        lines = [line for line in lines if line.strip() and not line.startswith("#")]
+
+        # drop anything before the first metadata block
+        while len(lines) > 0 and not lines[0].startswith(":"):
+            lines.pop(0)
+
+        while len(lines) > 0:
+            self.reset()
+            metadata = []
+            while len(lines) > 0 and lines[0].startswith(":"):
+                metadata.append(lines.pop(0))
+            self.parseMetadata(metadata)
+
+            table = []
+            while len(lines) > 0 and not lines[0].startswith(":"):
+                table.append(lines.pop(0))
+            self.parseTable(table)
+
+            self.writeTable()
+
+    def parseMetadata(self, lines):
+        for line in lines:
+            line = line[1:]
+            key, value = line.split("=", 1)
+            self.metadata[key.strip()] = value.strip()
+
+    def parseTable(self, lines):
+        header = []
+        body = []
+        while len(lines) > 0:
+            while len(lines) > 0 and lines[0].startswith("!"):
+                header.append(lines.pop(0))
+            while len(lines) > 0 and not lines[0].startswith("!"):
+                body.append(lines.pop(0))
+            self.parseTableRow(header, body)
+            header = []
+            body = []
+
+    def parseTableRow(self, header, body):
+        columns = []
+        for line in header:
+            data = line.lstrip("!")
+            level = len(line) - len(data)
+            label = data.strip()
+            #print " Inserting column on level ", level, " and label ", label
+            if level > self.maxLevel:
+                self.maxLevel = level;
+            if level == 1:
+                columns.append( tableColumn( 1, label ) )
+            if level > 1:
+                columns[ -1 ].insertSubcolumn( level, label )
+
+        # merge columns of this block with the previously parsed columns
+        self.mergeColumns(columns)
+
+        # pick leaf columns (data will be added here)
+        leafColumns = self.pickLeafColumns(columns)
+
+        # elements of the table row corresponding to the header just parsed
+        elements = [line.strip() for line in body]
+
+        if len(elements) != len(leafColumns):
+            raise Exception("Error in the table format: header has {} leaf columns, but the corresponding row has {} elements.".format(len(leafColumns), len(elements)))
+
+        row = collections.OrderedDict()
+        for element, column in zip(elements, leafColumns):
+            path = tuple(column.path)
+            row[path] = element
+        self.tableRows.append(row)
+
+    def pickLeafColumns(self, columns):
+        leafColumns = []
+        for column in columns:
+            column.pickLeafColumns(leafColumns)
+        return leafColumns
+
+    def mergeColumns(self, columns):
+        for col in columns:
+            path = tuple(col.path)
+            if path in self.tableColumns:
+                # merge all column attributes
+                self.tableColumns[path].attributes += " " + col.attributes
+                # merge new subcolumns
+                currentSubPaths = [tuple(col.path) for col in self.tableColumns[path].subcolumns]
+                for subcol in col.subcolumns:
+                    if tuple(subcol.path) not in currentSubPaths:
+                        self.tableColumns[path].subcolumns.append(subcol)
+            else:
+                self.tableColumns[path] = col
+            self.mergeColumns(col.subcolumns)
+
+    def mergeRows(self):
+        # sort table
+        self.tableRows.sort(key=lambda row: list(row.values()))
+
+        i = 0
+        while i < len(self.tableRows) - 1:
+            currentRow = self.tableRows[ i ]
+            nextRow = self.tableRows[ i + 1 ]
+
+            can_merge = True
+            for key, value in nextRow.items():
+                if key in currentRow and currentRow[key] != value:
+                    can_merge = False
+                    break
+            if can_merge is True:
+                currentRow.update(nextRow)
+                self.tableRows.pop(i + 1)
             else:
-               htmlFile.write( "         </tr>\n" )
-               htmlFile.write( "         <tr>\n" )
-               leafColumnsPointer = 0
-         if len( line ) > 1:
-            line = line.lstrip( ' ' )
-            line = line.rstrip( '\n' )
-            leafColumn = self.leafColumns[ leafColumnsPointer ]
-            htmlFile.write( "             <td" )
-            leafColumn.writeFormating( htmlFile, line )
-            htmlFile.write( ">")
-            htmlFile.write( line )
-            htmlFile.write( "</td>\n" )
-            leafColumnsPointer = leafColumnsPointer + 1
-      htmlFile.write( "         </tr>\n" )
-
-   def processSorting( self ):
-      for column in self.leafColumns:
-         column.processSorting()
-
-   def writeHtmlHeader( self, htmlFile, logFile ):
-      htmlFile.write( "<html>\n" )
-      htmlFile.write( "   <body>\n" )
-      htmlFile.write( "      <table border=1>\n")
-      self.initColumnsStructure( logFile )
-      self.countSubcolumns()
-      self.countHeight()
-      self.countRowspan()
-      self.recomputeLevel()
-      self.writeColumnsHeader( htmlFile )
-      self.pickLeafColumns();
-      self.writeTable( logFile, htmlFile )
-      htmlFile.write( "      </table>\n")
-      htmlFile.write( "   </body>\n" )
-      htmlFile.write( "</html>\n" )
-      self.processSorting()
-
-      
+                i += 1
+
+        # TODO: check this
+        # sort again (just in case, previous sorting might compare values from
+        # different columns)
+        self.tableRows.sort(key=lambda row: [getSortKey(value) for value in row.values()])
+
+    def countSubcolumns( self ):
+        for path, col in self.tableColumns.items():
+            if len(path) == 1:
+                col.countSubcolumns();
+
+    def countHeight( self ):
+        for path, col in self.tableColumns.items():
+            if len(path) == 1:
+                col.countHeight();
+
+    def countRowspan( self ):
+        for path, col in self.tableColumns.items():
+            if len(path) == 1:
+                col.countRowspan( self.maxLevel )
+
+    def recomputeLevel( self ):
+        for path, col in self.tableColumns.items():
+            if len(path) == 1:
+                col.recomputeLevel( 1 )
+
+    def processSorting(self):
+        for path, col in self.tableColumns.items():
+            if len(path) == 1:
+                col.processSorting()
+
+    def writeTable(self):
+        self.mergeRows()
+        self.countSubcolumns()
+        self.countHeight()
+        self.countRowspan()
+        self.recomputeLevel()
+#        self.processSorting()
+
+        # write metadata
+        self.writeMetadata()
+
+        self.html += "<table border=1>\n"
+
+        # write header
+        self.writeColumnsHeader()
+
+        # write data
+        firstLevelColumns = [column for path, column in self.tableColumns.items() if len(path) == 1]
+        leafColumns = self.pickLeafColumns(firstLevelColumns)
+        for row in self.tableRows:
+            self.html += "    <tr>\n"
+            # walk through leafColumns to ensure correct order
+            for col in leafColumns:
+                path = tuple(col.path)
+                if path in row:
+                    value = row[path]
+                    formating = col.getFormating(value)
+                    self.html += "        <td {}>{}</td>\n".format(formating, value)
+                else:
+                    self.html += "        <td></td>\n"
+            self.html += "    </tr>\n"
+
+        self.html += "</table>\n"
+
+    def writeMetadata(self):
+        self.html += "<h2>{}</h2>\n".format(self.metadata.get("title"))
+        self.html += "<table border=1>\n"
+        self.html += "<tbody>\n"
+        for key in sorted(self.metadata.keys()):
+            self.html += "    <tr><td>{}</td><td>{}</td></tr>\n".format(key, self.metadata[key])
+        self.html += "</tbody>\n"
+        self.html += "</table>\n"
+
+    def writeColumnsHeader(self):
+        level = 1
+        while level <= self.maxLevel:
+            self.html += "    <tr>\n"
+            for path, column in self.tableColumns.items():
+                self.html += column.getColumnHeader( level )
+            self.html += "    </tr>\n"
+            level += 1
+
+    def writeHtmlHeader(self):
+        self.html += "<html>\n"
+        self.html += "<body>\n"
+
+    def writeHtmlFooter(self):
+        self.html += "</body>\n"
+        self.html += "</html>\n"
+
+
 
 arguments = sys.argv[ 1: ]
 logFile = arguments[ 0 ]
diff --git a/tests/benchmarks/spmv.h b/tests/benchmarks/spmv.h
new file mode 100644
index 0000000000000000000000000000000000000000..00b968f5cdfdf492926047160e202accf12305fb
--- /dev/null
+++ b/tests/benchmarks/spmv.h
@@ -0,0 +1,184 @@
+#pragma once
+
+#include "benchmarks.h"
+
+#include <core/tnlList.h>
+#include <matrices/tnlCSRMatrix.h>
+#include <matrices/tnlEllpackMatrix.h>
+#include <matrices/tnlSlicedEllpackMatrix.h>
+#include <matrices/tnlChunkedEllpackMatrix.h>
+
+namespace tnl
+{
+namespace benchmarks
+{
+
+// silly alias to match the number of template parameters with other formats
+template< typename Real, typename Device, typename Index >
+using SlicedEllpackMatrix = tnlSlicedEllpackMatrix< Real, Device, Index >;
+
+template< typename Matrix >
+int setHostTestMatrix( Matrix& matrix,
+                       const int elementsPerRow )
+{
+    const int size = matrix.getRows();
+    int elements( 0 );
+    for( int row = 0; row < size; row++ ) {
+        int col = row - elementsPerRow / 2;
+        for( int element = 0; element < elementsPerRow; element++ ) {
+            if( col + element >= 0 &&
+                col + element < size )
+            {
+                matrix.setElement( row, col + element, element + 1 );
+                elements++;
+            }
+        }
+    }
+    return elements;
+}
+
+#ifdef HAVE_CUDA
+template< typename Matrix >
+__global__ void setCudaTestMatrixKernel( Matrix* matrix,
+                                         const int elementsPerRow,
+                                         const int gridIdx )
+{
+    const int rowIdx = ( gridIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
+    if( rowIdx >= matrix->getRows() )
+        return;
+    int col = rowIdx - elementsPerRow / 2;
+    for( int element = 0; element < elementsPerRow; element++ ) {
+        if( col + element >= 0 &&
+            col + element < matrix->getColumns() )
+           matrix->setElementFast( rowIdx, col + element, element + 1 );
+    }
+}
+#endif
+
+template< typename Matrix >
+void setCudaTestMatrix( Matrix& matrix,
+                        const int elementsPerRow )
+{
+#ifdef HAVE_CUDA
+    typedef typename Matrix::IndexType IndexType;
+    typedef typename Matrix::RealType RealType;
+    Matrix* kernel_matrix = tnlCuda::passToDevice( matrix );
+    dim3 cudaBlockSize( 256 ), cudaGridSize( tnlCuda::getMaxGridSize() );
+    const IndexType cudaBlocks = roundUpDivision( matrix.getRows(), cudaBlockSize.x );
+    const IndexType cudaGrids = roundUpDivision( cudaBlocks, tnlCuda::getMaxGridSize() );
+    for( IndexType gridIdx = 0; gridIdx < cudaGrids; gridIdx++ ) {
+        if( gridIdx == cudaGrids - 1 )
+            cudaGridSize.x = cudaBlocks % tnlCuda::getMaxGridSize();
+        setCudaTestMatrixKernel< Matrix >
+            <<< cudaGridSize, cudaBlockSize >>>
+            ( kernel_matrix, elementsPerRow, gridIdx );
+        checkCudaDevice;
+    }
+    tnlCuda::freeFromDevice( kernel_matrix );
+#endif
+}
+
+
+// TODO: rename as benchmark_SpMV_synthetic and move to spmv-synthetic.h
+template< typename Real,
+          template< typename, typename, typename > class Matrix,
+          template< typename, typename, typename > class Vector = tnlVector >
+bool
+benchmarkSpMV( Benchmark & benchmark,
+               const int & loops,
+               const int & size,
+               const int elementsPerRow = 5 )
+{
+    typedef Matrix< Real, tnlHost, int > HostMatrix;
+    typedef Matrix< Real, tnlCuda, int > DeviceMatrix;
+    typedef tnlVector< Real, tnlHost, int > HostVector;
+    typedef tnlVector< Real, tnlCuda, int > CudaVector;
+
+    HostMatrix hostMatrix;
+    DeviceMatrix deviceMatrix;
+    tnlVector< int, tnlHost, int > hostRowLengths;
+    tnlVector< int, tnlCuda, int > deviceRowLengths;
+    HostVector hostVector, hostVector2;
+    CudaVector deviceVector, deviceVector2;
+
+    // create benchmark group
+    tnlList< tnlString > parsedType;
+    parseObjectType( HostMatrix::getType(), parsedType );
+    benchmark.createHorizontalGroup( parsedType[ 0 ], 2 );
+
+    if( ! hostRowLengths.setSize( size ) ||
+        ! deviceRowLengths.setSize( size ) ||
+        ! hostMatrix.setDimensions( size, size ) ||
+        ! deviceMatrix.setDimensions( size, size ) ||
+        ! hostVector.setSize( size ) ||
+        ! hostVector2.setSize( size ) ||
+        ! deviceVector.setSize( size ) ||
+        ! deviceVector2.setSize( size ) )
+    {
+        const char* msg = "error: allocation of vectors failed";
+        cerr << msg << endl;
+        benchmark.addErrorMessage( msg, 2 );
+        return false;
+    }
+
+    hostRowLengths.setValue( elementsPerRow );
+    deviceRowLengths.setValue( elementsPerRow );
+
+    if( ! hostMatrix.setCompressedRowsLengths( hostRowLengths ) ) {
+        const char* msg = "error: allocation of host matrix failed";
+        cerr << msg << endl;
+        benchmark.addErrorMessage( msg, 2 );
+        return false;
+    }
+    if( ! deviceMatrix.setCompressedRowsLengths( deviceRowLengths ) ) {
+        const char* msg = "error: allocation of device matrix failed";
+        cerr << msg << endl;
+        benchmark.addErrorMessage( msg, 2 );
+        return false;
+    }
+
+    const int elements = setHostTestMatrix< HostMatrix >( hostMatrix, elementsPerRow );
+    setCudaTestMatrix< DeviceMatrix >( deviceMatrix, elementsPerRow );
+    const double datasetSize = ( double ) loops * elements * ( 2 * sizeof( Real ) + sizeof( int ) ) / oneGB;
+
+    // reset function
+    auto reset = [&]() {
+        hostVector.setValue( 1.0 );
+        deviceVector.setValue( 1.0 );
+        hostVector2.setValue( 0.0 );
+        deviceVector2.setValue( 0.0 );
+    };
+
+    // compute functions
+    auto spmvHost = [&]() {
+        hostMatrix.vectorProduct( hostVector, hostVector2 );
+    };
+    auto spmvCuda = [&]() {
+        deviceMatrix.vectorProduct( deviceVector, deviceVector2 );
+    };
+
+    benchmark.setOperation( datasetSize );
+    benchmark.time( reset,
+                    "CPU", spmvHost,
+                    "GPU", spmvCuda );
+
+    return true;
+}
+
+template< typename Real = double,
+          typename Index = int >
+bool
+benchmarkSpmvSynthetic( Benchmark & benchmark,
+                        const int & loops,
+                        const int & size,
+                        const int & elementsPerRow )
+{
+    // TODO: benchmark all formats from tnl-benchmark-spmv (different parameters of the base formats)
+    benchmarkSpMV< Real, tnlCSRMatrix >( benchmark, loops, size, elementsPerRow );
+    benchmarkSpMV< Real, tnlEllpackMatrix >( benchmark, loops, size, elementsPerRow );
+    benchmarkSpMV< Real, SlicedEllpackMatrix >( benchmark, loops, size, elementsPerRow );
+    benchmarkSpMV< Real, tnlChunkedEllpackMatrix >( benchmark, loops, size, elementsPerRow );
+}
+
+} // namespace benchmarks
+} // namespace tnl
diff --git a/tests/benchmarks/tnl-benchmark-linear-solvers.h b/tests/benchmarks/tnl-benchmark-linear-solvers.h
index 9ec5b34d02b6258a6b2a39a976e62d2f35be32ea..34de4f901017a993d90f099827fe8b4ccd35b220 100644
--- a/tests/benchmarks/tnl-benchmark-linear-solvers.h
+++ b/tests/benchmarks/tnl-benchmark-linear-solvers.h
@@ -49,14 +49,11 @@ void configSetup( tnlConfigDescription& config )
 {
    config.addDelimiter                            ( "General settings:" );
    config.addRequiredEntry< tnlString >( "test" , "Test to be performed." );
-      config.addEntryEnum< tnlString >( "tridiagonal" );
-      config.addEntryEnum< tnlString >( "multidiagonal" );
-      config.addEntryEnum< tnlString >( "multidiagonal-with-long-rows" );
       config.addEntryEnum< tnlString >( "mtx" );
       config.addEntryEnum< tnlString >( "tnl" );
    config.addRequiredEntry< tnlString >( "input-file" , "Input binary file name." );
    config.addEntry< tnlString >( "log-file", "Log file name.", "tnl-benchmark-linear-solvers.log");
-   config.addEntry< tnlString >( "precison", "Precision of the arithmetics.", "double" );
+   config.addEntry< tnlString >( "precision", "Precision of the arithmetics.", "double" );
    config.addEntry< tnlString >( "matrix-format", "Matrix format.", "csr" );
       config.addEntryEnum< tnlString >( "dense" );
       config.addEntryEnum< tnlString >( "tridiagonal" );
diff --git a/tests/benchmarks/tnl-benchmark-simple-heat-equation.h b/tests/benchmarks/tnl-benchmark-simple-heat-equation.h
index 7e540cee0833a51e57ff748f852d19a676b6d3db..b30210815a3303fcc0206510c37a6cecdedf94af 100644
--- a/tests/benchmarks/tnl-benchmark-simple-heat-equation.h
+++ b/tests/benchmarks/tnl-benchmark-simple-heat-equation.h
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <config/tnlConfigDescription.h>
 #include <config/tnlParameterContainer.h>
+#include <core/tnlTimer.h>
 #include <core/tnlTimerRT.h>
 #include <core/tnlCuda.h>
 
@@ -302,7 +303,7 @@ bool solveHeatEquationCuda( const tnlParameterContainer& parameters )
    const Real hy_inv = 1.0 / ( hy * hy );
    if( ! tau )
    {
-      tau = hx * hx < hy * hy ? hx * hx : hy * hy;
+      tau = hx < hy ? hx * hx : hy * hy;
       if( verbose )
          cout << "Setting tau to " << tau << "." << endl;
    }
@@ -447,8 +448,8 @@ bool solveHeatEquationHost( const tnlParameterContainer& parameters )
    /****
     * Initiation
     */   
-   Real* u = new Real[ gridXSize * gridYSize ];
-   Real* aux = new Real[ gridXSize * gridYSize ];
+   Real* __restrict__ u = new Real[ gridXSize * gridYSize ];
+   Real* __restrict__ aux = new Real[ gridXSize * gridYSize ];
    if( ! u || ! aux )
    {
       cerr << "I am not able to allocate grid function for grid size " << gridXSize << "x" << gridYSize << "." << endl;
@@ -461,7 +462,7 @@ bool solveHeatEquationHost( const tnlParameterContainer& parameters )
    const Real hy_inv = 1.0 / ( hy * hy );
    if( ! tau )
    {
-      tau = hx * hx < hy * hy ? hx * hx : hy * hy;
+      tau = hx < hy ? hx * hx : hy * hy;
       if( verbose )
          cout << "Setting tau to " << tau << "." << endl;
    }
@@ -484,13 +485,13 @@ bool solveHeatEquationHost( const tnlParameterContainer& parameters )
     */
    if( verbose )
       cout << "Starting the solver main loop..." << endl;
-   tnlTimerRT timer;
-   timer.reset();
+   tnlTimer timer, computationTimer, updateTimer;
    timer.start();
    Real time( 0.0 );   
    Index iteration( 0 );
    while( time < finalTime )
    {
+      computationTimer.start();
       const Real timeLeft = finalTime - time;
       const Real currentTau = tau < timeLeft ? tau : timeLeft;
 
@@ -524,20 +525,22 @@ bool solveHeatEquationHost( const tnlParameterContainer& parameters )
          for( Index i = 1; i < gridXSize - 1; i++ )
          {
             const Index c = j * gridXSize + i;
-            aux[ c ] = currentTau * ( ( u[ c - 1 ] - 2.0 * u[ c ] + u[ c + 1 ] ) * hx_inv +
+            aux[ c ] =  ( ( u[ c - 1 ] - 2.0 * u[ c ] + u[ c + 1 ] ) * hx_inv +
                                      ( u[ c - gridXSize ] - 2.0 * u[ c ] + u[ c + gridXSize ] ) * hy_inv );
          }
+      computationTimer.stop();
       
-      
-      Real absMax( 0.0 );
+      updateTimer.start();
+      Real absMax( 0.0 ), residue( 0.0 );
       for( Index i = 0; i < dofsCount; i++ )
       {
-         const Real a = fabs( aux[ i ] );
-         absMax = a > absMax ? a : absMax;
+         const Real add = currentTau * aux[ i ];
+         u[ i ] += add;
+         residue += fabs( add );
+         /*const Real a = fabs( aux[ i ] );         
+         absMax = a > absMax ? a : absMax;*/
       }
-      
-      for( Index i = 0; i < dofsCount; i++ )
-         u[ i ] += aux[ i ];         
+      updateTimer.stop();
       
       time += currentTau;
       iteration++;
@@ -547,7 +550,15 @@ bool solveHeatEquationHost( const tnlParameterContainer& parameters )
    timer.stop();
    if( verbose )      
       cout << endl << "Finished..." << endl;
-   cout << "Computation time is " << timer.getTime() << " sec. i.e. " << timer.getTime() / ( double ) iteration << "sec. per iteration." << endl;
+   tnlLogger logger( 72, std::cout );
+   logger.writeSeparator();
+   logger.writeParameter< const char* >( "Compute time:", "" );
+   timer.writeLog( logger, 1 );
+   logger.writeParameter< const char* >( "Explicit update computation:", "" );
+   computationTimer.writeLog( logger, 1 );
+   logger.writeParameter< const char* >( "Euler solver update:", "" );
+   updateTimer.writeLog( logger, 1 );
+   logger.writeSeparator();
    
    /***
     * Freeing allocated memory
diff --git a/tests/benchmarks/tnl-benchmark-spmv.h b/tests/benchmarks/tnl-benchmark-spmv.h
index 2f360605a64acfa4789ab6bfe1a05cd3722c9350..e5850f2f5ade1ffd94a488fe2a66b6ee8231f4f7 100644
--- a/tests/benchmarks/tnl-benchmark-spmv.h
+++ b/tests/benchmarks/tnl-benchmark-spmv.h
@@ -41,16 +41,12 @@ void setupConfig( tnlConfigDescription& config )
 {
    config.addDelimiter                            ( "General settings:" );
    config.addRequiredEntry< tnlString >( "test" , "Test to be performed." );
-      config.addEntryEnum< tnlString >( "tridiagonal" );
-      config.addEntryEnum< tnlString >( "multidiagonal" );
-      config.addEntryEnum< tnlString >( "multidiagonal-with-long-rows" );
       config.addEntryEnum< tnlString >( "mtx" );
       config.addEntryEnum< tnlString >( "tnl" );
    config.addRequiredEntry< tnlString >( "input-file" , "Input file name." );
-   config.addEntry< tnlString >( "log-file", "Log file name.", "tnl-benchmark-linear-solvers.log");
-   config.addEntry< tnlString >( "pdf-file", "PDf file name for the matrix pattern.", "tnl-benchmark.log");
+   config.addEntry< tnlString >( "log-file", "Log file name.", "tnl-benchmark-spmv.log");
    config.addEntry< tnlString >( "precision", "Precision of the arithmetics.", "double" );
-   config.addEntry< double >( "stop-time" ,"Seconds to iterate the SpMV operation.", 1.0 );
+   config.addEntry< double >( "stop-time", "Seconds to iterate the SpMV operation.", 1.0 );
    config.addEntry< int >( "verbose", "Verbose mode.", 1 );
 }
 
diff --git a/tests/benchmarks/tnl-cuda-benchmarks.h b/tests/benchmarks/tnl-cuda-benchmarks.h
index 437420c0df4864951fd34e51190073c1adcaaa29..bccf9ca8cc00d5f499581f06196ab4715e6b8e57 100644
--- a/tests/benchmarks/tnl-cuda-benchmarks.h
+++ b/tests/benchmarks/tnl-cuda-benchmarks.h
@@ -18,292 +18,170 @@
 #ifndef TNLCUDABENCHMARKS_H_
 #define TNLCUDBENCHMARKS_H_
 
-#include <tnlConfig.h>
-#include <core/vectors/tnlVector.h>
-#include <core/tnlTimerRT.h>
-#include <matrices/tnlSlicedEllpackMatrix.h>
-#include <matrices/tnlEllpackMatrix.h>
+#include <core/tnlSystemInfo.h>
+#include <core/tnlCudaDeviceInfo.h>
+#include <config/tnlConfigDescription.h>
+#include <config/tnlParameterContainer.h>
 
-#ifdef HAVE_CUBLAS
-//#include <cublas.h>
-#endif    
+#include "array-operations.h"
+#include "vector-operations.h"
+#include "spmv.h"
 
-template< typename Matrix >
-__global__ void setCudaTestMatrixKernel( Matrix* matrix,
-                                         const int elementsPerRow,
-                                         const int gridIdx )
+using namespace tnl::benchmarks;
+
+
+// TODO: should benchmarks check the result of the computation?
+
+
+template< typename Real >
+void
+runCudaBenchmarks( Benchmark & benchmark,
+                   Benchmark::MetadataMap metadata,
+                   const unsigned & minSize,
+                   const unsigned & maxSize,
+                   const double & sizeStepFactor,
+                   const unsigned & loops,
+                   const unsigned & elementsPerRow )
 {
-   const int rowIdx = ( gridIdx * tnlCuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x;
-   if( rowIdx >= matrix->getRows() )
-      return;
-   int col = rowIdx - elementsPerRow / 2;   
-   for( int element = 0; element < elementsPerRow; element++ )
-   {
-      if( col + element >= 0 &&
-          col + element < matrix->getColumns() )
-         matrix->setElementFast( rowIdx, col + element, element + 1 );
-   }      
+    const tnlString precision = getType< Real >();
+    metadata["precision"] = precision;
+
+    // Array operations
+    benchmark.newBenchmark( tnlString("Array operations (") + precision + ")",
+                            metadata );
+    for( unsigned size = minSize; size <= maxSize; size *= 2 ) {
+        benchmark.setMetadataColumns( Benchmark::MetadataColumns({
+           {"size", size},
+        } ));
+        benchmarkArrayOperations< Real >( benchmark, loops, size );
+    }
+
+    // Vector operations
+    benchmark.newBenchmark( tnlString("Vector operations (") + precision + ")",
+                            metadata );
+    for( unsigned size = minSize; size <= maxSize; size *= sizeStepFactor ) {
+        benchmark.setMetadataColumns( Benchmark::MetadataColumns({
+           {"size", size},
+        } ));
+        benchmarkVectorOperations< Real >( benchmark, loops, size );
+    }
+
+    // Sparse matrix-vector multiplication
+    benchmark.newBenchmark( tnlString("Sparse matrix-vector multiplication (") + precision + ")",
+                            metadata );
+    for( unsigned size = minSize; size <= maxSize; size *= 2 ) {
+        benchmark.setMetadataColumns( Benchmark::MetadataColumns({
+            {"rows", size},
+            {"columns", size},
+            {"elements per row", elementsPerRow},
+        } ));
+        benchmarkSpmvSynthetic< Real >( benchmark, loops, size, elementsPerRow );
+    }
 }
 
-template< typename Matrix >
-void setCudaTestMatrix( Matrix& matrix,
-                        const int elementsPerRow )
+void
+setupConfig( tnlConfigDescription & config )
 {
-   typedef typename Matrix::IndexType IndexType;
-   typedef typename Matrix::RealType RealType;
-   Matrix* kernel_matrix = tnlCuda::passToDevice( matrix );
-   dim3 cudaBlockSize( 256 ), cudaGridSize( tnlCuda::getMaxGridSize() );
-   const IndexType cudaBlocks = roundUpDivision( matrix.getRows(), cudaBlockSize.x );
-   const IndexType cudaGrids = roundUpDivision( cudaBlocks, tnlCuda::getMaxGridSize() );
-   for( IndexType gridIdx = 0; gridIdx < cudaGrids; gridIdx++ )
-   {
-      if( gridIdx == cudaGrids - 1 )
-         cudaGridSize.x = cudaBlocks % tnlCuda::getMaxGridSize();
-      setCudaTestMatrixKernel< Matrix >
-       <<< cudaGridSize, cudaBlockSize >>>
-       ( kernel_matrix, elementsPerRow, gridIdx );
-      checkCudaDevice;
-   }
-   tnlCuda::freeFromDevice( kernel_matrix );
+    config.addDelimiter( "Benchmark settings:" );
+    config.addEntry< tnlString >( "log-file", "Log file name.", "tnl-cuda-benchmarks.log");
+    config.addEntry< tnlString >( "output-mode", "Mode for opening the log file.", "overwrite" );
+    config.addEntryEnum( "append" );
+    config.addEntryEnum( "overwrite" );
+    config.addEntry< tnlString >( "precision", "Precision of the arithmetics.", "double" );
+    config.addEntryEnum( "float" );
+    config.addEntryEnum( "double" );
+    config.addEntryEnum( "all" );
+    config.addEntry< int >( "min-size", "Minimum size of arrays/vectors used in the benchmark.", 100000 );
+    config.addEntry< int >( "max-size", "Minimum size of arrays/vectors used in the benchmark.", 10000000 );
+    config.addEntry< int >( "size-step-factor", "Factor determining the size of arrays/vectors used in the benchmark. First size is min-size and each following size is stepFactor*previousSize, up to max-size.", 2 );
+    config.addEntry< int >( "loops", "Number of iterations for every computation.", 10 );
+    config.addEntry< int >( "elements-per-row", "Number of elements per row of the sparse matrix used in the matrix-vector multiplication benchmark.", 5 );
+    config.addEntry< int >( "verbose", "Verbose mode.", 1 );
 }
 
-int main( int argc, char* argv[] )
+int
+main( int argc, char* argv[] )
 {
 #ifdef HAVE_CUDA
-   
-   typedef double Real;
-   typedef tnlVector< Real, tnlHost > HostVector;
-   typedef tnlVector< Real, tnlCuda > CudaVector;
-
-   
-   /****
-    * The first argument of this program is the size od data set to be reduced.
-    * If no argument is given we use hardcoded default value.
-    */
-   int size = 1 << 22;
-   if( argc > 1 )
-      size = atoi( argv[ 1 ] );
-   int loops = 10;
-   if( argc > 2 )
-      loops = atoi( argv[ 2 ] );
-   
-   
-   
-   const double oneGB = 1024.0 * 1024.0 * 1024.0;
-   double datasetSize = ( double ) ( loops * size ) * sizeof( Real ) / oneGB;
-   
-   HostVector hostVector, hostVector2;
-   CudaVector deviceVector, deviceVector2;
-   hostVector.setSize( size );
-   if( ! deviceVector.setSize( size ) )
-      return EXIT_FAILURE;
-   hostVector2.setLike( hostVector );
-   if( ! deviceVector2.setLike( deviceVector ) )
-      return EXIT_FAILURE;
-
-   hostVector.setValue( 1.0 );
-   deviceVector.setValue( 1.0 );
-   hostVector2.setValue( 1.0 );
-   deviceVector2.setValue( 1.0 );
-
-   tnlTimerRT timer;
-   double bandwidth( 0.0 );
-
-   /*   
-   cout << "Benchmarking CPU-GPU memory bandwidth: ";
-   timer.reset();
-   timer.start();
-   for( int i = 0; i < loops; i++ )
-     deviceVector = hostVector;
-   timer.stop();    
-   bandwidth = datasetSize / timer.getTime();
-   cout << bandwidth << " GB/sec." << endl;
-    
-   cout << "Benchmarking vector addition on CPU: ";
-   timer.reset();
-   timer.start();
-   for( int i = 0; i < loops; i++ )
-     hostVector.addVector( hostVector2 );
-   timer.stop();
-   bandwidth = 2 * datasetSize / timer.getTime();
-   cout << bandwidth << " GB/sec." << endl;
-    
-    cout << "Benchmarking vector addition on GPU: ";
-    timer.reset();
-    timer.start();
-    for( int i = 0; i < loops; i++ )
-      deviceVector.addVector( deviceVector2 );
-    cudaThreadSynchronize();
-    timer.stop();
-    bandwidth = 3 * datasetSize / timer.getTime();
-    cout << bandwidth << " GB/sec." << endl;
-    */
-
-   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: " << bandwidth << " GB/sec, time: " << timer.getTime() << " sec." << 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 << "bandwidth: " << bandwidth << " GB/sec, time: " << timer.getTime() << " sec." << endl;
-   cout << "CPU/GPU speedup: " << timeHost / timeDevice << endl;
-
-   if( resultHost != resultDevice )
-   {
-      cerr << "Error. " << resultHost << " != " << resultDevice << endl;
-      //return EXIT_FAILURE;
-   }
-
-#ifdef HAVE_CUBLAS
-   cout << "Benchmarking scalar product on GPU with Cublas: " << endl;
-   cublasHandle_t handle;
-   cublasCreate( &handle );
-   timer.reset();
-   timer.start();   
-   for( int i = 0; i < loops; i++ )
-      cublasDdot( handle,
-                  size,
-                  deviceVector.getData(), 1,
-                  deviceVector.getData(), 1,
-                  &resultDevice );
-   cudaThreadSynchronize();
-   timer.stop();
-   bandwidth = 2 * datasetSize / timer.getTime();
-   cout << "Time: " << timer.getTime() << " bandwidth: " << bandwidth << " GB/sec." << endl;
-#endif    
-
-   cout << "Benchmarking L2 norm on CPU: ";
-   timer.reset();
-   timer.start();
-   for( int i = 0; i < loops; i++ )
-     resultHost = hostVector.lpNorm( 2.0 );
-   timer.stop();
-   bandwidth = datasetSize / timer.getTime();
-   cout << bandwidth << " GB/sec." << endl;
-    
-   cout << "Benchmarking L2 norm on GPU: " << endl;
-   timer.reset();
-   timer.start();
-   for( int i = 0; i < loops; i++ )
-      resultDevice = deviceVector.lpNorm( 2.0 );
-
-   timer.stop();
-   bandwidth = datasetSize / timer.getTime();
-   cout << "Time: " << timer.getTime() << " bandwidth: " << bandwidth << " GB/sec." << endl;
-   if( resultHost != resultDevice )
-   {
-      cerr << "Error. " << resultHost << " != " << resultDevice << endl;
-      //return EXIT_FAILURE;
-   }
-
-   /*
-   cout << "Benchmarking prefix-sum on CPU ..." << endl;
-   timer.reset();
-   timer.start();
-   hostVector.computePrefixSum();
-   timer.stop();
-   timeHost = timer.getTime();
-   bandwidth = 2 * datasetSize / loops / timer.getTime();
-   cout << "bandwidth: " << bandwidth << " GB/sec, time: " << timer.getTime() << " sec." << endl;
-   
-   cout << "Benchmarking prefix-sum on GPU: ";
-   timer.reset();
-   timer.start();
-   deviceVector.computePrefixSum();
-   timer.stop();
-   timeDevice = timer.getTime();
-   bandwidth = 2 * datasetSize / loops / timer.getTime();
-   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 ) != auxHostVector.getElement( i ) )
-      {
-         cerr << "Error in prefix sum at position " << i << ":  " << hostVector.getElement( i ) << " != " << auxHostVector.getElement( i ) << endl;
-      }
-*/
-   /****
-    * Sliced Ellpack test
-    */
-   const int elementsPerRow( 5 );
-   typedef tnlEllpackMatrix< double, tnlCuda > DeviceMatrix;
-   tnlEllpackMatrix< double, tnlHost > hostMatrix;
-   DeviceMatrix deviceMatrix;
-   tnlVector< int, tnlHost, int > hostRowLengths;
-   tnlVector< int, tnlCuda, int > deviceRowLengths;
-   hostRowLengths.setSize( size );
-   deviceRowLengths.setSize( size );
-   hostMatrix.setDimensions( size, size );
-   deviceMatrix.setDimensions( size, size );
-   hostRowLengths.setValue( elementsPerRow );
-   deviceRowLengths.setValue( elementsPerRow );
-   hostMatrix.setCompressedRowsLengths( hostRowLengths );
-   if( ! deviceMatrix.setCompressedRowsLengths( deviceRowLengths ) )
-   {
-      cerr << "Unable to allocate matrix elements." << endl;
-      return false;
-   }
-   int elements( 0 );
-   for( int row = 0; row < size; row++ )
-   {
-      if( row % 100 == 0 )
-         cout << "Row " << row << "/" << size << "     \r" << flush;
-      int col = row - elementsPerRow / 2;   
-      for( int element = 0; element < elementsPerRow; element++ )
-      {
-         if( col + element >= 0 && col + element < size )
-         {
-            hostMatrix.setElement( row, col + element, element + 1 );
-            //deviceMatrix.setElement( row, col + element, 1.0 );
-            elements++;
-         }
-      }      
-   }
-   cout << endl;
-   setCudaTestMatrix< DeviceMatrix >( deviceMatrix, elementsPerRow );
-   datasetSize = loops * elements * ( 2 * sizeof( Real ) + sizeof( int ) ) / oneGB;
-   hostVector.setValue( 1.0 );
-   deviceVector.setValue( 1.0 );
-   cout << "Benchmarking SpMV on CPU: ";
-   timer.reset();
-   for( int i = 0; i < loops; i++ )
-      hostMatrix.vectorProduct( hostVector, hostVector2 );
-   timer.stop();
-   double hostTime = timer.getTime();
-   bandwidth = datasetSize / timer.getTime();
-   cout << timer.getTime() << " => " << bandwidth << " GB/s" << endl;
-   
-   cout << "Benchmarking SpMV on GPU: ";
-   deviceVector2.setValue( 0.0 );
-   timer.reset();
-   for( int i = 0; i < loops; i++ )
-      deviceMatrix.vectorProduct( deviceVector, deviceVector2 );
-   timer.stop();
-      
-   if( hostVector2 != deviceVector2 )
-      cerr << "Error in Spmv kernel" << endl;
-   
-   bandwidth = datasetSize / timer.getTime();
-   cout << timer.getTime() << " => " << bandwidth << " GB/s" << " speedup " << hostTime / timer.getTime() << endl;
-   
-   return EXIT_SUCCESS;
+    tnlParameterContainer parameters;
+    tnlConfigDescription conf_desc;
+
+    setupConfig( conf_desc );
+
+    if( ! parseCommandLine( argc, argv, conf_desc, parameters ) ) {
+        conf_desc.printUsage( argv[ 0 ] );
+        return 1;
+    }
+
+    const tnlString & logFileName = parameters.getParameter< tnlString >( "log-file" );
+    const tnlString & outputMode = parameters.getParameter< tnlString >( "output-mode" );
+    const tnlString & precision = parameters.getParameter< tnlString >( "precision" );
+    const unsigned minSize = parameters.getParameter< unsigned >( "min-size" );
+    const unsigned maxSize = parameters.getParameter< unsigned >( "max-size" );
+    const unsigned sizeStepFactor = parameters.getParameter< unsigned >( "size-step-factor" );
+    const unsigned loops = parameters.getParameter< unsigned >( "loops" );
+    const unsigned elementsPerRow = parameters.getParameter< unsigned >( "elements-per-row" );
+    const unsigned verbose = parameters.getParameter< unsigned >( "verbose" );
+
+    if( sizeStepFactor <= 1 ) {
+        cerr << "The value of --size-step-factor must be greater than 1." << endl;
+        return EXIT_FAILURE;
+    }
+
+    // open log file
+    auto mode = ios::out;
+    if( outputMode == "append" )
+        mode |= ios::app;
+    ofstream logFile( logFileName.getString(), mode );
+
+    // init benchmark and common metadata
+    Benchmark benchmark( loops, verbose );
+
+    // prepare global metadata
+    tnlSystemInfo systemInfo;
+    const int cpu_id = 0;
+    tnlCacheSizes cacheSizes = systemInfo.getCPUCacheSizes( cpu_id );
+    tnlString cacheInfo = tnlString( cacheSizes.L1data ) + ", "
+                        + tnlString( cacheSizes.L1instruction ) + ", "
+                        + tnlString( cacheSizes.L2 ) + ", "
+                        + tnlString( cacheSizes.L3 );
+    const int activeGPU = tnlCudaDeviceInfo::getActiveDevice();
+    const tnlString deviceArch = tnlString( tnlCudaDeviceInfo::getArchitectureMajor( activeGPU ) ) + "." +
+                                 tnlString( tnlCudaDeviceInfo::getArchitectureMinor( activeGPU ) );
+    Benchmark::MetadataMap metadata {
+        { "host name", systemInfo.getHostname() },
+        { "architecture", systemInfo.getArchitecture() },
+        { "system", systemInfo.getSystemName() },
+        { "system release", systemInfo.getSystemRelease() },
+        { "start time", systemInfo.getCurrentTime() },
+        { "CPU model name", systemInfo.getCPUModelName( cpu_id ) },
+        { "CPU cores", systemInfo.getNumberOfCores( cpu_id ) },
+        { "CPU threads per core", systemInfo.getNumberOfThreads( cpu_id ) / systemInfo.getNumberOfCores( cpu_id ) },
+        { "CPU max frequency (MHz)", systemInfo.getCPUMaxFrequency( cpu_id ) / 1e3 },
+        { "CPU cache sizes (L1d, L1i, L2, L3) (kiB)", cacheInfo },
+        { "GPU name", tnlCudaDeviceInfo::getDeviceName( activeGPU ) },
+        { "GPU architecture", deviceArch },
+        { "GPU CUDA cores", tnlCudaDeviceInfo::getCudaCores( activeGPU ) },
+        { "GPU clock rate (MHz)", (double) tnlCudaDeviceInfo::getClockRate( activeGPU ) / 1e3 },
+        { "GPU global memory (GB)", (double) tnlCudaDeviceInfo::getGlobalMemory( activeGPU ) / 1e9 },
+        { "GPU memory clock rate (MHz)", (double) tnlCudaDeviceInfo::getMemoryClockRate( activeGPU ) / 1e3 },
+        { "GPU memory ECC enabled", tnlCudaDeviceInfo::getECCEnabled( activeGPU ) },
+    };
+
+    if( precision == "all" || precision == "float" )
+        runCudaBenchmarks< float >( benchmark, metadata, minSize, maxSize, sizeStepFactor, loops, elementsPerRow );
+    if( precision == "all" || precision == "double" )
+        runCudaBenchmarks< double >( benchmark, metadata, minSize, maxSize, sizeStepFactor, loops, elementsPerRow );
+
+    if( ! benchmark.save( logFile ) ) {
+        cerr << "Failed to write the benchmark results to file '" << parameters.getParameter< tnlString >( "log-file" ) << "'." << endl;
+        return EXIT_FAILURE;
+    }
+
+    return EXIT_SUCCESS;
+#else
+    tnlCudaSupportMissingMessage;
+    return EXIT_FAILURE;
 #endif
 }
 
diff --git a/tests/benchmarks/vector-operations.h b/tests/benchmarks/vector-operations.h
new file mode 100644
index 0000000000000000000000000000000000000000..3b1b6a614a990fb7d059502e4980c2f552d9ad5b
--- /dev/null
+++ b/tests/benchmarks/vector-operations.h
@@ -0,0 +1,318 @@
+#pragma once
+
+#include "benchmarks.h"
+
+#include <core/vectors/tnlVector.h>
+
+#ifdef HAVE_CUBLAS
+#include "cublasWrappers.h"
+#endif
+
+namespace tnl
+{
+namespace benchmarks
+{
+
+template< typename Real = double,
+          typename Index = int >
+bool
+benchmarkVectorOperations( Benchmark & benchmark,
+                           const int & loops,
+                           const int & size )
+{
+    typedef tnlVector< Real, tnlHost, Index > HostVector;
+    typedef tnlVector< Real, tnlCuda, Index > CudaVector;
+    using namespace std;
+
+    double datasetSize = ( double ) ( loops * size ) * sizeof( Real ) / oneGB;
+
+    HostVector hostVector, hostVector2;
+    CudaVector deviceVector, deviceVector2;
+    if( ! hostVector.setSize( size ) ||
+        ! hostVector2.setSize( size ) ||
+        ! deviceVector.setSize( size ) ||
+        ! deviceVector2.setSize( size ) )
+    {
+        const char* msg = "error: allocation of vectors failed";
+        cerr << msg << endl;
+        benchmark.addErrorMessage( msg );
+        return false;
+    }
+
+    Real resultHost, resultDevice;
+
+#ifdef HAVE_CUBLAS
+    cublasHandle_t cublasHandle;
+    cublasCreate( &cublasHandle );
+#endif
+
+
+    // reset functions
+    // (Make sure to always use some in benchmarks, even if it's not necessary
+    // to assure correct result - it helps to clear cache and avoid optimizations
+    // of the benchmark loop.)
+    auto reset1 = [&]() {
+        hostVector.setValue( 1.0 );
+        deviceVector.setValue( 1.0 );
+        resultHost = resultDevice = 0.0;
+    };
+    auto reset2 = [&]() {
+        hostVector2.setValue( 1.0 );
+        deviceVector2.setValue( 1.0 );
+    };
+    auto reset12 = [&]() {
+        reset1();
+        reset2();
+    };
+
+
+    reset12();
+
+
+    auto multiplyHost = [&]() {
+        hostVector *= 0.5;
+    };
+    auto multiplyCuda = [&]() {
+        deviceVector *= 0.5;
+    };
+#ifdef HAVE_CUBLAS
+    auto multiplyCublas = [&]() {
+        const Real alpha = 0.5;
+        cublasGscal( cublasHandle, size,
+                     &alpha,
+                     deviceVector.getData(), 1 );
+    };
+#endif
+    benchmark.setOperation( "scalar multiplication", 2 * datasetSize );
+    benchmark.time( reset1,
+                    "CPU", multiplyHost,
+                    "GPU", multiplyCuda );
+#ifdef HAVE_CUBLAS
+    benchmark.time( reset1, "cuBLAS", multiplyCublas );
+#endif
+
+
+    auto addVectorHost = [&]() {
+        hostVector.addVector( hostVector2 );
+    };
+    auto addVectorCuda = [&]() {
+        deviceVector.addVector( deviceVector2 );
+    };
+#ifdef HAVE_CUBLAS
+    auto addVectorCublas = [&]() {
+        const Real alpha = 1.0;
+        cublasGaxpy( cublasHandle, size,
+                     &alpha,
+                     deviceVector2.getData(), 1,
+                     deviceVector.getData(), 1 );
+    };
+#endif
+    benchmark.setOperation( "vector addition", 3 * datasetSize );
+    benchmark.time( reset1,
+                    "CPU", addVectorHost,
+                    "GPU", addVectorCuda );
+#ifdef HAVE_CUBLAS
+    benchmark.time( reset1, "cuBLAS", addVectorCublas );
+#endif
+
+
+    auto maxHost = [&]() {
+        resultHost = hostVector.max();
+    };
+    auto maxCuda = [&]() {
+        resultDevice = deviceVector.max();
+    };
+    benchmark.setOperation( "max", datasetSize );
+    benchmark.time( reset1,
+                    "CPU", maxHost,
+                    "GPU", maxCuda );
+
+
+    auto minHost = [&]() {
+        resultHost = hostVector.min();
+    };
+    auto minCuda = [&]() {
+        resultDevice = deviceVector.min();
+    };
+    benchmark.setOperation( "min", datasetSize );
+    benchmark.time( reset1,
+                    "CPU", minHost,
+                    "GPU", minCuda );
+
+
+    auto absMaxHost = [&]() {
+        resultHost = hostVector.absMax();
+    };
+    auto absMaxCuda = [&]() {
+        resultDevice = deviceVector.absMax();
+    };
+#ifdef HAVE_CUBLAS
+    auto absMaxCublas = [&]() {
+        int index = 0;
+        cublasIgamax( cublasHandle, size,
+                      deviceVector.getData(), 1,
+                      &index );
+        resultDevice = deviceVector.getElement( index );
+    };
+#endif
+    benchmark.setOperation( "absMax", datasetSize );
+    benchmark.time( reset1,
+                    "CPU", absMaxHost,
+                    "GPU", absMaxCuda );
+#ifdef HAVE_CUBLAS
+    benchmark.time( reset1, "cuBLAS", absMaxCublas );
+#endif
+
+
+    auto absMinHost = [&]() {
+        resultHost = hostVector.absMin();
+    };
+    auto absMinCuda = [&]() {
+        resultDevice = deviceVector.absMin();
+    };
+#ifdef HAVE_CUBLAS
+    auto absMinCublas = [&]() {
+        int index = 0;
+        cublasIgamin( cublasHandle, size,
+                      deviceVector.getData(), 1,
+                      &index );
+        resultDevice = deviceVector.getElement( index );
+    };
+#endif
+    benchmark.setOperation( "absMin", datasetSize );
+    benchmark.time( reset1,
+                    "CPU", absMinHost,
+                    "GPU", absMinCuda );
+#ifdef HAVE_CUBLAS
+    benchmark.time( reset1, "cuBLAS", absMinCublas );
+#endif
+
+
+    auto sumHost = [&]() {
+        resultHost = hostVector.sum();
+    };
+    auto sumCuda = [&]() {
+        resultDevice = deviceVector.sum();
+    };
+    benchmark.setOperation( "sum", datasetSize );
+    benchmark.time( reset1,
+                    "CPU", sumHost,
+                    "GPU", sumCuda );
+
+
+    auto l1normHost = [&]() {
+        resultHost = hostVector.lpNorm( 1.0 );
+    };
+    auto l1normCuda = [&]() {
+        resultDevice = deviceVector.lpNorm( 1.0 );
+    };
+#ifdef HAVE_CUBLAS
+    auto l1normCublas = [&]() {
+        cublasGasum( cublasHandle, size,
+                     deviceVector.getData(), 1,
+                     &resultDevice );
+    };
+#endif
+    benchmark.setOperation( "l1 norm", datasetSize );
+    benchmark.time( reset1,
+                    "CPU", l1normHost,
+                    "GPU", l1normCuda );
+#ifdef HAVE_CUBLAS
+    benchmark.time( reset1, "cuBLAS", l1normCublas );
+#endif
+
+
+    auto l2normHost = [&]() {
+        resultHost = hostVector.lpNorm( 2.0 );
+    };
+    auto l2normCuda = [&]() {
+        resultDevice = deviceVector.lpNorm( 2.0 );
+    };
+#ifdef HAVE_CUBLAS
+    auto l2normCublas = [&]() {
+        cublasGnrm2( cublasHandle, size,
+                     deviceVector.getData(), 1,
+                     &resultDevice );
+    };
+#endif
+    benchmark.setOperation( "l2 norm", datasetSize );
+    benchmark.time( reset1,
+                    "CPU", l2normHost,
+                    "GPU", l2normCuda );
+#ifdef HAVE_CUBLAS
+    benchmark.time( reset1, "cuBLAS", l2normCublas );
+#endif
+
+
+    auto l3normHost = [&]() {
+        resultHost = hostVector.lpNorm( 3.0 );
+    };
+    auto l3normCuda = [&]() {
+        resultDevice = deviceVector.lpNorm( 3.0 );
+    };
+    benchmark.setOperation( "l3 norm", datasetSize );
+    benchmark.time( reset1,
+                    "CPU", l3normHost,
+                    "GPU", l3normCuda );
+
+
+    auto scalarProductHost = [&]() {
+        resultHost = hostVector.scalarProduct( hostVector2 );
+    };
+    auto scalarProductCuda = [&]() {
+        resultDevice = deviceVector.scalarProduct( deviceVector2 );
+    };
+#ifdef HAVE_CUBLAS
+    auto scalarProductCublas = [&]() {
+        cublasGdot( cublasHandle, size,
+                    deviceVector.getData(), 1,
+                    deviceVector2.getData(), 1,
+                    &resultDevice );
+    };
+#endif
+    benchmark.setOperation( "scalar product", 2 * datasetSize );
+    benchmark.time( reset1,
+                    "CPU", scalarProductHost,
+                    "GPU", scalarProductCuda );
+#ifdef HAVE_CUBLAS
+    benchmark.time( reset1, "cuBLAS", scalarProductCublas );
+#endif
+
+    /*
+    cout << "Benchmarking prefix-sum:" << endl;
+    timer.reset();
+    timer.start();
+    hostVector.computePrefixSum();
+    timer.stop();
+    timeHost = timer.getTime();
+    bandwidth = 2 * datasetSize / loops / timer.getTime();
+    cout << "  CPU: bandwidth: " << bandwidth << " GB/sec, time: " << timer.getTime() << " sec." << endl;
+
+    timer.reset();
+    timer.start();
+    deviceVector.computePrefixSum();
+    timer.stop();
+    timeDevice = timer.getTime();
+    bandwidth = 2 * datasetSize / loops / timer.getTime();
+    cout << "  GPU: 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 ) != auxHostVector.getElement( i ) )
+       {
+          cerr << "Error in prefix sum at position " << i << ":  " << hostVector.getElement( i ) << " != " << auxHostVector.getElement( i ) << endl;
+       }
+    */
+
+#ifdef HAVE_CUBLAS
+    cublasDestroy( cublasHandle );
+#endif
+
+    return true;
+}
+
+} // namespace benchmarks
+} // namespace tnl
diff --git a/tests/long-time-unit-tests/CMakeLists.txt b/tests/long-time-unit-tests/CMakeLists.txt
index e526b0a7f9aa14b93b5845f54066328a988a0488..0cd6161978381eda3fd5e4ec287814ad5c89146d 100755
--- a/tests/long-time-unit-tests/CMakeLists.txt
+++ b/tests/long-time-unit-tests/CMakeLists.txt
@@ -3,10 +3,9 @@ set( ENABLE_CODECOVERAGE )
 SET( headers matrix-formats-test.h )
 
 if( BUILD_CUDA )
-    CUDA_ADD_EXECUTABLE( tnl-test-matrix-formats${mpiExt}${debugExt} ${headers} matrix-formats-test.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+    CUDA_ADD_EXECUTABLE( tnl-test-matrix-formats${mpiExt}${debugExt} ${headers} matrix-formats-test.cu )
 else()
-   ADD_EXECUTABLE( tnl-test-matrix-formats${mpiExt}${debugExt} ${headers} matrix-formats-test.cpp )                                                                   
+   ADD_EXECUTABLE( tnl-test-matrix-formats${mpiExt}${debugExt} ${headers} matrix-formats-test.cpp )
 endif()
 
 TARGET_LINK_LIBRARIES( tnl-test-matrix-formats${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
@@ -20,5 +19,5 @@ INSTALL( TARGETS tnl-test-matrix-formats${debugExt}
 INSTALL( FILES tnl-run-matrix-formats-test
          DESTINATION bin
          PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
-         
-unset( ENABLE_CODECOVERAGE )
\ No newline at end of file
+
+unset( ENABLE_CODECOVERAGE )
diff --git a/tests/unit-tests/core/arrays/CMakeLists.txt b/tests/unit-tests/core/arrays/CMakeLists.txt
index c41c849dfbf30a7dfd96d08239cf5b9852e942b3..ae7df53933a0921f99e5022ac9be2942801b3f1e 100755
--- a/tests/unit-tests/core/arrays/CMakeLists.txt
+++ b/tests/unit-tests/core/arrays/CMakeLists.txt
@@ -11,37 +11,33 @@ TARGET_LINK_LIBRARIES( tnlArrayOperationsTest${mpiExt}${debugExt} ${CPPUNIT_LIBR
 ADD_EXECUTABLE( tnlArrayTest${mpiExt}${debugExt} ${headers} tnlArrayTest.cpp )
 TARGET_LINK_LIBRARIES( tnlArrayTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                            tnl${mpiExt}${debugExt}-${tnlVersion} )
-                                                           
+
 ADD_EXECUTABLE( tnlStaticArrayTest${mpiExt}${debugExt} ${headers} tnlStaticArrayTest.cpp )
 TARGET_LINK_LIBRARIES( tnlStaticArrayTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                            tnl${mpiExt}${debugExt}-${tnlVersion} )
-                                                           
-                                                           
+
+
 ADD_EXECUTABLE( tnlMultiArrayTest${mpiExt}${debugExt} ${headers} tnlMultiArrayTest.cpp )
 TARGET_LINK_LIBRARIES( tnlMultiArrayTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                            tnl${mpiExt}${debugExt}-${tnlVersion} )
 
-             
+
 if( BUILD_CUDA )
-    CUDA_ADD_EXECUTABLE( tnlArrayOperationsTest-cuda${mpiExt}${debugExt} ${headers} tnlArrayOperationsTest.cu 
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+    CUDA_ADD_EXECUTABLE( tnlArrayOperationsTest-cuda${mpiExt}${debugExt} ${headers} tnlArrayOperationsTest.cu )
     TARGET_LINK_LIBRARIES( tnlArrayOperationsTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-${tnlVersion} )
-                                                              
-    CUDA_ADD_EXECUTABLE( tnlArrayTest-cuda${mpiExt}${debugExt} ${headers} tnlArrayTest.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+
+    CUDA_ADD_EXECUTABLE( tnlArrayTest-cuda${mpiExt}${debugExt} ${headers} tnlArrayTest.cu )
     TARGET_LINK_LIBRARIES( tnlArrayTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-${tnlVersion} )
-                                                              
-    CUDA_ADD_EXECUTABLE( tnlStaticArrayTest-cuda${mpiExt}${debugExt} ${headers} tnlStaticArrayTest.cu
-                         OPTIONS -arch sm_20 -shared )
+
+    CUDA_ADD_EXECUTABLE( tnlStaticArrayTest-cuda${mpiExt}${debugExt} ${headers} tnlStaticArrayTest.cu )
     TARGET_LINK_LIBRARIES( tnlStaticArrayTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-${tnlVersion} )
-                                                              
-    CUDA_ADD_EXECUTABLE( tnlMultiArrayTest-cuda${mpiExt}${debugExt} ${headers} tnlMultiArrayTest.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+
+    CUDA_ADD_EXECUTABLE( tnlMultiArrayTest-cuda${mpiExt}${debugExt} ${headers} tnlMultiArrayTest.cu )
     TARGET_LINK_LIBRARIES( tnlMultiArrayTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
-                                                              tnl${mpiExt}${debugExt}-${tnlVersion} )                                                                
-                                                                                                                                                                                                                                                            
+                                                              tnl${mpiExt}${debugExt}-${tnlVersion} )
+
 endif()
-                                                                       
\ No newline at end of file
+
diff --git a/tests/unit-tests/core/cuda/CMakeLists.txt b/tests/unit-tests/core/cuda/CMakeLists.txt
index 89ba567728f52579745333ce341fcfaeef2c503e..c8f59e049a2c19c2672b6a31c030676f04777718 100755
--- a/tests/unit-tests/core/cuda/CMakeLists.txt
+++ b/tests/unit-tests/core/cuda/CMakeLists.txt
@@ -1,19 +1,15 @@
 set( headers tnlCudaTester.h
              tnlCudaReductionTester.h )
-             
+
 if( BUILD_CUDA )
-    CUDA_ADD_EXECUTABLE( tnlCudaTest${mpiExt}${debugExt} ${headers} tnlCudaTest.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+    CUDA_ADD_EXECUTABLE( tnlCudaTest${mpiExt}${debugExt} ${headers} tnlCudaTest.cu )
     TARGET_LINK_LIBRARIES( tnlCudaTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-0.1 )
 
-    CUDA_ADD_EXECUTABLE( tnl-reduction-test${mpiExt}${debugExt} ${headers} reduction-test.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+    CUDA_ADD_EXECUTABLE( tnl-reduction-test${mpiExt}${debugExt} ${headers} reduction-test.cu )
     TARGET_LINK_LIBRARIES( tnl-reduction-test${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
-                                                              tnl${mpiExt}${debugExt}-0.1 )                                                                
+                                                              tnl${mpiExt}${debugExt}-0.1 )
+
 
-                                                                                                                                                                                                                                                            
 endif()
 
-                                                                       
-                                                                       
diff --git a/tests/unit-tests/core/vectors/CMakeLists.txt b/tests/unit-tests/core/vectors/CMakeLists.txt
index 2904e4359243d6b0561c4be42043823568fa7071..3cdb721dee9bc914a86b3281d39b8aa4254df2b0 100755
--- a/tests/unit-tests/core/vectors/CMakeLists.txt
+++ b/tests/unit-tests/core/vectors/CMakeLists.txt
@@ -4,29 +4,25 @@ set( headers tnlVectorTester.h
              tnlStaticVectorTester.h )
 
 if( BUILD_CUDA )
-    CUDA_ADD_EXECUTABLE( tnlVectorOperationsTest-cuda${mpiExt}${debugExt} ${headers} tnlVectorOperationsTest.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+    CUDA_ADD_EXECUTABLE( tnlVectorOperationsTest-cuda${mpiExt}${debugExt} ${headers} tnlVectorOperationsTest.cu )
     TARGET_LINK_LIBRARIES( tnlVectorOperationsTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-0.1 )
-    CUDA_ADD_EXECUTABLE( tnlVectorTest-cuda${mpiExt}${debugExt} ${headers} tnlVectorTest.cu
-                         OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+    CUDA_ADD_EXECUTABLE( tnlVectorTest-cuda${mpiExt}${debugExt} ${headers} tnlVectorTest.cu )
     TARGET_LINK_LIBRARIES( tnlVectorTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
-                                                              tnl${mpiExt}${debugExt}-0.1 )                                                                
-                                                                                                                              
+                                                              tnl${mpiExt}${debugExt}-0.1 )
+
 endif()
 
 
 ADD_EXECUTABLE( tnlVectorOperationsTest${mpiExt}${debugExt} ${headers} tnlVectorOperationsTest.cpp )
 TARGET_LINK_LIBRARIES( tnlVectorOperationsTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
-                                                              tnl${mpiExt}${debugExt}-0.1 )                                                                
+                                                              tnl${mpiExt}${debugExt}-0.1 )
 
 ADD_EXECUTABLE( tnlVectorTest${mpiExt}${debugExt} ${headers} tnlVectorTest.cpp )
 TARGET_LINK_LIBRARIES( tnlVectorTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                            tnl${mpiExt}${debugExt}-0.1 )
-             
+
 ADD_EXECUTABLE( tnlStaticVectorTest${mpiExt}${debugExt} ${headers} tnlStaticVectorTest.cpp )
 TARGET_LINK_LIBRARIES( tnlStaticVectorTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                            tnl${mpiExt}${debugExt}-0.1 )
 
-
-                                                                       
\ No newline at end of file
diff --git a/tests/unit-tests/matrices/CMakeLists.txt b/tests/unit-tests/matrices/CMakeLists.txt
index f8103ab520d567932d2933b7ece302488c5a1f56..a8b1498821728a32fbeaa1ac8418bc2ccbb9fa47 100755
--- a/tests/unit-tests/matrices/CMakeLists.txt
+++ b/tests/unit-tests/matrices/CMakeLists.txt
@@ -9,31 +9,28 @@ ADD_EXECUTABLE( tnlDenseMatrixTest${mpiExt}${debugExt} ${headers} tnlDenseMatrix
 TARGET_LINK_LIBRARIES( tnlDenseMatrixTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-${tnlVersion} )
 
-if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlDenseMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlDenseMatrixTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+if( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnlDenseMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlDenseMatrixTest.cu )
    TARGET_LINK_LIBRARIES( tnlDenseMatrixTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                       tnl${mpiExt}${debugExt}-${tnlVersion} )
-endif()                                                                      
+endif()
 
 ADD_EXECUTABLE( tnlTridiagonalMatrixTest${mpiExt}${debugExt} ${headers} tnlTridiagonalMatrixTest.cpp )
 TARGET_LINK_LIBRARIES( tnlTridiagonalMatrixTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-${tnlVersion} )
 
-if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlTridiagonalMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlTridiagonalMatrixTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+if( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnlTridiagonalMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlTridiagonalMatrixTest.cu )
    TARGET_LINK_LIBRARIES( tnlTridiagonalMatrixTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                       tnl${mpiExt}${debugExt}-${tnlVersion} )
-endif()                                                                      
-                                                                          
+endif()
+
 ADD_EXECUTABLE( tnlMultidiagonalMatrixTest${mpiExt}${debugExt} ${headers} tnlMultidiagonalMatrixTest.cpp )
 TARGET_LINK_LIBRARIES( tnlMultidiagonalMatrixTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-${tnlVersion} )
 
-if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlMultidiagonalMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlMultidiagonalMatrixTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+if( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnlMultidiagonalMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlMultidiagonalMatrixTest.cu )
    TARGET_LINK_LIBRARIES( tnlMultidiagonalMatrixTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                       tnl${mpiExt}${debugExt}-${tnlVersion} )
 endif()
@@ -42,20 +39,18 @@ ADD_EXECUTABLE( tnlEllpackMatrixTest${mpiExt}${debugExt} ${headers} tnlEllpackMa
 TARGET_LINK_LIBRARIES( tnlEllpackMatrixTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-${tnlVersion} )
 
-if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlEllpackMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlEllpackMatrixTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+if( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnlEllpackMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlEllpackMatrixTest.cu )
    TARGET_LINK_LIBRARIES( tnlEllpackMatrixTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                       tnl${mpiExt}${debugExt}-${tnlVersion} )
-endif()                                                                        
-             
+endif()
+
 ADD_EXECUTABLE( tnlSlicedEllpackMatrixTest${mpiExt}${debugExt} ${headers} tnlSlicedEllpackMatrixTest.cpp )
 TARGET_LINK_LIBRARIES( tnlSlicedEllpackMatrixTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-${tnlVersion} )
 
-if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlSlicedEllpackMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlSlicedEllpackMatrixTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+if( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnlSlicedEllpackMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlSlicedEllpackMatrixTest.cu )
    TARGET_LINK_LIBRARIES( tnlSlicedEllpackMatrixTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                       tnl${mpiExt}${debugExt}-${tnlVersion} )
 endif()
@@ -64,21 +59,19 @@ ADD_EXECUTABLE( tnlChunkedEllpackMatrixTest${mpiExt}${debugExt} ${headers} tnlCh
 TARGET_LINK_LIBRARIES( tnlChunkedEllpackMatrixTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-${tnlVersion} )
 
-if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlChunkedEllpackMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlChunkedEllpackMatrixTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+if( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnlChunkedEllpackMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlChunkedEllpackMatrixTest.cu )
    TARGET_LINK_LIBRARIES( tnlChunkedEllpackMatrixTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                       tnl${mpiExt}${debugExt}-${tnlVersion} )
-endif()              
-        
+endif()
+
 ADD_EXECUTABLE( tnlCSRMatrixTest${mpiExt}${debugExt} ${headers} tnlCSRMatrixTest.cpp )
 TARGET_LINK_LIBRARIES( tnlCSRMatrixTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-0.1 )
 
-if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlCSRMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlCSRMatrixTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+if( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnlCSRMatrixTest-cuda${mpiExt}${debugExt} ${headers} tnlCSRMatrixTest.cu )
    TARGET_LINK_LIBRARIES( tnlCSRMatrixTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                       tnl${mpiExt}${debugExt}-0.1 )
-endif()             
-                                                                                     
\ No newline at end of file
+endif()
+
diff --git a/tests/unit-tests/matrices/tnlAdaptiveRgCSRMatrixTester.h b/tests/unit-tests/matrices/tnlAdaptiveRgCSRMatrixTester.h
index 89fe32067057ebb976a356826495e77ebeae0d86..c12c8309244bb78779ccc8ef905916e9182a4ad3 100644
--- a/tests/unit-tests/matrices/tnlAdaptiveRgCSRMatrixTester.h
+++ b/tests/unit-tests/matrices/tnlAdaptiveRgCSRMatrixTester.h
@@ -101,7 +101,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       tnlCSRMatrix< Real > csrMatrix;
       //( "test-matrix:Empty" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:Empty" );
-      this -> setEmptyMatrix( csrMatrix, size );
+      this->setEmptyMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -118,7 +118,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       tnlCSRMatrix< Real > csrMatrix;
       //( "test-matrix:Diagonal" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:Diagonal" );
-      this -> setDiagonalMatrix( csrMatrix, size );
+      this->setDiagonalMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -135,7 +135,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       //( "test-matrix:Tridiagonal" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:Tridiagonal" );
       int size = 12;
-      this -> setTridiagonalMatrix( csrMatrix, size );
+      this->setTridiagonalMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -153,7 +153,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       //( "test-matrix:upperTriangular" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:upperTriangular" );
       const int size = 12;
-      this -> setUpperTriangularMatrix( csrMatrix, size );
+      this->setUpperTriangularMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -171,7 +171,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       //( "test-matrix:full" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:full" );
       const int size = 12;
-      this -> setFullMatrix( csrMatrix, size );
+      this->setFullMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -189,7 +189,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       //( "test-matrix:bcsstk20" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:bcsstk20" );
       const int size = 12;
-      this -> setBcsstk20Matrix( csrMatrix );
+      this->setBcsstk20Matrix( csrMatrix );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -208,7 +208,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       const int size = 35;
       tnlCSRMatrix< Real > csrMatrix;//( "test-matrix:Empty" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:Empty" );
-      this -> setEmptyMatrix( csrMatrix, size );
+      this->setEmptyMatrix( csrMatrix, size );
       if( Device :: getDevice() == tnlHostDevice )
          argcsrMatrix. copyFrom( csrMatrix );
       else
@@ -238,7 +238,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       const int size = 35;
       tnlCSRMatrix< Real > csrMatrix;//( "test-matrix:Diagonal" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:Diagonal" );
-      this -> setDiagonalMatrix( csrMatrix, size );
+      this->setDiagonalMatrix( csrMatrix, size );
       if( Device :: getDevice() == tnlHostDevice )
          argcsrMatrix. copyFrom( csrMatrix );
       else
@@ -267,7 +267,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       const int size = 12;
       tnlCSRMatrix< Real > csrMatrix;//( "test-matrix:TriDiagonal" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:TriDiagonal" );
-      this -> setTridiagonalMatrix( csrMatrix, size );
+      this->setTridiagonalMatrix( csrMatrix, size );
       if( Device :: getDevice() == tnlHostDevice )
          argcsrMatrix. copyFrom( csrMatrix );
       else
@@ -295,7 +295,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       const int size = 12;
       tnlCSRMatrix< Real > csrMatrix;//( "test-matrix:TriDiagonal" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:TriDiagonal" );
-      this -> setUpperTriangularMatrix( csrMatrix, size );
+      this->setUpperTriangularMatrix( csrMatrix, size );
       if( Device :: getDevice() == tnlHostDevice )
          argcsrMatrix. copyFrom( csrMatrix );
       else
@@ -324,7 +324,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
       const int size = 12;
       tnlCSRMatrix< Real > csrMatrix;//( "test-matrix:full" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:full" );
-      this -> setFullMatrix( csrMatrix, size );
+      this->setFullMatrix( csrMatrix, size );
       if( Device :: getDevice() == tnlHostDevice )
          argcsrMatrix. copyFrom( csrMatrix );
       else
@@ -352,7 +352,7 @@ template< class Real, typename Device > class tnlAdaptiveRgCSRMatrixTester : pub
    {
       tnlCSRMatrix< Real > csrMatrix;//( "test-matrix:TriDiagonal" );
       tnlAdaptiveRgCSRMatrix< Real, Device > argcsrMatrix( "test-matrix:TriDiagonal" );
-      this -> setBcsstk20Matrix( csrMatrix );
+      this->setBcsstk20Matrix( csrMatrix );
       if( Device :: getDevice() == tnlHostDevice )
          argcsrMatrix. copyFrom( csrMatrix );
       else
diff --git a/tests/unit-tests/matrices/tnlRgCSRMatrixTester.h b/tests/unit-tests/matrices/tnlRgCSRMatrixTester.h
index 6b24cbb1b2a04e7837a4a28f0ea18963dcdff30d..52c7260ee7b05939194cc48d9b1755937a7f2ab9 100644
--- a/tests/unit-tests/matrices/tnlRgCSRMatrixTester.h
+++ b/tests/unit-tests/matrices/tnlRgCSRMatrixTester.h
@@ -95,7 +95,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       const int size = 12;
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
-      this -> setEmptyMatrix( csrMatrix, size );
+      this->setEmptyMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -111,7 +111,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       const int size = 12;
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
-      this -> setDiagonalMatrix( csrMatrix, size );
+      this->setDiagonalMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -127,7 +127,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
       int size = 12;
-      this -> setTridiagonalMatrix( csrMatrix, size );
+      this->setTridiagonalMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -144,7 +144,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
       const int size = 12;
-      this -> setUpperTriangularMatrix( csrMatrix, size );
+      this->setUpperTriangularMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -161,7 +161,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
       const int size = 12;
-      this -> setUpperTriangularMatrix( csrMatrix, size );
+      this->setUpperTriangularMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -178,7 +178,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
       const int size = 12;
-      this -> setBcsstk20Matrix( csrMatrix );
+      this->setBcsstk20Matrix( csrMatrix );
       argcsrMatrix. copyFrom( csrMatrix );
 
       bool error( false );
@@ -195,7 +195,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       const int size = 35;
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
-      this -> setEmptyMatrix( csrMatrix, size );
+      this->setEmptyMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       tnlVector< T > x, b1, b2;
@@ -214,7 +214,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       const int size = 35;
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
-      this -> setDiagonalMatrix( csrMatrix, size );
+      this->setDiagonalMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       tnlVector< T > x, b1, b2;
@@ -233,7 +233,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       const int size = 12;
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
-      this -> setTridiagonalMatrix( csrMatrix, size );
+      this->setTridiagonalMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       tnlVector< T > x, b1, b2;
@@ -252,7 +252,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       const int size = 12;
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
-      this -> setUpperTriangularMatrix( csrMatrix, size );
+      this->setUpperTriangularMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       tnlVector< T > x, b1, b2;
@@ -271,7 +271,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
       const int size = 12;
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
-      this -> setFullMatrix( csrMatrix, size );
+      this->setFullMatrix( csrMatrix, size );
       argcsrMatrix. copyFrom( csrMatrix );
 
       tnlVector< T > x, b1, b2;
@@ -289,7 +289,7 @@ template< class T > class tnlRgCSRMatrixTester : public CppUnit :: TestCase,
    {
       tnlCSRMatrix< T > csrMatrix;
       tnlRgCSRMatrix< T > argcsrMatrix;
-      this -> setBcsstk20Matrix( csrMatrix );
+      this->setBcsstk20Matrix( csrMatrix );
       argcsrMatrix. copyFrom( csrMatrix );
       const int size = csrMatrix. getRows();
 
diff --git a/tests/unit-tests/operators/diffusion/CMakeLists.txt b/tests/unit-tests/operators/diffusion/CMakeLists.txt
index 44d626a4946483be0ff93bf76fb8515ef02e701c..5ad9a0af6f04b4798a5075bd6cd22b6191dd05a0 100644
--- a/tests/unit-tests/operators/diffusion/CMakeLists.txt
+++ b/tests/unit-tests/operators/diffusion/CMakeLists.txt
@@ -6,9 +6,8 @@ TARGET_LINK_LIBRARIES( tnlOneSidedMeanCurvatureTest${mpiExt}${debugExt} ${CPPUNI
                                                                              tnl${mpiExt}${debugExt}-0.1 )
 
 
-if( BUILD_CUDA )                                                           
-   CUDA_ADD_EXECUTABLE( tnlLinearDiffusionTest-cuda${mpiExt}${debugExt} ${headers} tnlLinearDiffusionTest.cu
-                        OPTIONS ${CUDA_ADD_EXECUTABLE_OPTIONS} )
+if( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( tnlLinearDiffusionTest-cuda${mpiExt}${debugExt} ${headers} tnlLinearDiffusionTest.cu )
    TARGET_LINK_LIBRARIES( tnlLinearDiffusionTest-cuda${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                                           tnl${mpiExt}${debugExt}-0.1 )
    CUDA_ADD_EXECUTABLE( tnlOneSidedMeanCurvatureTest-cuda${mpiExt}${debugExt} ${headers} tnlOneSidedMeanCurvatureTest.cu
diff --git a/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h
index 7a82fed0f79fba18745cc8b8ecb40beaae0bac6b..6b53f3d910a6a962d501fff696d3e3abda7b3bd6 100644
--- a/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h
+++ b/tests/unit-tests/operators/diffusion/tnlOneSidedMeanCurvatureTest.h
@@ -40,7 +40,7 @@ class tnlOneSidedMeanCurvatureTest
       typedef typename ApproximateOperator::RealType RealType;
       typedef typename ApproximateOperator::IndexType IndexType;   
       
-      const IndexType coarseMeshSize[ 3 ] = { 1024, 256, 64 };
+      const IndexType coarseMeshSize[ 3 ] = { 128, 256, 64 };
       
       const RealType  eoc[ 3 ] =       { 2.0,  2.0,  2.0 };
       const RealType  tolerance[ 3 ] = { 0.05, 0.05, 0.05 };
@@ -65,6 +65,8 @@ class tnlOneSidedMeanCurvatureTest
          this->setupMesh( meshSize );
          ApproximateOperator approximateOperator( this->mesh );
          ExactOperatorType exactOperator;
+         approximateOperator.setRegularizationEpsilon( 1.0 );
+         exactOperator.setRegularizationEpsilon( 1.0 );         
          this->performTest( approximateOperator,
                             exactOperator,
                             errors,
@@ -128,7 +130,7 @@ bool setMesh()
 int main( int argc, char* argv[] )
 {
    const bool verbose( true );
-   const bool write( false );
+   const bool write( true );
    
    if( ! setMesh< tnlHost, write, verbose  >() )
       return EXIT_FAILURE;
diff --git a/tests/unit-tests/solver/CMakeLists.txt b/tests/unit-tests/solver/CMakeLists.txt
index 060ba47aea3d8f1669d407114bdf5655397d592c..3c0439ba6f298252acfffa1f7de50565dc945557 100755
--- a/tests/unit-tests/solver/CMakeLists.txt
+++ b/tests/unit-tests/solver/CMakeLists.txt
@@ -4,8 +4,7 @@ set( headers tnlSolverTest.h
              tnlSolverTester.h )
 
 if( BUILD_CUDA )
-    CUDA_ADD_EXECUTABLE( tnlSolverTest${mpiExt}${debugExt} ${headers} tnlSolverTest.cu
-                          OPTIONS ${CUDA_ADD_LIBRARY_OPTIONS} )
+    CUDA_ADD_EXECUTABLE( tnlSolverTest${mpiExt}${debugExt} ${headers} tnlSolverTest.cu )
     TARGET_LINK_LIBRARIES( tnlSolverTest${mpiExt}${debugExt} ${CPPUNIT_LIBRARIES}
                                                               tnl${mpiExt}${debugExt}-0.1 )
 else()
@@ -14,4 +13,4 @@ else()
                                                               tnl${mpiExt}${debugExt}-0.1 )
 endif()
 
-ADD_TEST( tnlSolverTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/tnlSolverTest${mpiExt}${debugExt}  ) 
\ No newline at end of file
+ADD_TEST( tnlSolverTest${mpiExt}${debugExt} ${EXECUTABLE_OUTPUT_PATH}/tnlSolverTest${mpiExt}${debugExt}  ) 
diff --git a/tests/unit-tests/solver/tnlSolverTester.h b/tests/unit-tests/solver/tnlSolverTester.h
index 7f374cf242f6b30151ccd431d52d082ffb6f5b60..2a998cb0bd764150f5c7c687dddfee3b88a8d979 100644
--- a/tests/unit-tests/solver/tnlSolverTester.h
+++ b/tests/unit-tests/solver/tnlSolverTester.h
@@ -47,7 +47,7 @@ class tnlSolverTesterProblem
    void writeProlog( tnlLogger& logger,
                      const tnlParameterContainer& parameters ) const { };
 
-   bool setup( const tnlParameterContainer& parameters ) { this -> dofVector. setSize( 100 ); return true; };
+   bool setup( const tnlParameterContainer& parameters ) { this->dofVector. setSize( 100 ); return true; };
 
    bool setInitialCondition( const tnlParameterContainer& parameters ) { return true; };
 
@@ -55,7 +55,7 @@ class tnlSolverTesterProblem
 
    tnlSolverMonitor< RealType, IndexType >* getSolverMonitor() { return 0; };
 
-   DofVectorType& getDofVector() { return this -> dofVector;};
+   DofVectorType& getDofVector() { return this->dofVector;};
 
    void GetExplicitRHS( const RealType& time,
                         const RealType& tau,
diff --git a/tools/src/functions-benchmark.cpp b/tools/src/functions-benchmark.cpp
index 762ad97cef2baa871913e667ce5b10ad952b922b..45d6d911fb3be06c0411d055738876f6808decfb 100644
--- a/tools/src/functions-benchmark.cpp
+++ b/tools/src/functions-benchmark.cpp
@@ -15,15 +15,13 @@
  *                                                                         *
  ***************************************************************************/
 
-#include <core/tnlTimerRT.h>
-#include <core/tnlTimerCPU.h>
 #include "functions-benchmark.h"
 
 int main( int argc, char* argv[] )
 {
    const long int loops = 1 << 24;
 
-   cout << "Runnning benchmarks in single precision on CPU ... " << endl;
+   std::cout << "Runnning benchmarks in single precision on CPU ... " << std::endl;
    benchmarkAddition< float >( loops );
    benchmarkMultiplication< float >( loops );
    benchmarkDivision< float >( loops );
@@ -32,7 +30,7 @@ int main( int argc, char* argv[] )
    benchmarkExp< float >( loops );
    benchmarkPow< float >( loops );
 
-   cout << "Runnning benchmarks in double precision on CPU ... " << endl;
+   std::cout << "Runnning benchmarks in double precision on CPU ... " << std::endl;
    benchmarkAddition< double >( loops );
    benchmarkMultiplication< float >( loops );
    benchmarkDivision< double >( loops );
diff --git a/tools/src/functions-benchmark.h b/tools/src/functions-benchmark.h
index a9f79a0d1026a979cd42dec69154b057f096d654..e6e34e79836b6d1c7e17b5f72e92c2ce11ecc660 100644
--- a/tools/src/functions-benchmark.h
+++ b/tools/src/functions-benchmark.h
@@ -18,11 +18,15 @@
 #ifndef FUNCTIONSBENCHMARK_H_
 #define FUNCTIONSBENCHMARK_H_
 
+#include <iostream>
 #include <math.h>
 
+#include <core/tnlTimerRT.h>
+#include <core/tnlTimerCPU.h>
+
 template< typename REAL > void benchmarkAddition( long int loops )
 {
-   cout << "Benchmarking addition on CPU ( " << loops << " loops ) ... " << flush;
+   std::cout << "Benchmarking addition on CPU ( " << loops << " loops ) ... " << std::flush;
    tnlTimerCPU cpu_timer;
 
    REAL a1 = 1.2;
@@ -38,12 +42,12 @@ template< typename REAL > void benchmarkAddition( long int loops )
    }
 
    double cpu_time = cpu_timer. getTime();
-   cout << " ( " << a1 + a2 + a3 + a4 << " ) " <<  cpu_time << "secs. " << 4.0 * ( ( double ) loops ) / cpu_time * 1.0e-9 << " GFLOPS." << endl;
+   std::cout << " ( " << a1 + a2 + a3 + a4 << " ) " <<  cpu_time << "secs. " << 4.0 * ( ( double ) loops ) / cpu_time * 1.0e-9 << " GFLOPS." << std::endl;
 }
 
 template< typename REAL > void benchmarkMultiplication( const long int loops )
 {
-   cout << "Benchmarking multiplication on CPU ( " << loops << " loops ) ... " << flush;
+   std::cout << "Benchmarking multiplication on CPU ( " << loops << " loops ) ... " << std::flush;
    tnlTimerCPU cpu_timer;
 
    REAL a1 = 1.0e9;
@@ -62,12 +66,12 @@ template< typename REAL > void benchmarkMultiplication( const long int loops )
    }
 
    double cpu_time = cpu_timer. getTime();
-   cout << " ( " << a1 * a2 * a3 * a4 << " ) " <<  cpu_time << "secs. " << 4.0 * ( ( double ) loops ) / cpu_time * 1.0e-9 << " GFLOPS." << endl;
+   std::cout << " ( " << a1 * a2 * a3 * a4 << " ) " <<  cpu_time << "secs. " << 4.0 * ( ( double ) loops ) / cpu_time * 1.0e-9 << " GFLOPS." << std::endl;
 }
 
 template< typename REAL > void benchmarkDivision( long int loops )
 {
-   cout << "Benchmarking division on CPU ( " << loops << " loops ) ... " << flush;
+   std::cout << "Benchmarking division on CPU ( " << loops << " loops ) ... " << std::flush;
    tnlTimerCPU cpu_timer;
 
    REAL a1( 1.0e9 );
@@ -84,12 +88,12 @@ template< typename REAL > void benchmarkDivision( long int loops )
    }
 
    double cpu_time = cpu_timer. getTime();
-   cout << " ( " << a1 / a2 / a3 / a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops / 2 ) / cpu_time * 1.0e-9 << " GFLOPS." << endl;
+   std::cout << " ( " << a1 / a2 / a3 / a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops / 2 ) / cpu_time * 1.0e-9 << " GFLOPS." << std::endl;
 }
 
 template< typename REAL > void benchmarkSqrt( long int loops )
 {
-   cout << "Benchmarking sqrt on CPU ( " << loops << " loops ) ... " << flush;
+   std::cout << "Benchmarking sqrt on CPU ( " << loops << " loops ) ... " << std::flush;
    tnlTimerCPU cpu_timer;
 
    REAL a1( 1.0e9 );
@@ -106,12 +110,12 @@ template< typename REAL > void benchmarkSqrt( long int loops )
    }
 
    double cpu_time = cpu_timer. getTime();
-   cout << " ( " << a1 + a2 + a3 + a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops / 2 ) / cpu_time * 1.0e-9 << " GFLOPS." << endl;
+   std::cout << " ( " << a1 + a2 + a3 + a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops / 2 ) / cpu_time * 1.0e-9 << " GFLOPS." << std::endl;
 }
 
 template< typename REAL > void benchmarkSin( long int loops )
 {
-   cout << "Benchmarking sin on CPU ( " << loops << " loops ) ... " << flush;
+   std::cout << "Benchmarking sin on CPU ( " << loops << " loops ) ... " << std::flush;
    tnlTimerCPU cpu_timer;
 
    REAL a1( 1.0e9 );
@@ -127,12 +131,12 @@ template< typename REAL > void benchmarkSin( long int loops )
    }
 
    double cpu_time = cpu_timer. getTime();
-   cout << " ( " << a1 + a2 + a3 + a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops ) / cpu_time * 1.0e-9 << " GFLOPS." << endl;
+   std::cout << " ( " << a1 + a2 + a3 + a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops ) / cpu_time * 1.0e-9 << " GFLOPS." << std::endl;
 }
 
 template< typename REAL > void benchmarkExp( long int loops )
 {
-   cout << "Benchmarking exp on CPU ( " << loops << " loops ) ... " << flush;
+   std::cout << "Benchmarking exp on CPU ( " << loops << " loops ) ... " << std::flush;
    tnlTimerCPU cpu_timer;
 
    REAL a1( 1.1 );
@@ -149,12 +153,12 @@ template< typename REAL > void benchmarkExp( long int loops )
    }
 
    double cpu_time = cpu_timer. getTime();
-   cout << " ( " << a1 + a2 + a3 + a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops) / cpu_time * 1.0e-9 << " GFLOPS." << endl;
+   std::cout << " ( " << a1 + a2 + a3 + a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops) / cpu_time * 1.0e-9 << " GFLOPS." << std::endl;
 }
 
 template< typename REAL > void benchmarkPow( long int loops )
 {
-   cout << "Benchmarking pow on CPU ( " << loops << " loops ) ... " << flush;
+   std::cout << "Benchmarking pow on CPU ( " << loops << " loops ) ... " << std::flush;
    tnlTimerCPU cpu_timer;
 
    REAL a1( 1.0e9 );
@@ -171,7 +175,7 @@ template< typename REAL > void benchmarkPow( long int loops )
    }
 
    double cpu_time = cpu_timer. getTime();
-   cout << " ( " << a1 + a2 + a3 + a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops) / cpu_time * 1.0e-9 << " GFLOPS." << endl;
+   std::cout << " ( " << a1 + a2 + a3 + a4 << " ) " << cpu_time << "secs. " << 4.0 * ( ( double ) loops) / cpu_time * 1.0e-9 << " GFLOPS." << std::endl;
 }
 
 
diff --git a/tools/src/tnl-view.cpp b/tools/src/tnl-view.cpp
index 90fd1ce802b967fa533495828e7fadda0249cc9d..f697f74fb1334240c9526a4ea652c49d0ccc3208 100644
--- a/tools/src/tnl-view.cpp
+++ b/tools/src/tnl-view.cpp
@@ -40,7 +40,7 @@ void setupConfig( tnlConfigDescription& config )
    config.addEntry        < double >              ( "scale", "Multiply the function by given number.", 1.0 );
    config.addEntry        < tnlString >           ( "output-format", "Output file format.", "gnuplot" );
       config.addEntryEnum  < tnlString >             ( "gnuplot" );
-      config.addEntryEnum  < tnlString >             ( "vti" );
+      config.addEntryEnum  < tnlString >             ( "vtk" );
    config.addEntry        < int >                 ( "verbose", "Set the verbosity of the program.", 1 );
 
    config.addDelimiter( "Matrix settings:" );
diff --git a/tools/src/tnl-view.h b/tools/src/tnl-view.h
index f6760e202427c399002c76b7e56080d0edadf32b..61d0e1b280abdec440e7dbdbcc7948df125403df 100644
--- a/tools/src/tnl-view.h
+++ b/tools/src/tnl-view.h
@@ -40,14 +40,162 @@ bool getOutputFileName( const tnlString& inputFileName,
       outputFileName += ".gplt";
       return true;
    }
-   else
+   if( outputFormat == "vtk" )
    {
-      cerr << "Unknown file format " << outputFormat << ".";
+      outputFileName += ".vtk";
+      return true;
+   }   
+   cerr << "Unknown file format " << outputFormat << ".";
+   return false;
+}
+
+
+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 );
 }
 
 
+/*<<<<<<< HEAD
 template< typename MeshFunction >
 bool writeMeshFunction( const typename MeshFunction::MeshType& mesh,
                         const tnlString& inputFileName,
@@ -193,6 +341,8 @@ bool setMeshFunction( const Mesh& mesh,
 }
 
 
+=======
+>>>>>>> develop*/
 template< typename Mesh, typename Element, typename Real, typename Index, int Dimensions >
 bool convertObject( const Mesh& mesh,
                     const tnlString& inputFileName,
diff --git a/tools/tnl-compile.in b/tools/tnl-compile.in
index b5bd16e7ae1c88cc5138239211b73170e523a2eb..bf196432c86c188f1f5ac7a5dcc9532af478c8f0 100644
--- a/tools/tnl-compile.in
+++ b/tools/tnl-compile.in
@@ -12,4 +12,5 @@ do
     esac
 done
 
-echo -I@CMAKE_INSTALL_PREFIX@/include/tnl-@tnlVersion@ ${CUDA_FLAGS} ${CXX_STD_FLAGS} ${DEBUG_FLAGS}
\ No newline at end of file
+echo -I@CMAKE_INSTALL_PREFIX@/include/tnl-@tnlVersion@ ${CUDA_FLAGS} ${CXX_STD_FLAGS} ${DEBUG_FLAGS}
+
diff --git a/tools/tnl-quickstart/tnl-quickstart.py b/tools/tnl-quickstart/tnl-quickstart.py
index 7b8d2d755e3c2ef0c23aeee162a290f399ade211..3f1732c6aac2d28f6f3d4cf5031a45cabce7946e 100644
--- a/tools/tnl-quickstart/tnl-quickstart.py
+++ b/tools/tnl-quickstart/tnl-quickstart.py
@@ -60,7 +60,7 @@ def generateMain( problemName, problemBaseName, operatorName ):
     file.write( "#include <solvers/tnlBuildConfigTags.h>\n" )
     file.write( "#include <operators/tnlDirichletBoundaryConditions.h>\n" )
     file.write( "#include <operators/tnlNeumannBoundaryConditions.h>\n" )
-    file.write( "#include <functors/tnlConstantFunction.h>\n" )
+    file.write( "#include <functions/tnlConstantFunction.h>\n" )
     file.write( "#include \"" + problemBaseName + "Problem.h\"\n" )
     file.write( "#include \"" + operatorName + ".h\"\n" )
     file.write( "#include \"" + problemBaseName + "Rhs.h\"\n" )
@@ -356,7 +356,8 @@ def generateProblem( problemName, problemBaseName ):
     file.write( "                     MeshDependentDataType& meshDependentData )\n" )
     file.write( "{\n" )
     file.write( "   const tnlString& initialConditionFile = parameters.getParameter< tnlString >( \"initial-condition\" );\n" )
-    file.write( "   if( ! dofs.load( initialConditionFile ) )\n" )
+    file.write( "   tnlMeshFunction< Mesh > u( mesh, dofs );\n" )
+    file.write( "   if( ! u.boundLoad( initialConditionFile ) )\n" )
     file.write( "   {\n" )
     file.write( "      cerr << \"I am not able to load the initial condition from the file \" << initialConditionFile << \".\" << endl;\n" )
     file.write( "      return false;\n" )
@@ -792,11 +793,15 @@ def generateBuildConfigTags( problemBaseName ):
     file.write( " */\n" )
     file.write( "template<> struct tnlConfigTagIndex< " + problemBaseName + "BuildConfigTag, short int >{ enum { enabled = false }; };\n" )
     file.write( "template<> struct tnlConfigTagIndex< " + problemBaseName + "BuildConfigTag, long int >{ enum { enabled = false }; };\n" )
+    file.write( "\n" )    
+    file.write( "/****\n" )
+    file.write( " * How many dimensions may have the problem to be solved...\n" )
+    file.write( " */\n" )    
+    file.write( "template< int Dimensions > struct tnlConfigTagDimensions< " + problemName + "BuildConfigTag, Dimensions >{ enum { enabled = ( Dimensions == 1 ) }; };\n" )
     file.write( "\n" )
     file.write( "/****\n" )
     file.write( " * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types.\n" )
     file.write( " */\n" )
-    file.write( "\n" )
     file.write( "template< int Dimensions, typename Real, typename Device, typename Index >\n" )
     file.write( "   struct tnlConfigTagMesh< " + problemBaseName + "BuildConfigTag, tnlGrid< Dimensions, Real, Device, Index > >\n" )
     file.write( "      { enum { enabled = tnlConfigTagDimensions< " + problemBaseName + "BuildConfigTag, Dimensions >::enabled  &&\n" )